diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index b34d78a..62424a8 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -8,6 +8,9 @@ espressoCore = "3.7.0" appcompat = "1.7.1" material = "1.12.0" constraintlayout = "2.2.1" +lifecycleRuntimeKtx = "2.9.2" +activityCompose = "1.10.1" +composeBom = "2024.09.00" [libraries] androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } @@ -17,9 +20,19 @@ androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-co androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" } material = { group = "com.google.android.material", name = "material", version.ref = "material" } androidx-constraintlayout = { group = "androidx.constraintlayout", name = "constraintlayout", version.ref = "constraintlayout" } +androidx-material3 = { group = "androidx.compose.material3", name = "material3" } +androidx-compose-bom = { group = "androidx.compose", name = "compose-bom", version.ref = "composeBom" } +androidx-ui = { group = "androidx.compose.ui", name = "ui" } +androidx-ui-graphics = { group = "androidx.compose.ui", name = "ui-graphics" } +androidx-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" } +androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" } +androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" } +androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" } +androidx-activity-compose = { group = "androidx.activity", name = "activity-compose", version.ref = "activityCompose" } +androidx-lifecycle-runtime-ktx = { group = "androidx.lifecycle", name = "lifecycle-runtime-ktx", version.ref = "lifecycleRuntimeKtx" } [plugins] android-application = { id = "com.android.application", version.ref = "agp" } kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } android-library = { id = "com.android.library", version.ref = "agp" } - +kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index c7050c2..813f6fc 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,5 +1,6 @@ pluginManagement { repositories { + mavenLocal() google { content { includeGroupByRegex("com\\.android.*") @@ -14,6 +15,7 @@ pluginManagement { dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { + mavenLocal() google() mavenCentral() } @@ -24,3 +26,7 @@ include(":hello-swift") include(":hello-swift-callback") include(":hello-swift-library") include(":native-activity") +include(":hashing-lib") +project(":hashing-lib").projectDir = file("swift-java-hashing-example/hashing-lib") +include(":hashing-app") +project(":hashing-app").projectDir = file("swift-java-hashing-example/hashing-app") diff --git a/swift-java-hashing-example/.gitignore b/swift-java-hashing-example/.gitignore new file mode 100644 index 0000000..6e582d1 --- /dev/null +++ b/swift-java-hashing-example/.gitignore @@ -0,0 +1,41 @@ +.DS_STORE + +# Swift +.build/ +.swiftpm/ +Package.resolved + +# Gradle files +.gradle/ +build/ + +# Local configuration file (sdk path, etc) +local.properties + +# Log/OS Files +*.log + +# Android Studio generated files and folders +captures/ +.externalNativeBuild/ +.cxx/ +*.aab +*.apk +output-metadata.json + +# IntelliJ +*.iml +.idea/ +misc.xml +deploymentTargetDropDown.xml +render.experimental.xml + +# Keystore files +*.jks +*.keystore + +# Google Services (e.g. APIs or Firebase) +google-services.json + +# Android Profiling +*.hprof \ No newline at end of file diff --git a/swift-java-hashing-example/README.md b/swift-java-hashing-example/README.md new file mode 100644 index 0000000..b7c4c3a --- /dev/null +++ b/swift-java-hashing-example/README.md @@ -0,0 +1,66 @@ +# swift-java on Android + +This example contains a sample Android application that demonstrates how to call Swift code from a Android app. +The example consists of an Android application (`hashing-app`) and a Swift library (`hashing-lib`) that performs a SHA256 hash on a given string. +The Swift library uses [swift-java](https://github.com/swiftlang/swift-java) and the new JNI mode to automatically +generate Java wrappers for calling into the Swift library. + +![IDE Screenshot](resources/ide.png) + +## Overview + +The project is structured into two main parts: + +1. **`hashing-lib`**: A Swift package that uses `swift-crypto` to provide a hashing function. It is configured with a Gradle build script (`build.gradle`) that compiles the Swift code into an Android Archive (`.aar`) file. This module utilizes the [swift-java](https://github.com/swiftlang/swift-java) project to create the necessary JNI bindings. + +2. **`hashing-app`**: A standard Android application written in Kotlin using Jetpack Compose. It includes the `.aar` file generated by `hashing-lib` as a local dependency and calls the Swift `hash` function when the user presses a button. + +## Prerequisites + +Before you can build and run this project, you need to have the following installed: + +* **Java Development Kit (JDK)**: We recommend using JDK 21. Ensure the `JAVA_HOME` environment variable is set to your JDK installation path. +* **Swiftly**: You need to install [Swiftly](https://www.swift.org/install/) +* **Swift SDK for Android**: You need to install the [Swift Android SDK](https://swift.org/install) + +## Setup and Configuration + +### Publish `swift-java` packages locally +As the `swift-java` project does not yet publish the neccessary Java packages needed at runtime, we need to do it ourself, by performing the following steps: + +1. Enter the `hashing-lib` directory + ```bash + cd hashing-lib + ``` +2. Resolve Swift Packages + ```bash + swift package resolve + ``` +3. Publish the `swift-java` packages to local Maven repo + ```bash + ./.build/checkouts/swift-java/gradlew --project-dir .build/checkouts/swift-java :SwiftKitCore:publishToMavenLocal + ``` + +## Running the example + +1. Open the `swift-android-examples` project in Android Studio. + +2. Select the `hashing-app` Gradle target. + +3. Run the app on an Android emulator or a physical device. + +4. Enter any text into the text field and press the "Hash" button. The app will call the Swift `hash` function, and the resulting SHA256 digest will be displayed on the screen. + +### Only building the Swift Library (`hashing-lib`) + +1. Navigate to the `hashing-lib` directory: + ```bash + cd hashing-lib + ``` + +2. Run the Gradle assemble command. This will compile the Swift code for all supported Android ABIs (arm64-v8a, armeabi-v7a, x86_64), run the `jextract` plugin, and package everything into an `.aar` file. + ```bash + ./gradlew assembleRelease + ``` + +3. After a successful build, the Android library will be located at `hashing-lib/build/outputs/aar/hashing-lib-release.aar`. \ No newline at end of file diff --git a/swift-java-hashing-example/hashing-app/.gitignore b/swift-java-hashing-example/hashing-app/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/swift-java-hashing-example/hashing-app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/swift-java-hashing-example/hashing-app/build.gradle.kts b/swift-java-hashing-example/hashing-app/build.gradle.kts new file mode 100644 index 0000000..31a9ad3 --- /dev/null +++ b/swift-java-hashing-example/hashing-app/build.gradle.kts @@ -0,0 +1,60 @@ +plugins { + alias(libs.plugins.android.application) + alias(libs.plugins.kotlin.android) + alias(libs.plugins.kotlin.compose) +} + +android { + namespace = "com.example.hashingapp" + compileSdk = 36 + + defaultConfig { + applicationId = "com.example.hashingapp" + minSdk = 28 + targetSdk = 36 + versionCode = 1 + versionName = "1.0" + + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + isMinifyEnabled = false + proguardFiles( + getDefaultProguardFile("proguard-android-optimize.txt"), + "proguard-rules.pro" + ) + } + } + compileOptions { + sourceCompatibility = JavaVersion.VERSION_11 + targetCompatibility = JavaVersion.VERSION_11 + } + kotlinOptions { + jvmTarget = "11" + } + buildFeatures { + compose = true + } +} + +dependencies { + + implementation(libs.androidx.core.ktx) + implementation(libs.androidx.lifecycle.runtime.ktx) + implementation(libs.androidx.activity.compose) + implementation(platform(libs.androidx.compose.bom)) + implementation(libs.androidx.ui) + implementation(libs.androidx.ui.graphics) + implementation(libs.androidx.ui.tooling.preview) + implementation(libs.androidx.material3) + implementation(project(":hashing-lib")) + testImplementation(libs.junit) + androidTestImplementation(libs.androidx.junit) + androidTestImplementation(libs.androidx.espresso.core) + androidTestImplementation(platform(libs.androidx.compose.bom)) + androidTestImplementation(libs.androidx.ui.test.junit4) + debugImplementation(libs.androidx.ui.tooling) + debugImplementation(libs.androidx.ui.test.manifest) +} \ No newline at end of file diff --git a/swift-java-hashing-example/hashing-app/proguard-rules.pro b/swift-java-hashing-example/hashing-app/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/swift-java-hashing-example/hashing-app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/swift-java-hashing-example/hashing-app/src/androidTest/java/com/example/hashingapp/ExampleInstrumentedTest.kt b/swift-java-hashing-example/hashing-app/src/androidTest/java/com/example/hashingapp/ExampleInstrumentedTest.kt new file mode 100644 index 0000000..1bcc13c --- /dev/null +++ b/swift-java-hashing-example/hashing-app/src/androidTest/java/com/example/hashingapp/ExampleInstrumentedTest.kt @@ -0,0 +1,36 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2025 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +package com.example.hashingapp + +import androidx.test.platform.app.InstrumentationRegistry +import androidx.test.ext.junit.runners.AndroidJUnit4 + +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.Assert.* + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getInstrumentation().targetContext + assertEquals("com.example.hashingapp", appContext.packageName) + } +} \ No newline at end of file diff --git a/swift-java-hashing-example/hashing-app/src/main/AndroidManifest.xml b/swift-java-hashing-example/hashing-app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..45d5b76 --- /dev/null +++ b/swift-java-hashing-example/hashing-app/src/main/AndroidManifest.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/swift-java-hashing-example/hashing-app/src/main/java/com/example/hashingapp/MainActivity.kt b/swift-java-hashing-example/hashing-app/src/main/java/com/example/hashingapp/MainActivity.kt new file mode 100644 index 0000000..3ac0265 --- /dev/null +++ b/swift-java-hashing-example/hashing-app/src/main/java/com/example/hashingapp/MainActivity.kt @@ -0,0 +1,97 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2025 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +package com.example.hashingapp + +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.activity.enableEdgeToEdge +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.material3.TextField +import androidx.compose.runtime.Composable +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import com.example.hashingapp.ui.theme.HashingAppTheme +import com.example.swifthashing.SwiftHashing + +class MainActivity : ComponentActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + enableEdgeToEdge() + setContent { + HashingAppTheme { + Surface ( + modifier = Modifier.fillMaxSize().padding(top = 64.dp), + color = MaterialTheme.colorScheme.background + ) { + HashScreen() + } + } + } + } +} + +@Composable +fun HashScreen() { + val input = remember { mutableStateOf("") } + val hashResult = remember { mutableStateOf("") } + + Column( + modifier = Modifier + .fillMaxSize() + .padding(32.dp), + verticalArrangement = Arrangement.spacedBy(12.dp) + ) { + TextField( + value = input.value, + onValueChange = { input.value = it }, + label = { Text("Enter text to hash") }, + modifier = Modifier.fillMaxWidth() + ) + + Button( + colors = ButtonDefaults.buttonColors( + containerColor = Color(0xFFF05138), + contentColor = Color.White + ), + onClick = { + // This calls the Swift method `hash` from SwiftHashing.swift + hashResult.value = SwiftHashing.hash(input.value) + } + ) { + Text("Hash") + } + + if (hashResult.value.isNotEmpty()) { + Text( + text = hashResult.value, + style = MaterialTheme.typography.bodyMedium + ) + } + } +} \ No newline at end of file diff --git a/swift-java-hashing-example/hashing-app/src/main/java/com/example/hashingapp/ui/theme/Color.kt b/swift-java-hashing-example/hashing-app/src/main/java/com/example/hashingapp/ui/theme/Color.kt new file mode 100644 index 0000000..f5705ba --- /dev/null +++ b/swift-java-hashing-example/hashing-app/src/main/java/com/example/hashingapp/ui/theme/Color.kt @@ -0,0 +1,23 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2025 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +package com.example.hashingapp.ui.theme + +import androidx.compose.ui.graphics.Color + +val Purple80 = Color(0xFFD0BCFF) +val PurpleGrey80 = Color(0xFFCCC2DC) +val Pink80 = Color(0xFFEFB8C8) + +val Purple40 = Color(0xFF6650a4) +val PurpleGrey40 = Color(0xFF625b71) +val Pink40 = Color(0xFF7D5260) \ No newline at end of file diff --git a/swift-java-hashing-example/hashing-app/src/main/java/com/example/hashingapp/ui/theme/Theme.kt b/swift-java-hashing-example/hashing-app/src/main/java/com/example/hashingapp/ui/theme/Theme.kt new file mode 100644 index 0000000..8c20865 --- /dev/null +++ b/swift-java-hashing-example/hashing-app/src/main/java/com/example/hashingapp/ui/theme/Theme.kt @@ -0,0 +1,70 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2025 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +package com.example.hashingapp.ui.theme + +import android.app.Activity +import android.os.Build +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.darkColorScheme +import androidx.compose.material3.dynamicDarkColorScheme +import androidx.compose.material3.dynamicLightColorScheme +import androidx.compose.material3.lightColorScheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.platform.LocalContext + +private val DarkColorScheme = darkColorScheme( + primary = Purple80, + secondary = PurpleGrey80, + tertiary = Pink80 +) + +private val LightColorScheme = lightColorScheme( + primary = Purple40, + secondary = PurpleGrey40, + tertiary = Pink40 + + /* Other default colors to override + background = Color(0xFFFFFBFE), + surface = Color(0xFFFFFBFE), + onPrimary = Color.White, + onSecondary = Color.White, + onTertiary = Color.White, + onBackground = Color(0xFF1C1B1F), + onSurface = Color(0xFF1C1B1F), + */ +) + +@Composable +fun HashingAppTheme( + darkTheme: Boolean = isSystemInDarkTheme(), + // Dynamic color is available on Android 12+ + dynamicColor: Boolean = true, + content: @Composable () -> Unit +) { + val colorScheme = when { + dynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> { + val context = LocalContext.current + if (darkTheme) dynamicDarkColorScheme(context) else dynamicLightColorScheme(context) + } + + darkTheme -> DarkColorScheme + else -> LightColorScheme + } + + MaterialTheme( + colorScheme = colorScheme, + typography = Typography, + content = content + ) +} \ No newline at end of file diff --git a/swift-java-hashing-example/hashing-app/src/main/java/com/example/hashingapp/ui/theme/Type.kt b/swift-java-hashing-example/hashing-app/src/main/java/com/example/hashingapp/ui/theme/Type.kt new file mode 100644 index 0000000..336c677 --- /dev/null +++ b/swift-java-hashing-example/hashing-app/src/main/java/com/example/hashingapp/ui/theme/Type.kt @@ -0,0 +1,46 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2025 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +package com.example.hashingapp.ui.theme + +import androidx.compose.material3.Typography +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontFamily +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.sp + +// Set of Material typography styles to start with +val Typography = Typography( + bodyLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 16.sp, + lineHeight = 24.sp, + letterSpacing = 0.5.sp + ) + /* Other default text styles to override + titleLarge = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Normal, + fontSize = 22.sp, + lineHeight = 28.sp, + letterSpacing = 0.sp + ), + labelSmall = TextStyle( + fontFamily = FontFamily.Default, + fontWeight = FontWeight.Medium, + fontSize = 11.sp, + lineHeight = 16.sp, + letterSpacing = 0.5.sp + ) + */ +) \ No newline at end of file diff --git a/swift-java-hashing-example/hashing-app/src/main/res/drawable/ic_launcher_background.xml b/swift-java-hashing-example/hashing-app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..07d5da9 --- /dev/null +++ b/swift-java-hashing-example/hashing-app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/swift-java-hashing-example/hashing-app/src/main/res/drawable/ic_launcher_foreground.xml b/swift-java-hashing-example/hashing-app/src/main/res/drawable/ic_launcher_foreground.xml new file mode 100644 index 0000000..2b068d1 --- /dev/null +++ b/swift-java-hashing-example/hashing-app/src/main/res/drawable/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/swift-java-hashing-example/hashing-app/src/main/res/mipmap-anydpi/ic_launcher.xml b/swift-java-hashing-example/hashing-app/src/main/res/mipmap-anydpi/ic_launcher.xml new file mode 100644 index 0000000..6f3b755 --- /dev/null +++ b/swift-java-hashing-example/hashing-app/src/main/res/mipmap-anydpi/ic_launcher.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/swift-java-hashing-example/hashing-app/src/main/res/mipmap-anydpi/ic_launcher_round.xml b/swift-java-hashing-example/hashing-app/src/main/res/mipmap-anydpi/ic_launcher_round.xml new file mode 100644 index 0000000..6f3b755 --- /dev/null +++ b/swift-java-hashing-example/hashing-app/src/main/res/mipmap-anydpi/ic_launcher_round.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/swift-java-hashing-example/hashing-app/src/main/res/mipmap-hdpi/ic_launcher.webp b/swift-java-hashing-example/hashing-app/src/main/res/mipmap-hdpi/ic_launcher.webp new file mode 100644 index 0000000..c209e78 Binary files /dev/null and b/swift-java-hashing-example/hashing-app/src/main/res/mipmap-hdpi/ic_launcher.webp differ diff --git a/swift-java-hashing-example/hashing-app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/swift-java-hashing-example/hashing-app/src/main/res/mipmap-hdpi/ic_launcher_round.webp new file mode 100644 index 0000000..b2dfe3d Binary files /dev/null and b/swift-java-hashing-example/hashing-app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ diff --git a/swift-java-hashing-example/hashing-app/src/main/res/mipmap-mdpi/ic_launcher.webp b/swift-java-hashing-example/hashing-app/src/main/res/mipmap-mdpi/ic_launcher.webp new file mode 100644 index 0000000..4f0f1d6 Binary files /dev/null and b/swift-java-hashing-example/hashing-app/src/main/res/mipmap-mdpi/ic_launcher.webp differ diff --git a/swift-java-hashing-example/hashing-app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/swift-java-hashing-example/hashing-app/src/main/res/mipmap-mdpi/ic_launcher_round.webp new file mode 100644 index 0000000..62b611d Binary files /dev/null and b/swift-java-hashing-example/hashing-app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ diff --git a/swift-java-hashing-example/hashing-app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/swift-java-hashing-example/hashing-app/src/main/res/mipmap-xhdpi/ic_launcher.webp new file mode 100644 index 0000000..948a307 Binary files /dev/null and b/swift-java-hashing-example/hashing-app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ diff --git a/swift-java-hashing-example/hashing-app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/swift-java-hashing-example/hashing-app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp new file mode 100644 index 0000000..1b9a695 Binary files /dev/null and b/swift-java-hashing-example/hashing-app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ diff --git a/swift-java-hashing-example/hashing-app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/swift-java-hashing-example/hashing-app/src/main/res/mipmap-xxhdpi/ic_launcher.webp new file mode 100644 index 0000000..28d4b77 Binary files /dev/null and b/swift-java-hashing-example/hashing-app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ diff --git a/swift-java-hashing-example/hashing-app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/swift-java-hashing-example/hashing-app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp new file mode 100644 index 0000000..9287f50 Binary files /dev/null and b/swift-java-hashing-example/hashing-app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ diff --git a/swift-java-hashing-example/hashing-app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/swift-java-hashing-example/hashing-app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp new file mode 100644 index 0000000..aa7d642 Binary files /dev/null and b/swift-java-hashing-example/hashing-app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ diff --git a/swift-java-hashing-example/hashing-app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/swift-java-hashing-example/hashing-app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp new file mode 100644 index 0000000..9126ae3 Binary files /dev/null and b/swift-java-hashing-example/hashing-app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ diff --git a/swift-java-hashing-example/hashing-app/src/main/res/values/colors.xml b/swift-java-hashing-example/hashing-app/src/main/res/values/colors.xml new file mode 100644 index 0000000..f8c6127 --- /dev/null +++ b/swift-java-hashing-example/hashing-app/src/main/res/values/colors.xml @@ -0,0 +1,10 @@ + + + #FFBB86FC + #FF6200EE + #FF3700B3 + #FF03DAC5 + #FF018786 + #FF000000 + #FFFFFFFF + \ No newline at end of file diff --git a/swift-java-hashing-example/hashing-app/src/main/res/values/strings.xml b/swift-java-hashing-example/hashing-app/src/main/res/values/strings.xml new file mode 100644 index 0000000..ebc9430 --- /dev/null +++ b/swift-java-hashing-example/hashing-app/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + Hashing App + \ No newline at end of file diff --git a/swift-java-hashing-example/hashing-app/src/main/res/values/themes.xml b/swift-java-hashing-example/hashing-app/src/main/res/values/themes.xml new file mode 100644 index 0000000..9dee947 --- /dev/null +++ b/swift-java-hashing-example/hashing-app/src/main/res/values/themes.xml @@ -0,0 +1,5 @@ + + + +