Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
fc319d8
feat(14-01): install Capacitor 8 toolchain and declare app identity
dorthrithil Aug 8, 2026
3987ffc
chore(14-01): add verify:webdir build-sanity guard
dorthrithil Aug 8, 2026
aaec502
test(14-01): add RED specs for hardware back-button contract
dorthrithil Aug 8, 2026
dea0667
feat(14-02): add android environment and Angular build configuration
dorthrithil Aug 8, 2026
67d7e5b
feat(14-02): generate Android platform project and set app identity
dorthrithil Aug 8, 2026
1bd8954
feat(14-02): scope cleartext HTTP to debug builds only
dorthrithil Aug 8, 2026
827e826
feat(14-03): implement back-button priority ladder (D-11, D-12)
dorthrithil Aug 8, 2026
4806c23
feat(14-03): register hardware back-button listener at bootstrap
dorthrithil Aug 8, 2026
0d70fe4
feat(14-04): generate placeholder launcher icon and light/dark splash…
dorthrithil Aug 8, 2026
edb4dfa
feat(14-04): hide splash on bootstrap and sync status bar to web theme
dorthrithil Aug 8, 2026
3b726fe
chore(14-04): normalize quote style in placeholder-assets script
dorthrithil Aug 8, 2026
acd5e98
fix(14-05): bump Gradle wrapper to 8.14.4 for JDK 25 daemon support
dorthrithil Aug 9, 2026
7ad9a8a
fix(14-05): allow mixed content in debug builds so cleartext API call…
dorthrithil Aug 9, 2026
50804a7
fix(14-05): tolerate failed instance-settings/menu API calls during b…
dorthrithil Aug 9, 2026
9625ff8
fix(14-05): allow additional CORS origins for the Capacitor emulator …
dorthrithil Aug 9, 2026
ce61825
fix(14-05): load MinIO media on Android emulator
dorthrithil Aug 9, 2026
1f3d472
feat(15-01): enable CapacitorHttp and Preferences-backed resolveApiHost
dorthrithil Aug 9, 2026
16537cf
feat(15-02): inject runtime API host before bootstrap
dorthrithil Aug 9, 2026
60e6380
feat(15-03): add native login debug API host field
dorthrithil Aug 9, 2026
96020fe
feat(16-01): add LocalCrag health identity and instance registry
dorthrithil Aug 9, 2026
df69ee5
feat(16-02): namespace auth and Rock Explorer drafts per API host
dorthrithil Aug 9, 2026
4e404bc
feat(16-03): add native instance picker and remove login debug host
dorthrithil Aug 9, 2026
8be35b1
fix(16): accept legacy /api/health when saving instances
dorthrithil Aug 9, 2026
0e9100f
fix(16): chrome-less picker and open home after instance choice
dorthrithil Aug 9, 2026
bb367ea
test(17-01): add GpsBridge token and RED native-shim specs
dorthrithil Aug 9, 2026
1c5b42b
fix(17-01): disable Android mock GPS and gate native install
dorthrithil Aug 9, 2026
c121cf2
feat(17-02): add GpsBridge Fused Location plugin
dorthrithil Aug 9, 2026
e7f8fa2
feat(17-02): register GpsBridgePlugin before super.onCreate
dorthrithil Aug 9, 2026
7f1eebc
feat(17-03): implement native geolocation shim over GpsBridge
dorthrithil Aug 9, 2026
af384e8
feat(17-03): request location permission at Record start
dorthrithil Aug 9, 2026
b6cbc5e
feat(17-04): wire native GPS shim on Rock Explorer enter/leave
dorthrithil Aug 9, 2026
a747f7c
test(18-01): add RED staged-permissions specs and GpsBridge aliases
dorthrithil Aug 9, 2026
b184d06
test(18-01): add RED Cap App resume-flush specs and GPS-F01 signal
dorthrithil Aug 9, 2026
11b5cbf
feat(18-02): add location FGS and GpsBridge permission aliases
dorthrithil Aug 9, 2026
ef5d713
feat(18-03): GREEN staged GPS permissions and Record disclosure
dorthrithil Aug 9, 2026
d91156f
feat(18-03): Cap App resume flush and GPS-F01 indicator
dorthrithil Aug 9, 2026
f800476
fix(18-04): support physical-device LAN and adb-reverse debug
dorthrithil Aug 9, 2026
937ecbf
test(19-01): stub live-session guard + RED sequencing specs
dorthrithil Aug 9, 2026
2710767
test(19-01): add RED picker D-08 and menu Switch/logout specs
dorthrithil Aug 9, 2026
f88c811
feat(19-02): implement live-session guard DynamicDialog resolve
dorthrithil Aug 9, 2026
60c89ad
feat(19-02): wire live-session guard into facade menu picker
dorthrithil Aug 9, 2026
2086da5
feat(19-02): localize live-session guard dialog copy
dorthrithil Aug 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 101 additions & 0 deletions client/android/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# Using Android gitignore template: https://github.com/github/gitignore/blob/HEAD/Android.gitignore

# Built application files
*.apk
*.aar
*.ap_
*.aab

# Files for the ART/Dalvik VM
*.dex

# Java class files
*.class

# Generated files
bin/
gen/
out/
# Uncomment the following line in case you need and you don't have the release build type files in your app
# release/

# Gradle files
.gradle/
build/

# Local configuration file (sdk path, etc)
local.properties

# Proguard folder generated by Eclipse
proguard/

# Log Files
*.log

# Android Studio Navigation editor temp files
.navigation/

# Android Studio captures folder
captures/

# IntelliJ
*.iml
.idea/workspace.xml
.idea/tasks.xml
.idea/gradle.xml
.idea/assetWizardSettings.xml
.idea/dictionaries
.idea/libraries
# Android Studio 3 in .gitignore file.
.idea/caches
.idea/modules.xml
# Comment next line if keeping position of elements in Navigation Editor is relevant for you
.idea/navEditor.xml

# Keystore files
# Uncomment the following lines if you do not want to check your keystore files in.
#*.jks
#*.keystore

# External native build folder generated in Android Studio 2.2 and later
.externalNativeBuild
.cxx/

# Google Services (e.g. APIs or Firebase)
# google-services.json

# Freeline
freeline.py
freeline/
freeline_project_description.json

# fastlane
fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots
fastlane/test_output
fastlane/readme.md

# Version control
vcs.xml

# lint
lint/intermediates/
lint/generated/
lint/outputs/
lint/tmp/
# lint/reports/

# Android Profiling
*.hprof

# Cordova plugins for Capacitor
capacitor-cordova-android-plugins

# Copied web assets
app/src/main/assets/public

# Generated Config files
app/src/main/assets/capacitor.config.json
app/src/main/assets/capacitor.plugins.json
app/src/main/res/xml/config.xml
2 changes: 2 additions & 0 deletions client/android/app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/build/*
!/build/.npmkeep
61 changes: 61 additions & 0 deletions client/android/app/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
apply plugin: 'com.android.application'

android {
namespace = "de.localcrag.app"
compileSdk = rootProject.ext.compileSdkVersion
defaultConfig {
applicationId "de.localcrag.app"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 1
// Keep in sync with client/package.json version (single version story, D-04).
versionName "1.51.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
aaptOptions {
// Files and dirs to omit from the packaged assets dir, modified to accommodate modern web apps.
// Default: https://android.googlesource.com/platform/frameworks/base/+/282e181b58cf72b6ca770dc7ca5f91f135444502/tools/aapt/AaptAssets.cpp#61
ignoreAssetsPattern = '!.svn:!.git:!.ds_store:!*.scc:.*:!CVS:!thumbs.db:!picasa.ini:!*~'
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
buildFeatures {
// Needed for the BuildConfig.DEBUG guard around MainActivity's debug-only mixed-content
// relaxation (D-09/D-10) — AGP 8 no longer generates BuildConfig by default.
buildConfig true
}
}

repositories {
flatDir{
dirs '../capacitor-cordova-android-plugins/src/main/libs', 'libs'
}
}

dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
implementation "androidx.coordinatorlayout:coordinatorlayout:$androidxCoordinatorLayoutVersion"
implementation "androidx.core:core-splashscreen:$coreSplashScreenVersion"
implementation project(':capacitor-android')
implementation 'com.google.android.gms:play-services-location:21.4.0'
testImplementation "junit:junit:$junitVersion"
androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
implementation project(':capacitor-cordova-android-plugins')
}

apply from: 'capacitor.build.gradle'

try {
def servicesJSON = file('google-services.json')
if (servicesJSON.text) {
apply plugin: 'com.google.gms.google-services'
}
} catch(Exception e) {
logger.info("google-services.json not found, google-services plugin not applied. Push Notifications won't work")
}
22 changes: 22 additions & 0 deletions client/android/app/capacitor.build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// DO NOT EDIT THIS FILE! IT IS GENERATED EACH TIME "capacitor update" IS RUN

android {
compileOptions {
sourceCompatibility JavaVersion.VERSION_21
targetCompatibility JavaVersion.VERSION_21
}
}

apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle"
dependencies {
implementation project(':capacitor-app')
implementation project(':capacitor-preferences')
implementation project(':capacitor-splash-screen')
implementation project(':capacitor-status-bar')

}


if (hasProperty('postBuildExtras')) {
postBuildExtras()
}
21 changes: 21 additions & 0 deletions client/android/app/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.getcapacitor.myapp;

import static org.junit.Assert.*;

import android.content.Context;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.platform.app.InstrumentationRegistry;
import org.junit.Test;
import org.junit.runner.RunWith;

/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {

@Test
public void useAppContext() throws Exception {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();

assertEquals("com.getcapacitor.app", appContext.getPackageName());
}
}
4 changes: 4 additions & 0 deletions client/android/app/src/debug/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application android:networkSecurityConfig="@xml/network_security_config" />
</manifest>
14 changes: 14 additions & 0 deletions client/android/app/src/debug/res/xml/network_security_config.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Debug-only cleartext policy (src/debug). Release has no networkSecurityConfig
override and does not permit LAN/emulator HTTP.

Allow all cleartext in debug so:
- emulator can reach http://10.0.2.2:5000
- physical devices can reach http://192.168.x.x:5000 (CapacitorHttp respects this;
Chrome can still open cleartext URLs the app cannot without this)
- MinIO/S3 media on LAN/loopback hosts can load
-->
<network-security-config>
<base-config cleartextTrafficPermitted="true" />
</network-security-config>
47 changes: 47 additions & 0 deletions client/android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8" ?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode|navigation|density"
android:name=".MainActivity"
android:label="@string/title_activity_main"
android:theme="@style/AppTheme.NoActionBarLaunch"
android:launchMode="singleTask"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" />
</provider>

<!-- Phase 18 location FGS (D-01 / GPS-01 triad) -->
<service
android:name=".gps.GpsForegroundService"
android:exported="false"
android:foregroundServiceType="location" />
</application>

<!-- Permissions -->

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_LOCATION" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package de.localcrag.app;

import android.os.Bundle;
import android.webkit.WebSettings;
import com.getcapacitor.BridgeActivity;
import de.localcrag.app.gps.GpsBridgePlugin;

public class MainActivity extends BridgeActivity {

@Override
public void onCreate(Bundle savedInstanceState) {
registerPlugin(GpsBridgePlugin.class);
super.onCreate(savedInstanceState);
if (BuildConfig.DEBUG) {
// Belt-and-suspenders for cleartext API XHR to http://10.0.2.2:5000 (D-09/D-10).
// Primary fix for media is capacitor.config server.androidScheme = 'http' (avoids
// https://localhost mixed-content blocks on <img>). BuildConfig.DEBUG is false in
// release, matching the debug-only network security config in plan 02.
getBridge().getWebView().getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW);
}
}
}
Loading
Loading