├── .gitignore ├── .gitlab-ci.yml ├── .idea ├── .name ├── codeStyleSettings.xml ├── codeStyles │ ├── Project.xml │ └── codeStyleConfig.xml ├── compiler.xml ├── copyright │ ├── apache2.xml │ └── profiles_settings.xml ├── dictionaries │ └── Jacksgong.xml ├── encodings.xml ├── gradle.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── .travis.yml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── ISSUE_TEMPLATE.md ├── LICENSE.txt ├── README-zh.md ├── README.md ├── art ├── bunch-download.gif ├── check_before_chain.png ├── content-uri.gif ├── each-block-progress.gif ├── listener.png ├── notification.gif ├── okcat.png ├── queue-download.gif ├── sample-home.jpeg └── single-download.gif ├── benchmark ├── .gitignore ├── build.gradle ├── lint.xml ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── cn │ │ └── dreamtobe │ │ └── okdownload │ │ └── benchmark │ │ └── MainActivity.kt │ └── res │ ├── drawable │ ├── ic_dashboard_black_24dp.xml │ ├── ic_home_black_24dp.xml │ ├── ic_launcher_background.xml │ └── ic_notifications_black_24dp.xml │ ├── layout │ └── activity_main.xml │ ├── menu │ └── navigation.xml │ ├── mipmap-anydpi-v26 │ ├── ic_launcher.xml │ └── ic_launcher_round.xml │ ├── mipmap-hdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── mipmap-mdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── mipmap-xhdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── mipmap-xxhdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── mipmap-xxxhdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── values │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml │ └── xml │ └── backup_descriptor.xml ├── build.gradle ├── codecov.yml ├── deploy-snapshot.sh ├── gradle.properties ├── gradle ├── bintray.gradle ├── codecov.gradle ├── dependencies.gradle ├── gradle-mavenlocal.gradle ├── gradle-mvn-push.gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── keystore ├── okcat-okdownload.yml ├── okdownload-breakpoint-sqlite ├── .gitignore ├── build.gradle ├── gradle.properties ├── proguard-rules.pro └── src │ ├── main │ ├── AndroidManifest.xml │ └── java │ │ └── com │ │ └── liulishuo │ │ └── okdownload │ │ └── core │ │ ├── breakpoint │ │ ├── BlockInfoRow.java │ │ ├── BreakpointInfoRow.java │ │ ├── BreakpointSQLiteHelper.java │ │ ├── BreakpointSQLiteKey.java │ │ ├── BreakpointStoreOnSQLite.java │ │ ├── RemitStoreOnSQLite.java │ │ ├── RemitSyncExecutor.java │ │ └── RemitSyncToDBHelper.java │ │ └── exception │ │ └── SQLiteException.java │ └── test │ └── java │ └── com │ └── liulishuo │ └── okdownload │ └── core │ ├── breakpoint │ ├── BlockInfoRowTest.java │ ├── BreakpointInfoRowTest.java │ ├── BreakpointSQLiteHelperTest.java │ ├── BreakpointStoreOnSqliteTest.java │ ├── RemitStoreOnSQLiteTest.java │ ├── RemitSyncExecutorTest.java │ └── RemitSyncToDBHelperTest.java │ └── exception │ └── SQLiteExceptionTest.java ├── okdownload-connection-okhttp ├── .gitignore ├── build.gradle ├── consumer-proguard-rules.txt ├── gradle.properties ├── proguard-rules.pro └── src │ ├── main │ ├── AndroidManifest.xml │ └── java │ │ └── com │ │ └── liulishuo │ │ └── okdownload │ │ └── core │ │ └── connection │ │ └── DownloadOkHttp3Connection.java │ └── test │ └── java │ └── com │ └── liulishuo │ └── okdownload │ └── core │ └── connection │ └── DownloadOkHttp3ConnectionTest.java ├── okdownload-filedownloader ├── .gitignore ├── build.gradle ├── gradle.properties ├── proguard-rules.pro └── src │ ├── main │ ├── AndroidManifest.xml │ └── java │ │ └── com │ │ └── liulishuo │ │ └── filedownloader │ │ ├── BaseDownloadTask.java │ │ ├── CompatListenerAdaptee.java │ │ ├── CompatListenerAdapter.java │ │ ├── CompatListenerAssist.java │ │ ├── DownloadTaskAdapter.java │ │ ├── FileDownloadConnectListener.java │ │ ├── FileDownloadLargeFileListener.java │ │ ├── FileDownloadLine.java │ │ ├── FileDownloadLineAsync.java │ │ ├── FileDownloadList.java │ │ ├── FileDownloadListener.java │ │ ├── FileDownloadMonitor.java │ │ ├── FileDownloadQueueSet.java │ │ ├── FileDownloadSampleListener.java │ │ ├── FileDownloader.java │ │ ├── IDownloadSpeed.java │ │ ├── IFileDownloadMessenger.java │ │ ├── ITaskHunter.java │ │ ├── connection │ │ ├── DownloadConnectionAdapter.java │ │ ├── FileDownloadConnection.java │ │ └── FileDownloadUrlConnection.java │ │ ├── database │ │ └── FileDownloadDatabase.java │ │ ├── event │ │ ├── IDownloadEvent.java │ │ └── IDownloadListener.java │ │ ├── exception │ │ ├── FileDownloadGiveUpRetryException.java │ │ ├── FileDownloadHttpException.java │ │ ├── FileDownloadNetworkPolicyException.java │ │ ├── FileDownloadOutOfSpaceException.java │ │ ├── FileDownloadSecurityException.java │ │ └── PathConflictException.java │ │ ├── message │ │ ├── IMessageSnapshot.java │ │ └── MessageSnapshot.java │ │ ├── model │ │ ├── ConnectionModel.java │ │ ├── FileDownloadModel.java │ │ └── FileDownloadStatus.java │ │ ├── notification │ │ ├── BaseNotificationItem.java │ │ ├── FileDownloadNotificationHelper.java │ │ └── FileDownloadNotificationListener.java │ │ ├── progress │ │ └── ProgressAssist.java │ │ ├── retry │ │ └── RetryAssist.java │ │ ├── services │ │ ├── DownloadMgrInitialParams.java │ │ └── ForegroundServiceConfig.java │ │ ├── status │ │ └── StatusAssist.java │ │ ├── stream │ │ ├── DownloadOutputStreamAdapter.java │ │ └── FileDownloadOutputStream.java │ │ └── util │ │ ├── FileDownloadHelper.java │ │ ├── FileDownloadSerialQueue.java │ │ └── FileDownloadUtils.java │ └── test │ └── java │ ├── com.liulishuo.filedownloader │ ├── CompatListenerAssistTest.java │ ├── DownloadTaskAdapterTest.java │ ├── FileDownloadListTest.java │ ├── FileDownloadQueueSetTest.java │ ├── progress │ │ └── ProgressAssistTest.java │ ├── retry │ │ └── RetryAssistTest.java │ └── util │ │ ├── FileDownloadSerialQueueTest.java │ │ └── FileDownloadUtilsTest.java │ └── com │ └── liulishuo │ └── okdownload │ └── TestUtils.java ├── okdownload-kotlin-enhance ├── .gitignore ├── README.md ├── build.gradle ├── gradle.properties ├── proguard-rules.pro └── src │ ├── main │ ├── AndroidManifest.xml │ └── kotlin │ │ └── com.liulishuo.okdownload.kotlin │ │ ├── DownloadProgress.kt │ │ ├── DownloadResult.kt │ │ ├── DownloadTaskExtension.kt │ │ └── listener │ │ ├── DownloadContextListenerExtension.kt │ │ ├── DownloadListener1Extension.kt │ │ ├── DownloadListener2Extension.kt │ │ ├── DownloadListener3Extension.kt │ │ ├── DownloadListener4Extension.kt │ │ ├── DownloadListener4WithSpeedExtension.kt │ │ └── DownloadListenerExtension.kt │ └── test │ └── java │ └── com │ └── liulishuo │ └── okdownload │ └── kotlin │ ├── DownloadContextListenerExtensionTest.kt │ ├── DownloadListener1ExtensionTest.kt │ ├── DownloadListener2ExtensionTest.kt │ ├── DownloadListener3ExtensionTest.kt │ ├── DownloadListener4ExtensionTest.kt │ ├── DownloadListener4WithSpeedExtensionTest.kt │ ├── DownloadListenerExtensionTest.kt │ ├── DownloadProgressTest.kt │ ├── DownloadResultTest.kt │ └── DownloadTaskExtensionTest.kt ├── okdownload-process ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ └── AndroidManifest.xml ├── okdownload ├── .gitignore ├── build.gradle ├── gradle.properties ├── proguard-rules.pro └── src │ ├── main │ ├── AndroidManifest.xml │ └── java │ │ └── com │ │ └── liulishuo │ │ └── okdownload │ │ ├── DownloadContext.java │ │ ├── DownloadContextListener.java │ │ ├── DownloadListener.java │ │ ├── DownloadMonitor.java │ │ ├── DownloadSerialQueue.java │ │ ├── DownloadTask.java │ │ ├── IRedirectHandler.java │ │ ├── OkDownload.java │ │ ├── OkDownloadProvider.java │ │ ├── RedirectUtil.java │ │ ├── SpeedCalculator.java │ │ ├── StatusUtil.java │ │ ├── UnifiedListenerManager.java │ │ └── core │ │ ├── IdentifiedTask.java │ │ ├── NamedRunnable.java │ │ ├── Util.java │ │ ├── breakpoint │ │ ├── BlockInfo.java │ │ ├── BreakpointInfo.java │ │ ├── BreakpointStore.java │ │ ├── BreakpointStoreOnCache.java │ │ ├── DownloadStore.java │ │ └── KeyToIdMap.java │ │ ├── cause │ │ ├── EndCause.java │ │ └── ResumeFailedCause.java │ │ ├── connection │ │ ├── DownloadConnection.java │ │ └── DownloadUrlConnection.java │ │ ├── dispatcher │ │ ├── CallbackDispatcher.java │ │ └── DownloadDispatcher.java │ │ ├── download │ │ ├── BreakpointLocalCheck.java │ │ ├── BreakpointRemoteCheck.java │ │ ├── ConnectTrial.java │ │ ├── DownloadCache.java │ │ ├── DownloadCall.java │ │ ├── DownloadChain.java │ │ └── DownloadStrategy.java │ │ ├── exception │ │ ├── DownloadSecurityException.java │ │ ├── FileBusyAfterRunException.java │ │ ├── InterruptException.java │ │ ├── NetworkPolicyException.java │ │ ├── PreAllocateException.java │ │ ├── ResumeFailedException.java │ │ ├── RetryException.java │ │ └── ServerCanceledException.java │ │ ├── file │ │ ├── DownloadOutputStream.java │ │ ├── DownloadUriOutputStream.java │ │ ├── FileLock.java │ │ ├── MultiPointOutputStream.java │ │ └── ProcessFileStrategy.java │ │ ├── interceptor │ │ ├── BreakpointInterceptor.java │ │ ├── FetchDataInterceptor.java │ │ ├── Interceptor.java │ │ ├── RetryInterceptor.java │ │ └── connect │ │ │ ├── CallServerInterceptor.java │ │ │ └── HeaderInterceptor.java │ │ └── listener │ │ ├── DownloadListener1.java │ │ ├── DownloadListener2.java │ │ ├── DownloadListener3.java │ │ ├── DownloadListener4.java │ │ ├── DownloadListener4WithSpeed.java │ │ ├── DownloadListenerBunch.java │ │ └── assist │ │ ├── Listener1Assist.java │ │ ├── Listener4Assist.java │ │ ├── Listener4SpeedAssistExtend.java │ │ ├── ListenerAssist.java │ │ └── ListenerModelHandler.java │ └── test │ ├── java │ └── com │ │ └── liulishuo │ │ └── okdownload │ │ ├── DownloadContextTest.java │ │ ├── DownloadSerialQueueTest.java │ │ ├── DownloadTaskTest.java │ │ ├── OkDownloadProviderTest.java │ │ ├── OkDownloadTest.java │ │ ├── RedirectUtilTest.java │ │ ├── SpeedCalculatorTest.java │ │ ├── StatusUtilTest.java │ │ ├── TestUtils.java │ │ ├── UnifiedListenerManagerTest.java │ │ └── core │ │ ├── IdentifiedTaskTest.java │ │ ├── NamedRunnableTest.java │ │ ├── UtilTest.java │ │ ├── breakpoint │ │ ├── BlockInfoTest.java │ │ ├── BreakpointInfoTest.java │ │ ├── BreakpointStoreOnCacheTest.java │ │ └── KeyToIdMapTest.java │ │ ├── connection │ │ └── DownloadUrlConnectionTest.java │ │ ├── dispatcher │ │ ├── CallbackDispatcherTest.java │ │ └── DownloadDispatcherTest.java │ │ ├── download │ │ ├── BreakpointLocalCheckTest.java │ │ ├── BreakpointRemoteCheckTest.java │ │ ├── ConnectTrialTest.java │ │ ├── DownloadCacheTest.java │ │ ├── DownloadCallTest.java │ │ ├── DownloadChainTest.java │ │ └── DownloadStrategyTest.java │ │ ├── exception │ │ ├── InterruptExceptionTest.java │ │ ├── NetworkPolicyExceptionTest.java │ │ ├── PreAllocateExceptionTest.java │ │ ├── ResumeFailedExceptionTest.java │ │ ├── RetryExceptionTest.java │ │ └── ServerCanceledExceptionTest.java │ │ ├── file │ │ ├── DownloadUriOutputStreamTest.java │ │ ├── FileLockTest.java │ │ ├── MultiPointOutputStreamTest.java │ │ └── ProcessFileStrategyTest.java │ │ ├── interceptor │ │ ├── BreakpointInterceptorTest.java │ │ ├── FetchDataInterceptorTest.java │ │ ├── RetryInterceptorTest.java │ │ └── connect │ │ │ ├── CallServerInterceptorTest.java │ │ │ └── HeaderInterceptorTest.java │ │ └── listener │ │ ├── DownloadListener1Test.java │ │ ├── DownloadListener2Test.java │ │ ├── DownloadListener3Test.java │ │ ├── DownloadListener4Test.java │ │ ├── DownloadListenerBunchTest.java │ │ └── assist │ │ ├── Listener1AssistTest.java │ │ ├── Listener4AssistTest.java │ │ ├── Listener4SpeedAssistExtendTest.java │ │ └── ListenerModelHandlerTest.java │ └── resources │ └── mockito-extensions │ └── org.mockito.plugins.MockMaker ├── omni └── okdownload.graffle ├── publishToMavenLocal.sh ├── sample ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── liulishuo │ │ └── okdownload │ │ └── sample │ │ ├── BunchActivity.kt │ │ ├── ContentUriActivity.java │ │ ├── EachBlockProgressActivity.java │ │ ├── ListenerSample.kt │ │ ├── MainActivity.java │ │ ├── NotificationActivity.java │ │ ├── QueueActivity.kt │ │ ├── SingleActivity.kt │ │ ├── base │ │ ├── BaseListActivity.java │ │ └── BaseSampleActivity.kt │ │ └── util │ │ ├── DemoUtil.java │ │ ├── EachBlockProgressUtil.java │ │ ├── NotificationSampleListener.java │ │ ├── ProgressUtil.java │ │ └── queue │ │ ├── QueueController.kt │ │ ├── QueueListener.kt │ │ ├── QueueRecyclerAdapter.kt │ │ └── TagUtil.kt │ └── res │ ├── drawable │ ├── bg_queue_delete_file.xml │ ├── ic_dashboard_black_24dp.xml │ ├── ic_format_list_black_24dp.xml │ ├── ic_home_black_24dp.xml │ └── ic_launcher_background.xml │ ├── layout │ ├── activity_bunch.xml │ ├── activity_content_uri.xml │ ├── activity_each_block_progress.xml │ ├── activity_main.xml │ ├── activity_notification.xml │ ├── activity_queue.xml │ ├── activity_single.xml │ ├── fragment_multiple_task.xml │ ├── fragment_queue.xml │ ├── fragment_single_task.xml │ ├── item_base_list_activity.xml │ ├── item_multiple_task.xml │ └── item_queue.xml │ ├── menu │ ├── menu_main.xml │ └── navigation.xml │ ├── mipmap-anydpi-v26 │ ├── ic_launcher.xml │ └── ic_launcher_round.xml │ ├── mipmap-hdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── mipmap-mdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── mipmap-xhdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── mipmap-xxhdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── mipmap-xxxhdpi │ ├── ic_launcher.png │ ├── ic_launcher_foreground.png │ └── ic_launcher_round.png │ ├── values │ ├── colors.xml │ ├── dimens.xml │ ├── ids.xml │ ├── strings.xml │ └── styles.xml │ └── xml │ └── network_security_config.xml └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | /.idea/misc.xml 7 | /.idea/kotlinc.xml 8 | /.idea/checkstyle-idea.xml 9 | /.idea/caches 10 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | jacoco.exec 15 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | stages: 2 | - check 3 | 4 | check: 5 | stage: check 6 | script: 7 | - ./gradlew check 8 | image: stag-reg.llsops.com/android/lls:common-0.1 9 | tags: 10 | - k8s 11 | except: 12 | - tags 13 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | okdownload-root -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /.idea/copyright/apache2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/dictionaries/Jacksgong.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | okdownload 5 | okdownloader 6 | precon 7 | resumable 8 | sqlite 9 | unpark 10 | weixin 11 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 24 | 25 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: android 2 | 3 | jdk: 4 | - oraclejdk8 5 | android: 6 | components: 7 | - tools 8 | - platform-tools 9 | - build-tools-28.0.3 10 | - android-28 11 | - extra 12 | 13 | script: 14 | - ./gradlew -PignoreOkcheckDiff -PisCI clean okcheckDebug 15 | 16 | sudo: false 17 | 18 | before_cache: 19 | - rm -f $HOME/.gradle/caches/modules-2/modules-2.lock 20 | - rm -fr $HOME/.gradle/caches/*/plugin-resolution/ 21 | 22 | after_script: 23 | - bash <(curl -s https://codecov.io/bash) 24 | 25 | cache: 26 | directories: 27 | - $HOME/.gradle/caches/ 28 | - $HOME/.gradle/wrapper/ 29 | - $HOME/.android/build-cache 30 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | It's very welcome your pull requests: 2 | 3 | - Comments as much as possible. 4 | - Commit message format follow: [AngularJS's commit message convention](https://github.com/angular/angular.js/blob/master/CONTRIBUTING.md#-git-commit-guidelines) 5 | - Cover the unit test for your change 6 | 7 | #### What is AngularJS's commit message convention? 8 | 9 | in shortly: 10 | 11 | - if you want to commit a feature: `feat: bla bla bla` 12 | - if you want to commit a fix: `fix: bla bla bla` 13 | - if you want to commit some script not affect the code logic: `chore: bla bla bla` 14 | - if you want to commit some logic just on demo project: `demo: bla bla bla` 15 | - if you want to commit some logic improve performance: `prefs: bla bla bla` 16 | - if you want to commit some logic just on test: `tests: bla bla bla` 17 | 18 | #### Helpful explain 19 | 20 | ![][check_before_chain_img] 21 | 22 | [check_before_chain_img]: https://github.com/lingochamp/okdownload/raw/master/art/check_before_chain.png 23 | -------------------------------------------------------------------------------- /ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### OkDownload Version 2 | 3 | v1.0.2-SNAPSHOT 4 | 5 | ### Problem Describe 6 | 7 | I occur some problem, I also search on [issues][issues-url] and [wiki][wiki-url], I even checked the source code, but it can't help, so my real problem is:... 8 | 9 | ### Log 10 | 11 | There is the whole log from LogCat when I occur the problem(I know we can use [this tool][okcat-wiki-url] to let log more readable): 12 | 13 | ``` 14 | ``` 15 | 16 | [issues-url]: https://github.com/lingochamp/okdownload/issues 17 | [wiki-url]: https://github.com/lingochamp/okdownload/wiki 18 | [okcat-wiki-url]: https://github.com/lingochamp/okdownload/wiki/Debug-OkDownload 19 | -------------------------------------------------------------------------------- /art/bunch-download.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lingochamp/okdownload/cb6e20f2484927ef81728355fad3231bb87859a9/art/bunch-download.gif -------------------------------------------------------------------------------- /art/check_before_chain.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lingochamp/okdownload/cb6e20f2484927ef81728355fad3231bb87859a9/art/check_before_chain.png -------------------------------------------------------------------------------- /art/content-uri.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lingochamp/okdownload/cb6e20f2484927ef81728355fad3231bb87859a9/art/content-uri.gif -------------------------------------------------------------------------------- /art/each-block-progress.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lingochamp/okdownload/cb6e20f2484927ef81728355fad3231bb87859a9/art/each-block-progress.gif -------------------------------------------------------------------------------- /art/listener.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lingochamp/okdownload/cb6e20f2484927ef81728355fad3231bb87859a9/art/listener.png -------------------------------------------------------------------------------- /art/notification.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lingochamp/okdownload/cb6e20f2484927ef81728355fad3231bb87859a9/art/notification.gif -------------------------------------------------------------------------------- /art/okcat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lingochamp/okdownload/cb6e20f2484927ef81728355fad3231bb87859a9/art/okcat.png -------------------------------------------------------------------------------- /art/queue-download.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lingochamp/okdownload/cb6e20f2484927ef81728355fad3231bb87859a9/art/queue-download.gif -------------------------------------------------------------------------------- /art/sample-home.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lingochamp/okdownload/cb6e20f2484927ef81728355fad3231bb87859a9/art/sample-home.jpeg -------------------------------------------------------------------------------- /art/single-download.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lingochamp/okdownload/cb6e20f2484927ef81728355fad3231bb87859a9/art/single-download.gif -------------------------------------------------------------------------------- /benchmark/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /benchmark/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'kotlin-android' 3 | apply plugin: 'kotlin-android-extensions' 4 | android { 5 | compileSdkVersion rootProject.ext.compileSdkVersion 6 | buildToolsVersion rootProject.ext.buildToolsVersion 7 | 8 | compileOptions { 9 | sourceCompatibility rootProject.ext.sourceCompatibilityVersion 10 | targetCompatibility rootProject.ext.targetCompatibilityVersion 11 | } 12 | 13 | lintOptions { 14 | lintConfig file('lint.xml') 15 | textOutput 'stdout' 16 | textReport true 17 | } 18 | 19 | defaultConfig { 20 | applicationId "com.liulishuo.okdownload.benchmark" 21 | minSdkVersion rootProject.ext.minSdkVersion 22 | targetSdkVersion rootProject.ext.targetSdkVersion 23 | versionCode 1 24 | versionName "1.0" 25 | 26 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 27 | 28 | vectorDrawables.useSupportLibrary = true 29 | } 30 | buildTypes { 31 | release { 32 | minifyEnabled false 33 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 34 | } 35 | } 36 | } 37 | 38 | dependencies { 39 | implementation dep.kotlin 40 | 41 | implementation dep.supportV7 42 | implementation dep.supportDesign 43 | implementation dep.supportConstraintLayout 44 | 45 | testImplementation dep.junit 46 | } 47 | -------------------------------------------------------------------------------- /benchmark/lint.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /benchmark/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /benchmark/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 13 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /benchmark/src/main/java/cn/dreamtobe/okdownload/benchmark/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.liulishuo.okdownload.benchmark 2 | 3 | import android.os.Bundle 4 | import android.support.design.widget.BottomNavigationView 5 | import android.support.v7.app.AppCompatActivity 6 | import kotlinx.android.synthetic.main.activity_main.* 7 | 8 | class MainActivity : AppCompatActivity() { 9 | 10 | private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item -> 11 | when (item.itemId) { 12 | R.id.navigation_home -> { 13 | message.setText(R.string.title_home) 14 | return@OnNavigationItemSelectedListener true 15 | } 16 | R.id.navigation_dashboard -> { 17 | message.setText(R.string.title_dashboard) 18 | return@OnNavigationItemSelectedListener true 19 | } 20 | R.id.navigation_notifications -> { 21 | message.setText(R.string.title_notifications) 22 | return@OnNavigationItemSelectedListener true 23 | } 24 | } 25 | false 26 | } 27 | 28 | override fun onCreate(savedInstanceState: Bundle?) { 29 | super.onCreate(savedInstanceState) 30 | setContentView(R.layout.activity_main) 31 | 32 | navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /benchmark/src/main/res/drawable/ic_dashboard_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /benchmark/src/main/res/drawable/ic_home_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /benchmark/src/main/res/drawable/ic_notifications_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /benchmark/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 21 | 22 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /benchmark/src/main/res/menu/navigation.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 13 | 14 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /benchmark/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /benchmark/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /benchmark/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lingochamp/okdownload/cb6e20f2484927ef81728355fad3231bb87859a9/benchmark/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /benchmark/src/main/res/mipmap-hdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lingochamp/okdownload/cb6e20f2484927ef81728355fad3231bb87859a9/benchmark/src/main/res/mipmap-hdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /benchmark/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lingochamp/okdownload/cb6e20f2484927ef81728355fad3231bb87859a9/benchmark/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /benchmark/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lingochamp/okdownload/cb6e20f2484927ef81728355fad3231bb87859a9/benchmark/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /benchmark/src/main/res/mipmap-mdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lingochamp/okdownload/cb6e20f2484927ef81728355fad3231bb87859a9/benchmark/src/main/res/mipmap-mdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /benchmark/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lingochamp/okdownload/cb6e20f2484927ef81728355fad3231bb87859a9/benchmark/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /benchmark/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lingochamp/okdownload/cb6e20f2484927ef81728355fad3231bb87859a9/benchmark/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /benchmark/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lingochamp/okdownload/cb6e20f2484927ef81728355fad3231bb87859a9/benchmark/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /benchmark/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lingochamp/okdownload/cb6e20f2484927ef81728355fad3231bb87859a9/benchmark/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /benchmark/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lingochamp/okdownload/cb6e20f2484927ef81728355fad3231bb87859a9/benchmark/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /benchmark/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lingochamp/okdownload/cb6e20f2484927ef81728355fad3231bb87859a9/benchmark/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /benchmark/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lingochamp/okdownload/cb6e20f2484927ef81728355fad3231bb87859a9/benchmark/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /benchmark/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lingochamp/okdownload/cb6e20f2484927ef81728355fad3231bb87859a9/benchmark/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /benchmark/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lingochamp/okdownload/cb6e20f2484927ef81728355fad3231bb87859a9/benchmark/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png -------------------------------------------------------------------------------- /benchmark/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lingochamp/okdownload/cb6e20f2484927ef81728355fad3231bb87859a9/benchmark/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /benchmark/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #3F51B5 4 | #303F9F 5 | #FF4081 6 | 7 | -------------------------------------------------------------------------------- /benchmark/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 6 | -------------------------------------------------------------------------------- /benchmark/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | benchmark 3 | Home 4 | Dashboard 5 | Notifications 6 | 7 | -------------------------------------------------------------------------------- /benchmark/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /benchmark/src/main/res/xml/backup_descriptor.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | subprojects { 2 | buildscript { 3 | repositories { 4 | mavenCentral() 5 | } 6 | } 7 | repositories { 8 | mavenCentral() 9 | } 10 | 11 | group = GROUP 12 | version = VERSION_NAME 13 | } 14 | 15 | apply from: rootProject.file('gradle/dependencies.gradle') 16 | 17 | buildscript { 18 | repositories { 19 | jcenter() 20 | google() 21 | } 22 | dependencies { 23 | classpath 'com.liulishuo.okcheck:gradle:0.2.3' 24 | classpath 'com.android.tools.build:gradle:3.5.2' 25 | classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4' 26 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.50" 27 | classpath "org.jetbrains.dokka:dokka-gradle-plugin:0.10.0" 28 | } 29 | } 30 | 31 | allprojects { 32 | apply plugin: 'okcheck' 33 | repositories { 34 | jcenter() 35 | google() 36 | } 37 | 38 | okcheck { 39 | destination = buildDir 40 | } 41 | } 42 | 43 | task clean(type: Delete) { 44 | delete rootProject.buildDir 45 | } 46 | 47 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | codecov: 2 | branch: master 3 | notify: 4 | require_ci_to_pass: yes 5 | -------------------------------------------------------------------------------- /deploy-snapshot.sh: -------------------------------------------------------------------------------- 1 | ./gradlew clean uploadArchives 2 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx1536m 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | 15 | GROUP=com.liulishuo.okdownload 16 | VERSION_NAME=1.0.8-SNAPSHOT 17 | 18 | POM_URL=https://github.com/lingochamp/okdownload/ 19 | ISSUE_URL=https://github.com/lingochamp/okdownload/issues/ 20 | POM_SCM_URL=https://github.com/lingochamp/okdownload/ 21 | POM_SCM_CONNECTION=scm:git:git://github.com/lingochamp/okdownload.git 22 | POM_SCM_DEV_CONNECTION=scm:git:ssh://git@github.com/lingochamp/okdownload.git 23 | 24 | POM_LICENCE_NAME=The Apache Software License, Version 2.0 25 | POM_LICENCE_URL=http://www.apache.org/licenses/LICENSE-2.0.txt 26 | POM_LICENCE_DIST=repo 27 | 28 | POM_DEVELOPER_ID=jacksgong 29 | POM_DEVELOPER_NAME=Jacksgong.com. 30 | 31 | org.gradle.parallel=true 32 | -------------------------------------------------------------------------------- /gradle/codecov.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | apply plugin: 'jacoco' 18 | 19 | println "apply code-coverage" 20 | 21 | jacoco { 22 | toolVersion = "0.8.1" 23 | } 24 | 25 | tasks.withType(Test) { 26 | jacoco.includeNoLocationClasses = true 27 | } 28 | 29 | task jacocoTestReport(type: JacocoReport, dependsOn: ['testDebugUnitTest', 'createDebugCoverageReport']) { 30 | 31 | reports { 32 | xml.enabled = true 33 | html.enabled = true 34 | } 35 | 36 | def fileFilter = ['**/R.class', '**/R$*.class', '**/BuildConfig.*', '**/Manifest*.*', '**/*Test*.*', 'android/**/*.*'] 37 | def javaDebugTree = fileTree(dir: "${buildDir}/intermediates/javac/debug", excludes: fileFilter) 38 | def kotlinDebugTree = fileTree(dir: "${buildDir}/tmp/kotlin-classes/debug", excludes: fileFilter) 39 | def javaMainSrc = "${project.projectDir}/src/main/java" 40 | def kotlinMainSrc = "${project.projectDir}/src/main/kotlin" 41 | 42 | sourceDirectories = files([javaMainSrc, kotlinMainSrc]) 43 | classDirectories = files([javaDebugTree, kotlinDebugTree]) 44 | executionData = fileTree(dir: "$buildDir", includes: [ 45 | "jacoco/testDebugUnitTest.exec", 46 | "outputs/code-coverage/connected/*coverage.ec" 47 | ]) 48 | } 49 | 50 | android { 51 | buildTypes { 52 | debug { 53 | testCoverageEnabled true 54 | } 55 | } 56 | } 57 | 58 | project.tasks.whenTaskAdded { task -> 59 | if (task.name == "okcheckDebug" || task.name == 'okcheck') { 60 | task.dependsOn('jacocoTestReport') 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /gradle/gradle-mavenlocal.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | apply plugin: 'maven-publish' 18 | 19 | task sourceJar(type: Jar) { 20 | from android.sourceSets.main.java.srcDirs 21 | classifier "source" 22 | } 23 | 24 | publishing { 25 | publications { 26 | okdownload(MavenPublication) { 27 | groupId GROUP 28 | artifactId POM_ARTIFACT_ID 29 | version VERSION_NAME 30 | artifact(sourceJar) 31 | artifact("$buildDir/outputs/aar/${project.name}-release.aar") 32 | 33 | pom.withXml { 34 | def dependenciesNode = asNode().appendNode('dependencies') 35 | configurations.compile.allDependencies.each { 36 | if (it.group != null 37 | && (it.name != null || "unspecified" == it.name) 38 | && it.version != null) { 39 | def dependencyNode = dependenciesNode.appendNode('dependency') 40 | dependencyNode.appendNode('groupId', it.group) 41 | dependencyNode.appendNode('artifactId', it.name) 42 | dependencyNode.appendNode('version', it.version) 43 | } 44 | } 45 | } 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lingochamp/okdownload/cb6e20f2484927ef81728355fad3231bb87859a9/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sun Dec 01 00:35:30 CST 2019 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip 7 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /keystore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lingochamp/okdownload/cb6e20f2484927ef81728355fad3231bb87859a9/keystore -------------------------------------------------------------------------------- /okcat-okdownload.yml: -------------------------------------------------------------------------------- 1 | # You can use 'okcat -y=okcat-okdownload' to parse okdownload logcat runtime more easily. 2 | # More detail about okcat please move to https://github.com/Jacksgong/okcat 3 | package: com.liulishuo.okdownload.sample 4 | 5 | separator-regex-list: 6 | - 'enqueueLocked for (.*)' 7 | 8 | trans-tag-map: 9 | 'BunchActivity' : '[DEMO]' 10 | 'NotificationActivity' : '[DEMO]' 11 | 'RemitSyncExecutor' : '[REMIT DATABASE]' 12 | 13 | trans-msg-map: 14 | 'taskEnd ' : 'TASK END' 15 | 'downloadFromBreakpoint ': 'RESUMABLE' 16 | '----->' : 'REQUEST' 17 | '<-----' : 'RESPONSE' 18 | 'call is finished' : 'FINISH CALL' 19 | 'cancel task' : 'TASK CANCELED' 20 | 'finish cancel bunch task' : 'BUNCH TASK CANCELED' 21 | 'breakpoint invalid' : 'CANNOT RESUME' 22 | 'endTasks' : 'BUNCH END CALLBACKS' 23 | 'OutputStream sync success' : 'SAVED BREAKPOINT' 24 | 'OutputStream close' : 'CLOSE FILE STREAM' 25 | 'Create output stream' : 'CREATE OUTPUT-STREAM' 26 | 'AssembleHeaderRange (' : 'REQUEST RANGE FROM' 27 | 'OutputStream start flush looper' : 'FLUSH STREAM LOOPER' 28 | 'SingleBlock special check' : 'SPECIAL CASE' 29 | 30 | highlight-list: 31 | - 'connectStart' 32 | - 'fetchEnd' 33 | - 'task' 34 | - 'block' 35 | - 'waiting for sync cache to disk' 36 | - 'isNoMoreStream' 37 | - 'newNoMoreStreamBlockList' 38 | -------------------------------------------------------------------------------- /okdownload-breakpoint-sqlite/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /okdownload-breakpoint-sqlite/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion rootProject.ext.compileSdkVersion 5 | buildToolsVersion rootProject.ext.buildToolsVersion 6 | 7 | compileOptions { 8 | sourceCompatibility rootProject.ext.sourceCompatibilityVersion 9 | targetCompatibility rootProject.ext.targetCompatibilityVersion 10 | } 11 | 12 | dexOptions { 13 | preDexLibraries = !rootProject.ext.isCi 14 | } 15 | 16 | defaultConfig { 17 | minSdkVersion rootProject.ext.minSdkVersion 18 | } 19 | } 20 | 21 | dependencies { 22 | testImplementation dep.junit 23 | testImplementation dep.mockito 24 | testImplementation dep.assertj 25 | testImplementation dep.robolectric 26 | testImplementation project(':okdownload') 27 | 28 | implementation dep.supportAnnotations 29 | 30 | compileOnly project(':okdownload') 31 | } 32 | 33 | apply from: rootProject.file('gradle/gradle-mvn-push.gradle') 34 | if (hasProperty("isCI")) { 35 | apply from: rootProject.file('gradle/codecov.gradle') 36 | } 37 | -------------------------------------------------------------------------------- /okdownload-breakpoint-sqlite/gradle.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2017 LingoChamp Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | POM_ARTIFACT_ID=sqlite 18 | POM_NAME=OkDownload-SQLite 19 | POM_DESCRIPTION=A sqlite support for OkDownload 20 | POM_PACKAGING=aar 21 | -------------------------------------------------------------------------------- /okdownload-breakpoint-sqlite/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /okdownload-breakpoint-sqlite/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /okdownload-breakpoint-sqlite/src/main/java/com/liulishuo/okdownload/core/breakpoint/BlockInfoRow.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload.core.breakpoint; 18 | 19 | import android.database.Cursor; 20 | 21 | import static com.liulishuo.okdownload.core.breakpoint.BreakpointSQLiteKey.CONTENT_LENGTH; 22 | import static com.liulishuo.okdownload.core.breakpoint.BreakpointSQLiteKey.CURRENT_OFFSET; 23 | import static com.liulishuo.okdownload.core.breakpoint.BreakpointSQLiteKey.HOST_ID; 24 | import static com.liulishuo.okdownload.core.breakpoint.BreakpointSQLiteKey.START_OFFSET; 25 | 26 | public class BlockInfoRow { 27 | private final int breakpointId; 28 | 29 | private final long startOffset; 30 | private final long contentLength; 31 | private final long currentOffset; 32 | 33 | public BlockInfoRow(Cursor cursor) { 34 | this.breakpointId = cursor.getInt(cursor.getColumnIndex(HOST_ID)); 35 | this.startOffset = cursor.getInt(cursor.getColumnIndex(START_OFFSET)); 36 | this.contentLength = cursor.getInt(cursor.getColumnIndex(CONTENT_LENGTH)); 37 | this.currentOffset = cursor.getInt(cursor.getColumnIndex(CURRENT_OFFSET)); 38 | } 39 | 40 | public int getBreakpointId() { 41 | return breakpointId; 42 | } 43 | 44 | public long getStartOffset() { 45 | return startOffset; 46 | } 47 | 48 | public long getContentLength() { 49 | return contentLength; 50 | } 51 | 52 | public long getCurrentOffset() { 53 | return currentOffset; 54 | } 55 | 56 | public BlockInfo toInfo() { 57 | return new BlockInfo(startOffset, contentLength, currentOffset); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /okdownload-breakpoint-sqlite/src/main/java/com/liulishuo/okdownload/core/breakpoint/BreakpointSQLiteKey.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload.core.breakpoint; 18 | 19 | public interface BreakpointSQLiteKey { 20 | String ID = "id"; 21 | String URL = "url"; 22 | String ETAG = "etag"; 23 | 24 | String PARENT_PATH = "parent_path"; 25 | String FILENAME = "filename"; 26 | String TASK_ONLY_PARENT_PATH = "task_only_parent_path"; 27 | String CHUNKED = "chunked"; 28 | 29 | String HOST_ID = "breakpoint_id"; 30 | String BLOCK_INDEX = "block_index"; 31 | String START_OFFSET = "start_offset"; 32 | String CONTENT_LENGTH = "content_length"; 33 | String CURRENT_OFFSET = "current_offset"; 34 | } 35 | -------------------------------------------------------------------------------- /okdownload-breakpoint-sqlite/src/main/java/com/liulishuo/okdownload/core/breakpoint/RemitSyncToDBHelper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload.core.breakpoint; 18 | 19 | import android.support.annotation.NonNull; 20 | 21 | class RemitSyncToDBHelper { 22 | 23 | private final RemitSyncExecutor executor; 24 | 25 | long delayMillis; 26 | 27 | RemitSyncToDBHelper(@NonNull final RemitSyncExecutor.RemitAgent agent) { 28 | this(new RemitSyncExecutor(agent)); 29 | } 30 | 31 | RemitSyncToDBHelper(@NonNull final RemitSyncExecutor executor) { 32 | this.executor = executor; 33 | this.delayMillis = 1500; 34 | } 35 | 36 | void shutdown() { 37 | this.executor.shutdown(); 38 | } 39 | 40 | boolean isNotFreeToDatabase(int id) { 41 | return !executor.isFreeToDatabase(id); 42 | } 43 | 44 | void onTaskStart(int id) { 45 | // discard pending sync if we can 46 | executor.removePostWithId(id); 47 | 48 | executor.postSyncInfoDelay(id, delayMillis); 49 | } 50 | 51 | void endAndEnsureToDB(int id) { 52 | executor.removePostWithId(id); 53 | 54 | try { 55 | // already synced 56 | if (executor.isFreeToDatabase(id)) return; 57 | 58 | // force sync for ids 59 | executor.postSync(id); 60 | } finally { 61 | // remove free state 62 | executor.postRemoveFreeId(id); 63 | } 64 | } 65 | 66 | void discard(int id) { 67 | executor.removePostWithId(id); 68 | executor.postRemoveInfo(id); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /okdownload-breakpoint-sqlite/src/main/java/com/liulishuo/okdownload/core/exception/SQLiteException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload.core.exception; 18 | 19 | import java.io.IOException; 20 | 21 | public class SQLiteException extends IOException { 22 | public SQLiteException(String message) { 23 | super(message); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /okdownload-breakpoint-sqlite/src/test/java/com/liulishuo/okdownload/core/exception/SQLiteExceptionTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload.core.exception; 18 | 19 | import org.junit.Test; 20 | 21 | import static org.assertj.core.api.Java6Assertions.assertThat; 22 | 23 | public class SQLiteExceptionTest { 24 | 25 | @Test 26 | public void constructor() { 27 | final SQLiteException exception = new SQLiteException("message"); 28 | assertThat(exception.getMessage()).isEqualTo("message"); 29 | } 30 | } -------------------------------------------------------------------------------- /okdownload-connection-okhttp/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /okdownload-connection-okhttp/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion rootProject.ext.compileSdkVersion 5 | buildToolsVersion rootProject.ext.buildToolsVersion 6 | 7 | compileOptions { 8 | sourceCompatibility rootProject.ext.sourceCompatibilityVersion 9 | targetCompatibility rootProject.ext.targetCompatibilityVersion 10 | } 11 | 12 | dexOptions { 13 | preDexLibraries = !rootProject.ext.isCi 14 | } 15 | 16 | defaultConfig { 17 | minSdkVersion rootProject.ext.minSdkVersion 18 | 19 | consumerProguardFiles 'consumer-proguard-rules.txt' 20 | } 21 | } 22 | 23 | dependencies { 24 | testImplementation dep.junit 25 | testImplementation dep.mockito 26 | testImplementation dep.assertj 27 | testImplementation project(':okdownload') 28 | 29 | compileOnly project(':okdownload') 30 | 31 | implementation dep.okhttp3 32 | implementation dep.supportAnnotations 33 | } 34 | 35 | apply from: rootProject.file('gradle/gradle-mvn-push.gradle') 36 | if (hasProperty("isCI")) { 37 | apply from: rootProject.file('gradle/codecov.gradle') 38 | } 39 | -------------------------------------------------------------------------------- /okdownload-connection-okhttp/consumer-proguard-rules.txt: -------------------------------------------------------------------------------- 1 | ### OKHTTP 2 | 3 | # Platform calls Class.forName on types which do not exist on Android to determine platform. 4 | -dontnote okhttp3.internal.Platform 5 | -------------------------------------------------------------------------------- /okdownload-connection-okhttp/gradle.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2018 LingoChamp Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | POM_ARTIFACT_ID=okhttp 18 | POM_NAME=OkDownload-OkHttp 19 | POM_DESCRIPTION=A okhttp support for OkDownload 20 | POM_PACKAGING=aar 21 | -------------------------------------------------------------------------------- /okdownload-connection-okhttp/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/Jacksgong/sdk/android-sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /okdownload-connection-okhttp/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /okdownload-filedownloader/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /okdownload-filedownloader/build.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | apply plugin: 'com.android.library' 18 | 19 | android { 20 | compileSdkVersion rootProject.ext.compileSdkVersion 21 | buildToolsVersion rootProject.ext.buildToolsVersion 22 | 23 | compileOptions { 24 | sourceCompatibility rootProject.ext.sourceCompatibilityVersion 25 | targetCompatibility rootProject.ext.targetCompatibilityVersion 26 | } 27 | 28 | dexOptions { 29 | preDexLibraries = !rootProject.ext.isCi 30 | } 31 | 32 | defaultConfig { 33 | minSdkVersion rootProject.ext.minSdkVersion 34 | } 35 | } 36 | 37 | dependencies { 38 | testImplementation dep.junit 39 | testImplementation dep.mockito 40 | testImplementation dep.assertj 41 | testImplementation dep.robolectric 42 | testImplementation project(':okdownload') 43 | 44 | implementation project(':okdownload') 45 | implementation project(':okhttp') 46 | implementation dep.okhttp3 47 | 48 | implementation dep.supportAnnotations 49 | 50 | compileOnly dep.findbugsAnnotations 51 | } 52 | 53 | apply from: rootProject.file('gradle/gradle-mvn-push.gradle') 54 | -------------------------------------------------------------------------------- /okdownload-filedownloader/gradle.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2018 LingoChamp Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | POM_ARTIFACT_ID=filedownloader 18 | POM_NAME=OkDownload-FileDownloader 19 | POM_DESCRIPTION=A seamlessly replce of FileDownloader 20 | POM_PACKAGING=aar 21 | -------------------------------------------------------------------------------- /okdownload-filedownloader/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /okdownload-filedownloader/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 19 | -------------------------------------------------------------------------------- /okdownload-filedownloader/src/main/java/com/liulishuo/filedownloader/FileDownloadConnectListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.filedownloader; 18 | 19 | import com.liulishuo.filedownloader.event.IDownloadEvent; 20 | import com.liulishuo.filedownloader.event.IDownloadListener; 21 | 22 | /** 23 | * The listener for listening whether the service establishes connection or disconnected. 24 | * 25 | */ 26 | @Deprecated 27 | public abstract class FileDownloadConnectListener extends IDownloadListener { 28 | 29 | 30 | public FileDownloadConnectListener() { 31 | } 32 | 33 | @Override 34 | public boolean callback(IDownloadEvent event) { 35 | return false; 36 | } 37 | 38 | /** 39 | * connected file download service 40 | */ 41 | public abstract void connected(); 42 | 43 | /** 44 | * disconnected file download service 45 | */ 46 | public abstract void disconnected(); 47 | 48 | } 49 | -------------------------------------------------------------------------------- /okdownload-filedownloader/src/main/java/com/liulishuo/filedownloader/FileDownloadLine.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.filedownloader; 18 | 19 | import android.app.Notification; 20 | 21 | /** 22 | * The FileDownload synchronous line. 23 | * 24 | * @see FileDownloader#insureServiceBind() 25 | */ 26 | 27 | public class FileDownloadLine { 28 | 29 | @Deprecated 30 | public void startForeground(final int id, final Notification notification) { 31 | // do nothing 32 | } 33 | 34 | /** 35 | * The {@link FileDownloader#getSoFar(int)} request. 36 | */ 37 | public long getSoFar(final int id) { 38 | return FileDownloader.getImpl().getSoFar(id); 39 | } 40 | 41 | /** 42 | * The {@link FileDownloader#getTotal(int)} request. 43 | */ 44 | public long getTotal(final int id) { 45 | return FileDownloader.getImpl().getTotal(id); 46 | } 47 | 48 | /** 49 | * The {@link FileDownloader#getStatus(int, String)} request. 50 | */ 51 | public byte getStatus(final int id, final String path) { 52 | return FileDownloader.getImpl().getStatus(id, path); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /okdownload-filedownloader/src/main/java/com/liulishuo/filedownloader/FileDownloadLineAsync.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.filedownloader; 18 | 19 | import android.app.Notification; 20 | 21 | /** 22 | * The FileDownloader asynchronous line. 23 | */ 24 | @Deprecated 25 | public class FileDownloadLineAsync { 26 | 27 | @Deprecated 28 | public boolean startForeground(final int id, final Notification notification) { 29 | return false; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /okdownload-filedownloader/src/main/java/com/liulishuo/filedownloader/FileDownloadListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.filedownloader; 18 | 19 | public abstract class FileDownloadListener { 20 | 21 | public FileDownloadListener() { 22 | } 23 | 24 | public FileDownloadListener(int priority) { 25 | } 26 | 27 | protected boolean isInvalid() { 28 | return false; 29 | } 30 | 31 | protected abstract void pending(BaseDownloadTask task, int soFarBytes, 32 | int totalBytes); 33 | 34 | protected void started(BaseDownloadTask task) { 35 | } 36 | 37 | protected void connected(BaseDownloadTask task, String etag, 38 | boolean isContinue, int soFarBytes, int totalBytes) { 39 | } 40 | 41 | protected abstract void progress(BaseDownloadTask task, int soFarBytes, 42 | int totalBytes); 43 | 44 | protected void blockComplete(BaseDownloadTask task) throws Throwable { 45 | } 46 | 47 | protected void retry(BaseDownloadTask task, Throwable ex, int retryingTimes, 48 | int soFarBytes) { 49 | } 50 | 51 | protected abstract void completed(BaseDownloadTask task); 52 | 53 | protected abstract void paused(BaseDownloadTask task, int soFarBytes, 54 | int totalBytes); 55 | 56 | protected abstract void error(BaseDownloadTask task, Throwable e); 57 | 58 | protected abstract void warn(BaseDownloadTask task); 59 | 60 | } 61 | -------------------------------------------------------------------------------- /okdownload-filedownloader/src/main/java/com/liulishuo/filedownloader/FileDownloadSampleListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.filedownloader; 18 | 19 | /** 20 | * Simplify the {@link FileDownloadListener}. 21 | */ 22 | public class FileDownloadSampleListener extends FileDownloadListener { 23 | 24 | @Override 25 | protected void pending(BaseDownloadTask task, int soFarBytes, int totalBytes) { 26 | 27 | } 28 | 29 | @Override 30 | protected void progress(BaseDownloadTask task, int soFarBytes, int totalBytes) { 31 | 32 | } 33 | 34 | @Override 35 | protected void blockComplete(BaseDownloadTask task) { 36 | 37 | } 38 | 39 | @Override 40 | protected void completed(BaseDownloadTask task) { 41 | 42 | } 43 | 44 | @Override 45 | protected void paused(BaseDownloadTask task, int soFarBytes, int totalBytes) { 46 | 47 | } 48 | 49 | @Override 50 | protected void error(BaseDownloadTask task, Throwable e) { 51 | 52 | } 53 | 54 | @Override 55 | protected void warn(BaseDownloadTask task) { 56 | 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /okdownload-filedownloader/src/main/java/com/liulishuo/filedownloader/IDownloadSpeed.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.filedownloader; 18 | 19 | /** 20 | * The interface for the downloading speed. 21 | */ 22 | 23 | public interface IDownloadSpeed { 24 | 25 | /** 26 | * The downloading monitor, used for calculating downloading speed. 27 | */ 28 | interface Monitor { 29 | /** 30 | * Start the monitor. 31 | */ 32 | void start(long startBytes); 33 | 34 | /** 35 | * End the monitor, and calculate the average speed during the entire downloading processing 36 | * 37 | * @param sofarBytes The so far downloaded bytes. 38 | */ 39 | void end(long sofarBytes); 40 | 41 | /** 42 | * Refresh the downloading speed. 43 | * 44 | * @param sofarBytes The so far downloaded bytes. 45 | */ 46 | void update(long sofarBytes); 47 | 48 | /** 49 | * Reset the monitor. 50 | */ 51 | void reset(); 52 | 53 | } 54 | 55 | /** 56 | * For lookup the downloading speed data. 57 | */ 58 | interface Lookup { 59 | /** 60 | * @return The currently downloading speed when the task is running. 61 | * The average speed when the task is finished. 62 | */ 63 | int getSpeed(); 64 | 65 | /** 66 | * @param minIntervalUpdateSpeed The minimum interval to update the speed, used to adjust 67 | * the refresh frequent. 68 | */ 69 | void setMinIntervalUpdateSpeed(int minIntervalUpdateSpeed); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /okdownload-filedownloader/src/main/java/com/liulishuo/filedownloader/event/IDownloadEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.filedownloader.event; 18 | 19 | 20 | import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; 21 | 22 | /** 23 | * An atom event. 24 | */ 25 | @SuppressWarnings({"WeakerAccess", "CanBeFinal"}) 26 | public abstract class IDownloadEvent { 27 | @SuppressFBWarnings(value = "URF", justification = "Not so urgency") 28 | public Runnable callback = null; 29 | 30 | public IDownloadEvent(final String id) { 31 | this.id = id; 32 | } 33 | 34 | /** 35 | * @see #IDownloadEvent(String) 36 | * @deprecated do not handle ORDER any more. 37 | */ 38 | public IDownloadEvent(final String id, boolean order) { 39 | this.id = id; 40 | } 41 | 42 | @SuppressWarnings("WeakerAccess") 43 | protected final String id; 44 | 45 | public final String getId() { 46 | return this.id; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /okdownload-filedownloader/src/main/java/com/liulishuo/filedownloader/event/IDownloadListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.filedownloader.event; 18 | 19 | /** 20 | * The listener is used to listen the publish event from Event Pool. 21 | * 22 | * @see IDownloadEvent 23 | */ 24 | public abstract class IDownloadListener { 25 | 26 | public abstract boolean callback(IDownloadEvent event); 27 | 28 | } 29 | -------------------------------------------------------------------------------- /okdownload-filedownloader/src/main/java/com/liulishuo/filedownloader/exception/FileDownloadGiveUpRetryException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package com.liulishuo.filedownloader.exception; 17 | 18 | /** 19 | * Throwing this exception, when we can't know the size of the download file, and its 20 | * Transfer-Encoding is not Chunked either. 21 | *

22 | * When you occur this type exception, the chance of retry will be ignored. 23 | */ 24 | public class FileDownloadGiveUpRetryException extends RuntimeException { 25 | public FileDownloadGiveUpRetryException(final String detailMessage) { 26 | super(detailMessage); 27 | } 28 | } -------------------------------------------------------------------------------- /okdownload-filedownloader/src/main/java/com/liulishuo/filedownloader/exception/FileDownloadNetworkPolicyException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.filedownloader.exception; 18 | 19 | import com.liulishuo.filedownloader.BaseDownloadTask; 20 | 21 | /** 22 | * Throw this exception, If you have set {@code true} to {@link BaseDownloadTask#setWifiRequired} 23 | * when starting downloading with the network type isn't wifi or in downloading state the network 24 | * type change to non-Wifi type. 25 | */ 26 | 27 | public class FileDownloadNetworkPolicyException extends FileDownloadGiveUpRetryException { 28 | public FileDownloadNetworkPolicyException() { 29 | super("Only allows downloading this task on the wifi network type"); 30 | } 31 | } -------------------------------------------------------------------------------- /okdownload-filedownloader/src/main/java/com/liulishuo/filedownloader/exception/FileDownloadSecurityException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.filedownloader.exception; 18 | 19 | /** 20 | * Throwing this exception, when there are some security issues found on FileDownloader. 21 | */ 22 | public class FileDownloadSecurityException extends Exception { 23 | public FileDownloadSecurityException(String msg) { 24 | super(msg); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /okdownload-filedownloader/src/main/java/com/liulishuo/filedownloader/model/ConnectionModel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.filedownloader.model; 18 | 19 | /** 20 | * The connection model used for record each connections on multiple connections case. 21 | */ 22 | 23 | public class ConnectionModel { 24 | 25 | } 26 | -------------------------------------------------------------------------------- /okdownload-filedownloader/src/main/java/com/liulishuo/filedownloader/model/FileDownloadModel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.filedownloader.model; 18 | 19 | import com.liulishuo.filedownloader.database.FileDownloadDatabase; 20 | 21 | /** 22 | * The model of the downloading task will be used in the filedownloader database. 23 | * 24 | * @see FileDownloadDatabase 25 | */ 26 | @SuppressWarnings("WeakerAccess") 27 | public class FileDownloadModel { 28 | 29 | 30 | } 31 | -------------------------------------------------------------------------------- /okdownload-filedownloader/src/main/java/com/liulishuo/filedownloader/retry/RetryAssist.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.filedownloader.retry; 18 | 19 | import android.support.annotation.NonNull; 20 | import com.liulishuo.okdownload.DownloadTask; 21 | 22 | import java.util.concurrent.atomic.AtomicInteger; 23 | 24 | public class RetryAssist { 25 | 26 | @NonNull 27 | final AtomicInteger retriedTimes; 28 | final int retryTimes; 29 | 30 | public RetryAssist(int retryTimes) { 31 | this.retryTimes = retryTimes; 32 | this.retriedTimes = new AtomicInteger(0); 33 | } 34 | 35 | public void doRetry(@NonNull DownloadTask task) { 36 | final int retryingTime = retriedTimes.incrementAndGet(); 37 | if (retryingTime > retryTimes) { 38 | throw new RuntimeException("retry has exceeded limit"); 39 | } 40 | task.enqueue(task.getListener()); 41 | } 42 | 43 | public boolean canRetry() { 44 | return retriedTimes.get() < retryTimes; 45 | } 46 | 47 | public int getRetriedTimes() { 48 | return retriedTimes.get(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /okdownload-filedownloader/src/main/java/com/liulishuo/filedownloader/services/ForegroundServiceConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.filedownloader.services; 18 | 19 | import android.annotation.TargetApi; 20 | import android.app.Notification; 21 | import android.content.Context; 22 | 23 | /** 24 | * No service in OkDownload, so this configuration class is useless. 25 | */ 26 | @Deprecated 27 | @TargetApi(26) 28 | public class ForegroundServiceConfig { 29 | 30 | private ForegroundServiceConfig() { 31 | } 32 | 33 | private Notification buildDefaultNotification(Context context) { 34 | return null; 35 | } 36 | 37 | public static class Builder { 38 | 39 | public Builder notificationId(int notificationId) { 40 | return this; 41 | } 42 | 43 | public Builder notificationChannelId(String notificationChannelId) { 44 | return this; 45 | } 46 | 47 | public Builder notificationChannelName(String notificationChannelName) { 48 | return this; 49 | } 50 | 51 | public Builder notification(Notification notification) { 52 | return this; 53 | } 54 | 55 | public Builder needRecreateChannelId(boolean needRecreateChannelId) { 56 | return this; 57 | } 58 | 59 | public ForegroundServiceConfig build() { 60 | return new ForegroundServiceConfig(); 61 | } 62 | } 63 | } -------------------------------------------------------------------------------- /okdownload-filedownloader/src/main/java/com/liulishuo/filedownloader/status/StatusAssist.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.filedownloader.status; 18 | 19 | import com.liulishuo.filedownloader.model.FileDownloadStatus; 20 | import com.liulishuo.filedownloader.util.FileDownloadUtils; 21 | import com.liulishuo.okdownload.DownloadTask; 22 | import com.liulishuo.okdownload.StatusUtil; 23 | 24 | public class StatusAssist { 25 | 26 | private byte status = FileDownloadStatus.INVALID_STATUS; 27 | 28 | private DownloadTask downloadTask; 29 | 30 | public synchronized void setDownloadTask(DownloadTask downloadTask) { 31 | this.downloadTask = downloadTask; 32 | } 33 | 34 | public synchronized DownloadTask getDownloadTask() { 35 | return downloadTask; 36 | } 37 | 38 | public synchronized byte getStatus() { 39 | if (downloadTask == null) { 40 | return status; 41 | } 42 | StatusUtil.Status okDownloadStatus = StatusUtil.getStatus(downloadTask); 43 | status = convert(okDownloadStatus); 44 | return status; 45 | } 46 | 47 | private synchronized byte convert(StatusUtil.Status status) { 48 | return FileDownloadUtils.convertDownloadStatus(status); 49 | } 50 | 51 | public synchronized boolean isUsing() { 52 | return getStatus() != FileDownloadStatus.INVALID_STATUS; 53 | } 54 | 55 | public synchronized boolean isOver() { 56 | return FileDownloadStatus.isOver(getStatus()); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /okdownload-kotlin-enhance/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /okdownload-kotlin-enhance/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'kotlin-android' 3 | apply plugin: 'org.jetbrains.dokka' 4 | 5 | android { 6 | compileSdkVersion rootProject.ext.compileSdkVersion 7 | buildToolsVersion rootProject.ext.buildToolsVersion 8 | 9 | compileOptions { 10 | sourceCompatibility rootProject.ext.sourceCompatibilityVersion 11 | targetCompatibility rootProject.ext.targetCompatibilityVersion 12 | } 13 | 14 | dexOptions { 15 | preDexLibraries = !rootProject.ext.isCi 16 | } 17 | 18 | defaultConfig { 19 | minSdkVersion rootProject.ext.minSdkVersion 20 | } 21 | 22 | sourceSets { 23 | main.java.srcDirs += 'src/main/kotlin' 24 | } 25 | } 26 | 27 | dependencies { 28 | testImplementation dep.junit 29 | testImplementation dep.mockk 30 | testImplementation dep.assertj 31 | testImplementation project(':okdownload') 32 | testImplementation dep.robolectric 33 | 34 | implementation dep.kotlin 35 | implementation dep.kotlinxCoroutines 36 | compileOnly project(':okdownload') 37 | } 38 | 39 | dokka { 40 | outputFormat = 'html' 41 | outputDirectory = "$buildDir/docs/javadoc" 42 | } 43 | 44 | tasks.withType(Javadoc).all { 45 | excludes = ['**/*.kt'] 46 | dependsOn dokka 47 | } 48 | 49 | apply from: rootProject.file('gradle/gradle-mvn-push.gradle') 50 | if (hasProperty("isCI")) { 51 | apply from: rootProject.file('gradle/codecov.gradle') 52 | } -------------------------------------------------------------------------------- /okdownload-kotlin-enhance/gradle.properties: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright (c) 2018 LingoChamp Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | POM_ARTIFACT_ID=ktx 18 | POM_NAME=OkDownload-Kotlin-Extension 19 | POM_DESCRIPTION=A kotlin extension for OkDownload 20 | POM_PACKAGING=aar 21 | -------------------------------------------------------------------------------- /okdownload-kotlin-enhance/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /okdownload-kotlin-enhance/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /okdownload-kotlin-enhance/src/main/kotlin/com.liulishuo.okdownload.kotlin/DownloadProgress.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload.kotlin 18 | 19 | import com.liulishuo.okdownload.DownloadTask 20 | 21 | /** 22 | * This data class presents a single task progress and 23 | * provides some methods to get the progress info. 24 | */ 25 | data class DownloadProgress( 26 | val task: DownloadTask, 27 | val currentOffset: Long, 28 | val totalOffset: Long 29 | ) { 30 | companion object { 31 | private const val UNKNOWN_TOTAL_OFFSET = -1L 32 | const val UNKNOWN_PROGRESS = 0f 33 | } 34 | 35 | fun totalUnknown(): Boolean = totalOffset == UNKNOWN_TOTAL_OFFSET 36 | 37 | fun progress(): Float = when (totalOffset) { 38 | UNKNOWN_TOTAL_OFFSET -> UNKNOWN_PROGRESS 39 | 0L -> if (currentOffset == 0L) 1f else UNKNOWN_PROGRESS 40 | else -> currentOffset * 1.0f / totalOffset 41 | } 42 | } -------------------------------------------------------------------------------- /okdownload-kotlin-enhance/src/main/kotlin/com.liulishuo.okdownload.kotlin/DownloadResult.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload.kotlin 18 | 19 | import com.liulishuo.okdownload.core.cause.EndCause 20 | 21 | /** 22 | * This class only represents download successful. 23 | */ 24 | data class DownloadResult(val cause: EndCause) { 25 | fun becauseOfCompleted(): Boolean = cause == EndCause.COMPLETED 26 | fun becauseOfRepeatedTask(): Boolean = 27 | cause == EndCause.SAME_TASK_BUSY || cause == EndCause.FILE_BUSY 28 | } -------------------------------------------------------------------------------- /okdownload-kotlin-enhance/src/main/kotlin/com.liulishuo.okdownload.kotlin/listener/DownloadContextListenerExtension.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload.kotlin.listener 18 | 19 | import com.liulishuo.okdownload.DownloadContext 20 | import com.liulishuo.okdownload.DownloadContextListener 21 | import com.liulishuo.okdownload.DownloadTask 22 | import com.liulishuo.okdownload.core.cause.EndCause 23 | import java.lang.Exception 24 | 25 | /** 26 | * Correspond to [com.liulishuo.okdownload.DownloadContextListener.taskEnd]. 27 | */ 28 | typealias onQueueTaskEnd = ( 29 | context: DownloadContext, 30 | task: DownloadTask, 31 | cause: EndCause, 32 | realException: Exception?, 33 | remainCount: Int 34 | ) -> Unit 35 | 36 | /** 37 | * Correspond to [com.liulishuo.okdownload.DownloadContextListener.queueEnd]. 38 | */ 39 | typealias onQueueEnd = (context: DownloadContext) -> Unit 40 | 41 | /** 42 | * A concise way to create a [DownloadContextListener], only the 43 | * [DownloadContextListener.queueEnd] is necessary. 44 | */ 45 | fun createDownloadContextListener( 46 | onQueueTaskEnd: onQueueTaskEnd? = null, 47 | onQueueEnd: onQueueEnd 48 | ): DownloadContextListener = object : DownloadContextListener { 49 | override fun taskEnd( 50 | context: DownloadContext, 51 | task: DownloadTask, 52 | cause: EndCause, 53 | realCause: Exception?, 54 | remainCount: Int 55 | ) { 56 | onQueueTaskEnd?.invoke(context, task, cause, realCause, remainCount) 57 | } 58 | 59 | override fun queueEnd(context: DownloadContext) = onQueueEnd(context) 60 | } -------------------------------------------------------------------------------- /okdownload-kotlin-enhance/src/main/kotlin/com.liulishuo.okdownload.kotlin/listener/DownloadListener2Extension.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload.kotlin.listener 18 | 19 | import com.liulishuo.okdownload.DownloadTask 20 | import com.liulishuo.okdownload.core.cause.EndCause 21 | import com.liulishuo.okdownload.core.listener.DownloadListener2 22 | import java.lang.Exception 23 | 24 | /** 25 | * A concise way to create a [DownloadListener2], only the [DownloadListener2.taskEnd] is necessary. 26 | */ 27 | fun createListener2( 28 | onTaskStart: onTaskStart = {}, 29 | onTaskEnd: onTaskEnd 30 | ): DownloadListener2 = object : DownloadListener2() { 31 | override fun taskStart(task: DownloadTask) = onTaskStart(task) 32 | 33 | override fun taskEnd(task: DownloadTask, cause: EndCause, realCause: Exception?) = 34 | onTaskEnd(task, cause, realCause) 35 | } -------------------------------------------------------------------------------- /okdownload-kotlin-enhance/src/test/java/com/liulishuo/okdownload/kotlin/DownloadListener2ExtensionTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload.kotlin 18 | 19 | import com.liulishuo.okdownload.DownloadTask 20 | import com.liulishuo.okdownload.core.cause.EndCause 21 | import com.liulishuo.okdownload.kotlin.listener.createListener2 22 | import com.liulishuo.okdownload.kotlin.listener.onTaskEnd 23 | import com.liulishuo.okdownload.kotlin.listener.onTaskStart 24 | import io.mockk.MockKAnnotations 25 | import io.mockk.confirmVerified 26 | import io.mockk.impl.annotations.MockK 27 | import io.mockk.verify 28 | import org.junit.Before 29 | import org.junit.Test 30 | import java.lang.Exception 31 | 32 | class DownloadListener2ExtensionTest { 33 | 34 | @MockK 35 | lateinit var onTaskStart: onTaskStart 36 | @MockK 37 | lateinit var onTaskEnd: onTaskEnd 38 | @MockK 39 | lateinit var mockTask: DownloadTask 40 | @MockK 41 | lateinit var mockCause: EndCause 42 | @MockK 43 | lateinit var mockException: Exception 44 | 45 | @Before 46 | fun setup() = MockKAnnotations.init(this, relaxed = true) 47 | 48 | @Test 49 | fun `create DownloadListener2`() { 50 | val listener2 = createListener2(onTaskStart) { task, cause, realCause -> 51 | onTaskEnd(task, cause, realCause) 52 | } 53 | 54 | listener2.taskStart(mockTask) 55 | verify { onTaskStart(mockTask) } 56 | confirmVerified(onTaskStart) 57 | 58 | listener2.taskEnd(mockTask, mockCause, mockException) 59 | verify { onTaskEnd(mockTask, mockCause, mockException) } 60 | confirmVerified(onTaskEnd) 61 | } 62 | } -------------------------------------------------------------------------------- /okdownload-kotlin-enhance/src/test/java/com/liulishuo/okdownload/kotlin/DownloadProgressTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload.kotlin 18 | 19 | import com.liulishuo.okdownload.DownloadTask 20 | import io.mockk.MockKAnnotations 21 | import io.mockk.impl.annotations.MockK 22 | import org.junit.Before 23 | import org.junit.Test 24 | 25 | class DownloadProgressTest { 26 | 27 | @MockK 28 | lateinit var mockTask: DownloadTask 29 | 30 | @Before 31 | fun setup() = MockKAnnotations.init(this) 32 | 33 | @Test 34 | fun `totalUnknown returns true`() { 35 | val dp = DownloadProgress(mockTask, 100, -1) 36 | assert(dp.totalUnknown()) 37 | } 38 | 39 | @Test 40 | fun `totalUnknown returns false`() { 41 | val dp = DownloadProgress(mockTask, 100, 200) 42 | assert(!dp.totalUnknown()) 43 | } 44 | 45 | @Test 46 | fun `progress returns unknown progress`() { 47 | val dp1 = DownloadProgress(mockTask, 100, -1) 48 | assert(dp1.progress() == DownloadProgress.UNKNOWN_PROGRESS) 49 | 50 | val dp2 = DownloadProgress(mockTask, 1, 0) 51 | assert(dp2.progress() == DownloadProgress.UNKNOWN_PROGRESS) 52 | } 53 | 54 | @Test 55 | fun `progress returns full progress`() { 56 | val dp1 = DownloadProgress(mockTask, 100, 100) 57 | assert(dp1.progress() == 1f) 58 | 59 | val dp2 = DownloadProgress(mockTask, 0, 0) 60 | assert(dp2.progress() == 1f) 61 | } 62 | 63 | @Test 64 | fun `progress returns half progress`() { 65 | val dp = DownloadProgress(mockTask, 50, 100) 66 | assert(dp.progress() == 0.5f) 67 | } 68 | } -------------------------------------------------------------------------------- /okdownload-kotlin-enhance/src/test/java/com/liulishuo/okdownload/kotlin/DownloadResultTest.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload.kotlin 18 | 19 | import com.liulishuo.okdownload.core.cause.EndCause 20 | import org.junit.Test 21 | 22 | class DownloadResultTest { 23 | 24 | @Test 25 | fun becauseOfCompleted() { 26 | val result = DownloadResult(EndCause.COMPLETED) 27 | assert(result.becauseOfCompleted()) 28 | } 29 | 30 | @Test 31 | fun becauseOfRepeatedTask() { 32 | var result = DownloadResult(EndCause.SAME_TASK_BUSY) 33 | assert(result.becauseOfRepeatedTask()) 34 | 35 | result = DownloadResult(EndCause.FILE_BUSY) 36 | assert(result.becauseOfRepeatedTask()) 37 | } 38 | } -------------------------------------------------------------------------------- /okdownload-process/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /okdownload-process/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion rootProject.ext.compileSdkVersion 5 | buildToolsVersion rootProject.ext.buildToolsVersion 6 | 7 | compileOptions { 8 | sourceCompatibility rootProject.ext.sourceCompatibilityVersion 9 | targetCompatibility rootProject.ext.targetCompatibilityVersion 10 | } 11 | 12 | dexOptions { 13 | preDexLibraries = !rootProject.ext.isCi 14 | } 15 | 16 | defaultConfig { 17 | minSdkVersion rootProject.ext.minSdkVersion 18 | } 19 | } 20 | 21 | dependencies { 22 | testImplementation dep.junit 23 | testImplementation dep.mockito 24 | testImplementation dep.assertj 25 | } 26 | -------------------------------------------------------------------------------- /okdownload-process/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/Jacksgong/sdk/android-sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /okdownload-process/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /okdownload/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /okdownload/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion rootProject.ext.compileSdkVersion 5 | buildToolsVersion rootProject.ext.buildToolsVersion 6 | 7 | defaultConfig { 8 | versionName VERSION_NAME as String 9 | } 10 | 11 | compileOptions { 12 | sourceCompatibility rootProject.ext.sourceCompatibilityVersion 13 | targetCompatibility rootProject.ext.targetCompatibilityVersion 14 | } 15 | 16 | dexOptions { 17 | preDexLibraries = !rootProject.ext.isCi 18 | } 19 | 20 | defaultConfig { 21 | minSdkVersion rootProject.ext.minSdkVersion 22 | } 23 | } 24 | 25 | dependencies { 26 | testImplementation dep.junit 27 | testImplementation dep.mockito 28 | testImplementation dep.assertj 29 | testImplementation dep.robolectric 30 | 31 | implementation dep.supportAnnotations 32 | 33 | compileOnly dep.findbugsAnnotations 34 | } 35 | 36 | apply from: rootProject.file('gradle/gradle-mvn-push.gradle') 37 | if (hasProperty("isCI")) { 38 | apply from: rootProject.file('gradle/codecov.gradle') 39 | } 40 | -------------------------------------------------------------------------------- /okdownload/gradle.properties: -------------------------------------------------------------------------------- 1 | POM_ARTIFACT_ID=okdownload 2 | POM_NAME=OkDownload 3 | POM_DESCRIPTION=A powerful file downloading library for Android 4 | POM_PACKAGING=aar 5 | -------------------------------------------------------------------------------- /okdownload/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/Jacksgong/sdk/android-sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | -------------------------------------------------------------------------------- /okdownload/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /okdownload/src/main/java/com/liulishuo/okdownload/DownloadContextListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload; 18 | 19 | import android.support.annotation.NonNull; 20 | import android.support.annotation.Nullable; 21 | 22 | import com.liulishuo.okdownload.core.cause.EndCause; 23 | 24 | public interface DownloadContextListener { 25 | void taskEnd(@NonNull DownloadContext context, @NonNull DownloadTask task, 26 | @NonNull EndCause cause, @Nullable Exception realCause, int remainCount); 27 | 28 | void queueEnd(@NonNull DownloadContext context); 29 | } 30 | -------------------------------------------------------------------------------- /okdownload/src/main/java/com/liulishuo/okdownload/DownloadMonitor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload; 18 | 19 | import android.support.annotation.NonNull; 20 | import android.support.annotation.Nullable; 21 | 22 | import com.liulishuo.okdownload.core.breakpoint.BreakpointInfo; 23 | import com.liulishuo.okdownload.core.cause.EndCause; 24 | import com.liulishuo.okdownload.core.cause.ResumeFailedCause; 25 | 26 | /** 27 | * If you set monitor to okdownload, the lifecycle of every task on okdownload will be caught and 28 | * callback to this monitor. 29 | * 30 | * @see OkDownload#setMonitor(DownloadMonitor) 31 | * @see OkDownload.Builder#setMonitor(DownloadMonitor) 32 | */ 33 | public interface DownloadMonitor { 34 | void taskStart(DownloadTask task); 35 | 36 | /** 37 | * Call this monitor function when the {@code task} just end trial connection, and its 38 | * {@code info} is ready and also certain this task will resume from the past breakpoint. 39 | * 40 | * @param task the target task. 41 | * @param info has certainly total-length and offset-length now. 42 | */ 43 | void taskDownloadFromBreakpoint(@NonNull DownloadTask task, @NonNull BreakpointInfo info); 44 | 45 | /** 46 | * Call this monitor function when the {@code task} just end trial connection, and its 47 | * {@code info} is ready and also certain this task will download from the very beginning. 48 | * 49 | * @param task the target task. 50 | * @param info has certainly total-length and offset-length now. 51 | * @param cause the cause of why download from the very beginning instead of from the past 52 | * breakpoint. 53 | */ 54 | void taskDownloadFromBeginning(@NonNull DownloadTask task, @NonNull BreakpointInfo info, 55 | @Nullable ResumeFailedCause cause); 56 | 57 | void taskEnd(DownloadTask task, EndCause cause, @Nullable Exception realCause); 58 | } 59 | -------------------------------------------------------------------------------- /okdownload/src/main/java/com/liulishuo/okdownload/IRedirectHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload; 18 | 19 | import android.support.annotation.Nullable; 20 | 21 | import com.liulishuo.okdownload.core.connection.DownloadConnection; 22 | 23 | import java.io.IOException; 24 | import java.util.List; 25 | import java.util.Map; 26 | 27 | public interface IRedirectHandler { 28 | 29 | /** 30 | * handle redirect during connection 31 | * 32 | * @param originalConnection original connection of original url, contain connection info 33 | * 34 | * @param originalConnected connected connection of original url, contain request response 35 | * of first connect 36 | * 37 | * @param headerProperties request headers of the connection, these headers should be added in 38 | * the new connection during handle redirect 39 | */ 40 | void handleRedirect( 41 | DownloadConnection originalConnection, 42 | DownloadConnection.Connected originalConnected, 43 | Map> headerProperties 44 | ) throws IOException; 45 | 46 | @Nullable 47 | String getRedirectLocation(); 48 | } 49 | -------------------------------------------------------------------------------- /okdownload/src/main/java/com/liulishuo/okdownload/OkDownloadProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload; 18 | 19 | import android.annotation.SuppressLint; 20 | import android.content.ContentProvider; 21 | import android.content.ContentValues; 22 | import android.content.Context; 23 | import android.database.Cursor; 24 | import android.net.Uri; 25 | import android.support.annotation.NonNull; 26 | import android.support.annotation.Nullable; 27 | 28 | import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; 29 | 30 | public class OkDownloadProvider extends ContentProvider { 31 | @SuppressFBWarnings(value = "ST") 32 | @SuppressLint("StaticFieldLeak") 33 | public static Context context; 34 | 35 | @Override 36 | public boolean onCreate() { 37 | context = getContext(); 38 | return true; 39 | } 40 | 41 | @Nullable 42 | @Override 43 | public Cursor query(@NonNull Uri uri, @Nullable String[] projection, 44 | @Nullable String selection, @Nullable String[] selectionArgs, 45 | @Nullable String sortOrder) { 46 | return null; 47 | } 48 | 49 | @Nullable 50 | @Override 51 | public String getType(@NonNull Uri uri) { 52 | return null; 53 | } 54 | 55 | @Nullable 56 | @Override 57 | public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) { 58 | return null; 59 | } 60 | 61 | @Override 62 | public int delete(@NonNull Uri uri, @Nullable String selection, 63 | @Nullable String[] selectionArgs) { 64 | return 0; 65 | } 66 | 67 | @Override 68 | public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, 69 | @Nullable String[] selectionArgs) { 70 | return 0; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /okdownload/src/main/java/com/liulishuo/okdownload/RedirectUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload; 18 | 19 | import android.support.annotation.NonNull; 20 | 21 | import com.liulishuo.okdownload.core.connection.DownloadConnection; 22 | 23 | import java.io.IOException; 24 | import java.net.HttpURLConnection; 25 | import java.net.ProtocolException; 26 | 27 | public class RedirectUtil { 28 | 29 | /** 30 | * How many redirects and auth challenges should we attempt? Chrome follows 21 redirects; 31 | * Firefox, curl, and wget follow 20; Safari follows 16; and HTTP/1.0 recommends 5. 32 | */ 33 | public static final int MAX_REDIRECT_TIMES = 10; 34 | 35 | /** 36 | * The target resource resides temporarily under a different URI and the user agent MUST NOT 37 | * change the request method if it performs an automatic redirection to that URI. 38 | */ 39 | static final int HTTP_TEMPORARY_REDIRECT = 307; 40 | /** 41 | * The target resource has been assigned a new permanent URI and any future references to this 42 | * resource ought to use one of the enclosed URIs. 43 | */ 44 | static final int HTTP_PERMANENT_REDIRECT = 308; 45 | 46 | 47 | public static boolean isRedirect(int code) { 48 | return code == HttpURLConnection.HTTP_MOVED_PERM 49 | || code == HttpURLConnection.HTTP_MOVED_TEMP 50 | || code == HttpURLConnection.HTTP_SEE_OTHER 51 | || code == HttpURLConnection.HTTP_MULT_CHOICE 52 | || code == HTTP_TEMPORARY_REDIRECT 53 | || code == HTTP_PERMANENT_REDIRECT; 54 | } 55 | 56 | @NonNull 57 | public static String getRedirectedUrl(DownloadConnection.Connected connected, int responseCode) 58 | throws IOException { 59 | String url = connected.getResponseHeaderField("Location"); 60 | if (url == null) { 61 | throw new ProtocolException( 62 | "Response code is " + responseCode + " but can't find Location field"); 63 | 64 | } 65 | return url; 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /okdownload/src/main/java/com/liulishuo/okdownload/core/IdentifiedTask.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload.core; 18 | 19 | import android.support.annotation.NonNull; 20 | import android.support.annotation.Nullable; 21 | 22 | import java.io.File; 23 | 24 | public abstract class IdentifiedTask { 25 | 26 | public static final String EMPTY_URL = ""; 27 | public static final File EMPTY_FILE = new File(""); 28 | 29 | public abstract int getId(); 30 | 31 | @NonNull public abstract String getUrl(); 32 | 33 | @NonNull protected abstract File getProvidedPathFile(); 34 | 35 | @NonNull public abstract File getParentFile(); 36 | 37 | @Nullable public abstract String getFilename(); 38 | 39 | public boolean compareIgnoreId(IdentifiedTask another) { 40 | if (!getUrl().equals(another.getUrl())) return false; 41 | 42 | if (getUrl().equals(EMPTY_URL) || getParentFile().equals(EMPTY_FILE)) return false; 43 | 44 | if (getProvidedPathFile().equals(another.getProvidedPathFile())) return true; 45 | 46 | if (!getParentFile().equals(another.getParentFile())) return false; 47 | 48 | // cover the case of filename is provided by response. 49 | final String filename = getFilename(); 50 | final String anotherFilename = another.getFilename(); 51 | return anotherFilename != null && filename != null && anotherFilename.equals(filename); 52 | } 53 | } -------------------------------------------------------------------------------- /okdownload/src/main/java/com/liulishuo/okdownload/core/NamedRunnable.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload.core; 18 | 19 | public abstract class NamedRunnable implements Runnable { 20 | 21 | protected final String name; 22 | 23 | public NamedRunnable(String name) { 24 | this.name = name; 25 | } 26 | 27 | @Override 28 | public final void run() { 29 | String oldName = Thread.currentThread().getName(); 30 | Thread.currentThread().setName(name); 31 | try { 32 | execute(); 33 | } catch (InterruptedException e) { 34 | Thread.currentThread().interrupt(); 35 | interrupted(e); 36 | } finally { 37 | Thread.currentThread().setName(oldName); 38 | finished(); 39 | } 40 | } 41 | 42 | protected abstract void execute() throws InterruptedException; 43 | 44 | protected abstract void interrupted(InterruptedException e); 45 | 46 | protected abstract void finished(); 47 | } 48 | -------------------------------------------------------------------------------- /okdownload/src/main/java/com/liulishuo/okdownload/core/breakpoint/BreakpointStore.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload.core.breakpoint; 18 | 19 | 20 | import android.support.annotation.NonNull; 21 | import android.support.annotation.Nullable; 22 | 23 | import com.liulishuo.okdownload.DownloadTask; 24 | 25 | import java.io.IOException; 26 | 27 | public interface BreakpointStore { 28 | 29 | @Nullable 30 | BreakpointInfo get(int id); 31 | 32 | @NonNull 33 | BreakpointInfo createAndInsert(@NonNull DownloadTask task) throws IOException; 34 | 35 | int findOrCreateId(@NonNull DownloadTask task); 36 | 37 | boolean update(@NonNull BreakpointInfo breakpointInfo) throws IOException; 38 | 39 | void remove(int id); 40 | 41 | @Nullable 42 | String getResponseFilename(String url); 43 | 44 | @Nullable 45 | BreakpointInfo findAnotherInfoFromCompare(@NonNull DownloadTask task, 46 | @NonNull BreakpointInfo ignored); 47 | 48 | /** 49 | * Whether only store breakpoint on memory cache. 50 | * 51 | * @return {@code true} if breakpoint on this store is only store on the memory cache. 52 | */ 53 | boolean isOnlyMemoryCache(); 54 | 55 | /** 56 | * Whether the file relate to the task id {@code id} is dirty, which means the file isn't 57 | * complete download yet. 58 | * 59 | * @param id the task id. 60 | * @return {@code true} the file relate to {@code id} is dirty 61 | */ 62 | boolean isFileDirty(int id); 63 | } 64 | -------------------------------------------------------------------------------- /okdownload/src/main/java/com/liulishuo/okdownload/core/breakpoint/DownloadStore.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload.core.breakpoint; 18 | 19 | import android.support.annotation.NonNull; 20 | import android.support.annotation.Nullable; 21 | 22 | import com.liulishuo.okdownload.core.cause.EndCause; 23 | 24 | import java.io.IOException; 25 | 26 | public interface DownloadStore extends BreakpointStore { 27 | 28 | void onSyncToFilesystemSuccess(@NonNull BreakpointInfo info, int blockIndex, 29 | long increaseLength) throws IOException; 30 | 31 | void onTaskStart(int id); 32 | 33 | void onTaskEnd(int id, @NonNull EndCause cause, @Nullable Exception exception); 34 | 35 | /** 36 | * Get the breakpoint info after the {@code id} task has been completed, this function is just 37 | * for ignore real operation and just return {@code null} directly since on some logic model we 38 | * already delete info from store after task has been completed to enhance performance. 39 | */ 40 | @Nullable 41 | BreakpointInfo getAfterCompleted(int id); 42 | 43 | /** 44 | * Mark the file relate to the {@code id} is dirty state. 45 | * 46 | * @param id the task id 47 | */ 48 | boolean markFileDirty(int id); 49 | 50 | /** 51 | * Mark the file relate to the {@code id} is clear state. 52 | *

53 | * Normally, which means the task is completed download. 54 | * 55 | * @param id the task id 56 | */ 57 | boolean markFileClear(int id); 58 | } 59 | -------------------------------------------------------------------------------- /okdownload/src/main/java/com/liulishuo/okdownload/core/breakpoint/KeyToIdMap.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload.core.breakpoint; 18 | 19 | import android.support.annotation.NonNull; 20 | import android.support.annotation.Nullable; 21 | import android.util.SparseArray; 22 | 23 | import com.liulishuo.okdownload.DownloadTask; 24 | 25 | import java.util.HashMap; 26 | 27 | public class KeyToIdMap { 28 | 29 | @SuppressWarnings("PMD.AvoidFieldNameMatchingTypeName") 30 | @NonNull private final HashMap keyToIdMap; 31 | @NonNull private final SparseArray idToKeyMap; 32 | 33 | KeyToIdMap() { 34 | this(new HashMap(), new SparseArray()); 35 | } 36 | 37 | KeyToIdMap(@NonNull HashMap keyToIdMap, 38 | @NonNull SparseArray idToKeyMap) { 39 | this.keyToIdMap = keyToIdMap; 40 | this.idToKeyMap = idToKeyMap; 41 | } 42 | 43 | @Nullable public Integer get(@NonNull DownloadTask task) { 44 | final Integer candidate = keyToIdMap.get(generateKey(task)); 45 | if (candidate != null) return candidate; 46 | return null; 47 | } 48 | 49 | public void remove(int id) { 50 | final String key = idToKeyMap.get(id); 51 | if (key != null) { 52 | keyToIdMap.remove(key); 53 | idToKeyMap.remove(id); 54 | } 55 | } 56 | 57 | public void add(@NonNull DownloadTask task, int id) { 58 | final String key = generateKey(task); 59 | keyToIdMap.put(key, id); 60 | idToKeyMap.put(id, key); 61 | } 62 | 63 | String generateKey(@NonNull DownloadTask task) { 64 | return task.getUrl() + task.getUri() + task.getFilename(); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /okdownload/src/main/java/com/liulishuo/okdownload/core/cause/EndCause.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload.core.cause; 18 | 19 | public enum EndCause { 20 | COMPLETED, 21 | ERROR, 22 | CANCELED, 23 | FILE_BUSY, 24 | SAME_TASK_BUSY, 25 | PRE_ALLOCATE_FAILED 26 | } -------------------------------------------------------------------------------- /okdownload/src/main/java/com/liulishuo/okdownload/core/cause/ResumeFailedCause.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload.core.cause; 18 | 19 | public enum ResumeFailedCause { 20 | INFO_DIRTY, 21 | FILE_NOT_EXIST, 22 | OUTPUT_STREAM_NOT_SUPPORT, 23 | RESPONSE_ETAG_CHANGED, 24 | RESPONSE_PRECONDITION_FAILED, 25 | RESPONSE_CREATED_RANGE_NOT_FROM_0, 26 | RESPONSE_RESET_RANGE_NOT_FROM_0, 27 | CONTENT_LENGTH_CHANGED, 28 | } -------------------------------------------------------------------------------- /okdownload/src/main/java/com/liulishuo/okdownload/core/exception/DownloadSecurityException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload.core.exception; 18 | 19 | import java.io.IOException; 20 | 21 | public class DownloadSecurityException extends IOException { 22 | 23 | public DownloadSecurityException(String message) { 24 | super(message); 25 | } 26 | } 27 | 28 | -------------------------------------------------------------------------------- /okdownload/src/main/java/com/liulishuo/okdownload/core/exception/FileBusyAfterRunException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload.core.exception; 18 | 19 | import java.io.IOException; 20 | 21 | public class FileBusyAfterRunException extends IOException { 22 | private FileBusyAfterRunException() { 23 | super("File busy after run"); 24 | } 25 | 26 | public static final FileBusyAfterRunException SIGNAL = new FileBusyAfterRunException() { 27 | }; 28 | } 29 | -------------------------------------------------------------------------------- /okdownload/src/main/java/com/liulishuo/okdownload/core/exception/InterruptException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload.core.exception; 18 | 19 | import java.io.IOException; 20 | 21 | public class InterruptException extends IOException { 22 | private InterruptException() { 23 | super("Interrupted"); 24 | } 25 | 26 | public static final InterruptException SIGNAL = new InterruptException() { 27 | 28 | @Override public void printStackTrace() { 29 | throw new IllegalAccessError("Stack is ignored for signal"); 30 | } 31 | }; 32 | } 33 | -------------------------------------------------------------------------------- /okdownload/src/main/java/com/liulishuo/okdownload/core/exception/NetworkPolicyException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload.core.exception; 18 | 19 | import java.io.IOException; 20 | 21 | /** 22 | * Throw this exception only if the {@link com.liulishuo.okdownload.DownloadTask#isWifiRequired} is 23 | * {@code true} but the current network type is not Wifi. 24 | */ 25 | public class NetworkPolicyException extends IOException { 26 | public NetworkPolicyException() { 27 | super("Only allows downloading this task on the wifi network type!"); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /okdownload/src/main/java/com/liulishuo/okdownload/core/exception/PreAllocateException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload.core.exception; 18 | 19 | import java.io.IOException; 20 | 21 | public class PreAllocateException extends IOException { 22 | private final long requireSpace; 23 | private final long freeSpace; 24 | 25 | public PreAllocateException(long requireSpace, long freeSpace) { 26 | super("There is Free space less than Require space: " + freeSpace + " < " + requireSpace); 27 | this.requireSpace = requireSpace; 28 | this.freeSpace = freeSpace; 29 | } 30 | 31 | public long getRequireSpace() { 32 | return requireSpace; 33 | } 34 | 35 | public long getFreeSpace() { 36 | return freeSpace; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /okdownload/src/main/java/com/liulishuo/okdownload/core/exception/ResumeFailedException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload.core.exception; 18 | 19 | import java.io.IOException; 20 | 21 | import com.liulishuo.okdownload.core.cause.ResumeFailedCause; 22 | 23 | public class ResumeFailedException extends IOException { 24 | private final ResumeFailedCause resumeFailedCause; 25 | 26 | public ResumeFailedException(ResumeFailedCause cause) { 27 | super("Resume failed because of " + cause); 28 | this.resumeFailedCause = cause; 29 | } 30 | 31 | public ResumeFailedCause getResumeFailedCause() { 32 | return resumeFailedCause; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /okdownload/src/main/java/com/liulishuo/okdownload/core/exception/RetryException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload.core.exception; 18 | 19 | import java.io.IOException; 20 | 21 | public class RetryException extends IOException { 22 | public RetryException(String message) { 23 | super(message); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /okdownload/src/main/java/com/liulishuo/okdownload/core/exception/ServerCanceledException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload.core.exception; 18 | 19 | import java.io.IOException; 20 | 21 | public class ServerCanceledException extends IOException { 22 | private final int responseCode; 23 | 24 | public ServerCanceledException(int responseCode, long currentOffset) { 25 | super("Response code can't handled on internal " + responseCode + " with current offset " 26 | + currentOffset); 27 | this.responseCode = responseCode; 28 | } 29 | 30 | public int getResponseCode() { 31 | return responseCode; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /okdownload/src/main/java/com/liulishuo/okdownload/core/file/DownloadOutputStream.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload.core.file; 18 | 19 | import android.content.Context; 20 | import android.net.Uri; 21 | 22 | import java.io.File; 23 | import java.io.FileNotFoundException; 24 | import java.io.IOException; 25 | 26 | public interface DownloadOutputStream { 27 | void write(byte[] b, int off, int len) throws IOException; 28 | 29 | void close() throws IOException; 30 | 31 | void flushAndSync() throws IOException; 32 | 33 | void seek(long offset) throws IOException; 34 | 35 | void setLength(long newLength) throws IOException; 36 | 37 | interface Factory { 38 | DownloadOutputStream create(Context context, File file, int flushBufferSize) 39 | throws FileNotFoundException; 40 | 41 | DownloadOutputStream create(Context context, Uri uri, int flushBufferSize) 42 | throws FileNotFoundException; 43 | 44 | boolean supportSeek(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /okdownload/src/main/java/com/liulishuo/okdownload/core/file/ProcessFileStrategy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload.core.file; 18 | 19 | import android.support.annotation.NonNull; 20 | 21 | import com.liulishuo.okdownload.DownloadTask; 22 | import com.liulishuo.okdownload.OkDownload; 23 | import com.liulishuo.okdownload.core.breakpoint.BreakpointInfo; 24 | import com.liulishuo.okdownload.core.breakpoint.DownloadStore; 25 | 26 | import java.io.File; 27 | import java.io.IOException; 28 | 29 | public class ProcessFileStrategy { 30 | private final FileLock fileLock = new FileLock(); 31 | 32 | @NonNull public MultiPointOutputStream createProcessStream(@NonNull DownloadTask task, 33 | @NonNull BreakpointInfo info, 34 | @NonNull DownloadStore store) { 35 | return new MultiPointOutputStream(task, info, store); 36 | } 37 | 38 | public void completeProcessStream(@NonNull MultiPointOutputStream processOutputStream, 39 | @NonNull DownloadTask task) { 40 | } 41 | 42 | public void discardProcess(@NonNull DownloadTask task) throws IOException { 43 | // Remove target file. 44 | final File file = task.getFile(); 45 | // Do nothing, because the filename hasn't found yet. 46 | if (file == null) return; 47 | 48 | if (file.exists() && !file.delete()) { 49 | throw new IOException("Delete file failed!"); 50 | } 51 | } 52 | 53 | @NonNull public FileLock getFileLock() { 54 | return fileLock; 55 | } 56 | 57 | public boolean isPreAllocateLength(@NonNull DownloadTask task) { 58 | // if support seek, enable pre-allocate length. 59 | boolean supportSeek = OkDownload.with().outputStreamFactory().supportSeek(); 60 | if (!supportSeek) return false; 61 | 62 | if (task.getSetPreAllocateLength() != null) return task.getSetPreAllocateLength(); 63 | return true; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /okdownload/src/main/java/com/liulishuo/okdownload/core/interceptor/Interceptor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload.core.interceptor; 18 | 19 | import android.support.annotation.NonNull; 20 | 21 | import com.liulishuo.okdownload.core.connection.DownloadConnection; 22 | import com.liulishuo.okdownload.core.download.DownloadChain; 23 | 24 | import java.io.IOException; 25 | 26 | public interface Interceptor { 27 | interface Connect { 28 | @NonNull DownloadConnection.Connected interceptConnect(DownloadChain chain) 29 | throws IOException; 30 | } 31 | 32 | interface Fetch { 33 | long interceptFetch(DownloadChain chain) throws IOException; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /okdownload/src/main/java/com/liulishuo/okdownload/core/interceptor/RetryInterceptor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload.core.interceptor; 18 | 19 | import android.support.annotation.NonNull; 20 | 21 | import com.liulishuo.okdownload.core.connection.DownloadConnection; 22 | import com.liulishuo.okdownload.core.download.DownloadCache; 23 | import com.liulishuo.okdownload.core.download.DownloadChain; 24 | import com.liulishuo.okdownload.core.exception.InterruptException; 25 | import com.liulishuo.okdownload.core.exception.RetryException; 26 | 27 | import java.io.IOException; 28 | 29 | public class RetryInterceptor implements Interceptor.Connect, Interceptor.Fetch { 30 | 31 | @NonNull @Override 32 | public DownloadConnection.Connected interceptConnect(DownloadChain chain) throws IOException { 33 | final DownloadCache cache = chain.getCache(); 34 | 35 | while (true) { 36 | try { 37 | if (cache.isInterrupt()) { 38 | throw InterruptException.SIGNAL; 39 | } 40 | return chain.processConnect(); 41 | } catch (IOException e) { 42 | if (e instanceof RetryException) { 43 | chain.resetConnectForRetry(); 44 | continue; 45 | } 46 | 47 | chain.getCache().catchException(e); 48 | chain.getOutputStream().catchBlockConnectException(chain.getBlockIndex()); 49 | throw e; 50 | } 51 | } 52 | } 53 | 54 | @Override 55 | public long interceptFetch(DownloadChain chain) throws IOException { 56 | try { 57 | return chain.processFetch(); 58 | } catch (IOException e) { 59 | chain.getCache().catchException(e); 60 | throw e; 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /okdownload/src/main/java/com/liulishuo/okdownload/core/interceptor/connect/CallServerInterceptor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload.core.interceptor.connect; 18 | 19 | import android.support.annotation.NonNull; 20 | 21 | import com.liulishuo.okdownload.OkDownload; 22 | import com.liulishuo.okdownload.core.connection.DownloadConnection; 23 | import com.liulishuo.okdownload.core.download.DownloadChain; 24 | import com.liulishuo.okdownload.core.interceptor.Interceptor; 25 | 26 | import java.io.IOException; 27 | 28 | public class CallServerInterceptor implements Interceptor.Connect { 29 | @NonNull @Override 30 | public DownloadConnection.Connected interceptConnect(DownloadChain chain) throws IOException { 31 | OkDownload.with().downloadStrategy().inspectNetworkOnWifi(chain.getTask()); 32 | OkDownload.with().downloadStrategy().inspectNetworkAvailable(); 33 | 34 | return chain.getConnectionOrCreate().execute(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /okdownload/src/main/java/com/liulishuo/okdownload/core/listener/assist/ListenerAssist.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload.core.listener.assist; 18 | 19 | public interface ListenerAssist { 20 | /** 21 | * As default there isn't need to always recover the model, because model is bind with the 22 | * callback lifecycle 23 | * 24 | * @return whether model need to recover always 25 | */ 26 | boolean isAlwaysRecoverAssistModel(); 27 | 28 | void setAlwaysRecoverAssistModel(boolean isAlwaysRecoverAssistModel); 29 | 30 | void setAlwaysRecoverAssistModelIfNotSet(boolean isAlwaysRecoverAssistModel); 31 | } 32 | -------------------------------------------------------------------------------- /okdownload/src/test/java/com/liulishuo/okdownload/OkDownloadProviderTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload; 18 | 19 | import android.net.Uri; 20 | 21 | import org.junit.Before; 22 | import org.junit.Test; 23 | import org.junit.runner.RunWith; 24 | import org.mockito.Mock; 25 | import org.robolectric.RobolectricTestRunner; 26 | import org.robolectric.annotation.Config; 27 | 28 | import static org.assertj.core.api.Java6Assertions.assertThat; 29 | import static org.mockito.MockitoAnnotations.initMocks; 30 | import static org.robolectric.annotation.Config.NONE; 31 | 32 | @RunWith(RobolectricTestRunner.class) 33 | @Config(manifest = NONE) 34 | public class OkDownloadProviderTest { 35 | 36 | private OkDownloadProvider provider; 37 | @Mock Uri uri; 38 | 39 | @Before 40 | public void setup() { 41 | initMocks(this); 42 | provider = new OkDownloadProvider(); 43 | } 44 | 45 | @Test 46 | public void onCreate() { 47 | assertThat(provider.onCreate()).isTrue(); 48 | } 49 | 50 | @Test 51 | public void query() { 52 | assertThat(provider.query(uri, null, null, null, null)).isNull(); 53 | } 54 | 55 | @Test 56 | public void getType() { 57 | assertThat(provider.getType(uri)).isNull(); 58 | } 59 | 60 | @Test 61 | public void insert() { 62 | assertThat(provider.insert(uri, null)).isNull(); 63 | } 64 | 65 | @Test 66 | public void delete() { 67 | assertThat(provider.delete(uri, null, null)).isZero(); 68 | } 69 | 70 | @Test 71 | public void update() { 72 | assertThat(provider.update(uri, null, null, null)).isZero(); 73 | } 74 | } -------------------------------------------------------------------------------- /okdownload/src/test/java/com/liulishuo/okdownload/core/NamedRunnableTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload.core; 18 | 19 | import org.junit.Before; 20 | import org.junit.Test; 21 | 22 | import static org.assertj.core.api.Java6Assertions.assertThat; 23 | import static org.mockito.ArgumentMatchers.any; 24 | import static org.mockito.Mockito.doThrow; 25 | import static org.mockito.Mockito.never; 26 | import static org.mockito.Mockito.spy; 27 | import static org.mockito.Mockito.verify; 28 | 29 | public class NamedRunnableTest { 30 | 31 | private NamedRunnable runnable; 32 | 33 | @Before 34 | public void setup() { 35 | String name = "name"; 36 | runnable = spy(new NamedRunnable(name) { 37 | @Override protected void execute() { 38 | } 39 | 40 | @Override protected void interrupted(InterruptedException e) { 41 | } 42 | 43 | @Override protected void finished() { 44 | } 45 | }); 46 | } 47 | 48 | @Test 49 | public void run_nonInterrupt() throws InterruptedException { 50 | Thread.currentThread().setName("oldName"); 51 | runnable.run(); 52 | 53 | verify(runnable).execute(); 54 | verify(runnable, never()).interrupted(any(InterruptedException.class)); 55 | verify(runnable).finished(); 56 | assertThat(Thread.currentThread().getName()).isEqualTo("oldName"); 57 | } 58 | 59 | @Test 60 | public void run_interrupt() throws InterruptedException { 61 | doThrow(InterruptedException.class).when(runnable).execute(); 62 | 63 | runnable.run(); 64 | verify(runnable).execute(); 65 | verify(runnable).interrupted(any(InterruptedException.class)); 66 | verify(runnable).finished(); 67 | } 68 | } -------------------------------------------------------------------------------- /okdownload/src/test/java/com/liulishuo/okdownload/core/breakpoint/BlockInfoTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload.core.breakpoint; 18 | 19 | import org.junit.Before; 20 | import org.junit.Test; 21 | 22 | import static com.liulishuo.okdownload.core.Util.CHUNKED_CONTENT_LENGTH; 23 | import static org.assertj.core.api.Java6Assertions.assertThat; 24 | 25 | public class BlockInfoTest { 26 | 27 | private BlockInfo info; 28 | 29 | @Before 30 | public void setup() { 31 | info = new BlockInfo(0, 1000); 32 | } 33 | 34 | @Test 35 | public void increase() { 36 | info.increaseCurrentOffset(123); 37 | assertThat(info.getCurrentOffset()).isEqualTo(123); 38 | } 39 | 40 | @Test 41 | public void copyNotClone() { 42 | info.increaseCurrentOffset(1); 43 | final BlockInfo copy = info.copy(); 44 | copy.increaseCurrentOffset(1); 45 | 46 | assertThat(info.getCurrentOffset()).isEqualTo(1); 47 | assertThat(copy.getCurrentOffset()).isEqualTo(2); 48 | } 49 | 50 | @Test 51 | public void getRangeRight() { 52 | BlockInfo info = new BlockInfo(0, 3, 1); 53 | assertThat(info.getRangeRight()).isEqualTo(2); 54 | 55 | info = new BlockInfo(12, 6, 2); 56 | assertThat(info.getRangeRight()).isEqualTo(17); 57 | } 58 | 59 | @Test 60 | public void chunked() { 61 | BlockInfo info = new BlockInfo(0, CHUNKED_CONTENT_LENGTH); 62 | assertThat(info.getContentLength()).isEqualTo(CHUNKED_CONTENT_LENGTH); 63 | } 64 | } -------------------------------------------------------------------------------- /okdownload/src/test/java/com/liulishuo/okdownload/core/exception/InterruptExceptionTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload.core.exception; 18 | 19 | import com.liulishuo.okdownload.core.NamedRunnable; 20 | 21 | import org.junit.Assert; 22 | import org.junit.Rule; 23 | import org.junit.Test; 24 | import org.junit.rules.ExpectedException; 25 | 26 | import java.util.concurrent.CountDownLatch; 27 | import java.util.concurrent.TimeUnit; 28 | 29 | import static org.assertj.core.api.Java6Assertions.assertThat; 30 | 31 | public class InterruptExceptionTest { 32 | 33 | @Rule 34 | public ExpectedException thrown = ExpectedException.none(); 35 | 36 | @Test 37 | public void printStackTrace() { 38 | assertThat(InterruptException.SIGNAL.getMessage()).isEqualTo("Interrupted"); 39 | 40 | thrown.expect(IllegalAccessError.class); 41 | thrown.expectMessage("Stack is ignored for signal"); 42 | InterruptException.SIGNAL.printStackTrace(); 43 | } 44 | 45 | @Test 46 | public void testInterruptedStatus() { 47 | final CountDownLatch latch = new CountDownLatch(1); 48 | final Thread r1 = new Thread(new NamedRunnable("test runnable") { 49 | @Override 50 | protected void execute() throws InterruptedException { 51 | latch.countDown(); 52 | Thread.sleep(100); 53 | } 54 | 55 | @Override 56 | protected void interrupted(InterruptedException e) { 57 | } 58 | 59 | @Override 60 | protected void finished() { 61 | Assert.assertTrue(Thread.currentThread().isInterrupted()); 62 | } 63 | }); 64 | r1.start(); 65 | try { 66 | latch.await(100, TimeUnit.MILLISECONDS); 67 | r1.interrupt(); 68 | r1.join(); 69 | } catch (Exception ignored) { 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /okdownload/src/test/java/com/liulishuo/okdownload/core/exception/NetworkPolicyExceptionTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload.core.exception; 18 | 19 | import org.junit.Before; 20 | import org.junit.Test; 21 | 22 | import static org.assertj.core.api.Java6Assertions.assertThat; 23 | 24 | public class NetworkPolicyExceptionTest { 25 | 26 | private NetworkPolicyException exception; 27 | 28 | @Before 29 | public void setup() { 30 | exception = new NetworkPolicyException(); 31 | } 32 | 33 | @Test 34 | public void construct() { 35 | assertThat(exception.getMessage()) 36 | .isEqualTo("Only allows downloading this task on the wifi network type!"); 37 | } 38 | } -------------------------------------------------------------------------------- /okdownload/src/test/java/com/liulishuo/okdownload/core/exception/PreAllocateExceptionTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload.core.exception; 18 | 19 | import org.junit.Before; 20 | import org.junit.Test; 21 | 22 | import static org.assertj.core.api.Java6Assertions.assertThat; 23 | 24 | public class PreAllocateExceptionTest { 25 | 26 | private PreAllocateException exception; 27 | private long freeSpace = 1; 28 | private long requireSpace = 2; 29 | 30 | @Before 31 | public void setup() { 32 | exception = new PreAllocateException(requireSpace, freeSpace); 33 | } 34 | 35 | @Test 36 | public void construct() { 37 | assertThat(exception.getMessage()).isEqualTo( 38 | "There is Free space less than Require space: " + freeSpace + " < " + requireSpace); 39 | assertThat(exception.getRequireSpace()).isEqualTo(requireSpace); 40 | assertThat(exception.getFreeSpace()).isEqualTo(freeSpace); 41 | } 42 | } -------------------------------------------------------------------------------- /okdownload/src/test/java/com/liulishuo/okdownload/core/exception/ResumeFailedExceptionTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload.core.exception; 18 | 19 | import com.liulishuo.okdownload.core.cause.ResumeFailedCause; 20 | 21 | import org.junit.Test; 22 | 23 | import static org.assertj.core.api.Java6Assertions.assertThat; 24 | 25 | public class ResumeFailedExceptionTest { 26 | 27 | @Test 28 | public void construct() { 29 | final ResumeFailedCause cause = ResumeFailedCause.FILE_NOT_EXIST; 30 | 31 | ResumeFailedException exception = new ResumeFailedException(cause); 32 | assertThat(exception.getMessage()).isEqualTo("Resume failed because of " + cause); 33 | assertThat(exception.getResumeFailedCause()).isEqualTo(cause); 34 | } 35 | } -------------------------------------------------------------------------------- /okdownload/src/test/java/com/liulishuo/okdownload/core/exception/RetryExceptionTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload.core.exception; 18 | 19 | import org.junit.Test; 20 | 21 | import static org.assertj.core.api.Java6Assertions.assertThat; 22 | 23 | public class RetryExceptionTest { 24 | 25 | @Test 26 | public void construct() { 27 | String message = "message"; 28 | RetryException exception = new RetryException(message); 29 | assertThat(exception.getMessage()).isEqualTo(message); 30 | } 31 | } -------------------------------------------------------------------------------- /okdownload/src/test/java/com/liulishuo/okdownload/core/exception/ServerCanceledExceptionTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload.core.exception; 18 | 19 | import org.junit.Test; 20 | 21 | import static org.assertj.core.api.Java6Assertions.assertThat; 22 | 23 | public class ServerCanceledExceptionTest { 24 | 25 | @Test 26 | public void construct() { 27 | int responseCode = 1; 28 | long offset = 2; 29 | 30 | ServerCanceledException exception = new ServerCanceledException(responseCode, offset); 31 | assertThat(exception.getMessage()) 32 | .isEqualTo("Response code can't handled on internal " + responseCode 33 | + " with current offset " 34 | + offset); 35 | assertThat(exception.getResponseCode()).isEqualTo(responseCode); 36 | } 37 | } -------------------------------------------------------------------------------- /okdownload/src/test/java/com/liulishuo/okdownload/core/interceptor/connect/CallServerInterceptorTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload.core.interceptor.connect; 18 | 19 | import com.liulishuo.okdownload.DownloadTask; 20 | import com.liulishuo.okdownload.OkDownload; 21 | import com.liulishuo.okdownload.core.connection.DownloadConnection; 22 | import com.liulishuo.okdownload.core.download.DownloadChain; 23 | import com.liulishuo.okdownload.core.download.DownloadStrategy; 24 | 25 | import org.junit.Before; 26 | import org.junit.BeforeClass; 27 | import org.junit.Test; 28 | import org.mockito.Mock; 29 | 30 | import java.io.IOException; 31 | 32 | import static com.liulishuo.okdownload.TestUtils.mockOkDownload; 33 | import static org.mockito.ArgumentMatchers.eq; 34 | import static org.mockito.Mockito.verify; 35 | import static org.mockito.Mockito.when; 36 | import static org.mockito.MockitoAnnotations.initMocks; 37 | 38 | public class CallServerInterceptorTest { 39 | 40 | private CallServerInterceptor serverInterceptor; 41 | @Mock private DownloadChain chain; 42 | @Mock private DownloadConnection connection; 43 | @Mock private DownloadTask task; 44 | 45 | @BeforeClass 46 | public static void setupClass() throws IOException { 47 | mockOkDownload(); 48 | } 49 | 50 | @Before 51 | public void setUp() throws Exception { 52 | initMocks(this); 53 | serverInterceptor = new CallServerInterceptor(); 54 | when(chain.getConnectionOrCreate()).thenReturn(connection); 55 | when(chain.getTask()).thenReturn(task); 56 | } 57 | 58 | @Test 59 | public void interceptConnect() throws Exception { 60 | serverInterceptor.interceptConnect(chain); 61 | 62 | final DownloadStrategy downloadStrategy = OkDownload.with().downloadStrategy(); 63 | verify(downloadStrategy).inspectNetworkOnWifi(eq(task)); 64 | verify(downloadStrategy).inspectNetworkAvailable(); 65 | } 66 | } -------------------------------------------------------------------------------- /okdownload/src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker: -------------------------------------------------------------------------------- 1 | mock-maker-inline -------------------------------------------------------------------------------- /omni/okdownload.graffle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lingochamp/okdownload/cb6e20f2484927ef81728355fad3231bb87859a9/omni/okdownload.graffle -------------------------------------------------------------------------------- /publishToMavenLocal.sh: -------------------------------------------------------------------------------- 1 | ./gradlew clean assembleRelease 2 | ./gradlew publishToMavenLocal 3 | -------------------------------------------------------------------------------- /sample/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /sample/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/Jacksgong/sdk/android-sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile 26 | 27 | 28 | # ------- because of we using okhttp on sample ---- 29 | # https://github.com/square/okhttp/#proguard 30 | -dontwarn okhttp3.** 31 | -dontwarn okio.** 32 | -dontwarn javax.annotation.** 33 | -dontwarn org.conscrypt.** 34 | # A resource is loaded with a relative path so the package of this class must be preserved. 35 | -keepnames class okhttp3.internal.publicsuffix.PublicSuffixDatabase 36 | # ------- end okhttp proguard rules ---- 37 | 38 | # ------- because of we using com.liulishuo.okdownload:okhttp on sample ---- 39 | -keepnames class com.liulishuo.okdownload.core.connection.DownloadOkHttp3Connection 40 | # ------- end com.liulishuo.okdownload:okhttp proguard rules ---- 41 | 42 | # ------- because of we using com.liulishuo.okdownload:sqlite on sample ---- 43 | -keep class com.liulishuo.okdownload.core.breakpoint.BreakpointStoreOnSQLite { 44 | public com.liulishuo.okdownload.core.breakpoint.DownloadStore createRemitSelf(); 45 | public com.liulishuo.okdownload.core.breakpoint.BreakpointStoreOnSQLite(android.content.Context); 46 | } 47 | # ------- end com.liulishuo.okdownload:sqlite proguard rules ---- 48 | 49 | # don't warn SuppressFBWarnings annotation used in com.liulishuo.okdownload.DownloadContex.java 50 | -dontwarn edu.umd.cs.findbugs.annotations.SuppressFBWarnings 51 | 52 | -dontwarn kotlinx.coroutines.** -------------------------------------------------------------------------------- /sample/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 20 | 21 | 31 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /sample/src/main/java/com/liulishuo/okdownload/sample/MainActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload.sample; 18 | 19 | 20 | import android.os.Bundle; 21 | import android.support.annotation.Nullable; 22 | 23 | import com.liulishuo.okdownload.core.Util; 24 | import com.liulishuo.okdownload.sample.base.BaseListActivity; 25 | 26 | public class MainActivity extends BaseListActivity { 27 | 28 | @Override protected void onCreate(@Nullable Bundle savedInstanceState) { 29 | super.onCreate(savedInstanceState); 30 | Util.enableConsoleLog(); 31 | } 32 | 33 | @Override protected void setupAdapter(BaseListActivity.ItemsHolder holder) { 34 | holder.addItem(R.string.single_download_title, R.string.single_download_desc, 35 | SingleActivity.class); 36 | holder.addItem(R.string.each_block_progress_title, R.string.each_block_progress_desc, 37 | EachBlockProgressActivity.class); 38 | holder.addItem(R.string.queue_download_title, R.string.queue_download_desc, 39 | QueueActivity.class); 40 | holder.addItem(R.string.bunch_download_title, R.string.bunch_download_desc, 41 | BunchActivity.class); 42 | // holder.addItem(R.string.task_manager_title, R.string.task_manager_desc, 43 | // ManagerActivity.class); 44 | holder.addItem(R.string.title_content_uri, R.string.content_uri_desc, 45 | ContentUriActivity.class); 46 | holder.addItem(R.string.title_notification, R.string.notification_desc, 47 | NotificationActivity.class); 48 | // holder.addItem(R.string.comprehensive_case_title, R.string.comprehensive_case_desc, 49 | // ComprehensiveActivity.class); 50 | } 51 | 52 | @Override public int titleRes() { 53 | return R.string.app_name; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /sample/src/main/java/com/liulishuo/okdownload/sample/base/BaseSampleActivity.kt: -------------------------------------------------------------------------------- 1 | package com.liulishuo.okdownload.sample.base 2 | 3 | import android.content.Intent 4 | import android.net.Uri 5 | import android.os.Bundle 6 | import android.support.annotation.StringRes 7 | import android.support.v7.app.AppCompatActivity 8 | import android.view.Menu 9 | import android.view.MenuItem 10 | import com.liulishuo.okdownload.sample.R 11 | 12 | abstract class BaseSampleActivity : AppCompatActivity() { 13 | 14 | override fun onCreate(savedInstanceState: Bundle?) { 15 | super.onCreate(savedInstanceState) 16 | title = getString(titleRes()) 17 | } 18 | 19 | @StringRes abstract fun titleRes(): Int 20 | 21 | override fun onCreateOptionsMenu(menu: Menu?): Boolean { 22 | menuInflater.inflate(R.menu.menu_main, menu) 23 | return super.onCreateOptionsMenu(menu) 24 | } 25 | 26 | override fun onOptionsItemSelected(item: MenuItem): Boolean { 27 | when (item.itemId) { 28 | R.id.menu_github -> { 29 | openGithub() 30 | return true 31 | } 32 | } 33 | return super.onOptionsItemSelected(item) 34 | } 35 | 36 | private fun openGithub() { 37 | val uri = Uri.parse(getString(R.string.github_url)) 38 | startActivity(Intent(Intent.ACTION_VIEW, uri)) 39 | } 40 | } -------------------------------------------------------------------------------- /sample/src/main/java/com/liulishuo/okdownload/sample/util/DemoUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload.sample.util; 18 | 19 | import android.content.Context; 20 | import android.support.annotation.NonNull; 21 | import android.widget.ProgressBar; 22 | 23 | import java.io.File; 24 | 25 | public class DemoUtil { 26 | 27 | public static final String URL = 28 | "https://cdn.llscdn.com/yy/files/tkzpx40x-lls-LLS-5.7-785-20171108-111118.apk"; 29 | 30 | public static void calcProgressToView(ProgressBar progressBar, long offset, long total) { 31 | final float percent = (float) offset / total; 32 | progressBar.setProgress((int) (percent * progressBar.getMax())); 33 | } 34 | 35 | 36 | public static File getParentFile(@NonNull Context context) { 37 | final File externalSaveDir = context.getExternalCacheDir(); 38 | if (externalSaveDir == null) { 39 | return context.getCacheDir(); 40 | } else { 41 | return externalSaveDir; 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /sample/src/main/java/com/liulishuo/okdownload/sample/util/queue/QueueRecyclerAdapter.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2017 LingoChamp Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.liulishuo.okdownload.sample.util.queue 18 | 19 | import android.support.v7.widget.RecyclerView 20 | import android.view.LayoutInflater 21 | import android.view.View 22 | import android.view.ViewGroup 23 | import android.widget.ProgressBar 24 | import android.widget.SeekBar 25 | import android.widget.TextView 26 | 27 | import com.liulishuo.okdownload.sample.R 28 | 29 | class QueueRecyclerAdapter( 30 | private val controller: QueueController 31 | ) : RecyclerView.Adapter() { 32 | 33 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): QueueViewHolder { 34 | return QueueViewHolder(LayoutInflater.from(parent.context).inflate( 35 | R.layout.item_queue, 36 | parent, false) 37 | ) 38 | } 39 | 40 | override fun onBindViewHolder(holder: QueueViewHolder, position: Int) { 41 | controller.bind(holder, position) 42 | } 43 | 44 | override fun getItemCount(): Int = controller.size() 45 | 46 | class QueueViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { 47 | var nameTv: TextView = itemView.findViewById(R.id.nameTv) 48 | var priorityTv: TextView = itemView.findViewById(R.id.priorityTv) 49 | var prioritySb: SeekBar = itemView.findViewById(R.id.prioritySb) 50 | var statusTv: TextView = itemView.findViewById(R.id.statusTv) 51 | var progressBar: ProgressBar = itemView.findViewById(R.id.progressBar) 52 | } 53 | } -------------------------------------------------------------------------------- /sample/src/main/res/drawable/bg_queue_delete_file.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 21 | 22 | 24 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/ic_dashboard_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 22 | 25 | 26 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/ic_format_list_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 22 | 25 | 26 | -------------------------------------------------------------------------------- /sample/src/main/res/drawable/ic_home_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 22 | 25 | 26 | -------------------------------------------------------------------------------- /sample/src/main/res/layout/activity_content_uri.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 20 | 21 | 22 | 35 | 36 | 37 | 45 | 46 | 51 | 52 | 53 | 54 | 55 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /sample/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 18 | 19 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /sample/src/main/res/layout/activity_notification.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 23 | 24 | 35 | 36 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /sample/src/main/res/layout/activity_single.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 20 | 21 | 22 | 35 | 36 | 37 | 45 | 46 | 51 | 52 | 53 | 54 | -------------------------------------------------------------------------------- /sample/src/main/res/layout/fragment_multiple_task.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 23 | -------------------------------------------------------------------------------- /sample/src/main/res/layout/fragment_queue.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 23 | 24 |