Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • videolan/vlc-android
  • thresh/vlc-android
  • Dekans/vlc-android
  • robUx4/vlc-android
  • tguillem/vlc-android
  • Corbax/vlc-android
  • judeosby/vlc-android
  • chouquette/vlc-android
  • washingtonmurphy93/vlc-android
  • wipawanbeadklang540/vlc-android
  • xcorail/vlc-android
  • Aza/vlc-android
  • Skantes/vlc-android
  • filipjares/vlc-android
  • kazemihabib/vlc-android
  • amq10x/vlc-android
  • qadrian370/vlc-android
  • shivanshs9/vlc-android
  • vitaliyg2/vlc-android
  • orgads/vlc-android
  • rom1v/vlc-android
  • evidence/vlc-android
  • lk888/vlc-android
  • Klaus81/vlc-android
  • EwoutH/vlc-android
  • XilasZ/vlc-android
  • pawelpablo1975/vlc-android
  • uae2ae/vlc-android
  • Garf/vlc-android
  • abetatsunori7/vlc-android
  • ePirat/vlc-android
  • magsoft/vlc-android
  • quink/vlc-android
  • Ektos974/vlc-android
  • CymGen30/vlc-android
  • b1ue/vlc-android
  • alessiavalenti8/vlc-android
  • bars27101982/vlc-android
  • billybanda18/vlc-android
  • dklvip/vlc-android
  • sherylynn/vlc-android
  • ramcoach5/vlc-android
  • takise/vlc-android
  • peibolovedie/vlc-android
  • AMHeijboer/vlc-android
  • dahburj/vlc-android
  • gobennyb/vlc-android
  • masripmasrip824/vlc-android
  • bubu/vlc-android
  • tmk907/vlc-android
  • gorbahaaa/vlc-android
  • govind3321/vlc-android
  • jamieboyer42818/vlc-android
  • mrtakilapop/vlc-android
  • kazikarter90/vlc-android
  • chunyie771/vlc-android
  • nop404/vlc-android
  • hcalzazperz/vlc-android
  • zagwojtek69/vlc-android
  • nikonnick24/vlc-android
  • gmohiuddin215/vlc-android
  • stheinthan31/vlc-android
  • rogelioloreto29/vlc-android
  • philippestcyr5/vlc-android
  • Happyheather20/vlc-android
  • jimbobmcgee/vlc-android
  • mohwie/vlc-android
  • HeartBeat1608/vlc-android
  • jahan/vlc-android
  • Kevo1987/vlc-android
  • rrangel3584/vlc-android
  • xfridrich/vlc-android
  • devswami23/vlc-android
  • Isira-Seneviratne/vlc-android
  • PartyPhone22/vlc-android
  • kmajeshkrishnan/vlc-android
  • ramirotorresjr/vlc-android
  • aaronsalas469/vlc-android
  • arnan.np31/vlc-android
  • hkosacki/vlc-android
  • mg0691872/vlc-android
  • louregni/vlc-android
  • ritmapp/vlc-android
  • diegofn/vlc-android
  • s-ayush2903/vlc-android
  • chrisbohn1984/vlc-android
  • alexandre-janniaux/vlc-android
  • optimumpr/vlc-android
  • chirag-jn/vlc-android
  • e9ab98e991ab/vlc-android
  • suvDev/vlc-android
  • killthelord/vlc-android
  • Phoenix/vlc-android
  • soriyallc/vlc-android
  • tda1009/vlc-android
  • rhstone/vlc-android
  • ltnokiago/vlc-android
  • elbrujo1987/vlc-android
  • m1s4k1/vlc-android
  • mdc/vlc-android
  • arnaudj/vlc-android
  • abhinavmarwaha/vlc-android
  • dali546/vlc-android
  • Jeffset/vlc-android
  • megan30/vlc-android
  • lizhengdao/vlc-android
  • YajTPG/vlc-android
  • halcyon/vlc-android
  • ilya.yanok/vlc-android
  • jeramydhallmon/vlc-android
  • tijoemecano77/vlc-android
  • cjcj125125/vlc-android
  • dejan2609/vlc-android
  • JATIN2111999/vlc-android
  • imrohitkumar/vlc-android
  • sagudev/vlc-android
  • ILoveLin/vlc-android
  • tfighiera/vlc-android
  • snehil101/vlc-android
  • MKornelsen/vlc-android
  • m/vlc-android
  • core1024/vlc-android
  • vadimdolgachev/vlc-android
  • Kk77539/vlc-android
  • linzj/vlc-android
  • dantalian-pv/vlc-android
  • admkhalid/vlc-android
  • yaron/vlc-android
  • kn21091974/vlc-android
  • mylove1302/vlc-android
  • roblav96/vlc-android
  • alabiaga/vlc-android
  • kmnaveen101/vlc-android
  • nikiforoff1407/vlc-android
  • Android-Jester/vlc-android
  • frieda.rtwski/vlc-android
  • glaciers7506/vlc-android
  • rahul-gill/vlc-android
  • gaoxugang/vlc-android
  • Rishavgupta12345/vlc-android
  • dinho991556460/vlc-android
  • lighterowl/vlc-android
  • mary-kate/vlc-android
  • adnank20216/vlc-android
  • anthonylgutierrez79/vlc-android
  • Heliottw/vlc-android
  • mu1zix.ft3/vlc-android
  • yvesmaltais1212/vlc-android
  • ereme/vlc-android
  • jhonypalomino829/vlc-android
  • mx1up/vlc-android
  • sjwaddy/vlc-android
  • MohitMandalia/vlc-android
  • temaershov/vlc-android
  • js6pak/vlc-android
  • mishikallu/vlc-android
  • irfanmumtaz008/vlc-android
  • smurfohrachie/vlc-android
  • Goooler/vlc-android
  • eldo203050/vlc-android
  • dejesuszeus99/vlc-android
  • mfkl/vlc-android
  • Samfun75/vlc-android
  • markg85/vlc-android-ipfs
  • doktamelek911/vlc-android
  • wikwity/vlc-android
  • aangelmaker/vlc-android
  • krawczykradek119/vlc-android
  • ylz18180813163/vlc-android
  • galaxy9sx3/vlc-android
  • huajie2020/vlc-android
  • XuanTung95/vlc-android
  • kl/vlc-android
  • melihyolcu83/vlc-android
  • rt1shnik/vlc-android
  • jerryboy307/vlc-android
  • ikeuzochukwu6/vlc-android
  • patrikgolis/vlc-android
  • Ismavv/vlc-android
  • clementosumo/vlc-android
  • joshlamp66/vlc-android
  • nkmoyonyathiericyounge/vlc-android
  • DanTm99/vlc-android
  • Jeffrow41/vlc-android
  • fromphfr/vlc-android
  • 16project/vlc-android
  • Tomas8874/vlc-android
  • fixxxer87/vlc-android
  • sanjay/vlc-android
  • franciscojrp/vlc-android
  • cashellauswaus23/vlc-android
  • hengwu0/vlc-android
  • naythu2020rain/vlc-android
  • TongtengInhole/vlc-android
  • pupdoggy666/vlc-android
  • jcj921013/vlc-android
  • Gc6026/vlc-android
  • crijojc/vlc-android
  • mdrewight/vlc-android
  • davidhaywood0782/vlc-android
  • jbschtt/vlc-android
  • macfarlandcamel/vlc-android
  • syazairi/vlc-android
  • Commander01/vlc-android
  • baileyterry014/vlc-android
  • rodrickfranklin38/vlc-android
  • diego1245hernb/vlc-android
  • anton.canada/vlc-android
  • egazaekb/vlc-android
  • Marissa111113/vlc-android
  • jeinerbruno2/vlc-android
  • wehnie13/vlc-android
  • ozill87/vlc-android
  • legionfso/vlc-android
  • anazahirajoel/vlc-android
  • naomirojas1227/vlc-android
  • xbao/vlc-android
  • antoni.kozubek/vlc-android
  • pajela8482/vlc-android
  • karlfandango55/vlc-android
  • ruanbester07/vlc-android
  • chigita73/vlc-android
  • giu.pat6/vlc-android
  • Aura/vlc-android
  • marcwabo/vlc-android
  • contact.adgrafix/vlc-android
  • exlaverdad/vlc-android
  • simon.marquis88/vlc-android
  • youngkinsamantha421/vlc-android
  • edgard1161/vlc-android
  • agzx77/vlc-android
  • ha7204993/vlc-android
  • alghazwani.jar.6090/vlc-android
  • zrowton1206/vlc-android
  • darek1979513/vlc-android
  • matthiaskett18198/vlc-android
  • kubadyr77/vlc-android
  • romanstudeny1982/vlc-android
  • kumar107375/vlc-android
  • schong0525/vlc-android
  • Kt/vlc-android
  • jovelyn.esconde125/vlc-android
  • corriemacbarnard/vlc-android
  • apisbg91/vlc-android
  • yyusea/vlc-android
  • protechq88/vlc-android
  • rmangaraman/vlc-android
  • soutomikel/vlc-android
  • goregladaleksej5/vlc-android
  • tao/vlc-android
  • aruiz595/vlc-android
  • horvathpeter1202/vlc-android
  • litteh82/vlc-android
  • kerriochoa96/vlc-android
  • skshemul2022/vlc-android
  • popy/vlc-android
  • mizadpanahdev/vlc-android
  • pinarim2035/vlc-android
  • davidgooch1127/vlc-android
  • NyanCatTW1/vlc-android
  • Pendynurcahyo/vlc-android
  • fcartegnie/vlc-android
  • xiaoxiao921/vlc-android
  • rjtoell/vlc-android
  • devanshu6445/vlc-android
  • DopeDo69/vlc-android
  • quimsical/vlc-android
  • nickita.koltsoff/vlc-android
  • zeestander8617/vlc-android
  • alexsonarin06/vlc-android
  • minh189999h/vlc-android
  • JonnycatMeow/vlc-android
  • pup.ragnarok.1984/vlc-android2
  • jlcalderon13/vlc-android
  • franciszekk51214/vlc-android
  • yinsheng996/vlc-android
  • KenN3RD/vlc-android
  • leogps/vlc-android
  • alicuteo0407/vlc-android
  • MessirVoland/vlc-android
  • brett2uk/vlc-android
  • thomas.hermes/vlc-android
  • dgyudin/vlc-android
  • anuoshemohammad/vlc-android
  • r7truong/vlc-android
  • aaa1115910/vlc-android
  • arunkennedy78/vlc-android
  • nicholaszarra0069/vlc-android
  • georgipetrovdochev/vlc-android
  • Nikhil-z/vlc-android
  • misb1033/vlc-android
  • ktcoooot1/vlc-android
  • manmuc5/vlc-android
  • ahwhatisinttaken/vlc-android
  • m.nozka90/vlc-android
  • kabeermuhammad124319/vlc-android
  • ANGELONCE/vlc-android
  • manstabuk/vlc-android
  • yajcoca/vlc-android
  • dreamscell83/vlc-android
  • oldsssteveo/vlc-android
  • c0ff330k/vlc-android
  • ZhangXinmin528/vlc-android
  • lacsimarnald09/vlc-android
  • boykaisaac758/vlc-android
  • ooseidesmond/vlc-android
  • andresbott/vlc-android
  • yolandawanttoplay/vlc-android
  • lapaz17/vlc-android
  • sillyearl0138/vlc-android
  • NF-Repo/vlc-android
  • aaasg4001/vlc-android
  • mongia.puneet/vlc-android
  • slablaykon/vlc-android
  • Shabgardtanha1111/vlc-android
  • Benjamin_Loison/vlc-android
  • ashishami2002/vlc-android
  • Niram7777/vlc-android
  • Yashraj254/vlc-android
  • Choucroute_melba/vlc-android
  • Soete/vlc-android
  • MangalK/vlc-android
  • mohak2003/vlc-android
  • advait-0/vlc-android
  • McLP/vlc-android
  • fhuber/vlc-android
  • sami-sweng/vlc-android
  • josiahcarlson/vlc-android
328 results
Show changes
Showing
with 797 additions and 71 deletions
......@@ -3,8 +3,6 @@ package org.videolan.vlc.gui.preferences
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.intent.rule.IntentsTestRule
import androidx.test.espresso.matcher.ViewMatchers.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.ObsoleteCoroutinesApi
import org.hamcrest.Matchers.equalTo
import org.junit.Rule
import org.junit.Test
......@@ -12,12 +10,8 @@ import org.videolan.tools.*
import org.videolan.vlc.BuildConfig
import org.videolan.vlc.PreferenceMatchers.withKey
import org.videolan.vlc.R
import org.videolan.vlc.gui.helpers.UiTools
import org.videolan.vlc.onPreferenceRow
import org.videolan.vlc.util.*
@ExperimentalCoroutinesApi
@ObsoleteCoroutinesApi
class PreferencesUIUITest: BasePreferenceUITest() {
@get:Rule
val intentsTestRule = IntentsTestRule(PreferencesActivity::class.java)
......@@ -67,7 +61,7 @@ class PreferencesUIUITest: BasePreferenceUITest() {
@Test
fun checkLocaleSetting() {
val lp = LocaleUtils.getLocalesUsedInProject(context, BuildConfig.TRANSLATION_ARRAY, context.getString(R.string.device_default))
val lp = LocaleUtils.getLocalesUsedInProject(BuildConfig.TRANSLATION_ARRAY, context.getString(R.string.device_default))
val lpEntries = lp.localeEntries
val lpValues = lp.localeEntryValues
......@@ -108,7 +102,7 @@ class PreferencesUIUITest: BasePreferenceUITest() {
@Test
fun checkVideoPlaylistMode() {
val key = FORCE_PLAY_ALL
val key = PLAYLIST_MODE_VIDEO
checkToggleWorks(key, settings)
}
......
......@@ -4,8 +4,6 @@ import android.os.Build
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.intent.rule.IntentsTestRule
import androidx.test.filters.SdkSuppress
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.ObsoleteCoroutinesApi
import org.junit.Rule
import org.junit.Test
import org.videolan.tools.*
......@@ -14,8 +12,6 @@ import org.videolan.vlc.R
import org.videolan.vlc.onPreferenceRow
import org.videolan.vlc.util.*
@ExperimentalCoroutinesApi
@ObsoleteCoroutinesApi
class PreferencesVideoUITest: BasePreferenceUITest() {
@get:Rule
val intentsTestRule = IntentsTestRule(PreferencesActivity::class.java)
......@@ -47,12 +43,6 @@ class PreferencesVideoUITest: BasePreferenceUITest() {
checkToggleWorks(key, settings, default = false)
}
@Test
fun checkFastSeekMediaSetting() {
val key = "media_fast_seek"
checkToggleWorks(key, settings)
}
@Test
fun checkVideoTitleOnTransitionSetting() {
val key = "video_transition_show"
......
/*
* ************************************************************************
* DpadHelper.kt
* *************************************************************************
* Copyright © 2020 VLC authors and VideoLAN
* Author: Nicolas POMEPUY
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
* **************************************************************************
*
*
*/
package org.videolan.vlc.util
import android.os.SystemClock
import android.view.KeyEvent
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.Direction
import androidx.test.uiautomator.UiDevice
object DpadHelper {
private val device: UiDevice by lazy { UiDevice.getInstance(InstrumentationRegistry.getInstrumentation()) }
fun pressDPad(direction: Direction?, nbTimes: Int = 1) {
for (i in 0 until nbTimes) {
when (direction) {
Direction.DOWN -> device.pressDPadDown()
Direction.LEFT -> device.pressDPadLeft()
Direction.UP -> device.pressDPadUp()
Direction.RIGHT -> device.pressDPadRight()
else -> {}
}
if (i < nbTimes - 1) SystemClock.sleep(300)
}
}
fun pressHome() = device.pressHome()
fun pressPip() = device.pressKeyCode(KeyEvent.KEYCODE_WINDOW)
fun pressStop() = device.pressKeyCode(KeyEvent.KEYCODE_MEDIA_STOP)
fun pressBack() = device.pressBack()
fun pressDPadCenter() = device.pressDPadCenter()
}
\ No newline at end of file
......@@ -21,6 +21,8 @@
package org.videolan.vlc.util
import androidx.lifecycle.LiveData
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.onEach
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
......@@ -43,6 +45,20 @@ fun <T> getValue(liveData: LiveData<T>): T {
}
latch.await(2, TimeUnit.SECONDS)
@Suppress("UNCHECKED_CAST")
return data[0] as T
}
@Throws(InterruptedException::class)
fun <T> getValue(liveData: Flow<T>): T {
val data = arrayOfNulls<Any>(1)
val latch = CountDownLatch(1)
liveData.onEach { o ->
data[0] = o
latch.countDown()
}
latch.await(2, TimeUnit.SECONDS)
@Suppress("UNCHECKED_CAST")
return data[0] as T
}
\ No newline at end of file
/*
* ************************************************************************
* ScreenshotUtil.kt
* *************************************************************************
* Copyright © 2020 VLC authors and VideoLAN
* Author: Nicolas POMEPUY
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
* **************************************************************************
*
*
*/
package org.videolan.vlc.util
import tools.fastlane.screengrab.Screengrab
object ScreenshotUtil {
fun takeScreenshot(number:Int, title:String) {
Screengrab.screenshot("${normalizeNumber(number)}_$title")
}
private fun normalizeNumber(number:Int) = if (number < 10) "0$number" else "$number"
}
\ No newline at end of file
......@@ -21,11 +21,10 @@
package org.videolan.vlc.util
import android.net.Uri
import androidx.core.net.toUri
import org.videolan.libvlc.interfaces.IMedia
import org.videolan.resources.TYPE_LOCAL_FAV
import org.videolan.resources.TYPE_NETWORK_FAV
import org.videolan.resources.opensubtitles.OpenSubtitle
import org.videolan.resources.opensubtitles.QueryParameters
import org.videolan.vlc.gui.dialogs.State
import org.videolan.vlc.gui.dialogs.SubtitleItem
......@@ -46,7 +45,7 @@ object TestUtil {
fun createLocalFavs(count: Int): List<org.videolan.vlc.mediadb.models.BrowserFav> {
return (0 until count).map {
createLocalFav(Uri.parse("${fakeMediaUri}_$it.mp4"), "local$it", null)
createLocalFav("${fakeMediaUri}_$it.mp4".toUri(), "local$it", null)
}
}
......@@ -61,7 +60,7 @@ object TestUtil {
fun createNetworkFavs(count: Int): List<org.videolan.vlc.mediadb.models.BrowserFav> {
return (0 until count).map {
createNetworkFav(
Uri.parse(fakeUri + "network" + it),
"${fakeUri}network${it}".toUri(),
"network" + 1,
null)
}
......@@ -74,12 +73,12 @@ object TestUtil {
mediaPath: String,
subLanguageID: String,
movieReleaseName: String): org.videolan.vlc.mediadb.models.ExternalSub {
return org.videolan.vlc.mediadb.models.ExternalSub(idSubtitle, subtitlePath, mediaPath, subLanguageID, movieReleaseName)
return org.videolan.vlc.mediadb.models.ExternalSub(idSubtitle, subtitlePath, mediaPath, subLanguageID, movieReleaseName, false)
}
fun createExternalSubsForMedia(mediaPath: String, mediaName: String, count: Int): List<org.videolan.vlc.mediadb.models.ExternalSub> {
return (0 until count).map {
org.videolan.vlc.mediadb.models.ExternalSub(it.toString(), "${fakeSubUri}$mediaName$it", mediaPath, "en", mediaName)
org.videolan.vlc.mediadb.models.ExternalSub(it.toString(), "${fakeSubUri}$mediaName$it", mediaPath, "en", mediaName, false)
}
}
......@@ -109,26 +108,6 @@ object TestUtil {
mediaUri: Uri,
subLanguageID: String,
movieReleaseName: String,
zipDownloadLink: String): SubtitleItem = SubtitleItem(idSubtitle, mediaUri, subLanguageID, movieReleaseName, State.Downloading, zipDownloadLink)
zipDownloadLink: String): SubtitleItem = SubtitleItem(idSubtitle, -1L, mediaUri, subLanguageID, movieReleaseName, State.Downloading, zipDownloadLink, false, 0F, 0L, "")
fun createDownloadingSubtitleItem(
idSubtitle: String,
mediaPath: String,
subLanguageID: String,
movieReleaseName: String,
zipDownloadLink: String): SubtitleItem = TestUtil.createDownloadingSubtitleItem(idSubtitle, Uri.parse(mediaPath), subLanguageID, movieReleaseName, zipDownloadLink)
fun createOpenSubtitle(
idSubtitle: String,
subLanguageID: String,
movieReleaseName: String,
zipDownloadLink: String) = OpenSubtitle(
idSubtitle = idSubtitle, subLanguageID = subLanguageID, movieReleaseName = movieReleaseName, zipDownloadLink = zipDownloadLink,
idMovie = "", idMovieImdb = "", idSubMovieFile = "", idSubtitleFile = "", infoFormat = "", infoOther = "", infoReleaseGroup = "",
userID = "", iSO639 = "", movieFPS = "", languageName = "", subActualCD = "", subSumVotes = "", subAuthorComment = "", subComments = "",
score = 0.0, seriesEpisode = "", seriesIMDBParent = "", seriesSeason = "", subAddDate = "", subAutoTranslation = "", subBad = "", subDownloadLink = "",
subDownloadsCnt = "", subEncoding = "", subFeatured = "", subFileName = "", subForeignPartsOnly = "", subFormat = "", subFromTrusted = "", subHash = "",
subHD = "", subHearingImpaired = "", subLastTS = "", subRating = "", subSize = "", subSumCD = "", subtitlesLink = "", subTranslator = "", subTSGroup = "",
subTSGroupHash = "", movieByteSize = "", movieHash = "", movieTimeMS = "", queryParameters = QueryParameters("", "", ""), queryNumber = "",
userNickName = "", userRank = "", matchedBy = "", movieImdbRating = "", movieKind = "", movieName = "", movieNameEng = "", movieYear = "")
}
/*
* ************************************************************************
* UiUtils.kt
* *************************************************************************
* Copyright © 2020 VLC authors and VideoLAN
* Author: Nicolas POMEPUY
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
* **************************************************************************
*
*
*/
package org.videolan.vlc.util
import android.app.Activity
import android.os.SystemClock
import android.view.View
import androidx.recyclerview.widget.RecyclerView
import androidx.test.espresso.Espresso
import androidx.test.espresso.PerformException
import androidx.test.espresso.UiController
import androidx.test.espresso.ViewAction
import androidx.test.espresso.matcher.ViewMatchers
import androidx.test.espresso.util.HumanReadables
import androidx.test.espresso.util.TreeIterables
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.runner.lifecycle.ActivityLifecycleMonitorRegistry
import androidx.test.runner.lifecycle.Stage
import org.hamcrest.Matcher
import java.util.concurrent.TimeoutException
object UiUtils {
/**
* Perform action of waiting for a specific view id.
* @param viewId The id of the view to wait for.
* @param millis The timeout of until when to wait for.
*/
fun waitId(viewId: Int, millis: Long): ViewAction? {
return object : ViewAction {
override fun getConstraints(): Matcher<View> = ViewMatchers.isEnabled()
override fun getDescription() = "wait for a specific view with id <$viewId> during $millis millis."
override fun perform(uiController: UiController, view: View?) {
uiController.loopMainThreadUntilIdle()
val startTime = System.currentTimeMillis()
val endTime = startTime + millis
val viewMatcher: Matcher<View> = ViewMatchers.withId(viewId)
val alphaViewMatcher = ViewMatchers.withAlpha(1F)
do {
for (child in TreeIterables.breadthFirstViewTraversal(view)) { // found view with required ID
if (viewMatcher.matches(child)) {
if (alphaViewMatcher.matches(child))
return
}
}
uiController.loopMainThreadForAtLeast(50)
} while (System.currentTimeMillis() < endTime)
throw PerformException.Builder()
.withActionDescription(description)
.withViewDescription(HumanReadables.describe(view))
.withCause(TimeoutException())
.build()
}
}
}
/**
* Stop the test until RecyclerView's data gets loaded.
*
* Passed [recyclerProvider] will be activated in UI thread, allowing you to retrieve the View.
*
* Workaround for https://issuetracker.google.com/issues/123653014
*/
inline fun waitUntilLoaded(crossinline recyclerProvider: () -> RecyclerView) {
Espresso.onIdle()
lateinit var recycler: RecyclerView
InstrumentationRegistry.getInstrumentation().runOnMainSync {
recycler = recyclerProvider()
}
while (recycler.hasPendingAdapterUpdates()) {
Thread.sleep(10)
}
}
fun waitForActivity(activityType: Class<out Activity>, timeout: Int = 10): Boolean {
val endTime = System.currentTimeMillis() + (timeout * 1000)
do {
val currentActivity = getActivityInstance()
// THIS LINE IS MY ISSUE **********************************************
if (currentActivity != null && activityType.isInstance(currentActivity::class.java))
return true
// ********************************************************************
SystemClock.sleep(100)
} while (System.currentTimeMillis() < endTime)
return false
}
private fun getActivityInstance(): Activity? {
val activity = arrayOfNulls<Activity>(1)
InstrumentationRegistry.getInstrumentation().runOnMainSync {
val currentActivity: Activity?
val resumedActivities = ActivityLifecycleMonitorRegistry.getInstance().getActivitiesInStage(Stage.RESUMED)
if (resumedActivities.iterator().hasNext()) {
currentActivity = resumedActivities.iterator().next() as Activity
activity[0] = currentActivity
}
}
return activity[0]
}
/**
* Stop the test until RecyclerView's has children.
*
* Passed [recyclerProvider] will be activated in UI thread, allowing you to retrieve the View.
*
* Workaround for https://issuetracker.google.com/issues/123653014
*/
inline fun waitUntilHasChildren(crossinline recyclerProvider: () -> RecyclerView) {
Espresso.onIdle()
lateinit var recycler: RecyclerView
InstrumentationRegistry.getInstrumentation().runOnMainSync {
recycler = recyclerProvider()
}
while (recycler.childCount == 0) {
Thread.sleep(10)
}
}
}
\ No newline at end of file
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="org.videolan.mobile.app"
android:installLocation="auto">
android:installLocation="auto">
<application
android:name=".VLCApplication"
android:allowBackup="true"
android:appCategory="video"
android:appCategory="audio"
android:banner="@drawable/banner"
android:fullBackupContent="@xml/backup_rules"
android:hardwareAccelerated="true"
......
......@@ -20,10 +20,17 @@
package org.videolan.mobile.app
import android.annotation.TargetApi
import android.app.Activity
import android.app.Application
import android.app.Application.ActivityLifecycleCallbacks
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import kotlinx.coroutines.DEBUG_PROPERTY_NAME
import kotlinx.coroutines.DEBUG_PROPERTY_VALUE_ON
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import org.videolan.libvlc.Dialog
......@@ -36,20 +43,26 @@ import org.videolan.mobile.app.delegates.IIndexersDelegate
import org.videolan.mobile.app.delegates.IMediaContentDelegate
import org.videolan.mobile.app.delegates.IndexersDelegate
import org.videolan.mobile.app.delegates.MediaContentDelegate
import org.videolan.resources.AndroidDevices
import org.videolan.resources.AppContextProvider
import org.videolan.resources.VLCInstance
import org.videolan.resources.util.startRemoteAccess
import org.videolan.tools.AppScope
import org.videolan.tools.KEY_ENABLE_REMOTE_ACCESS
import org.videolan.tools.KEY_INCOGNITO
import org.videolan.tools.Settings
import org.videolan.tools.putSingle
import org.videolan.vlc.BuildConfig
import org.videolan.vlc.gui.SendCrashActivity
import org.videolan.vlc.gui.helpers.AudioUtil
import org.videolan.vlc.gui.helpers.NotificationHelper
import org.videolan.vlc.util.DialogDelegate
import org.videolan.vlc.util.SettingsMigration
import org.videolan.vlc.util.NetworkConnectionManager
import org.videolan.vlc.util.VersionMigration
import org.videolan.vlc.widget.MiniPlayerAppWidgetProvider
interface AppDelegate {
val appContextProvider : AppContextProvider
fun Context.setupApplication()
fun Application.setupApplication()
}
class AppSetupDelegate : AppDelegate,
......@@ -60,13 +73,14 @@ class AppSetupDelegate : AppDelegate,
override val appContextProvider = AppContextProvider
@TargetApi(Build.VERSION_CODES.O)
override fun Context.setupApplication() {
override fun Application.setupApplication() {
appContextProvider.init(this)
NotificationHelper.createNotificationChannels(this)
// Service loaders
FactoryManager.registerFactory(IMediaFactory.factoryId, MediaFactory())
FactoryManager.registerFactory(ILibVLCFactory.factoryId, LibVLCFactory())
System.setProperty(DEBUG_PROPERTY_NAME, DEBUG_PROPERTY_VALUE_ON)
if (BuildConfig.DEBUG) {
Settings.getInstance(this)
......@@ -79,23 +93,48 @@ class AppSetupDelegate : AppDelegate,
}
}
//App restarted, leave the incognito mode
Settings.getInstance (this).putSingle(KEY_INCOGNITO, false)
AppContextProvider.setLocale(Settings.getInstance(this).getString("set_locale", ""))
//Initiate Kotlinx Dispatchers in a thread to prevent ANR
backgroundInit()
if (Settings.getInstance(this).getBoolean(KEY_ENABLE_REMOTE_ACCESS, false))
startRemoteAccess()
registerActivityLifecycleCallbacks(object : ActivityLifecycleCallbacks {
override fun onActivityResumed(activity: Activity) {
AppContextProvider.currentActivity = activity
}
override fun onActivityPaused(activity: Activity) {
AppContextProvider.currentActivity = null
}
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {}
override fun onActivityStarted(activity: Activity) {}
override fun onActivityStopped(activity: Activity) {}
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
override fun onActivityDestroyed(activity: Activity) {}
})
}
// init operations executed in background threads
private fun Context.backgroundInit() {
Thread(Runnable {
AppContextProvider.setLocale(Settings.getInstance(this).getString("set_locale", ""))
AppScope.launch(Dispatchers.IO) {
private fun Context.backgroundInit() = AppScope.launch outerLaunch@ {
VersionMigration.migrateVersion(this@backgroundInit)
launch(Dispatchers.IO) innerLaunch@ {
if (!VLCInstance.testCompatibleCPU(AppContextProvider.appContext)) return@innerLaunch
Dialog.setCallbacks(VLCInstance.getInstance(this@backgroundInit), DialogDelegate)
}
packageManager.setComponentEnabledSetting(ComponentName(this@backgroundInit, SendCrashActivity::class.java),
if (BuildConfig.BETA) PackageManager.COMPONENT_ENABLED_STATE_ENABLED else PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP)
if (!AndroidDevices.isAndroidTv) sendBroadcast(Intent(MiniPlayerAppWidgetProvider.ACTION_WIDGET_INIT).apply {
component = ComponentName(appContextProvider.appContext, MiniPlayerAppWidgetProvider::class.java)
})
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
NetworkConnectionManager.start(AppContextProvider.appContext)
}
if (!VLCInstance.testCompatibleCPU(AppContextProvider.appContext)) return@launch
Dialog.setCallbacks(VLCInstance.getInstance(this@backgroundInit), DialogDelegate)
}
packageManager.setComponentEnabledSetting(ComponentName(this, SendCrashActivity::class.java),
if (BuildConfig.BETA) PackageManager.COMPONENT_ENABLED_STATE_ENABLED else PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP)
SettingsMigration.migrateSettings(this)
}).start()
}
}
\ No newline at end of file
}
......@@ -25,16 +25,13 @@ import android.os.Build
import android.util.Log
import androidx.appcompat.app.AppCompatDelegate
import androidx.multidex.MultiDexApplication
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.ObsoleteCoroutinesApi
import org.videolan.libvlc.Dialog
import org.videolan.tools.BitmapCache
import org.videolan.vlc.ArtworkProvider
import org.videolan.vlc.util.DialogDelegate
private const val TAG = "VLC/VLCApplication"
@ObsoleteCoroutinesApi
@ExperimentalCoroutinesApi
class VLCApplication : MultiDexApplication(), Dialog.Callbacks by DialogDelegate, AppDelegate by AppSetupDelegate() {
init {
......@@ -59,11 +56,13 @@ class VLCApplication : MultiDexApplication(), Dialog.Callbacks by DialogDelegate
super.onLowMemory()
Log.w(TAG, "System is running low on memory")
BitmapCache.clear()
ArtworkProvider.clear()
}
override fun onTrimMemory(level: Int) {
super.onTrimMemory(level)
Log.w(TAG, "onTrimMemory, level: $level")
BitmapCache.clear()
ArtworkProvider.clear()
}
}
......@@ -7,8 +7,8 @@ import android.content.IntentFilter
import kotlinx.coroutines.launch
import org.videolan.moviepedia.MediaScraper
import org.videolan.resources.ACTION_CONTENT_INDEXING
import org.videolan.resources.util.registerReceiverCompat
import org.videolan.tools.AppScope
import org.videolan.tools.localBroadcastManager
internal interface IIndexersDelegate {
fun Context.setupIndexers()
......@@ -17,7 +17,7 @@ internal interface IIndexersDelegate {
internal class IndexersDelegate : BroadcastReceiver(), IIndexersDelegate {
override fun Context.setupIndexers() {
localBroadcastManager.registerReceiver(this@IndexersDelegate, IntentFilter(ACTION_CONTENT_INDEXING))
registerReceiverCompat(this@IndexersDelegate, IntentFilter(ACTION_CONTENT_INDEXING), false)
}
override fun onReceive(context: Context?, intent: Intent?) {
......
/build
\ No newline at end of file
/*
* ************************************************************************
* build.gradle
* *************************************************************************
* Copyright © 2020 VLC authors and VideoLAN
* Author: Nicolas POMEPUY
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
* **************************************************************************
*
*
*/
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
android {
dataBinding {
enabled = true
}
packagingOptions {
jniLibs {
pickFirsts += ['**/*.so']
}
}
defaultConfig {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
compileSdk rootProject.ext.compileSdkVersion
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles 'consumer-rules.pro'
multiDexEnabled true
buildConfigField "String", "PUBLIC_API_KEY", "\"${getPublicApiKey(project)}\""
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
debug {
jniDebuggable true
}
dev {
initWith debug
matchingFallbacks = ['debug']
}
vlcBundle {
initWith release
matchingFallbacks = ['release']
}
}
namespace 'org.videolan.vlc.donations'
buildFeatures {
aidl true
buildConfig true
}
}
static def getPublicApiKey(project) {
return System.getenv('K8S_SECRET_VLC_PLAYSTORE_PUBLIC_API_KEY') ?: project.properties['vlc_playstore_public_api_key'] ?: ""
}
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation project(':application:tools')
implementation "androidx.core:core-ktx:$rootProject.ext.androidxCoreVersion"
implementation "androidx.appcompat:appcompat:$rootProject.ext.appCompatVersion"
testImplementation "junit:junit:$rootProject.ext.junitVersion"
androidTestImplementation "androidx.test.ext:junit:$rootProject.ext.junitExtVersion"
androidTestImplementation "androidx.test.espresso:espresso-core:$rootProject.ext.espressoVersion"
}
\ No newline at end of file
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /home/dekans/SDK/android-sdk-linux/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
\ No newline at end of file
/*
* ************************************************************************
* ExampleInstrumentedTest.kt
* *************************************************************************
* Copyright © 2020 VLC authors and VideoLAN
* Author: Nicolas POMEPUY
* 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 2 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, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
* **************************************************************************
*
*
*/
package org.videolan.vlc.donations
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("org.videolan.vlc.donations", appContext.packageName)
}
}
\ No newline at end of file
<!--
~ *************************************************************************
~ AndroidManifest.xml
~ **************************************************************************
~ Copyright © 2020 VLC authors and VideoLAN
~ Author: Nicolas POMEPUY
~ 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 2 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, write to the Free Software
~ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
~ ***************************************************************************
~
~
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="com.android.vending.BILLING" />
<application/>
</manifest>
\ No newline at end of file
/*
* Copyright (C) 2012 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 com.android.vending.billing;
import android.os.Bundle;
/**
* InAppBillingService is the service that provides in-app billing version 3 and beyond.
* This service provides the following features:
* 1. Provides a new API to get details of in-app items published for the app including
* price, type, title and description.
* 2. The purchase flow is synchronous and purchase information is available immediately
* after it completes.
* 3. Purchase information of in-app purchases is maintained within the Google Play system
* till the purchase is consumed.
* 4. An API to consume a purchase of an inapp item. All purchases of one-time
* in-app items are consumable and thereafter can be purchased again.
* 5. An API to get current purchases of the user immediately. This will not contain any
* consumed purchases.
*
* All calls will give a response code with the following possible values
* RESULT_OK = 0 - success
* RESULT_USER_CANCELED = 1 - User pressed back or canceled a dialog
* RESULT_SERVICE_UNAVAILABLE = 2 - The network connection is down
* RESULT_BILLING_UNAVAILABLE = 3 - This billing API version is not supported for the type requested
* RESULT_ITEM_UNAVAILABLE = 4 - Requested SKU is not available for purchase
* RESULT_DEVELOPER_ERROR = 5 - Invalid arguments provided to the API
* RESULT_ERROR = 6 - Fatal error during the API action
* RESULT_ITEM_ALREADY_OWNED = 7 - Failure to purchase since item is already owned
* RESULT_ITEM_NOT_OWNED = 8 - Failure to consume since item is not owned
*/
interface IInAppBillingService {
/**
* Checks support for the requested billing API version, package and in-app type.
* Minimum API version supported by this interface is 3.
* @param apiVersion billing API version that the app is using
* @param packageName the package name of the calling app
* @param type type of the in-app item being purchased ("inapp" for one-time purchases
* and "subs" for subscriptions)
* @return RESULT_OK(0) on success and appropriate response code on failures.
*/
int isBillingSupported(int apiVersion, String packageName, String type);
/**
* Provides details of a list of SKUs
* Given a list of SKUs of a valid type in the skusBundle, this returns a bundle
* with a list JSON strings containing the productId, price, title and description.
* This API can be called with a maximum of 20 SKUs.
* @param apiVersion billing API version that the app is using
* @param packageName the package name of the calling app
* @param type of the in-app items ("inapp" for one-time purchases
* and "subs" for subscriptions)
* @param skusBundle bundle containing a StringArrayList of SKUs with key "ITEM_ID_LIST"
* @return Bundle containing the following key-value pairs
* "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes
* on failures.
* "DETAILS_LIST" with a StringArrayList containing purchase information
* in JSON format similar to:
* '{ "productId" : "exampleSku",
* "type" : "inapp",
* "price" : "$5.00",
* "price_currency": "USD",
* "price_amount_micros": 5000000,
* "title : "Example Title",
* "description" : "This is an example description" }'
*/
Bundle getSkuDetails(int apiVersion, String packageName, String type, in Bundle skusBundle);
/**
* Returns a pending intent to launch the purchase flow for an in-app item by providing a SKU,
* the type, a unique purchase token and an optional developer payload.
* @param apiVersion billing API version that the app is using
* @param packageName package name of the calling app
* @param sku the SKU of the in-app item as published in the developer console
* @param type of the in-app item being purchased ("inapp" for one-time purchases
* and "subs" for subscriptions)
* @param developerPayload optional argument to be sent back with the purchase information
* @return Bundle containing the following key-value pairs
* "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes
* on failures.
* "BUY_INTENT" - PendingIntent to start the purchase flow
*
* The Pending intent should be launched with startIntentSenderForResult. When purchase flow
* has completed, the onActivityResult() will give a resultCode of OK or CANCELED.
* If the purchase is successful, the result data will contain the following key-value pairs
* "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response
* codes on failures.
* "INAPP_PURCHASE_DATA" - String in JSON format similar to
* '{"orderId":"12999763169054705758.1371079406387615",
* "packageName":"com.example.app",
* "productId":"exampleSku",
* "purchaseTime":1345678900000,
* "purchaseToken" : "122333444455555",
* "developerPayload":"example developer payload" }'
* "INAPP_DATA_SIGNATURE" - String containing the signature of the purchase data that
* was signed with the private key of the developer
*/
Bundle getBuyIntent(int apiVersion, String packageName, String sku, String type,
String developerPayload);
/**
* Returns the current SKUs owned by the user of the type and package name specified along with
* purchase information and a signature of the data to be validated.
* This will return all SKUs that have been purchased in V3 and managed items purchased using
* V1 and V2 that have not been consumed.
* @param apiVersion billing API version that the app is using
* @param packageName package name of the calling app
* @param type of the in-app items being requested ("inapp" for one-time purchases
* and "subs" for subscriptions)
* @param continuationToken to be set as null for the first call, if the number of owned
* skus are too many, a continuationToken is returned in the response bundle.
* This method can be called again with the continuation token to get the next set of
* owned skus.
* @return Bundle containing the following key-value pairs
* "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes
on failures.
* "INAPP_PURCHASE_ITEM_LIST" - StringArrayList containing the list of SKUs
* "INAPP_PURCHASE_DATA_LIST" - StringArrayList containing the purchase information
* "INAPP_DATA_SIGNATURE_LIST"- StringArrayList containing the signatures
* of the purchase information
* "INAPP_CONTINUATION_TOKEN" - String containing a continuation token for the
* next set of in-app purchases. Only set if the
* user has more owned skus than the current list.
*/
Bundle getPurchases(int apiVersion, String packageName, String type, String continuationToken);
/**
* Consume the last purchase of the given SKU. This will result in this item being removed
* from all subsequent responses to getPurchases() and allow re-purchase of this item.
* @param apiVersion billing API version that the app is using
* @param packageName package name of the calling app
* @param purchaseToken token in the purchase information JSON that identifies the purchase
* to be consumed
* @return RESULT_OK(0) if consumption succeeded, appropriate response codes on failures.
*/
int consumePurchase(int apiVersion, String packageName, String purchaseToken);
/**
* This API is currently under development.
*/
int stub(int apiVersion, String packageName, String type);
/**
* Returns a pending intent to launch the purchase flow for upgrading or downgrading a
* subscription. The existing owned SKU(s) should be provided along with the new SKU that
* the user is upgrading or downgrading to.
* @param apiVersion billing API version that the app is using, must be 5 or later
* @param packageName package name of the calling app
* @param oldSkus the SKU(s) that the user is upgrading or downgrading from,
* if null or empty this method will behave like {@link #getBuyIntent}
* @param newSku the SKU that the user is upgrading or downgrading to
* @param type of the item being purchased, currently must be "subs"
* @param developerPayload optional argument to be sent back with the purchase information
* @return Bundle containing the following key-value pairs
* "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response codes
* on failures.
* "BUY_INTENT" - PendingIntent to start the purchase flow
*
* The Pending intent should be launched with startIntentSenderForResult. When purchase flow
* has completed, the onActivityResult() will give a resultCode of OK or CANCELED.
* If the purchase is successful, the result data will contain the following key-value pairs
* "RESPONSE_CODE" with int value, RESULT_OK(0) if success, appropriate response
* codes on failures.
* "INAPP_PURCHASE_DATA" - String in JSON format similar to
* '{"orderId":"12999763169054705758.1371079406387615",
* "packageName":"com.example.app",
* "productId":"exampleSku",
* "purchaseTime":1345678900000,
* "purchaseToken" : "122333444455555",
* "developerPayload":"example developer payload" }'
* "INAPP_DATA_SIGNATURE" - String containing the signature of the purchase data that
* was signed with the private key of the developer
*/
Bundle getBuyIntentToReplaceSkus(int apiVersion, String packageName,
in List<String> oldSkus, String newSku, String type, String developerPayload);
/**
* Returns a pending intent to launch the purchase flow for an in-app item. This method is
* a variant of the {@link #getBuyIntent} method and takes an additional {@code extraParams}
* parameter. This parameter is a Bundle of optional keys and values that affect the
* operation of the method.
* @param apiVersion billing API version that the app is using, must be 6 or later
* @param packageName package name of the calling app
* @param sku the SKU of the in-app item as published in the developer console
* @param type of the in-app item being purchased ("inapp" for one-time purchases
* and "subs" for subscriptions)
* @param developerPayload optional argument to be sent back with the purchase information
* @extraParams a Bundle with the following optional keys:
* "skusToReplace" - List<String> - an optional list of SKUs that the user is
* upgrading or downgrading from.
* Pass this field if the purchase is upgrading or downgrading
* existing subscriptions.
* The specified SKUs are replaced with the SKUs that the user is
* purchasing. Google Play replaces the specified SKUs at the start of
* the next billing cycle.
* "replaceSkusProration" - Boolean - whether the user should be credited for any unused
* subscription time on the SKUs they are upgrading or downgrading.
* If you set this field to true, Google Play swaps out the old SKUs
* and credits the user with the unused value of their subscription
* time on a pro-rated basis.
* Google Play applies this credit to the new subscription, and does
* not begin billing the user for the new subscription until after
* the credit is used up.
* If you set this field to false, the user does not receive credit for
* any unused subscription time and the recurrence date does not
* change.
* Default value is true. Ignored if you do not pass skusToReplace.
* "accountId" - String - an optional obfuscated string that is uniquely
* associated with the user's account in your app.
* If you pass this value, Google Play can use it to detect irregular
* activity, such as many devices making purchases on the same
* account in a short period of time.
* Do not use the developer ID or the user's Google ID for this field.
* In addition, this field should not contain the user's ID in
* cleartext.
* We recommend that you use a one-way hash to generate a string from
* the user's ID, and store the hashed string in this field.
* "vr" - Boolean - an optional flag indicating whether the returned intent
* should start a VR purchase flow. The apiVersion must also be 7 or
* later to use this flag.
*/
Bundle getBuyIntentExtraParams(int apiVersion, String packageName, String sku,
String type, String developerPayload, in Bundle extraParams);
/**
* Returns the most recent purchase made by the user for each SKU, even if that purchase is
* expired, canceled, or consumed.
* @param apiVersion billing API version that the app is using, must be 6 or later
* @param packageName package name of the calling app
* @param type of the in-app items being requested ("inapp" for one-time purchases
* and "subs" for subscriptions)
* @param continuationToken to be set as null for the first call, if the number of owned
* skus is too large, a continuationToken is returned in the response bundle.
* This method can be called again with the continuation token to get the next set of
* owned skus.
* @param extraParams a Bundle with extra params that would be appended into http request
* query string. Not used at this moment. Reserved for future functionality.
* @return Bundle containing the following key-value pairs
* "RESPONSE_CODE" with int value: RESULT_OK(0) if success,
* {@link IabHelper#BILLING_RESPONSE_RESULT_*} response codes on failures.
*
* "INAPP_PURCHASE_ITEM_LIST" - ArrayList<String> containing the list of SKUs
* "INAPP_PURCHASE_DATA_LIST" - ArrayList<String> containing the purchase information
* "INAPP_DATA_SIGNATURE_LIST"- ArrayList<String> containing the signatures
* of the purchase information
* "INAPP_CONTINUATION_TOKEN" - String containing a continuation token for the
* next set of in-app purchases. Only set if the
* user has more owned skus than the current list.
*/
Bundle getPurchaseHistory(int apiVersion, String packageName, String type,
String continuationToken, in Bundle extraParams);
/**
* This method is a variant of {@link #isBillingSupported}} that takes an additional
* {@code extraParams} parameter.
* @param apiVersion billing API version that the app is using, must be 7 or later
* @param packageName package name of the calling app
* @param type of the in-app item being purchased ("inapp" for one-time purchases and "subs"
* for subscriptions)
* @param extraParams a Bundle with the following optional keys:
* "vr" - Boolean - an optional flag to indicate whether {link #getBuyIntentExtraParams}
* supports returning a VR purchase flow.
* @return RESULT_OK(0) on success and appropriate response code on failures.
*/
int isBillingSupportedExtraParams(int apiVersion, String packageName, String type,
in Bundle extraParams);
}