├── ackpine-api ├── build.gradle.kts ├── api-stubs │ ├── src │ │ └── main │ │ │ └── kotlin │ │ │ ├── android │ │ │ └── content │ │ │ │ └── Context.kt │ │ │ └── ru │ │ │ └── solrudev │ │ │ └── ackpine │ │ │ ├── installer │ │ │ └── PackageInstaller.kt │ │ │ ├── uninstaller │ │ │ └── PackageUninstaller.kt │ │ │ ├── SdkInt.kt │ │ │ └── impl │ │ │ ├── installer │ │ │ └── PackageInstallerImpl.kt │ │ │ └── uninstaller │ │ │ └── PackageUninstallerImpl.kt │ └── build.gradle.kts └── api-main │ ├── consumer-rules.pro │ ├── src │ └── main │ │ └── kotlin │ │ └── ru │ │ └── solrudev │ │ └── ackpine │ │ ├── session │ │ ├── Progress.kt │ │ ├── Failure.kt │ │ └── parameters │ │ │ └── ConfirmationAware.kt │ │ ├── exceptions │ │ └── Exceptions.kt │ │ ├── SdkIntWrapper.kt │ │ ├── PackageInstallerApiCheck.kt │ │ ├── Annotations.kt │ │ └── plugability │ │ └── AckpinePluginRegistry.kt │ └── build.gradle.kts ├── ackpine-assets ├── consumer-rules.pro ├── build.gradle.kts └── src │ └── main │ └── AndroidManifest.xml ├── ackpine-core ├── consumer-rules.pro ├── api │ └── ackpine-core.api ├── src │ └── main │ │ ├── res │ │ ├── values │ │ │ ├── public.xml │ │ │ ├── styles.xml │ │ │ └── themes.xml │ │ ├── values-af-rZA │ │ │ └── strings.xml │ │ ├── anim │ │ │ └── ackpine_fade_out.xml │ │ ├── values-v19 │ │ │ └── themes.xml │ │ ├── values-v29 │ │ │ └── themes.xml │ │ ├── layout │ │ │ └── ackpine_activity_session_commit.xml │ │ ├── values-v21 │ │ │ └── themes.xml │ │ ├── values-vi │ │ │ └── strings.xml │ │ └── values-ru │ │ │ └── strings.xml │ │ └── kotlin │ │ └── ru │ │ └── solrudev │ │ └── ackpine │ │ ├── SdkInt.kt │ │ ├── impl │ │ ├── database │ │ │ ├── dao │ │ │ │ ├── SessionFailureDao.kt │ │ │ │ ├── SessionNameDao.kt │ │ │ │ ├── InstallPreapprovalDao.kt │ │ │ │ ├── NotificationIdDao.kt │ │ │ │ ├── ConfirmationLaunchDao.kt │ │ │ │ ├── InstallConstraintsDao.kt │ │ │ │ └── NativeSessionIdDao.kt │ │ │ └── model │ │ │ │ ├── InstallUriEntity.kt │ │ │ │ ├── SessionNameEntity.kt │ │ │ │ ├── PackageNameEntity.kt │ │ │ │ ├── NotificationIdEntity.kt │ │ │ │ ├── UpdateOwnershipEntity.kt │ │ │ │ ├── NativeSessionIdEntity.kt │ │ │ │ ├── LastUpdateTimestampEntity.kt │ │ │ │ ├── ConfirmationLaunchEntity.kt │ │ │ │ └── InstallFailureEntity.kt │ │ ├── plugability │ │ │ └── AckpineService.kt │ │ ├── helpers │ │ │ └── concurrent │ │ │ │ └── BinarySemaphore.kt │ │ └── uninstaller │ │ │ └── helpers │ │ │ └── PackageManagerHelpers.kt │ │ ├── exceptions │ │ └── Exceptions.kt │ │ └── AckpineInitializer.kt └── build.gradle.kts ├── ackpine-ktx ├── consumer-rules.pro ├── src │ └── main │ │ └── kotlin │ │ └── ru │ │ └── solrudev │ │ └── ackpine │ │ ├── session │ │ └── parameters │ │ │ ├── SessionParametersDsl.kt │ │ │ ├── NotificationData.kt │ │ │ └── ConfirmationDsl.kt │ │ ├── DisposableSubscriptionContainer.kt │ │ ├── uninstaller │ │ └── parameters │ │ │ └── UninstallParameters.kt │ │ └── installer │ │ └── parameters │ │ ├── InstallConstraints.kt │ │ ├── ApkList.kt │ │ └── InstallParameters.kt └── build.gradle.kts ├── ackpine-plugins ├── build.gradle.kts ├── shizuku-ktx │ ├── consumer-rules.pro │ ├── src │ │ └── main │ │ │ └── kotlin │ │ │ └── ru │ │ │ └── solrudev │ │ │ └── ackpine │ │ │ └── shizuku │ │ │ ├── ShizukuPluginParameters.kt │ │ │ ├── InstallParametersDsl.kt │ │ │ ├── ShizukuUninstallPluginParameters.kt │ │ │ └── UninstallParametersDsl.kt │ └── build.gradle.kts ├── shizuku-stubs │ ├── consumer-rules.pro │ ├── build.gradle.kts │ └── src │ │ └── main │ │ └── java │ │ └── android │ │ └── content │ │ └── pm │ │ ├── IPackageInstallerSession.java │ │ ├── IPackageManager.java │ │ └── IPackageInstaller.java └── shizuku │ ├── src │ └── main │ │ ├── resources │ │ └── META-INF │ │ │ └── services │ │ │ └── ru.solrudev.ackpine.impl.plugability.AckpineServiceProvider │ │ └── kotlin │ │ └── ru │ │ └── solrudev │ │ └── ackpine │ │ └── shizuku │ │ ├── DeleteFlags.kt │ │ └── InstallFlags.kt │ └── consumer-rules.pro ├── ackpine-splits ├── build.gradle.kts ├── splits-ktx │ ├── consumer-rules.pro │ ├── api │ │ └── splits-ktx.api │ ├── build.gradle.kts │ └── src │ │ └── main │ │ └── kotlin │ │ └── ru │ │ └── solrudev │ │ └── ackpine │ │ └── splits │ │ └── SplitPackageProvider.kt ├── splits-main │ ├── consumer-rules.pro │ ├── src │ │ └── main │ │ │ ├── kotlin │ │ │ └── ru │ │ │ │ └── solrudev │ │ │ │ └── ackpine │ │ │ │ ├── io │ │ │ │ ├── NonClosingInputStream.kt │ │ │ │ └── ToByteBuffer.kt │ │ │ │ ├── helpers │ │ │ │ └── ZipHelpers.kt │ │ │ │ └── splits │ │ │ │ └── helpers │ │ │ │ ├── SplitTypePart.kt │ │ │ │ ├── IsApk.kt │ │ │ │ ├── UriHelpers.kt │ │ │ │ └── LocaleHelpers.kt │ │ │ └── AndroidManifest.xml │ └── build.gradle.kts └── compress-android │ ├── consumer-rules.pro │ └── src │ └── main │ └── java │ └── ru │ └── solrudev │ └── ackpine │ └── compress │ └── compressors │ └── deflate64 │ └── HuffmanState.java ├── dokka-plugins ├── build.gradle.kts └── suppress-annotated-api │ ├── src │ └── main │ │ ├── resources │ │ └── META-INF │ │ │ └── services │ │ │ └── org.jetbrains.dokka.plugability.DokkaPlugin │ │ └── kotlin │ │ └── ru │ │ └── solrudev │ │ └── ackpine │ │ └── documentation │ │ └── SuppressAnnotatedApiConfig.kt │ └── build.gradle.kts ├── sample-api34 ├── proguard-rules.pro ├── src │ └── main │ │ ├── assets │ │ └── ackpine_icon.webp │ │ ├── res │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.webp │ │ │ └── ic_launcher_round.webp │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.webp │ │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.webp │ │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.webp │ │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.webp │ │ │ └── ic_launcher_round.webp │ │ ├── values-vi │ │ │ └── strings.xml │ │ ├── values-af-rZA │ │ │ └── strings.xml │ │ ├── values │ │ │ ├── ic_launcher_background.xml │ │ │ ├── dimens.xml │ │ │ ├── styles.xml │ │ │ └── strings.xml │ │ ├── values-v29 │ │ │ └── themes.xml │ │ ├── values-ru │ │ │ └── strings.xml │ │ ├── mipmap-anydpi-v26 │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ └── drawable │ │ │ └── ic_launcher_foreground.xml │ │ └── kotlin │ │ └── ru │ │ └── solrudev │ │ └── ackpine │ │ └── sample │ │ └── updater │ │ └── UpdaterUiState.kt └── build.gradle.kts ├── sample-java ├── proguard-rules.pro ├── src │ └── main │ │ ├── res │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.webp │ │ │ └── ic_launcher_round.webp │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.webp │ │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.webp │ │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.webp │ │ │ └── ic_launcher_round.webp │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.webp │ │ │ └── ic_launcher_round.webp │ │ ├── values │ │ │ ├── ic_launcher_background.xml │ │ │ ├── styles.xml │ │ │ └── dimens.xml │ │ ├── values-v29 │ │ │ └── themes.xml │ │ ├── drawable │ │ │ ├── ic_install.xml │ │ │ ├── ic_uninstall.xml │ │ │ ├── ic_launcher_foreground.xml │ │ │ └── ic_install_filled.xml │ │ ├── mipmap-anydpi-v26 │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ ├── values-af-rZA │ │ │ └── strings.xml │ │ ├── values-vi │ │ │ └── strings.xml │ │ ├── menu │ │ │ └── bottom_nav_menu.xml │ │ └── navigation │ │ │ └── ackpine_navigation_graph.xml │ │ └── java │ │ └── ru │ │ └── solrudev │ │ └── ackpine │ │ └── sample │ │ └── install │ │ ├── SessionData.java │ │ ├── SessionProgress.java │ │ └── SessionDataRepository.java └── build.gradle.kts ├── sample-ktx ├── proguard-rules.pro └── src │ └── main │ ├── res │ ├── mipmap-hdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ ├── mipmap-mdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ ├── mipmap-xhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.webp │ │ └── ic_launcher_round.webp │ ├── values │ │ ├── ic_launcher_background.xml │ │ ├── styles.xml │ │ └── dimens.xml │ ├── values-v29 │ │ └── themes.xml │ ├── drawable │ │ ├── ic_install.xml │ │ ├── ic_uninstall.xml │ │ ├── ic_launcher_foreground.xml │ │ └── ic_install_filled.xml │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ ├── values-af-rZA │ │ └── strings.xml │ ├── menu │ │ └── bottom_nav_menu.xml │ ├── values-vi │ │ └── strings.xml │ └── navigation │ │ └── ackpine_navigation_graph.xml │ └── kotlin │ └── ru │ └── solrudev │ └── ackpine │ └── sample │ ├── uninstall │ ├── ApplicationData.kt │ └── UninstallUiState.kt │ ├── util │ ├── FragmentExt.kt │ └── PackageManagerExt.kt │ └── install │ ├── InstallUiState.kt │ ├── SessionData.kt │ ├── SessionProgress.kt │ └── SessionDataRepository.kt ├── ackpine-runtime ├── consumer-rules.pro ├── api │ └── ackpine-runtime.api ├── src │ └── main │ │ ├── res │ │ ├── values │ │ │ └── public.xml │ │ └── xml │ │ │ └── ackpine_file_provider_paths.xml │ │ ├── AndroidManifest.xml │ │ └── kotlin │ │ └── ru │ │ └── solrudev │ │ └── ackpine │ │ ├── AckpineFileProvider.kt │ │ └── AckpineThreadPool.kt └── build.gradle.kts ├── docs ├── .meta.yml ├── css │ ├── logo-styles.css │ └── docs.css ├── images │ ├── logo-white.svg │ └── logo-icon.svg ├── samples.md ├── permissions.md └── architecture.md ├── version.properties ├── gradle ├── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── kotlinx.versions.toml └── settings │ ├── settings.gradle.kts │ ├── src │ └── main │ │ └── kotlin │ │ └── ru │ │ └── solrudev │ │ └── ackpine │ │ └── gradle │ │ └── ConfigureRepositories.kt │ └── build.gradle.kts ├── ackpine-resources ├── consumer-rules.pro ├── build.gradle.kts └── api │ └── ackpine-resources.api ├── gradle.properties ├── .github ├── ci-gradle.properties ├── workflows │ └── release-tag.yml └── actions │ └── setup-gradle-environment-action │ └── action.yml ├── settings.gradle.kts └── api-documentation └── build.gradle.kts /ackpine-api/build.gradle.kts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ackpine-assets/consumer-rules.pro: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ackpine-core/consumer-rules.pro: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ackpine-ktx/consumer-rules.pro: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ackpine-plugins/build.gradle.kts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ackpine-splits/build.gradle.kts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dokka-plugins/build.gradle.kts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /sample-api34/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /sample-java/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /sample-ktx/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ackpine-runtime/consumer-rules.pro: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/.meta.yml: -------------------------------------------------------------------------------- 1 | hide: 2 | - navigation -------------------------------------------------------------------------------- /ackpine-plugins/shizuku-ktx/consumer-rules.pro: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ackpine-plugins/shizuku-stubs/consumer-rules.pro: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ackpine-splits/splits-ktx/consumer-rules.pro: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /ackpine-splits/splits-main/consumer-rules.pro: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /version.properties: -------------------------------------------------------------------------------- 1 | MAJOR_VERSION=0 2 | MINOR_VERSION=18 3 | PATCH_VERSION=4 4 | SUFFIX= 5 | SNAPSHOT=false -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solrudev/Ackpine/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /sample-api34/src/main/assets/ackpine_icon.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solrudev/Ackpine/HEAD/sample-api34/src/main/assets/ackpine_icon.webp -------------------------------------------------------------------------------- /sample-java/src/main/res/mipmap-hdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solrudev/Ackpine/HEAD/sample-java/src/main/res/mipmap-hdpi/ic_launcher.webp -------------------------------------------------------------------------------- /sample-java/src/main/res/mipmap-mdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solrudev/Ackpine/HEAD/sample-java/src/main/res/mipmap-mdpi/ic_launcher.webp -------------------------------------------------------------------------------- /sample-ktx/src/main/res/mipmap-hdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solrudev/Ackpine/HEAD/sample-ktx/src/main/res/mipmap-hdpi/ic_launcher.webp -------------------------------------------------------------------------------- /sample-ktx/src/main/res/mipmap-mdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solrudev/Ackpine/HEAD/sample-ktx/src/main/res/mipmap-mdpi/ic_launcher.webp -------------------------------------------------------------------------------- /sample-ktx/src/main/res/mipmap-xhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solrudev/Ackpine/HEAD/sample-ktx/src/main/res/mipmap-xhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /sample-api34/src/main/res/mipmap-hdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solrudev/Ackpine/HEAD/sample-api34/src/main/res/mipmap-hdpi/ic_launcher.webp -------------------------------------------------------------------------------- /sample-api34/src/main/res/mipmap-mdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solrudev/Ackpine/HEAD/sample-api34/src/main/res/mipmap-mdpi/ic_launcher.webp -------------------------------------------------------------------------------- /sample-api34/src/main/res/mipmap-xhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solrudev/Ackpine/HEAD/sample-api34/src/main/res/mipmap-xhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /sample-java/src/main/res/mipmap-xhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solrudev/Ackpine/HEAD/sample-java/src/main/res/mipmap-xhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /sample-java/src/main/res/mipmap-xxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solrudev/Ackpine/HEAD/sample-java/src/main/res/mipmap-xxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /sample-ktx/src/main/res/mipmap-xxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solrudev/Ackpine/HEAD/sample-ktx/src/main/res/mipmap-xxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /sample-ktx/src/main/res/mipmap-xxxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solrudev/Ackpine/HEAD/sample-ktx/src/main/res/mipmap-xxxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /sample-api34/src/main/res/mipmap-xxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solrudev/Ackpine/HEAD/sample-api34/src/main/res/mipmap-xxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /sample-api34/src/main/res/mipmap-xxxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solrudev/Ackpine/HEAD/sample-api34/src/main/res/mipmap-xxxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /sample-java/src/main/res/mipmap-xxxhdpi/ic_launcher.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solrudev/Ackpine/HEAD/sample-java/src/main/res/mipmap-xxxhdpi/ic_launcher.webp -------------------------------------------------------------------------------- /sample-ktx/src/main/res/mipmap-hdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solrudev/Ackpine/HEAD/sample-ktx/src/main/res/mipmap-hdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /sample-ktx/src/main/res/mipmap-mdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solrudev/Ackpine/HEAD/sample-ktx/src/main/res/mipmap-mdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /ackpine-plugins/shizuku/src/main/resources/META-INF/services/ru.solrudev.ackpine.impl.plugability.AckpineServiceProvider: -------------------------------------------------------------------------------- 1 | ru.solrudev.ackpine.shizuku.ShizukuServiceProvider -------------------------------------------------------------------------------- /sample-api34/src/main/res/mipmap-hdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solrudev/Ackpine/HEAD/sample-api34/src/main/res/mipmap-hdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /sample-api34/src/main/res/mipmap-mdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solrudev/Ackpine/HEAD/sample-api34/src/main/res/mipmap-mdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /sample-java/src/main/res/mipmap-hdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solrudev/Ackpine/HEAD/sample-java/src/main/res/mipmap-hdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /sample-java/src/main/res/mipmap-mdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solrudev/Ackpine/HEAD/sample-java/src/main/res/mipmap-mdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /sample-java/src/main/res/mipmap-xhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solrudev/Ackpine/HEAD/sample-java/src/main/res/mipmap-xhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /sample-ktx/src/main/res/mipmap-xhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solrudev/Ackpine/HEAD/sample-ktx/src/main/res/mipmap-xhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /sample-ktx/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solrudev/Ackpine/HEAD/sample-ktx/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /docs/css/logo-styles.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --dokka-logo-image-url: url('../../images/logo-white.svg'); 3 | --dokka-logo-height: 50px; 4 | --dokka-logo-width: 50px; 5 | } -------------------------------------------------------------------------------- /sample-api34/src/main/res/mipmap-xhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solrudev/Ackpine/HEAD/sample-api34/src/main/res/mipmap-xhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /sample-api34/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solrudev/Ackpine/HEAD/sample-api34/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /sample-api34/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solrudev/Ackpine/HEAD/sample-api34/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /sample-java/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solrudev/Ackpine/HEAD/sample-java/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /sample-java/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solrudev/Ackpine/HEAD/sample-java/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /sample-ktx/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/solrudev/Ackpine/HEAD/sample-ktx/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp -------------------------------------------------------------------------------- /ackpine-runtime/api/ackpine-runtime.api: -------------------------------------------------------------------------------- 1 | public final class ru/solrudev/ackpine/AckpineFileProvider$Companion { 2 | public final fun getAuthority ()Ljava/lang/String; 3 | } 4 | 5 | -------------------------------------------------------------------------------- /dokka-plugins/suppress-annotated-api/src/main/resources/META-INF/services/org.jetbrains.dokka.plugability.DokkaPlugin: -------------------------------------------------------------------------------- 1 | ru.solrudev.ackpine.documentation.SuppressAnnotatedApiDokkaPlugin -------------------------------------------------------------------------------- /gradle/kotlinx.versions.toml: -------------------------------------------------------------------------------- 1 | [libraries] 2 | coroutines-core = "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.10.2" 3 | serialization-json = "org.jetbrains.kotlinx:kotlinx-serialization-json:1.9.0" -------------------------------------------------------------------------------- /ackpine-splits/compress-android/consumer-rules.pro: -------------------------------------------------------------------------------- 1 | -dontwarn com.github.luben.zstd.ZstdInputStream 2 | -dontwarn org.tukaani.xz.MemoryLimitException 3 | -dontwarn org.tukaani.xz.SingleXZInputStream 4 | -dontwarn org.tukaani.xz.XZInputStream -------------------------------------------------------------------------------- /ackpine-splits/splits-ktx/api/splits-ktx.api: -------------------------------------------------------------------------------- 1 | public final class ru/solrudev/ackpine/splits/SplitPackageProviderKt { 2 | public static final fun get (Lru/solrudev/ackpine/splits/SplitPackage$Provider;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; 3 | } 4 | 5 | -------------------------------------------------------------------------------- /sample-api34/src/main/res/values-vi/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Cài đặt 4 | Cài đặt 5 | Huỷ 6 | Có lỗi 7 | Lỗi: %s 8 | -------------------------------------------------------------------------------- /ackpine-plugins/shizuku/consumer-rules.pro: -------------------------------------------------------------------------------- 1 | -dontwarn android.content.pm.IPackageInstaller$Stub 2 | -dontwarn android.content.pm.IPackageInstaller 3 | -dontwarn android.content.pm.IPackageInstallerSession$Stub 4 | -dontwarn android.content.pm.IPackageInstallerSession 5 | -dontwarn android.content.pm.IPackageManager$Stub 6 | -dontwarn android.content.pm.IPackageManager -------------------------------------------------------------------------------- /sample-api34/src/main/res/values-af-rZA/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Installeer 4 | Installeer 5 | Kanselleer 6 | Fout 7 | Fout: %s 8 | -------------------------------------------------------------------------------- /ackpine-resources/consumer-rules.pro: -------------------------------------------------------------------------------- 1 | # Serializable 2 | -keep class ru.solrudev.ackpine.resources.ResolvableString { *; } 3 | -keep class ru.solrudev.ackpine.resources.ResolvableString$* { *; } 4 | -keep class * extends ru.solrudev.ackpine.resources.ResolvableString$Resource { *; } 5 | -keep class ru.solrudev.ackpine.resources.Empty { *; } 6 | -keep class ru.solrudev.ackpine.resources.Raw { *; } -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionSha256Sum=72f44c9f8ebcb1af43838f45ee5c4aa9c5444898b3468ab3f4af7b6076c5bc3f 4 | distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip 5 | networkTimeout=10000 6 | validateDistributionUrl=true 7 | zipStoreBase=GRADLE_USER_HOME 8 | zipStorePath=wrapper/dists 9 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx4g -XX:+UseParallelGC -Dfile.encoding=UTF-8 -XX:MaxMetaspaceSize=1g 2 | org.gradle.daemon=true 3 | org.gradle.parallel=true 4 | org.gradle.configuration-cache=true 5 | org.gradle.configuration-cache.parallel=true 6 | org.gradle.configureondemand=true 7 | android.useAndroidX=true 8 | kotlin.code.style=official 9 | android.r8.maxWorkers=2 10 | android.lint.useK2Uast=true -------------------------------------------------------------------------------- /.github/ci-gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx4g -XX:+UseParallelGC -Dfile.encoding=UTF-8 -XX:MaxMetaspaceSize=1g 2 | org.gradle.daemon=false 3 | org.gradle.caching=true 4 | org.gradle.parallel=true 5 | org.gradle.configuration-cache=true 6 | org.gradle.configuration-cache.parallel=true 7 | org.gradle.configureondemand=true 8 | android.useAndroidX=true 9 | kotlin.code.style=official 10 | android.r8.maxWorkers=2 11 | android.lint.useK2Uast=true -------------------------------------------------------------------------------- /docs/images/logo-white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /ackpine-core/api/ackpine-core.api: -------------------------------------------------------------------------------- 1 | public final class ru/solrudev/ackpine/Ackpine { 2 | public static final field INSTANCE Lru/solrudev/ackpine/Ackpine; 3 | public static final fun deleteNotificationChannel (Landroid/content/Context;)V 4 | } 5 | 6 | public final class ru/solrudev/ackpine/AckpineInitializer : androidx/startup/Initializer { 7 | public fun ()V 8 | public synthetic fun create (Landroid/content/Context;)Ljava/lang/Object; 9 | public fun create (Landroid/content/Context;)Lru/solrudev/ackpine/Ackpine; 10 | public fun dependencies ()Ljava/util/List; 11 | } 12 | 13 | public final class ru/solrudev/ackpine/exceptions/AckpineReinitializeException : java/lang/Exception { 14 | public fun ()V 15 | } 16 | 17 | -------------------------------------------------------------------------------- /ackpine-core/src/main/res/values/public.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /ackpine-runtime/src/main/res/values/public.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /ackpine-api/api-stubs/src/main/kotlin/android/content/Context.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 Ilya Fomichev 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 android.content 18 | 19 | /** 20 | * Stub for `android.content.Context`. 21 | */ 22 | public abstract class Context -------------------------------------------------------------------------------- /sample-api34/src/main/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | #FFFFFF 19 | -------------------------------------------------------------------------------- /sample-java/src/main/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | #FFFFFF 19 | -------------------------------------------------------------------------------- /sample-ktx/src/main/res/values/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | #FFFFFF 19 | -------------------------------------------------------------------------------- /docs/images/logo-icon.svg: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /ackpine-api/api-main/consumer-rules.pro: -------------------------------------------------------------------------------- 1 | # Serializable 2 | -keep interface ru.solrudev.ackpine.session.parameters.DrawableId { *; } 3 | -keep class * implements ru.solrudev.ackpine.session.parameters.DrawableId { *; } 4 | -keep class ru.solrudev.ackpine.installer.InstallFailure { *; } 5 | -keep class * extends ru.solrudev.ackpine.installer.InstallFailure { *; } 6 | -keep interface ru.solrudev.ackpine.uninstaller.UninstallFailure { *; } 7 | -keep class * implements ru.solrudev.ackpine.uninstaller.UninstallFailure { *; } 8 | -keep interface ru.solrudev.ackpine.installer.parameters.InstallConstraints$TimeoutStrategy { *; } 9 | -keep class * implements ru.solrudev.ackpine.installer.parameters.InstallConstraints$TimeoutStrategy { *; } 10 | 11 | # Plugins 12 | -keep interface ru.solrudev.ackpine.plugability.AckpinePlugin { *; } 13 | -keep class * implements ru.solrudev.ackpine.plugability.AckpinePlugin { *; } -------------------------------------------------------------------------------- /ackpine-api/api-stubs/src/main/kotlin/ru/solrudev/ackpine/installer/PackageInstaller.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 Ilya Fomichev 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 ru.solrudev.ackpine.installer 18 | 19 | /** 20 | * Stub for `PackageInstaller` from `ackpine-api`. 21 | */ 22 | public interface PackageInstaller -------------------------------------------------------------------------------- /ackpine-core/src/main/res/values-af-rZA/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Bevestig asseblief installasie. 4 | Bevestig asseblief installasie van %s. 5 | Installasie 6 | Bevestig asseblief verwydering van %s. 7 | Verwydering 8 | As u dit afskakel, word pakket installerings funksionaliteit verbreek 9 | Installeer en verwyder 10 | Bevestig asseblief verwydering. 11 | -------------------------------------------------------------------------------- /ackpine-api/api-stubs/src/main/kotlin/ru/solrudev/ackpine/uninstaller/PackageUninstaller.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 Ilya Fomichev 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 ru.solrudev.ackpine.uninstaller 18 | 19 | /** 20 | * Stub for `PackageUninstaller` from `ackpine-api`. 21 | */ 22 | public interface PackageUninstaller -------------------------------------------------------------------------------- /gradle/settings/settings.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 Ilya Fomichev 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 | plugins { 18 | id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0" 19 | } 20 | 21 | dependencyResolutionManagement { 22 | repositories { 23 | mavenCentral() 24 | gradlePluginPortal() 25 | } 26 | } -------------------------------------------------------------------------------- /ackpine-api/api-stubs/build.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 Ilya Fomichev 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 | import ru.solrudev.ackpine.gradle.Constants 18 | 19 | description = "Ackpine API stubs" 20 | 21 | plugins { 22 | kotlin("jvm") 23 | } 24 | 25 | kotlin { 26 | jvmToolchain(Constants.JDK_VERSION) 27 | explicitApi() 28 | } -------------------------------------------------------------------------------- /ackpine-plugins/shizuku/src/main/kotlin/ru/solrudev/ackpine/shizuku/DeleteFlags.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 Ilya Fomichev 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 ru.solrudev.ackpine.shizuku 18 | 19 | @JvmSynthetic 20 | internal const val DELETE_KEEP_DATA = 0x00000001 21 | 22 | @JvmSynthetic 23 | internal const val DELETE_ALL_USERS = 0x00000002 -------------------------------------------------------------------------------- /ackpine-core/src/main/kotlin/ru/solrudev/ackpine/SdkInt.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 Ilya Fomichev 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 ru.solrudev.ackpine 18 | 19 | import android.os.Build 20 | 21 | @Suppress("Unused") 22 | internal object SdkInt { 23 | @JvmSynthetic 24 | @JvmName("get") 25 | internal fun get() = Build.VERSION.SDK_INT 26 | } -------------------------------------------------------------------------------- /ackpine-api/api-stubs/src/main/kotlin/ru/solrudev/ackpine/SdkInt.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 Ilya Fomichev 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 ru.solrudev.ackpine 18 | 19 | /** 20 | * A replaceable stub for getting current SDK version. 21 | */ 22 | public object SdkInt { 23 | public fun get(): Int { 24 | throw NotImplementedError() 25 | } 26 | } -------------------------------------------------------------------------------- /sample-ktx/src/main/kotlin/ru/solrudev/ackpine/sample/uninstall/ApplicationData.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 Ilya Fomichev 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 ru.solrudev.ackpine.sample.uninstall 18 | 19 | import android.graphics.drawable.Drawable 20 | 21 | data class ApplicationData( 22 | val name: String, 23 | val packageName: String, 24 | val icon: Drawable 25 | ) -------------------------------------------------------------------------------- /ackpine-api/api-main/src/main/kotlin/ru/solrudev/ackpine/session/Progress.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 Ilya Fomichev 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 ru.solrudev.ackpine.session 18 | 19 | /** 20 | * Represents progress data. 21 | */ 22 | public data class Progress @JvmOverloads public constructor( 23 | public val progress: Int = 0, 24 | public val max: Int = 100 25 | ) -------------------------------------------------------------------------------- /sample-ktx/src/main/kotlin/ru/solrudev/ackpine/sample/uninstall/UninstallUiState.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 Ilya Fomichev 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 ru.solrudev.ackpine.sample.uninstall 18 | 19 | data class UninstallUiState( 20 | val isLoading: Boolean = false, 21 | val applications: List = emptyList(), 22 | val failure: String? = null 23 | ) -------------------------------------------------------------------------------- /ackpine-core/src/main/res/anim/ackpine_fade_out.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | -------------------------------------------------------------------------------- /ackpine-splits/splits-main/src/main/kotlin/ru/solrudev/ackpine/io/NonClosingInputStream.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 Ilya Fomichev 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 ru.solrudev.ackpine.io 18 | 19 | import ru.solrudev.ackpine.compress.utils.CloseShieldInputStream 20 | import java.io.InputStream 21 | 22 | @JvmSynthetic 23 | internal fun InputStream.nonClosing() = CloseShieldInputStream.wrap(this) 24 | -------------------------------------------------------------------------------- /docs/samples.md: -------------------------------------------------------------------------------- 1 | Samples 2 | ======= 3 | 4 | Sample app showcasing the usage of Ackpine can be found in the [GitHub repository](https://github.com/solrudev/Ackpine). 5 | 6 | It utilizes `ackpine-splits` functionality and allows to install zipped split packages as well as monolithic APKs and uninstall an application from the list of installed user applications. The sample app correctly handles process death, so install sessions aren't going to waste if Android decides to kill the app. 7 | 8 | [`sample-java`](https://github.com/solrudev/Ackpine/tree/master/sample-java) is fully written in Java, while [`sample-ktx`](https://github.com/solrudev/Ackpine/tree/master/sample-ktx) is leveraging the `ackpine-ktx` artifact. 9 | 10 | [`sample-api34`](https://github.com/solrudev/Ackpine/tree/master/sample-api34) showcases usage of features supported on API level 34 and higher, such as [install pre-commit preapproval](configuration.md#preapproval) and [installation constraints](configuration.md#constraints). -------------------------------------------------------------------------------- /.github/workflows/release-tag.yml: -------------------------------------------------------------------------------- 1 | name: release-tag 2 | 3 | on: 4 | pull_request: 5 | types: 6 | - closed 7 | branches: 8 | - master 9 | 10 | permissions: 11 | contents: read 12 | 13 | jobs: 14 | push-tag: 15 | runs-on: ubuntu-latest 16 | if: github.event.pull_request.merged == true && contains(github.event.pull_request.labels.*.name, 'release') 17 | 18 | steps: 19 | - name: Checkout 20 | uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # 6.0.0 21 | with: 22 | ref: ${{ github.event.pull_request.merge_commit_sha }} 23 | fetch-depth: '0' 24 | persist-credentials: false 25 | 26 | - name: Push tag 27 | uses: anothrNick/github-tag-action@4ed44965e0db8dab2b466a16da04aec3cc312fd8 # 1.75.0 28 | env: 29 | GITHUB_TOKEN: ${{ secrets.PAT_AUTOTAG }} 30 | CUSTOM_TAG: ${{ github.event.pull_request.title }} 31 | WITH_V: false 32 | PRERELEASE: false -------------------------------------------------------------------------------- /sample-java/src/main/res/values-v29/themes.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 19 | 22 | 23 | 22 | 23 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /sample-ktx/src/main/kotlin/ru/solrudev/ackpine/sample/install/InstallUiState.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 Ilya Fomichev 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 ru.solrudev.ackpine.sample.install 18 | 19 | import ru.solrudev.ackpine.resources.ResolvableString 20 | 21 | data class InstallUiState( 22 | val error: ResolvableString = ResolvableString.empty(), 23 | val sessions: List = emptyList(), 24 | val sessionsProgress: List = emptyList() 25 | ) -------------------------------------------------------------------------------- /ackpine-core/src/main/kotlin/ru/solrudev/ackpine/impl/database/dao/SessionFailureDao.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 Ilya Fomichev 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 ru.solrudev.ackpine.impl.database.dao 18 | 19 | import androidx.annotation.RestrictTo 20 | import ru.solrudev.ackpine.session.Failure 21 | 22 | @RestrictTo(RestrictTo.Scope.LIBRARY) 23 | internal interface SessionFailureDao { 24 | fun getFailure(id: String): F? 25 | fun setFailure(id: String, failure: F) 26 | } -------------------------------------------------------------------------------- /ackpine-core/src/main/kotlin/ru/solrudev/ackpine/exceptions/Exceptions.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 Ilya Fomichev 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 ru.solrudev.ackpine.exceptions 18 | 19 | /** 20 | * Thrown if Ackpine initialization is attempted more than once. 21 | */ 22 | public class AckpineReinitializeException : Exception( 23 | "Attempt of Ackpine re-initialization. Make sure you're not initializing Ackpine manually without disabling " + 24 | "automatic initialization." 25 | ) -------------------------------------------------------------------------------- /ackpine-runtime/src/main/res/xml/ackpine_file_provider_paths.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 21 | 24 | 27 | -------------------------------------------------------------------------------- /ackpine-splits/splits-main/src/main/kotlin/ru/solrudev/ackpine/io/ToByteBuffer.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2024 Ilya Fomichev 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 ru.solrudev.ackpine.io 18 | 19 | import java.io.ByteArrayOutputStream 20 | import java.io.InputStream 21 | import java.nio.ByteBuffer 22 | 23 | @JvmSynthetic 24 | internal fun InputStream.toByteBuffer(): ByteBuffer { 25 | val buffer = ByteArrayOutputStream() 26 | copyTo(buffer) 27 | return ByteBuffer.wrap(buffer.toByteArray()) 28 | } -------------------------------------------------------------------------------- /sample-api34/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /sample-java/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /sample-ktx/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /sample-api34/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /sample-java/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /sample-ktx/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /ackpine-splits/splits-main/src/main/kotlin/ru/solrudev/ackpine/helpers/ZipHelpers.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 Ilya Fomichev 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 ru.solrudev.ackpine.helpers 18 | 19 | import java.util.zip.ZipInputStream 20 | 21 | /** 22 | * The returned sequence is constrained to be iterated only once. 23 | */ 24 | @JvmSynthetic 25 | internal fun ZipInputStream.entries() = sequence { 26 | while (true) { 27 | val entry = nextEntry ?: break 28 | yield(entry) 29 | } 30 | }.constrainOnce() -------------------------------------------------------------------------------- /ackpine-assets/build.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 Ilya Fomichev 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 | description = "Provides support of asset files inside of application's package for Ackpine" 18 | 19 | plugins { 20 | id("ru.solrudev.ackpine.library") 21 | id("ru.solrudev.ackpine.library-publish") 22 | id("ru.solrudev.ackpine.dokka") 23 | } 24 | 25 | ackpine { 26 | id = "assets" 27 | artifact { 28 | name = "Ackpine Assets" 29 | } 30 | } 31 | 32 | dependencies { 33 | implementation(projects.ackpineRuntime) 34 | } -------------------------------------------------------------------------------- /ackpine-assets/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 20 | 21 | 26 | 27 | -------------------------------------------------------------------------------- /docs/permissions.md: -------------------------------------------------------------------------------- 1 | Permissions 2 | =========== 3 | 4 | Ackpine adds the following permissions to `AndroidManifest.xml`: 5 | 6 | - `WRITE_EXTERNAL_STORAGE` — used by `INTENT_BASED` package installer to create temporary APK copy; 7 | - `REQUEST_INSTALL_PACKAGES` and `REQUEST_DELETE_PACKAGES` — self-explanatory; 8 | - `VIBRATE` — to be able to set heads-up notifications' vibration when using `DEFERRED` confirmation; 9 | - `POST_NOTIFICATIONS` — for posting notifications when using `DEFERRED` confirmation; 10 | - `UPDATE_PACKAGES_WITHOUT_USER_ACTION` — to be able to leverage `requireUserAction` feature on API >= 31; 11 | - `ENFORCE_UPDATE_OWNERSHIP` — to be able to leverage update ownership enforcement feature on API >= 34. 12 | 13 | If you don't need some of the features listed above and don't want to have unneeded permissions in your app, you can remove them from the resulting merged `AndroidManifest.xml`, but do so carefully to not break the library functionality you use: 14 | 15 | ```xml 16 | 19 | ``` -------------------------------------------------------------------------------- /ackpine-ktx/src/main/kotlin/ru/solrudev/ackpine/uninstaller/parameters/UninstallParameters.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 Ilya Fomichev 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 ru.solrudev.ackpine.uninstaller.parameters 18 | 19 | /** 20 | * Constructs a new instance of [UninstallParameters]. 21 | */ 22 | public inline fun UninstallParameters( 23 | packageName: String, 24 | configure: UninstallParametersDsl.() -> Unit 25 | ): UninstallParameters { 26 | return UninstallParametersDslBuilder(packageName).apply(configure).build() 27 | } -------------------------------------------------------------------------------- /ackpine-resources/build.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2024 Ilya Fomichev 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 | description = "Abstractions for resolvable and persistable Android resources" 18 | 19 | plugins { 20 | id("ru.solrudev.ackpine.library") 21 | id("ru.solrudev.ackpine.library-publish") 22 | id("ru.solrudev.ackpine.dokka") 23 | } 24 | 25 | ackpine { 26 | id = "resources" 27 | artifact { 28 | name = "Ackpine Resources" 29 | inceptionYear = "2024" 30 | } 31 | } 32 | 33 | dependencies { 34 | api(androidx.annotation) 35 | } -------------------------------------------------------------------------------- /gradle/settings/src/main/kotlin/ru/solrudev/ackpine/gradle/ConfigureRepositories.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 Ilya Fomichev 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 ru.solrudev.ackpine.gradle 18 | 19 | import org.gradle.api.artifacts.dsl.RepositoryHandler 20 | 21 | internal fun RepositoryHandler.configureRepositories() { 22 | google { 23 | content { 24 | includeGroupAndSubgroups("androidx") 25 | includeGroupAndSubgroups("com.android") 26 | includeGroupAndSubgroups("com.google") 27 | } 28 | } 29 | mavenCentral() 30 | } -------------------------------------------------------------------------------- /ackpine-plugins/shizuku-ktx/src/main/kotlin/ru/solrudev/ackpine/shizuku/ShizukuPluginParameters.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 Ilya Fomichev 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 ru.solrudev.ackpine.shizuku 18 | 19 | /** 20 | * Constructs a new instance of [ShizukuPlugin.Parameters]. 21 | */ 22 | @Suppress("FunctionName") 23 | public inline fun ShizukuPluginParameters( 24 | configure: ShizukuPluginParametersDsl.() -> Unit = {} 25 | ): ShizukuPlugin.Parameters { 26 | return ShizukuPluginParametersDslBuilder().apply(configure).build() 27 | } -------------------------------------------------------------------------------- /ackpine-splits/splits-main/src/main/kotlin/ru/solrudev/ackpine/splits/helpers/SplitTypePart.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 Ilya Fomichev 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 ru.solrudev.ackpine.splits.helpers 18 | 19 | private const val CONFIG_PART = "config." 20 | 21 | @JvmSynthetic 22 | internal fun splitTypePart(name: String): String? { 23 | if (!name.contains(CONFIG_PART, ignoreCase = true) && !name.contains(".$CONFIG_PART", ignoreCase = true)) { 24 | return null 25 | } 26 | return name.substringAfter(CONFIG_PART).lowercase() 27 | } -------------------------------------------------------------------------------- /ackpine-splits/compress-android/src/main/java/ru/solrudev/ackpine/compress/compressors/deflate64/HuffmanState.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Licensed to the Apache Software Foundation (ASF) under one 3 | * or more contributor license agreements. See the NOTICE file 4 | * distributed with this work for additional information 5 | * regarding copyright ownership. The ASF licenses this file 6 | * to you under the Apache License, Version 2.0 (the 7 | * "License"); you may not use this file except in compliance 8 | * with the License. You may obtain a copy of the License at 9 | * 10 | * https://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, 13 | * software distributed under the License is distributed on an 14 | * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 | * KIND, either express or implied. See the License for the 16 | * specific language governing permissions and limitations 17 | * under the License. 18 | */ 19 | package ru.solrudev.ackpine.compress.compressors.deflate64; 20 | 21 | enum HuffmanState { 22 | INITIAL, STORED, DYNAMIC_CODES, FIXED_CODES 23 | } 24 | -------------------------------------------------------------------------------- /ackpine-splits/splits-main/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 20 | 21 | 22 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /ackpine-plugins/shizuku-ktx/src/main/kotlin/ru/solrudev/ackpine/shizuku/InstallParametersDsl.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 Ilya Fomichev 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 ru.solrudev.ackpine.shizuku 18 | 19 | import ru.solrudev.ackpine.installer.parameters.InstallParametersDsl 20 | 21 | /** 22 | * Applies [ShizukuPlugin] to the session. 23 | */ 24 | public inline fun InstallParametersDsl.useShizuku( 25 | configure: ShizukuPluginParametersDsl.() -> Unit = {} 26 | ) { 27 | usePlugin(ShizukuPlugin::class, ShizukuPluginParameters(configure)) 28 | } -------------------------------------------------------------------------------- /ackpine-api/api-main/src/main/kotlin/ru/solrudev/ackpine/exceptions/Exceptions.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 Ilya Fomichev 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 ru.solrudev.ackpine.exceptions 18 | 19 | import ru.solrudev.ackpine.SdkIntWrapper 20 | 21 | /** 22 | * Thrown if installation of split packages is not supported when creating session with split package is attempted. 23 | */ 24 | public class SplitPackagesNotSupportedException : IllegalStateException( 25 | "Split packages are not supported on current Android API level: ${SdkIntWrapper.get()}" 26 | ) -------------------------------------------------------------------------------- /sample-java/src/main/res/values-af-rZA/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Installeer 4 | Verwyder 5 | Kanselleer 6 | Installeer 7 | Verwyder 8 | Fout 9 | Fout: %s 10 | Geen installasie sessies nie 11 | Geen geïnstalleerde toepassings nie 12 | Geen basis APK gevind nie 13 | Meer as een basis APK gevind 14 | Botesende gesplete naam: %s 15 | Botesende pakket naam. Verwag: %1$s, gevind: %2$s, naam: %3$s 16 | Botesende weergawe kode. Verwag: %1$s, gevind: %2$s, naam: %3$s 17 | -------------------------------------------------------------------------------- /sample-ktx/src/main/res/values-af-rZA/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Installeer 4 | Verwyder 5 | Kanselleer 6 | Installeer 7 | Verwyder 8 | Fout 9 | Fout: %s 10 | Geen installasie sessies nie 11 | Geen geïnstalleerde toepassings nie 12 | Geen basis APK gevind nie 13 | Meer as een basis APK gevind 14 | Botesende gesplete naam: %s 15 | Botesende pakket naam. Verwag: %1$s, gevind: %2$s, naam: %3$s 16 | Botesende weergawe kode. Verwag: %1$s, gevind: %2$s, naam: %3$s 17 | -------------------------------------------------------------------------------- /ackpine-ktx/build.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 Ilya Fomichev 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 | description = "Kotlin extensions for Ackpine" 18 | 19 | plugins { 20 | id("ru.solrudev.ackpine.library") 21 | id("ru.solrudev.ackpine.library-publish") 22 | id("ru.solrudev.ackpine.dokka") 23 | } 24 | 25 | ackpine { 26 | id = "ktx" 27 | artifact { 28 | name = "Ackpine Kotlin Extensions" 29 | } 30 | } 31 | 32 | dependencies { 33 | api(projects.ackpineApi.apiMain) 34 | api(kotlinx.coroutines.core) 35 | implementation(androidx.concurrent.futures.ktx) 36 | } -------------------------------------------------------------------------------- /ackpine-runtime/build.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 Ilya Fomichev 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 | description = "Ackpine Runtime dependency" 18 | 19 | plugins { 20 | id("ru.solrudev.ackpine.library") 21 | id("ru.solrudev.ackpine.library-publish") 22 | } 23 | 24 | ackpine { 25 | id = "runtime" 26 | artifact { 27 | name = "Ackpine Runtime" 28 | } 29 | } 30 | 31 | dependencies { 32 | api(androidx.annotation) 33 | compileOnly(libs.listenableFuture) 34 | implementation(androidx.core.ktx) 35 | implementation(androidx.concurrent.futures.core) 36 | } -------------------------------------------------------------------------------- /sample-ktx/src/main/kotlin/ru/solrudev/ackpine/sample/install/SessionData.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 Ilya Fomichev 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 ru.solrudev.ackpine.sample.install 18 | 19 | import android.os.Parcelable 20 | import kotlinx.parcelize.Parcelize 21 | import ru.solrudev.ackpine.resources.ResolvableString 22 | import java.util.UUID 23 | 24 | @Parcelize 25 | data class SessionData( 26 | val id: UUID, 27 | val name: String, 28 | val error: ResolvableString = ResolvableString.empty(), 29 | val isCancellable: Boolean = true 30 | ) : Parcelable -------------------------------------------------------------------------------- /ackpine-core/src/main/kotlin/ru/solrudev/ackpine/impl/database/dao/SessionNameDao.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 Ilya Fomichev 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 ru.solrudev.ackpine.impl.database.dao 18 | 19 | import androidx.annotation.RestrictTo 20 | import androidx.room.Dao 21 | import androidx.room.Query 22 | 23 | @RestrictTo(RestrictTo.Scope.LIBRARY) 24 | @Dao 25 | internal interface SessionNameDao { 26 | 27 | @Query("INSERT OR REPLACE INTO sessions_names(session_id, name) VALUES (:sessionId, :name)") 28 | fun setSessionName(sessionId: String, name: String) 29 | } -------------------------------------------------------------------------------- /sample-java/src/main/res/values-vi/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Cài đặt 4 | Gỡ cài đặt 5 | Huỷ 6 | Cài đặt 7 | Gỡ cài đặt 8 | Lỗi 9 | Lỗi: %s 10 | Không có quá trình cài đặt nào 11 | Chưa có ứng dụng nào được cài đặt 12 | Không tìm thấy tệp APK gốc (base.apk) 13 | Có nhiều hơn một tệp APK gốc (base.apk) 14 | Tên split bị trùng: %s 15 | Xung đột tên gói. Mong đợi: %1$s, nhưng tìm thấy: %2$s (tên: %3$s) 16 | Mã phiên bản bị xung đột. Mong đợi: %1$s, nhưng tìm thấy: %2$s (tên: %3$s) 17 | -------------------------------------------------------------------------------- /sample-ktx/src/main/res/menu/bottom_nav_menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 20 | 24 | 25 | 29 | 30 | -------------------------------------------------------------------------------- /sample-ktx/src/main/res/values-vi/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | Cài đặt 4 | Gỡ cài đặt 5 | Huỷ 6 | Cài đặt 7 | Gỡ cài đặt 8 | Lỗi 9 | Lỗi: %s 10 | Không có quá trình cài đặt nào 11 | Chưa có ứng dụng nào được cài đặt 12 | Không tìm thấy tệp APK gốc (base.apk) 13 | Có nhiều hơn một tệp APK gốc (base.apk) 14 | Tên split bị trùng: %s 15 | Xung đột tên gói. Mong đợi: %1$s, nhưng tìm thấy: %2$s (tên: %3$s) 16 | Mã phiên bản bị xung đột. Mong đợi: %1$s, nhưng tìm thấy: %2$s (tên: %3$s) 17 | -------------------------------------------------------------------------------- /sample-java/src/main/res/menu/bottom_nav_menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 20 | 24 | 25 | 29 | 30 | -------------------------------------------------------------------------------- /sample-api34/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 6dp 20 | 50dp 21 | 8dp 22 | 100dp 23 | 16dp 24 | 16dp 25 | 16dp 26 | -------------------------------------------------------------------------------- /ackpine-core/src/main/kotlin/ru/solrudev/ackpine/impl/database/dao/InstallPreapprovalDao.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2024 Ilya Fomichev 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 ru.solrudev.ackpine.impl.database.dao 18 | 19 | import androidx.annotation.RestrictTo 20 | import androidx.room.Dao 21 | import androidx.room.Query 22 | 23 | @RestrictTo(RestrictTo.Scope.LIBRARY) 24 | @Dao 25 | internal interface InstallPreapprovalDao { 26 | 27 | @Query("UPDATE OR IGNORE sessions_install_preapproval SET is_preapproved = 1 WHERE session_id = :sessionId") 28 | fun setPreapproved(sessionId: String) 29 | } -------------------------------------------------------------------------------- /ackpine-core/src/main/res/values-v19/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 20 | 24 | 25 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /sample-ktx/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 25 | -------------------------------------------------------------------------------- /ackpine-core/src/main/kotlin/ru/solrudev/ackpine/AckpineInitializer.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 Ilya Fomichev 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 ru.solrudev.ackpine 18 | 19 | import android.content.Context 20 | import androidx.startup.Initializer 21 | 22 | /** 23 | * Initializes [Ackpine] using `androidx.startup`. 24 | */ 25 | public class AckpineInitializer : Initializer { 26 | 27 | override fun create(context: Context): Ackpine { 28 | Ackpine.init(context) 29 | return Ackpine 30 | } 31 | 32 | override fun dependencies(): List>> { 33 | return emptyList() 34 | } 35 | } -------------------------------------------------------------------------------- /ackpine-core/src/main/res/layout/ackpine_activity_session_commit.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 21 | 22 | 28 | -------------------------------------------------------------------------------- /dokka-plugins/suppress-annotated-api/build.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 Ilya Fomichev 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 | import ru.solrudev.ackpine.gradle.Constants 18 | 19 | description = "Dokka plugin allowing to hide declarations marked with provided annotations from API documentation" 20 | 21 | plugins { 22 | kotlin("jvm") 23 | alias(libs.plugins.kotlin.serialization) 24 | } 25 | 26 | kotlin { 27 | jvmToolchain(Constants.JDK_VERSION) 28 | explicitApi() 29 | } 30 | 31 | dependencies { 32 | compileOnly(libs.dokka.core) 33 | implementation(libs.dokka.base) 34 | implementation(kotlinx.serialization.json) 35 | } -------------------------------------------------------------------------------- /sample-api34/src/main/kotlin/ru/solrudev/ackpine/sample/updater/UpdaterUiState.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2024 Ilya Fomichev 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 ru.solrudev.ackpine.sample.updater 18 | 19 | import ru.solrudev.ackpine.resources.ResolvableString 20 | import ru.solrudev.ackpine.session.Progress 21 | 22 | data class UpdaterUiState( 23 | val isInstalling: Boolean = false, 24 | val progress: Progress = Progress(), 25 | val error: ResolvableString = ResolvableString.empty(), 26 | val isCancellable: Boolean = true, 27 | val buttonText: ResolvableString = ResolvableString.transientResource(R.string.install) 28 | ) -------------------------------------------------------------------------------- /sample-ktx/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 6dp 20 | 8dp 21 | 80dp 22 | 16dp 23 | 50dp 24 | 16dp 25 | 16dp 26 | 16dp 27 | -------------------------------------------------------------------------------- /ackpine-api/api-stubs/src/main/kotlin/ru/solrudev/ackpine/impl/uninstaller/PackageUninstallerImpl.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 Ilya Fomichev 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 ru.solrudev.ackpine.impl.uninstaller 18 | 19 | import android.content.Context 20 | import ru.solrudev.ackpine.uninstaller.PackageUninstaller 21 | 22 | /** 23 | * Stub for `PackageUninstallerImpl` from `ackpine-core`. 24 | */ 25 | public interface PackageUninstallerImpl : PackageUninstaller { 26 | public companion object { 27 | public fun getInstance(context: Context): PackageUninstallerImpl { 28 | throw NotImplementedError() 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /sample-java/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 6dp 20 | 8dp 21 | 80dp 22 | 16dp 23 | 50dp 24 | 16dp 25 | 16dp 26 | 16dp 27 | -------------------------------------------------------------------------------- /ackpine-core/src/main/kotlin/ru/solrudev/ackpine/impl/database/dao/ConfirmationLaunchDao.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 Ilya Fomichev 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 ru.solrudev.ackpine.impl.database.dao 18 | 19 | import androidx.annotation.RestrictTo 20 | import androidx.room.Dao 21 | import androidx.room.Query 22 | 23 | @RestrictTo(RestrictTo.Scope.LIBRARY) 24 | @Dao 25 | internal interface ConfirmationLaunchDao { 26 | 27 | @Query( 28 | "INSERT OR IGNORE INTO sessions_confirmation_launches(session_id, was_confirmation_launched) " + 29 | "VALUES (:sessionId, 1)" 30 | ) 31 | fun setConfirmationLaunched(sessionId: String) 32 | } -------------------------------------------------------------------------------- /ackpine-splits/splits-ktx/build.gradle.kts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 Ilya Fomichev 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 | description = "Kotlin extensions for Ackpine Splits" 18 | 19 | plugins { 20 | id("ru.solrudev.ackpine.library") 21 | id("ru.solrudev.ackpine.library-publish") 22 | id("ru.solrudev.ackpine.dokka") 23 | } 24 | 25 | ackpine { 26 | id = "splits-ktx" 27 | minSdk = 21 28 | artifact { 29 | name = "Ackpine Splits Kotlin Extensions" 30 | inceptionYear = "2025" 31 | } 32 | } 33 | 34 | dependencies { 35 | api(projects.ackpineSplits.splitsMain) 36 | api(kotlinx.coroutines.core) 37 | implementation(androidx.concurrent.futures.ktx) 38 | } -------------------------------------------------------------------------------- /ackpine-ktx/src/main/kotlin/ru/solrudev/ackpine/installer/parameters/InstallConstraints.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2024 Ilya Fomichev 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 ru.solrudev.ackpine.installer.parameters 18 | 19 | import kotlin.time.Duration 20 | 21 | /** 22 | * Constructs a new instance of [InstallConstraints]. 23 | * @param timeout the maximum time to wait, in milliseconds until the constraints are satisfied. 24 | */ 25 | public inline fun InstallConstraints( 26 | timeout: Duration, 27 | configure: InstallConstraintsDsl.() -> Unit = {} 28 | ): InstallConstraints { 29 | return InstallConstraintsDslBuilder(timeout).apply(configure).build() 30 | } -------------------------------------------------------------------------------- /sample-ktx/src/main/kotlin/ru/solrudev/ackpine/sample/util/PackageManagerExt.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 Ilya Fomichev 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 ru.solrudev.ackpine.sample.util 18 | 19 | import android.content.pm.ApplicationInfo 20 | import android.content.pm.PackageManager 21 | import android.os.Build 22 | 23 | @Suppress("DEPRECATION") 24 | fun PackageManager.getInstalledApplicationsCompat(flags: Int): List { 25 | return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { 26 | getInstalledApplications(PackageManager.ApplicationInfoFlags.of(flags.toLong())) 27 | } else { 28 | getInstalledApplications(flags) 29 | } 30 | } -------------------------------------------------------------------------------- /dokka-plugins/suppress-annotated-api/src/main/kotlin/ru/solrudev/ackpine/documentation/SuppressAnnotatedApiConfig.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 Ilya Fomichev 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 ru.solrudev.ackpine.documentation 18 | 19 | import kotlinx.serialization.Serializable 20 | 21 | /** 22 | * Configuration for [SuppressAnnotatedApiDokkaPlugin]. 23 | */ 24 | @Serializable 25 | public data class SuppressAnnotatedApiConfig( 26 | 27 | /** 28 | * Fully qualified names of annotation classes. 29 | * 30 | * Every declaration marked with any of these annotations will be hidden from resulting documentation. 31 | */ 32 | val annotatedWith: Set 33 | ) -------------------------------------------------------------------------------- /sample-api34/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 26 | -------------------------------------------------------------------------------- /ackpine-core/src/main/kotlin/ru/solrudev/ackpine/impl/database/dao/InstallConstraintsDao.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2024 Ilya Fomichev 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 ru.solrudev.ackpine.impl.database.dao 18 | 19 | import androidx.annotation.RestrictTo 20 | import androidx.room.Dao 21 | import androidx.room.Query 22 | 23 | @RestrictTo(RestrictTo.Scope.LIBRARY) 24 | @Dao 25 | internal interface InstallConstraintsDao { 26 | 27 | @Query( 28 | "UPDATE OR IGNORE sessions_install_constraints SET commit_attempts_count = :commitAttemptsCount " + 29 | "WHERE session_id = :sessionId" 30 | ) 31 | fun setCommitAttemptsCount(sessionId: String, commitAttemptsCount: Int) 32 | } -------------------------------------------------------------------------------- /ackpine-plugins/shizuku-stubs/src/main/java/android/content/pm/IPackageInstallerSession.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 Ilya Fomichev 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 android.content.pm; 18 | 19 | import android.os.Binder; 20 | import android.os.IBinder; 21 | import android.os.IInterface; 22 | 23 | /** 24 | * Stub for {@code android.content.pm.IPackageInstallerSession}. 25 | */ 26 | public interface IPackageInstallerSession extends IInterface { 27 | abstract class Stub extends Binder implements IPackageInstallerSession { 28 | public static IPackageInstallerSession asInterface(IBinder binder) { 29 | throw new UnsupportedOperationException(); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /ackpine-plugins/shizuku-stubs/src/main/java/android/content/pm/IPackageManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 Ilya Fomichev 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 android.content.pm; 18 | 19 | import android.os.Binder; 20 | import android.os.IBinder; 21 | import android.os.IInterface; 22 | 23 | /** 24 | * Stub for {@code android.content.pm.IPackageManager}. 25 | */ 26 | public interface IPackageManager extends IInterface { 27 | IPackageInstaller getPackageInstaller(); 28 | abstract class Stub extends Binder implements IPackageManager { 29 | public static IPackageManager asInterface(IBinder obj) { 30 | throw new UnsupportedOperationException(); 31 | } 32 | } 33 | } -------------------------------------------------------------------------------- /ackpine-api/api-main/src/main/kotlin/ru/solrudev/ackpine/PackageInstallerApiCheck.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 Ilya Fomichev 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 ru.solrudev.ackpine 18 | 19 | import android.os.Build 20 | import androidx.annotation.ChecksSdkIntAtLeast 21 | 22 | @ChecksSdkIntAtLeast(api = Build.VERSION_CODES.LOLLIPOP) 23 | @JvmSynthetic 24 | internal fun isPackageInstallerApiAvailable(): Boolean = isPackageInstallerAvailable 25 | 26 | // To avoid referencing Build.VERSION.SDK_INT 27 | private val isPackageInstallerAvailable = try { 28 | Class.forName("android.content.pm.PackageInstaller") 29 | true 30 | } catch (_: ClassNotFoundException) { 31 | false 32 | } -------------------------------------------------------------------------------- /ackpine-runtime/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 16 | 17 | 18 | 19 | 20 | 21 | 26 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /sample-ktx/src/main/kotlin/ru/solrudev/ackpine/sample/install/SessionProgress.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 Ilya Fomichev 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 ru.solrudev.ackpine.sample.install 18 | 19 | import android.os.Parcelable 20 | import kotlinx.parcelize.Parcelize 21 | import ru.solrudev.ackpine.session.Progress 22 | import java.util.UUID 23 | 24 | @Parcelize 25 | data class SessionProgress( 26 | val id: UUID, 27 | val currentProgress: Int, 28 | val progressMax: Int 29 | ) : Parcelable { 30 | 31 | constructor(id: UUID, progress: Progress) : this(id, progress.progress, progress.max) 32 | 33 | val progress: Progress 34 | get() = Progress(currentProgress, progressMax) 35 | } -------------------------------------------------------------------------------- /ackpine-core/src/main/kotlin/ru/solrudev/ackpine/impl/plugability/AckpineService.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 Ilya Fomichev 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 ru.solrudev.ackpine.impl.plugability 18 | 19 | import androidx.annotation.RestrictTo 20 | import ru.solrudev.ackpine.plugability.AckpinePlugin 21 | import java.util.UUID 22 | 23 | /** 24 | * A service provided by an [AckpinePlugin] via [AckpineServiceProvider]. 25 | */ 26 | @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) 27 | public interface AckpineService { 28 | 29 | /** 30 | * Applies [parameters] of an [AckpinePlugin] to a session with ID equal to [sessionId]. 31 | */ 32 | public fun applyParameters(sessionId: UUID, parameters: AckpinePlugin.Parameters) 33 | } -------------------------------------------------------------------------------- /sample-api34/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | Ackpine Updater 20 | Ackpine 21 | 0% 22 | %d%% 23 | Install 24 | Install 25 | Cancel 26 | Error 27 | Error: %s 28 | -------------------------------------------------------------------------------- /ackpine-plugins/shizuku-stubs/src/main/java/android/content/pm/IPackageInstaller.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2025 Ilya Fomichev 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 android.content.pm; 18 | 19 | import android.os.Binder; 20 | import android.os.IBinder; 21 | import android.os.IInterface; 22 | 23 | /** 24 | * Stub for {@code android.content.pm.IPackageInstaller}. 25 | */ 26 | public interface IPackageInstaller extends IInterface { 27 | void abandonSession(int sessionId); 28 | IPackageInstallerSession openSession(int sessionId); 29 | abstract class Stub extends Binder implements IPackageInstaller { 30 | public static IPackageInstaller asInterface(IBinder binder) { 31 | throw new UnsupportedOperationException(); 32 | } 33 | } 34 | } -------------------------------------------------------------------------------- /ackpine-ktx/src/main/kotlin/ru/solrudev/ackpine/session/parameters/ConfirmationDsl.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 Ilya Fomichev 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 ru.solrudev.ackpine.session.parameters 18 | 19 | import ru.solrudev.ackpine.session.Session 20 | 21 | /** 22 | * DSL allowing to configure user-facing confirmation for the [Session]. 23 | */ 24 | public interface ConfirmationDsl : ConfirmationAware { 25 | override var confirmation: Confirmation 26 | override var notificationData: NotificationData 27 | } 28 | 29 | /** 30 | * Configures [notification DSL][NotificationDataDsl]. 31 | */ 32 | public inline fun ConfirmationDsl.notification(configure: NotificationDataDsl.() -> Unit) { 33 | this.notificationData = NotificationData(configure) 34 | } -------------------------------------------------------------------------------- /ackpine-core/src/main/res/values/themes.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 20 | 24 | 25 | 26 | 27 |