Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

#13282: Fixes Android Studio Warnings under Kotlin Header #15704

Closed
wants to merge 15 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import com.ichi2.anki.NoteEditor.Companion.intentLaunchedWithImage
import com.ichi2.anki.tests.InstrumentedTest
import com.ichi2.anki.testutil.GrantStoragePermission
import com.ichi2.testutils.Flaky
import com.ichi2.testutils.OS
import junit.framework.TestCase.assertFalse
import org.hamcrest.MatcherAssert
import org.hamcrest.Matchers
Expand All @@ -44,6 +46,7 @@ class NoteEditorIntentTest : InstrumentedTest() {
)

@Test
@Flaky(OS.ALL, "Issue 15707 - java.lang.ArrayIndexOutOfBoundsException: length=0; index=0")
fun launchActivityWithIntent() {
col
val scenario = activityRuleIntent!!.scenario
Expand Down
2 changes: 2 additions & 0 deletions AnkiDroid/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,7 @@
<receiver
android:name="com.ichi2.widget.AnkiDroidWidgetSmall"
android:label="@string/widget_small"
android:enabled="false"
android:exported="true"
>
<intent-filter>
Expand All @@ -516,6 +517,7 @@
<receiver
android:name="com.ichi2.widget.AddNoteWidget"
android:label="@string/menu_add_note"
android:enabled="false"
android:exported="true">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2043,7 +2043,7 @@ abstract class AbstractFlashcardViewer :

/** #6141 - blocks clicking links from executing "touch" gestures.
* COULD_BE_BETTER: Make base class static and move this out of the CardViewer */
internal inner class LinkDetectingGestureDetector() :
internal inner class LinkDetectingGestureDetector :
MyGestureDetector(), ShakeDetector.Listener {
private var shakeDetector: ShakeDetector? = null

Expand Down
23 changes: 11 additions & 12 deletions AnkiDroid/src/main/java/com/ichi2/anki/AnkiActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,11 @@ import android.media.AudioManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.view.*
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.view.Window
import android.view.WindowManager
import android.view.animation.Animation
import android.widget.ProgressBar
import androidx.activity.result.ActivityResultLauncher
Expand All @@ -27,8 +31,10 @@ 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
import androidx.browser.customtabs.CustomTabsIntent.*
import androidx.browser.customtabs.CustomTabsIntent.Builder
import androidx.browser.customtabs.CustomTabsIntent.COLOR_SCHEME_DARK
import androidx.browser.customtabs.CustomTabsIntent.COLOR_SCHEME_LIGHT
import androidx.browser.customtabs.CustomTabsIntent.COLOR_SCHEME_SYSTEM
import androidx.core.app.NotificationCompat
import androidx.core.app.PendingIntentCompat
import androidx.fragment.app.DialogFragment
Expand Down Expand Up @@ -322,15 +328,8 @@ open class AnkiActivity : AppCompatActivity, SimpleMessageDialogListener {

@KotlinCleanup("toast -> snackbar")
open fun openUrl(url: Uri) {
// DEFECT: We might want a custom view for the toast, given i8n may make the text too long for some OSes to
// display the toast
if (!AdaptionUtil.hasWebBrowser(this)) {
@KotlinCleanup("check RTL with concat")
showThemedToast(
this,
resources.getString(R.string.no_browser_notification) + url,
false
)
showSnackbar(getString(R.string.no_browser_msg, url.toString()))
return
}
val toolbarColor = MaterialColors.getColor(this, R.attr.appBarColor, 0)
Expand All @@ -339,7 +338,7 @@ open class AnkiActivity : AppCompatActivity, SimpleMessageDialogListener {
.setToolbarColor(toolbarColor)
.setNavigationBarColor(navBarColor)
.build()
val builder = CustomTabsIntent.Builder(customTabActivityHelper.session)
val builder = Builder(customTabActivityHelper.session)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This shouldn't be imported as we lose context for the containing type

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you recommend reverting the change or is there a preferred approach for handling this? @david-allison

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

revert the change, remove the import if possible

.setShowTitle(true)
.setStartAnimations(this, R.anim.slide_right_in, R.anim.slide_left_out)
.setExitAnimations(this, R.anim.slide_left_in, R.anim.slide_right_out)
Expand Down
3 changes: 1 addition & 2 deletions AnkiDroid/src/main/java/com/ichi2/anki/CardBrowser.kt
Original file line number Diff line number Diff line change
Expand Up @@ -1490,7 +1490,7 @@ open class CardBrowser :

// convenience method for updateCardsInList(...)
private fun updateCardInList(card: Card) {
val cards: MutableList<Card> = java.util.ArrayList(1)
val cards: MutableList<Card> = ArrayList(1)
cards.add(card)
updateCardsInList(cards)
}
Expand Down Expand Up @@ -1773,7 +1773,6 @@ open class CardBrowser :
return v
}

@Suppress("UNCHECKED_CAST")
@KotlinCleanup("Unchecked cast")
private fun bindView(position: Int, v: View) {
// Draw the content in the columns
Expand Down
8 changes: 0 additions & 8 deletions AnkiDroid/src/main/java/com/ichi2/anki/DeckPicker.kt
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,6 @@ import timber.log.Timber
import java.io.File
import java.lang.Runnable
import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.ExperimentalTime
import kotlin.time.measureTimedValue

const val MIGRATION_WAS_LAST_POSTPONED_AT_SECONDS = "secondWhenMigrationWasPostponedLast"
Expand Down Expand Up @@ -599,10 +598,6 @@ open class DeckPicker :
}
}

private fun hasShownAppIntro(): Boolean {
return this.sharedPrefs().getBoolean(IntroductionActivity.INTRODUCTION_SLIDES_SHOWN, false)
}

/**
* Check if the current WebView version is older than the last supported version and if it is,
* inform the developer with a snackbar.
Expand Down Expand Up @@ -1225,7 +1220,6 @@ open class DeckPicker :
}
}

@Suppress("DEPRECATION") // onBackPressed
@Deprecated("Deprecated in Java")
override fun onBackPressed() {
val preferences = baseContext.sharedPrefs()
Expand Down Expand Up @@ -1852,7 +1846,6 @@ open class DeckPicker :
}
negativeButton(R.string.dialog_cancel)
if (AdaptionUtil.hasWebBrowser(this@DeckPicker)) {
@Suppress("DEPRECATION")
neutralButton(text = getColUnsafe.tr.schedulingUpdateMoreInfoButton()) {
this@DeckPicker.openUrl(Uri.parse("https://faqs.ankiweb.net/the-anki-2.1-scheduler.html#updating"))
}
Expand Down Expand Up @@ -2348,7 +2341,6 @@ open class DeckPicker :
MigrationService.start(baseContext)
}

@OptIn(ExperimentalTime::class)
private fun launchShowingHidingEssentialFileMigrationProgressDialog() = lifecycleScope.launch {
while (true) {
MigrationService.flowOfProgress
Expand Down
21 changes: 8 additions & 13 deletions AnkiDroid/src/main/java/com/ichi2/anki/Info.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
package com.ichi2.anki

import android.annotation.SuppressLint
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.view.View
Expand All @@ -31,7 +30,8 @@ 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.utils.AdaptionUtil
import com.ichi2.anki.snackbar.BaseSnackbarBuilderProvider
import com.ichi2.anki.snackbar.SnackbarBuilder
import com.ichi2.utils.IntentUtil.canOpenIntent
import com.ichi2.utils.IntentUtil.tryOpenIntent
import com.ichi2.utils.VersionUtils.appName
Expand All @@ -45,9 +45,13 @@ private const val CHANGE_LOG_URL = "https://docs.ankidroid.org/changelog.html"
/**
* Shows an about box, which is a small HTML page.
*/
class Info : AnkiActivity() {
class Info : AnkiActivity(), BaseSnackbarBuilderProvider {
private lateinit var webView: WebView

override val baseSnackbarBuilder: SnackbarBuilder = {
anchorView = findViewById(R.id.info_buttons)
}

@SuppressLint("SetJavaScriptEnabled")
override fun onCreate(savedInstanceState: Bundle?) {
if (showedActivityFailedScreen(savedInstanceState)) {
Expand Down Expand Up @@ -138,16 +142,7 @@ class Info : AnkiActivity() {
if (url == CHANGE_LOG_URL) {
return false
}
if (!AdaptionUtil.hasWebBrowser(this@Info)) {
// snackbar can't be used here as it's a webview and lack coordinator layout
UIUtils.showThemedToast(
this@Info,
resources.getString(R.string.no_browser_notification) + url,
false
)
} else {
startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(url)))
}
this@Info.openUrl(url)
return true
}

Expand Down
35 changes: 35 additions & 0 deletions AnkiDroid/src/main/java/com/ichi2/anki/IntentHandler.kt
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@
package com.ichi2.anki

import android.app.Activity
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Bundle
import android.os.Message
Expand Down Expand Up @@ -46,6 +48,8 @@ import com.ichi2.utils.Permissions
import com.ichi2.utils.Permissions.hasStorageAccessPermission
import com.ichi2.utils.copyToClipboard
import com.ichi2.utils.trimToLength
import com.ichi2.widget.AddNoteWidget
import com.ichi2.widget.AnkiDroidWidgetSmall
import timber.log.Timber
import java.io.File
import kotlin.math.max
Expand All @@ -72,6 +76,12 @@ class IntentHandler : Activity() {
// #6157 - We want to block actions that need permissions we don't have, but not the default case
// as this requires nothing
val runIfStoragePermissions = { runnable: () -> Unit -> performActionIfStorageAccessible(reloadIntent, action) { runnable() } }

runIfStoragePermissions {
enableWidgets(this)
NavigationDrawerActivity.enablePostShortcut(this)
}

when (getLaunchType(intent)) {
LaunchType.FILE_IMPORT -> runIfStoragePermissions {
handleFileImport(fileIntent, reloadIntent, action)
Expand Down Expand Up @@ -156,6 +166,11 @@ class IntentHandler : Activity() {

private fun handleFileImport(intent: Intent, reloadIntent: Intent, action: String?) {
Timber.i("Handling file import")
if (!hasShownAppIntro()) {
Timber.i("Trying to import a file when the app was not started at all")
showThemedToast(this, R.string.app_not_initialized, false)
return
}
val importResult = handleFileImport(this, intent)
// attempt to delete the downloaded deck if it is a shared deck download import
if (intent.hasExtra(SharedDecksDownloadFragment.EXTRA_IS_SHARED_DOWNLOAD)) {
Expand Down Expand Up @@ -263,6 +278,26 @@ class IntentHandler : Activity() {
return !isInvalidViewIntent(intent)
}

/**
* Enables the widgets if the storage permission is granted. It enables both the small widget
* and the "Add Note" widget by setting their component enabled state to ENABLED.
**/
fun enableWidgets(context: Context) {
val smallWidgetComponentName = ComponentName(context, AnkiDroidWidgetSmall::class.java)
context.packageManager.setComponentEnabledSetting(
smallWidgetComponentName,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP
)

val addNoteWidgetComponentName = ComponentName(context, AddNoteWidget::class.java)
context.packageManager.setComponentEnabledSetting(
addNoteWidgetComponentName,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP
)
}

@VisibleForTesting
@CheckResult
fun getLaunchType(intent: Intent): LaunchType {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

package com.ichi2.anki

import android.content.Context
import android.content.Intent
import android.os.Bundle
import androidx.activity.result.ActivityResult
Expand Down Expand Up @@ -90,3 +91,7 @@ class IntroductionActivity : AnkiActivity() {
const val INTRODUCTION_SLIDES_SHOWN = "IntroductionSlidesShown"
}
}

internal fun Context.hasShownAppIntro(): Boolean {
return sharedPrefs().getBoolean(IntroductionActivity.INTRODUCTION_SLIDES_SHOWN, false)
}
2 changes: 1 addition & 1 deletion AnkiDroid/src/main/java/com/ichi2/anki/ModelFieldEditor.kt
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,7 @@ class ModelFieldEditor : AnkiActivity(), LocaleSelectionDialogHandler {

private suspend fun changeSortField(notetype: NotetypeJson, idx: Int) {
withProgress(resources.getString(R.string.model_field_editor_changing)) {
CollectionManager.withCol {
withCol {
Timber.d("doInBackgroundChangeSortField")
notetypes.set_sort_index(notetype, idx)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,6 @@ abstract class NavigationDrawerActivity :
}
drawerToggle.isDrawerSlideAnimationEnabled = animationEnabled()
drawerLayout.addDrawerListener(drawerToggle)

enablePostShortcut(this)
}

/**
Expand Down
17 changes: 16 additions & 1 deletion AnkiDroid/src/main/java/com/ichi2/anki/NoteEditor.kt
Original file line number Diff line number Diff line change
Expand Up @@ -1227,11 +1227,26 @@ class NoteEditor : AnkiActivity(), DeckSelectionListener, SubtitleListener, Tags
// Send the previewer all our current editing information
val noteEditorBundle = Bundle()
addInstanceStateToBundle(noteEditorBundle)
noteEditorBundle.putBundle("editFields", fieldsAsBundleForPreview)
addFieldsToBundle(noteEditorBundle)
previewer.putExtra("noteEditorBundle", noteEditorBundle)
startActivity(previewer)
}

@NeedsTest("IO fields are passed to the template previewer and the card can be previewed")
private fun addFieldsToBundle(bundle: Bundle) {
val fieldsBundle = if (currentNotetypeIsImageOcclusion()) {
val ioFieldsBundle = Bundle()
fieldsFromSelectedNote.forEachIndexed { index, field ->
val fieldValue = NoteService.convertToHtmlNewline(field[1], shouldReplaceNewlines())
ioFieldsBundle.putString(index.toString(), fieldValue)
}
ioFieldsBundle
} else {
fieldsAsBundleForPreview
}
bundle.putBundle("editFields", fieldsBundle)
}

/**
* finish when sd card is ejected
*/
Expand Down
Loading
Loading