From b333b06772c89d96aacb5490d6a219fba7c09cc6 Mon Sep 17 00:00:00 2001 From: Mitja Felicijan Date: Thu, 12 Feb 2026 20:57:17 +0100 Subject: Engage! --- .../llama.android/app/src/main/AndroidManifest.xml | 27 ++ .../main/java/com/example/llama/MainActivity.kt | 275 +++++++++++++++++++++ .../main/java/com/example/llama/MessageAdapter.kt | 51 ++++ .../src/main/res/drawable/bg_assistant_message.xml | 4 + .../app/src/main/res/drawable/bg_user_message.xml | 4 + .../main/res/drawable/ic_launcher_background.xml | 170 +++++++++++++ .../main/res/drawable/ic_launcher_foreground.xml | 30 +++ .../main/res/drawable/outline_folder_open_24.xml | 10 + .../app/src/main/res/drawable/outline_send_24.xml | 11 + .../app/src/main/res/layout/activity_main.xml | 77 ++++++ .../src/main/res/layout/item_message_assistant.xml | 16 ++ .../app/src/main/res/layout/item_message_user.xml | 16 ++ .../app/src/main/res/mipmap-anydpi/ic_launcher.xml | 6 + .../main/res/mipmap-anydpi/ic_launcher_round.xml | 6 + .../app/src/main/res/mipmap-hdpi/ic_launcher.webp | Bin 0 -> 1404 bytes .../main/res/mipmap-hdpi/ic_launcher_round.webp | Bin 0 -> 2898 bytes .../app/src/main/res/mipmap-mdpi/ic_launcher.webp | Bin 0 -> 982 bytes .../main/res/mipmap-mdpi/ic_launcher_round.webp | Bin 0 -> 1772 bytes .../app/src/main/res/mipmap-xhdpi/ic_launcher.webp | Bin 0 -> 1900 bytes .../main/res/mipmap-xhdpi/ic_launcher_round.webp | Bin 0 -> 3918 bytes .../src/main/res/mipmap-xxhdpi/ic_launcher.webp | Bin 0 -> 2884 bytes .../main/res/mipmap-xxhdpi/ic_launcher_round.webp | Bin 0 -> 5914 bytes .../src/main/res/mipmap-xxxhdpi/ic_launcher.webp | Bin 0 -> 3844 bytes .../main/res/mipmap-xxxhdpi/ic_launcher_round.webp | Bin 0 -> 7778 bytes .../app/src/main/res/values/colors.xml | 10 + .../app/src/main/res/values/strings.xml | 3 + .../app/src/main/res/values/themes.xml | 10 + .../app/src/main/res/xml/backup_rules.xml | 13 + .../app/src/main/res/xml/data_extraction_rules.xml | 19 ++ 29 files changed, 758 insertions(+) create mode 100644 llama.cpp/examples/llama.android/app/src/main/AndroidManifest.xml create mode 100644 llama.cpp/examples/llama.android/app/src/main/java/com/example/llama/MainActivity.kt create mode 100644 llama.cpp/examples/llama.android/app/src/main/java/com/example/llama/MessageAdapter.kt create mode 100644 llama.cpp/examples/llama.android/app/src/main/res/drawable/bg_assistant_message.xml create mode 100644 llama.cpp/examples/llama.android/app/src/main/res/drawable/bg_user_message.xml create mode 100644 llama.cpp/examples/llama.android/app/src/main/res/drawable/ic_launcher_background.xml create mode 100644 llama.cpp/examples/llama.android/app/src/main/res/drawable/ic_launcher_foreground.xml create mode 100644 llama.cpp/examples/llama.android/app/src/main/res/drawable/outline_folder_open_24.xml create mode 100644 llama.cpp/examples/llama.android/app/src/main/res/drawable/outline_send_24.xml create mode 100644 llama.cpp/examples/llama.android/app/src/main/res/layout/activity_main.xml create mode 100644 llama.cpp/examples/llama.android/app/src/main/res/layout/item_message_assistant.xml create mode 100644 llama.cpp/examples/llama.android/app/src/main/res/layout/item_message_user.xml create mode 100644 llama.cpp/examples/llama.android/app/src/main/res/mipmap-anydpi/ic_launcher.xml create mode 100644 llama.cpp/examples/llama.android/app/src/main/res/mipmap-anydpi/ic_launcher_round.xml create mode 100644 llama.cpp/examples/llama.android/app/src/main/res/mipmap-hdpi/ic_launcher.webp create mode 100644 llama.cpp/examples/llama.android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp create mode 100644 llama.cpp/examples/llama.android/app/src/main/res/mipmap-mdpi/ic_launcher.webp create mode 100644 llama.cpp/examples/llama.android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp create mode 100644 llama.cpp/examples/llama.android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp create mode 100644 llama.cpp/examples/llama.android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp create mode 100644 llama.cpp/examples/llama.android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp create mode 100644 llama.cpp/examples/llama.android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp create mode 100644 llama.cpp/examples/llama.android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp create mode 100644 llama.cpp/examples/llama.android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp create mode 100644 llama.cpp/examples/llama.android/app/src/main/res/values/colors.xml create mode 100644 llama.cpp/examples/llama.android/app/src/main/res/values/strings.xml create mode 100644 llama.cpp/examples/llama.android/app/src/main/res/values/themes.xml create mode 100644 llama.cpp/examples/llama.android/app/src/main/res/xml/backup_rules.xml create mode 100644 llama.cpp/examples/llama.android/app/src/main/res/xml/data_extraction_rules.xml (limited to 'llama.cpp/examples/llama.android/app/src') diff --git a/llama.cpp/examples/llama.android/app/src/main/AndroidManifest.xml b/llama.cpp/examples/llama.android/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..8f7c606 --- /dev/null +++ b/llama.cpp/examples/llama.android/app/src/main/AndroidManifest.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + diff --git a/llama.cpp/examples/llama.android/app/src/main/java/com/example/llama/MainActivity.kt b/llama.cpp/examples/llama.android/app/src/main/java/com/example/llama/MainActivity.kt new file mode 100644 index 0000000..872ec2b --- /dev/null +++ b/llama.cpp/examples/llama.android/app/src/main/java/com/example/llama/MainActivity.kt @@ -0,0 +1,275 @@ +package com.example.llama + +import android.net.Uri +import android.os.Bundle +import android.util.Log +import android.widget.EditText +import android.widget.TextView +import android.widget.Toast +import androidx.activity.addCallback +import androidx.activity.enableEdgeToEdge +import androidx.activity.result.contract.ActivityResultContracts +import androidx.appcompat.app.AppCompatActivity +import androidx.lifecycle.lifecycleScope +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import com.arm.aichat.AiChat +import com.arm.aichat.InferenceEngine +import com.arm.aichat.gguf.GgufMetadata +import com.arm.aichat.gguf.GgufMetadataReader +import com.google.android.material.floatingactionbutton.FloatingActionButton +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.Job +import kotlinx.coroutines.flow.onCompletion +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import java.io.File +import java.io.FileOutputStream +import java.io.InputStream +import java.util.UUID + +class MainActivity : AppCompatActivity() { + + // Android views + private lateinit var ggufTv: TextView + private lateinit var messagesRv: RecyclerView + private lateinit var userInputEt: EditText + private lateinit var userActionFab: FloatingActionButton + + // Arm AI Chat inference engine + private lateinit var engine: InferenceEngine + private var generationJob: Job? = null + + // Conversation states + private var isModelReady = false + private val messages = mutableListOf() + private val lastAssistantMsg = StringBuilder() + private val messageAdapter = MessageAdapter(messages) + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + enableEdgeToEdge() + setContentView(R.layout.activity_main) + // View model boilerplate and state management is out of this basic sample's scope + onBackPressedDispatcher.addCallback { Log.w(TAG, "Ignore back press for simplicity") } + + // Find views + ggufTv = findViewById(R.id.gguf) + messagesRv = findViewById(R.id.messages) + messagesRv.layoutManager = LinearLayoutManager(this).apply { stackFromEnd = true } + messagesRv.adapter = messageAdapter + userInputEt = findViewById(R.id.user_input) + userActionFab = findViewById(R.id.fab) + + // Arm AI Chat initialization + lifecycleScope.launch(Dispatchers.Default) { + engine = AiChat.getInferenceEngine(applicationContext) + } + + // Upon CTA button tapped + userActionFab.setOnClickListener { + if (isModelReady) { + // If model is ready, validate input and send to engine + handleUserInput() + } else { + // Otherwise, prompt user to select a GGUF metadata on the device + getContent.launch(arrayOf("*/*")) + } + } + } + + private val getContent = registerForActivityResult( + ActivityResultContracts.OpenDocument() + ) { uri -> + Log.i(TAG, "Selected file uri:\n $uri") + uri?.let { handleSelectedModel(it) } + } + + /** + * Handles the file Uri from [getContent] result + */ + private fun handleSelectedModel(uri: Uri) { + // Update UI states + userActionFab.isEnabled = false + userInputEt.hint = "Parsing GGUF..." + ggufTv.text = "Parsing metadata from selected file \n$uri" + + lifecycleScope.launch(Dispatchers.IO) { + // Parse GGUF metadata + Log.i(TAG, "Parsing GGUF metadata...") + contentResolver.openInputStream(uri)?.use { + GgufMetadataReader.create().readStructuredMetadata(it) + }?.let { metadata -> + // Update UI to show GGUF metadata to user + Log.i(TAG, "GGUF parsed: \n$metadata") + withContext(Dispatchers.Main) { + ggufTv.text = metadata.toString() + } + + // Ensure the model file is available + val modelName = metadata.filename() + FILE_EXTENSION_GGUF + contentResolver.openInputStream(uri)?.use { input -> + ensureModelFile(modelName, input) + }?.let { modelFile -> + loadModel(modelName, modelFile) + + withContext(Dispatchers.Main) { + isModelReady = true + userInputEt.hint = "Type and send a message!" + userInputEt.isEnabled = true + userActionFab.setImageResource(R.drawable.outline_send_24) + userActionFab.isEnabled = true + } + } + } + } + } + + /** + * Prepare the model file within app's private storage + */ + private suspend fun ensureModelFile(modelName: String, input: InputStream) = + withContext(Dispatchers.IO) { + File(ensureModelsDirectory(), modelName).also { file -> + // Copy the file into local storage if not yet done + if (!file.exists()) { + Log.i(TAG, "Start copying file to $modelName") + withContext(Dispatchers.Main) { + userInputEt.hint = "Copying file..." + } + + FileOutputStream(file).use { input.copyTo(it) } + Log.i(TAG, "Finished copying file to $modelName") + } else { + Log.i(TAG, "File already exists $modelName") + } + } + } + + /** + * Load the model file from the app private storage + */ + private suspend fun loadModel(modelName: String, modelFile: File) = + withContext(Dispatchers.IO) { + Log.i(TAG, "Loading model $modelName") + withContext(Dispatchers.Main) { + userInputEt.hint = "Loading model..." + } + engine.loadModel(modelFile.path) + } + + /** + * Validate and send the user message into [InferenceEngine] + */ + private fun handleUserInput() { + userInputEt.text.toString().also { userMsg -> + if (userMsg.isEmpty()) { + Toast.makeText(this, "Input message is empty!", Toast.LENGTH_SHORT).show() + } else { + userInputEt.text = null + userInputEt.isEnabled = false + userActionFab.isEnabled = false + + // Update message states + messages.add(Message(UUID.randomUUID().toString(), userMsg, true)) + lastAssistantMsg.clear() + messages.add(Message(UUID.randomUUID().toString(), lastAssistantMsg.toString(), false)) + + generationJob = lifecycleScope.launch(Dispatchers.Default) { + engine.sendUserPrompt(userMsg) + .onCompletion { + withContext(Dispatchers.Main) { + userInputEt.isEnabled = true + userActionFab.isEnabled = true + } + }.collect { token -> + withContext(Dispatchers.Main) { + val messageCount = messages.size + check(messageCount > 0 && !messages[messageCount - 1].isUser) + + messages.removeAt(messageCount - 1).copy( + content = lastAssistantMsg.append(token).toString() + ).let { messages.add(it) } + + messageAdapter.notifyItemChanged(messages.size - 1) + } + } + } + } + } + } + + /** + * Run a benchmark with the model file + */ + @Deprecated("This benchmark doesn't accurately indicate GUI performance expected by app developers") + private suspend fun runBenchmark(modelName: String, modelFile: File) = + withContext(Dispatchers.Default) { + Log.i(TAG, "Starts benchmarking $modelName") + withContext(Dispatchers.Main) { + userInputEt.hint = "Running benchmark..." + } + engine.bench( + pp=BENCH_PROMPT_PROCESSING_TOKENS, + tg=BENCH_TOKEN_GENERATION_TOKENS, + pl=BENCH_SEQUENCE, + nr=BENCH_REPETITION + ).let { result -> + messages.add(Message(UUID.randomUUID().toString(), result, false)) + withContext(Dispatchers.Main) { + messageAdapter.notifyItemChanged(messages.size - 1) + } + } + } + + /** + * Create the `models` directory if not exist. + */ + private fun ensureModelsDirectory() = + File(filesDir, DIRECTORY_MODELS).also { + if (it.exists() && !it.isDirectory) { it.delete() } + if (!it.exists()) { it.mkdir() } + } + + override fun onStop() { + generationJob?.cancel() + super.onStop() + } + + override fun onDestroy() { + engine.destroy() + super.onDestroy() + } + + companion object { + private val TAG = MainActivity::class.java.simpleName + + private const val DIRECTORY_MODELS = "models" + private const val FILE_EXTENSION_GGUF = ".gguf" + + private const val BENCH_PROMPT_PROCESSING_TOKENS = 512 + private const val BENCH_TOKEN_GENERATION_TOKENS = 128 + private const val BENCH_SEQUENCE = 1 + private const val BENCH_REPETITION = 3 + } +} + +fun GgufMetadata.filename() = when { + basic.name != null -> { + basic.name?.let { name -> + basic.sizeLabel?.let { size -> + "$name-$size" + } ?: name + } + } + architecture?.architecture != null -> { + architecture?.architecture?.let { arch -> + basic.uuid?.let { uuid -> + "$arch-$uuid" + } ?: "$arch-${System.currentTimeMillis()}" + } + } + else -> { + "model-${System.currentTimeMillis().toHexString()}" + } +} diff --git a/llama.cpp/examples/llama.android/app/src/main/java/com/example/llama/MessageAdapter.kt b/llama.cpp/examples/llama.android/app/src/main/java/com/example/llama/MessageAdapter.kt new file mode 100644 index 0000000..0439f96 --- /dev/null +++ b/llama.cpp/examples/llama.android/app/src/main/java/com/example/llama/MessageAdapter.kt @@ -0,0 +1,51 @@ +package com.example.llama + +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.recyclerview.widget.RecyclerView + +data class Message( + val id: String, + val content: String, + val isUser: Boolean +) + +class MessageAdapter( + private val messages: List +) : RecyclerView.Adapter() { + + companion object { + private const val VIEW_TYPE_USER = 1 + private const val VIEW_TYPE_ASSISTANT = 2 + } + + override fun getItemViewType(position: Int): Int { + return if (messages[position].isUser) VIEW_TYPE_USER else VIEW_TYPE_ASSISTANT + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { + val layoutInflater = LayoutInflater.from(parent.context) + return if (viewType == VIEW_TYPE_USER) { + val view = layoutInflater.inflate(R.layout.item_message_user, parent, false) + UserMessageViewHolder(view) + } else { + val view = layoutInflater.inflate(R.layout.item_message_assistant, parent, false) + AssistantMessageViewHolder(view) + } + } + + override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { + val message = messages[position] + if (holder is UserMessageViewHolder || holder is AssistantMessageViewHolder) { + val textView = holder.itemView.findViewById(R.id.msg_content) + textView.text = message.content + } + } + + override fun getItemCount(): Int = messages.size + + class UserMessageViewHolder(view: View) : RecyclerView.ViewHolder(view) + class AssistantMessageViewHolder(view: View) : RecyclerView.ViewHolder(view) +} diff --git a/llama.cpp/examples/llama.android/app/src/main/res/drawable/bg_assistant_message.xml b/llama.cpp/examples/llama.android/app/src/main/res/drawable/bg_assistant_message.xml new file mode 100644 index 0000000..f90c3db --- /dev/null +++ b/llama.cpp/examples/llama.android/app/src/main/res/drawable/bg_assistant_message.xml @@ -0,0 +1,4 @@ + + + + diff --git a/llama.cpp/examples/llama.android/app/src/main/res/drawable/bg_user_message.xml b/llama.cpp/examples/llama.android/app/src/main/res/drawable/bg_user_message.xml new file mode 100644 index 0000000..3ca7dae --- /dev/null +++ b/llama.cpp/examples/llama.android/app/src/main/res/drawable/bg_user_message.xml @@ -0,0 +1,4 @@ + + + + diff --git a/llama.cpp/examples/llama.android/app/src/main/res/drawable/ic_launcher_background.xml b/llama.cpp/examples/llama.android/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..07d5da9 --- /dev/null +++ b/llama.cpp/examples/llama.android/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/llama.cpp/examples/llama.android/app/src/main/res/drawable/ic_launcher_foreground.xml b/llama.cpp/examples/llama.android/app/src/main/res/drawable/ic_launcher_foreground.xml new file mode 100644 index 0000000..7706ab9 --- /dev/null +++ b/llama.cpp/examples/llama.android/app/src/main/res/drawable/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + diff --git a/llama.cpp/examples/llama.android/app/src/main/res/drawable/outline_folder_open_24.xml b/llama.cpp/examples/llama.android/app/src/main/res/drawable/outline_folder_open_24.xml new file mode 100644 index 0000000..f58b501 --- /dev/null +++ b/llama.cpp/examples/llama.android/app/src/main/res/drawable/outline_folder_open_24.xml @@ -0,0 +1,10 @@ + + + diff --git a/llama.cpp/examples/llama.android/app/src/main/res/drawable/outline_send_24.xml b/llama.cpp/examples/llama.android/app/src/main/res/drawable/outline_send_24.xml new file mode 100644 index 0000000..712adc0 --- /dev/null +++ b/llama.cpp/examples/llama.android/app/src/main/res/drawable/outline_send_24.xml @@ -0,0 +1,11 @@ + + + diff --git a/llama.cpp/examples/llama.android/app/src/main/res/layout/activity_main.xml b/llama.cpp/examples/llama.android/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..d15772b --- /dev/null +++ b/llama.cpp/examples/llama.android/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/llama.cpp/examples/llama.android/app/src/main/res/layout/item_message_assistant.xml b/llama.cpp/examples/llama.android/app/src/main/res/layout/item_message_assistant.xml new file mode 100644 index 0000000..2c8e4bc --- /dev/null +++ b/llama.cpp/examples/llama.android/app/src/main/res/layout/item_message_assistant.xml @@ -0,0 +1,16 @@ + + + + + diff --git a/llama.cpp/examples/llama.android/app/src/main/res/layout/item_message_user.xml b/llama.cpp/examples/llama.android/app/src/main/res/layout/item_message_user.xml new file mode 100644 index 0000000..5aa79f2 --- /dev/null +++ b/llama.cpp/examples/llama.android/app/src/main/res/layout/item_message_user.xml @@ -0,0 +1,16 @@ + + + + + diff --git a/llama.cpp/examples/llama.android/app/src/main/res/mipmap-anydpi/ic_launcher.xml b/llama.cpp/examples/llama.android/app/src/main/res/mipmap-anydpi/ic_launcher.xml new file mode 100644 index 0000000..b3e26b4 --- /dev/null +++ b/llama.cpp/examples/llama.android/app/src/main/res/mipmap-anydpi/ic_launcher.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/llama.cpp/examples/llama.android/app/src/main/res/mipmap-anydpi/ic_launcher_round.xml b/llama.cpp/examples/llama.android/app/src/main/res/mipmap-anydpi/ic_launcher_round.xml new file mode 100644 index 0000000..b3e26b4 --- /dev/null +++ b/llama.cpp/examples/llama.android/app/src/main/res/mipmap-anydpi/ic_launcher_round.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/llama.cpp/examples/llama.android/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/llama.cpp/examples/llama.android/app/src/main/res/mipmap-hdpi/ic_launcher.webp new file mode 100644 index 0000000..c209e78 Binary files /dev/null and b/llama.cpp/examples/llama.android/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ diff --git a/llama.cpp/examples/llama.android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/llama.cpp/examples/llama.android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp new file mode 100644 index 0000000..b2dfe3d Binary files /dev/null and b/llama.cpp/examples/llama.android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ diff --git a/llama.cpp/examples/llama.android/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/llama.cpp/examples/llama.android/app/src/main/res/mipmap-mdpi/ic_launcher.webp new file mode 100644 index 0000000..4f0f1d6 Binary files /dev/null and b/llama.cpp/examples/llama.android/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ diff --git a/llama.cpp/examples/llama.android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/llama.cpp/examples/llama.android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp new file mode 100644 index 0000000..62b611d Binary files /dev/null and b/llama.cpp/examples/llama.android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ diff --git a/llama.cpp/examples/llama.android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/llama.cpp/examples/llama.android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp new file mode 100644 index 0000000..948a307 Binary files /dev/null and b/llama.cpp/examples/llama.android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ diff --git a/llama.cpp/examples/llama.android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/llama.cpp/examples/llama.android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp new file mode 100644 index 0000000..1b9a695 Binary files /dev/null and b/llama.cpp/examples/llama.android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ diff --git a/llama.cpp/examples/llama.android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/llama.cpp/examples/llama.android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp new file mode 100644 index 0000000..28d4b77 Binary files /dev/null and b/llama.cpp/examples/llama.android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ diff --git a/llama.cpp/examples/llama.android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/llama.cpp/examples/llama.android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp new file mode 100644 index 0000000..9287f50 Binary files /dev/null and b/llama.cpp/examples/llama.android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ diff --git a/llama.cpp/examples/llama.android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/llama.cpp/examples/llama.android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp new file mode 100644 index 0000000..aa7d642 Binary files /dev/null and b/llama.cpp/examples/llama.android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ diff --git a/llama.cpp/examples/llama.android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/llama.cpp/examples/llama.android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp new file mode 100644 index 0000000..9126ae3 Binary files /dev/null and b/llama.cpp/examples/llama.android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ diff --git a/llama.cpp/examples/llama.android/app/src/main/res/values/colors.xml b/llama.cpp/examples/llama.android/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..ca1931b --- /dev/null +++ b/llama.cpp/examples/llama.android/app/src/main/res/values/colors.xml @@ -0,0 +1,10 @@ + + + #FFBB86FC + #FF6200EE + #FF3700B3 + #FF03DAC5 + #FF018786 + #FF000000 + #FFFFFFFF + diff --git a/llama.cpp/examples/llama.android/app/src/main/res/values/strings.xml b/llama.cpp/examples/llama.android/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..36059fc --- /dev/null +++ b/llama.cpp/examples/llama.android/app/src/main/res/values/strings.xml @@ -0,0 +1,3 @@ + + AI Chat basic sample + diff --git a/llama.cpp/examples/llama.android/app/src/main/res/values/themes.xml b/llama.cpp/examples/llama.android/app/src/main/res/values/themes.xml new file mode 100644 index 0000000..2e4fdad --- /dev/null +++ b/llama.cpp/examples/llama.android/app/src/main/res/values/themes.xml @@ -0,0 +1,10 @@ + + + + + +