Merge pull request #3492 from kiwix/Issue#3491

Fixed, The File transfer feature does not work in android 12, android 13.
This commit is contained in:
Kelson 2023-10-05 13:01:26 +02:00 committed by GitHub
commit 03b5f3dfce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 163 additions and 17 deletions

View File

@ -19,9 +19,12 @@
package org.kiwix.kiwixmobile.localFileTransfer package org.kiwix.kiwixmobile.localFileTransfer
import applyWithViewHierarchyPrinting import applyWithViewHierarchyPrinting
import com.adevinta.android.barista.interaction.BaristaSleepInteractions
import org.kiwix.kiwixmobile.BaseRobot import org.kiwix.kiwixmobile.BaseRobot
import org.kiwix.kiwixmobile.Findable.ViewId
import org.kiwix.kiwixmobile.Findable.StringId.TextId import org.kiwix.kiwixmobile.Findable.StringId.TextId
import org.kiwix.kiwixmobile.R import org.kiwix.kiwixmobile.R
import org.kiwix.kiwixmobile.testutils.TestUtils
/** /**
* Authored by Ayush Shrivastava on 29/10/20 * Authored by Ayush Shrivastava on 29/10/20
@ -32,7 +35,24 @@ fun localFileTransfer(func: LocalFileTransferRobot.() -> Unit) =
class LocalFileTransferRobot : BaseRobot() { class LocalFileTransferRobot : BaseRobot() {
init { fun assertReceiveFileTitleVisible() {
isVisible(TextId(R.string.receive_files_title)) isVisible(TextId(R.string.receive_files_title))
} }
fun assertSearchDeviceMenuItemVisible() {
isVisible(ViewId(R.id.menu_item_search_devices))
}
fun clickOnSearchDeviceMenuItem() {
clickOn(ViewId(R.id.menu_item_search_devices))
}
fun assertLocalFileTransferScreenVisible() {
BaristaSleepInteractions.sleep(TestUtils.TEST_PAUSE_MS_FOR_DOWNLOAD_TEST.toLong())
assertReceiveFileTitleVisible()
}
fun assertLocalLibraryVisible() {
isVisible(TextId(R.string.library))
}
} }

View File

@ -0,0 +1,120 @@
/*
* Kiwix Android
* Copyright (c) 2023 Kiwix <android.kiwix.org>
* 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 org.kiwix.kiwixmobile.localFileTransfer
import android.Manifest
import android.app.Instrumentation
import android.content.Context
import android.os.Build
import androidx.core.content.edit
import androidx.lifecycle.Lifecycle
import androidx.preference.PreferenceManager
import androidx.test.core.app.ActivityScenario
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.rule.GrantPermissionRule
import androidx.test.uiautomator.UiDevice
import leakcanary.LeakAssertions
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.kiwix.kiwixmobile.R
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
import org.kiwix.kiwixmobile.main.KiwixMainActivity
import org.kiwix.kiwixmobile.nav.destination.library.library
import org.kiwix.kiwixmobile.testutils.RetryRule
import org.kiwix.kiwixmobile.testutils.TestUtils
class LocalFileTransferTest {
@Rule
@JvmField
var retryRule = RetryRule()
private var context: Context? = null
private lateinit var activityScenario: ActivityScenario<KiwixMainActivity>
private val permissions = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
arrayOf(
Manifest.permission.NEARBY_WIFI_DEVICES
)
} else {
arrayOf(
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION
)
}
@Rule
@JvmField
var permissionRules: GrantPermissionRule =
GrantPermissionRule.grant(*permissions)
private val instrumentation: Instrumentation by lazy {
InstrumentationRegistry.getInstrumentation()
}
@Before
fun setup() {
context = instrumentation.targetContext.applicationContext
UiDevice.getInstance(instrumentation).apply {
if (TestUtils.isSystemUINotRespondingDialogVisible(this)) {
TestUtils.closeSystemDialogs(context)
}
waitForIdle()
}
PreferenceManager.getDefaultSharedPreferences(context).edit {
putBoolean(SharedPreferenceUtil.PREF_SHOW_INTRO, false)
putBoolean(SharedPreferenceUtil.PREF_WIFI_ONLY, false)
putBoolean(SharedPreferenceUtil.PREF_IS_TEST, true)
}
activityScenario = ActivityScenario.launch(KiwixMainActivity::class.java).apply {
moveToState(Lifecycle.State.RESUMED)
}
}
@Test
fun localFileTransfer() {
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N_MR1) {
activityScenario.onActivity {
it.navigate(R.id.libraryFragment)
}
library {
assertGetZimNearbyDeviceDisplayed()
clickFileTransferIcon {
assertReceiveFileTitleVisible()
assertSearchDeviceMenuItemVisible()
clickOnSearchDeviceMenuItem()
assertLocalFileTransferScreenVisible()
pressBack()
assertLocalLibraryVisible()
}
}
LeakAssertions.assertNoLeaks()
}
}
@After
fun setIsTestPreference() {
PreferenceManager.getDefaultSharedPreferences(context).edit {
putBoolean(SharedPreferenceUtil.PREF_IS_TEST, false)
}
}
}

View File

@ -31,6 +31,7 @@ import org.junit.Test
import org.kiwix.kiwixmobile.BaseActivityTest import org.kiwix.kiwixmobile.BaseActivityTest
import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil import org.kiwix.kiwixmobile.core.utils.SharedPreferenceUtil
import org.kiwix.kiwixmobile.help.HelpRobot import org.kiwix.kiwixmobile.help.HelpRobot
import org.kiwix.kiwixmobile.localFileTransfer.LocalFileTransferRobot
import org.kiwix.kiwixmobile.nav.destination.library.OnlineLibraryRobot import org.kiwix.kiwixmobile.nav.destination.library.OnlineLibraryRobot
import org.kiwix.kiwixmobile.settings.SettingsRobot import org.kiwix.kiwixmobile.settings.SettingsRobot
import org.kiwix.kiwixmobile.testutils.RetryRule import org.kiwix.kiwixmobile.testutils.RetryRule
@ -72,8 +73,7 @@ class TopLevelDestinationTest : BaseActivityTest() {
} }
clickLibraryOnBottomNav { clickLibraryOnBottomNav {
assertGetZimNearbyDeviceDisplayed() assertGetZimNearbyDeviceDisplayed()
clickFileTransferIcon { clickFileTransferIcon(LocalFileTransferRobot::assertReceiveFileTitleVisible)
}
} }
clickDownloadOnBottomNav(OnlineLibraryRobot::assertLibraryListDisplayed) clickDownloadOnBottomNav(OnlineLibraryRobot::assertLibraryListDisplayed)
clickBookmarksOnNavDrawer { clickBookmarksOnNavDrawer {

View File

@ -16,15 +16,16 @@
* *
*/ */
@file:Suppress("PackageNaming") @file:Suppress("PackageNaming", "DEPRECATION")
package org.kiwix.kiwixmobile.localFileTransfer package org.kiwix.kiwixmobile.localFileTransfer
import android.content.BroadcastReceiver import android.content.BroadcastReceiver
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.net.ConnectivityManager import android.net.NetworkInfo
import android.net.wifi.p2p.WifiP2pDevice import android.net.wifi.p2p.WifiP2pDevice
import android.net.wifi.p2p.WifiP2pManager.EXTRA_NETWORK_INFO
import android.net.wifi.p2p.WifiP2pManager.EXTRA_WIFI_P2P_DEVICE import android.net.wifi.p2p.WifiP2pManager.EXTRA_WIFI_P2P_DEVICE
import android.net.wifi.p2p.WifiP2pManager.EXTRA_WIFI_STATE import android.net.wifi.p2p.WifiP2pManager.EXTRA_WIFI_STATE
import android.net.wifi.p2p.WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION import android.net.wifi.p2p.WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION
@ -33,7 +34,6 @@ import android.net.wifi.p2p.WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION
import android.net.wifi.p2p.WifiP2pManager.WIFI_P2P_STATE_ENABLED import android.net.wifi.p2p.WifiP2pManager.WIFI_P2P_STATE_ENABLED
import android.net.wifi.p2p.WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION import android.net.wifi.p2p.WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION
import android.os.Build import android.os.Build
import org.kiwix.kiwixmobile.core.compat.CompatHelper.Companion.isNetworkAvailable
/** /**
* Helper class for the local file sharing module. * Helper class for the local file sharing module.
@ -43,8 +43,7 @@ import org.kiwix.kiwixmobile.core.compat.CompatHelper.Companion.isNetworkAvailab
*/ */
class KiwixWifiP2pBroadcastReceiver( class KiwixWifiP2pBroadcastReceiver(
private val p2pEventListener: P2pEventListener, private val p2pEventListener: P2pEventListener
private val connectivityManager: ConnectivityManager
) : ) :
BroadcastReceiver() { BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) { override fun onReceive(context: Context, intent: Intent) {
@ -55,16 +54,25 @@ class KiwixWifiP2pBroadcastReceiver(
} }
WIFI_P2P_PEERS_CHANGED_ACTION -> p2pEventListener.onPeersChanged() WIFI_P2P_PEERS_CHANGED_ACTION -> p2pEventListener.onPeersChanged()
WIFI_P2P_CONNECTION_CHANGED_ACTION -> { WIFI_P2P_CONNECTION_CHANGED_ACTION -> {
p2pEventListener.onConnectionChanged(connectivityManager.isNetworkAvailable()) val networkInfo = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
intent.getParcelableExtra(
EXTRA_NETWORK_INFO,
NetworkInfo::class.java
)
} else {
intent.getParcelableExtra(EXTRA_NETWORK_INFO)
}
networkInfo?.let {
p2pEventListener.onConnectionChanged(networkInfo.isConnected)
}
} }
WIFI_P2P_THIS_DEVICE_CHANGED_ACTION -> { WIFI_P2P_THIS_DEVICE_CHANGED_ACTION -> {
val userDevice = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { val userDevice = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
intent.getParcelableArrayExtra( intent.getParcelableExtra(
EXTRA_WIFI_P2P_DEVICE, EXTRA_WIFI_P2P_DEVICE,
WifiP2pDevice::class.java WifiP2pDevice::class.java
)?.get(0) )
} else { } else {
@Suppress("DEPRECATION")
intent.getParcelableExtra(EXTRA_WIFI_P2P_DEVICE) intent.getParcelableExtra(EXTRA_WIFI_P2P_DEVICE)
} }
p2pEventListener.onDeviceChanged(userDevice) p2pEventListener.onDeviceChanged(userDevice)

View File

@ -20,7 +20,6 @@ package org.kiwix.kiwixmobile.localFileTransfer
import android.content.BroadcastReceiver import android.content.BroadcastReceiver
import android.content.Context import android.content.Context
import android.content.IntentFilter import android.content.IntentFilter
import android.net.ConnectivityManager
import android.net.Uri import android.net.Uri
import android.net.wifi.WpsInfo import android.net.wifi.WpsInfo
import android.net.wifi.p2p.WifiP2pConfig import android.net.wifi.p2p.WifiP2pConfig
@ -62,8 +61,7 @@ class WifiDirectManager @Inject constructor(
private val context: Context, private val context: Context,
private val sharedPreferenceUtil: SharedPreferenceUtil, private val sharedPreferenceUtil: SharedPreferenceUtil,
private val alertDialogShower: AlertDialogShower, private val alertDialogShower: AlertDialogShower,
private val manager: WifiP2pManager?, private val manager: WifiP2pManager?
private val connectivityManager: ConnectivityManager
) : ChannelListener, PeerListListener, ConnectionInfoListener, P2pEventListener { ) : ChannelListener, PeerListListener, ConnectionInfoListener, P2pEventListener {
var callbacks: Callbacks? = null var callbacks: Callbacks? = null
@ -98,7 +96,7 @@ class WifiDirectManager @Inject constructor(
} }
private fun registerWifiDirectBroadcastReceiver() { private fun registerWifiDirectBroadcastReceiver() {
receiver = KiwixWifiP2pBroadcastReceiver(this, connectivityManager) receiver = KiwixWifiP2pBroadcastReceiver(this)
// For specifying broadcasts (of the P2P API) that the module needs to respond to // For specifying broadcasts (of the P2P API) that the module needs to respond to
val intentFilter = IntentFilter() val intentFilter = IntentFilter()

View File

@ -74,7 +74,7 @@ class BasicAuthInterceptorTest {
@Test @Test
fun testUrlWithFormattingVariations() { fun testUrlWithFormattingVariations() {
val formattedUrl1 = "https:// {{ BASIC_AUTH_KEY } } @example.com/kiwix/f/somefile.zim" val formattedUrl1 = "https:// {{ BASIC_AUTH_KEY }} @example.com/kiwix/f/somefile.zim"
val formattedUrl2 = "https://{{BASIC_AUTH_KEY}}@example.com/kiwix/f/somefile.zim " val formattedUrl2 = "https://{{BASIC_AUTH_KEY}}@example.com/kiwix/f/somefile.zim "
assertEquals(true, formattedUrl1.isAuthenticationUrl) assertEquals(true, formattedUrl1.isAuthenticationUrl)
assertEquals(true, formattedUrl2.isAuthenticationUrl) assertEquals(true, formattedUrl2.isAuthenticationUrl)