Skip to content

Commit

Permalink
refactor: add MenuItemImpl utils
Browse files Browse the repository at this point in the history
will be used in the next commit

refactor: move getJavaFieldAsAccessible to main

I also changed the method to not throw by default if the field name could not be found
  • Loading branch information
BrayanDSO committed Dec 10, 2024
1 parent a9b18b6 commit c842d4b
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 16 deletions.
34 changes: 34 additions & 0 deletions AnkiDroid/src/main/java/com/ichi2/anki/utils/Reflection.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Copyright (c) 2024 Brayan Oliveira <[email protected]>
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 3 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.ichi2.anki.utils

import timber.log.Timber
import java.lang.reflect.Field

/**
* @param clazz Java class to get the field
* @param fieldName name of the field
* @return a [Field] with `isAccessible` set to true, or null if the field could not be found
*/
fun getJavaFieldAsAccessible(clazz: Class<*>, fieldName: String): Field? {
val field = clazz.declaredFields.firstOrNull { it.name == fieldName }?.apply {
isAccessible = true
}
if (field == null) {
Timber.d("Could not find field $fieldName in class $clazz")
}
return field
}
30 changes: 30 additions & 0 deletions AnkiDroid/src/main/java/com/ichi2/anki/utils/ext/MenuItemImpl.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
* Copyright (c) 2024 Brayan Oliveira <[email protected]>
*
* This program is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by the Free Software
* Foundation; either version 3 of the License, or (at your option) any later
* version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.ichi2.anki.utils.ext

import androidx.appcompat.view.menu.MenuBuilder
import androidx.appcompat.view.menu.MenuItemImpl
import com.ichi2.anki.utils.getJavaFieldAsAccessible

fun MenuItemImpl.removeSubMenu() {
val subMenuField = getJavaFieldAsAccessible(MenuItemImpl::class.java, "mSubMenu")
subMenuField?.set(this, null)
}

val MenuItemImpl.menu: MenuBuilder get() {
val menuField = getJavaFieldAsAccessible(MenuItemImpl::class.java, "mMenu")
return menuField?.get(this) as MenuBuilder
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import com.bytehamster.lib.preferencesearch.PreferenceItem
import com.bytehamster.lib.preferencesearch.SearchConfiguration
import com.ichi2.anki.RobolectricTest
import com.ichi2.testutils.getJavaFieldAsAccessible
import com.ichi2.anki.utils.getJavaFieldAsAccessible
import org.hamcrest.MatcherAssert.assertThat
import org.hamcrest.Matchers.equalTo
import org.junit.Test
Expand All @@ -45,15 +45,15 @@ class SettingsSearchBarTest : RobolectricTest() {
val prefItemResIdField = getJavaFieldAsAccessible(PreferenceItem::class.java, "resId")

// Get the resIds of the files indexed with `SearchConfiguration.index`
val filesToIndex = filesToIndexField.get(searchConfig) as ArrayList<SearchConfiguration.SearchIndexItem>
val filesToIndex = filesToIndexField?.get(searchConfig) as ArrayList<SearchConfiguration.SearchIndexItem>
val filesResIds = filesToIndex.map {
searchItemResIdField.get(it)
searchItemResIdField?.get(it)
}

// Get the resIds of preferences indexed with `SearchConfiguration.indexItem`
val preferencesToIndex = preferencesToIndexField.get(searchConfig) as ArrayList<PreferenceItem>
val preferencesToIndex = preferencesToIndexField?.get(searchConfig) as ArrayList<PreferenceItem>
val prefItemsResIds = preferencesToIndex.map {
prefItemResIdField.get(it)
prefItemResIdField?.get(it)
}

// Join both lists
Expand Down
11 changes: 0 additions & 11 deletions AnkiDroid/src/test/java/com/ichi2/testutils/ReflectionUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,6 @@ import kotlin.reflect.full.createType
/** For use when checking to see if a KType is equal to another type */
inline fun <reified T> KCallable<*>.isType() = returnType == T::class.createType()

/**
* @param clazz Java class to get the field
* @param fieldName name of the field
* @return a [Field] object with `isAccessible` set to true
*/
fun getJavaFieldAsAccessible(clazz: Class<*>, fieldName: String): Field {
return clazz.getDeclaredField(fieldName).apply {
isAccessible = true
}
}

/**
* @param clazz Java class to get the field
* @param methodName name of the method
Expand Down

0 comments on commit c842d4b

Please sign in to comment.