Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android 13 and multiple updates #193

Open
wants to merge 22 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
f550c13
improved docker image rebuild speed
tuffnerdstuff Mar 27, 2021
6c788e3
Android client sends altitude data
tuffnerdstuff Mar 27, 2021
13b6664
Backend: push altitude value into points on post
tuffnerdstuff Mar 27, 2021
6b556c1
Frontend: Read and display altitude data
tuffnerdstuff Mar 27, 2021
8fd96ba
Added ALTITUDE_UNIT
tuffnerdstuff Mar 27, 2021
24750a3
hiding all metrics when client is dead
tuffnerdstuff Mar 27, 2021
9cbd1cc
Refactored LocationUpdatePackage
tuffnerdstuff Mar 27, 2021
b5dad6e
Refactored post.php
tuffnerdstuff Mar 27, 2021
082da40
Moved altitude to its own line and added labels
tuffnerdstuff Apr 1, 2021
27a1959
Displaying metrics is optional
tuffnerdstuff Apr 2, 2021
4ae423a
Hiding altitude if value is null
tuffnerdstuff Apr 2, 2021
33e19cb
Only unhide altitude if config allows it
tuffnerdstuff Apr 2, 2021
e6263e7
Automatically resume shares on device start
Aug 8, 2021
00ad4bd
Fix sharing not resuming on boot under android 11
Aug 22, 2021
f33b453
Merge pull request #1 from MaeIsBad/master
Bartixxx32 Jun 15, 2022
94f8866
Merge pull request #3 from tuffnerdstuff/feature/altitude
Bartixxx32 Jun 15, 2022
349c5f2
build: upgrade gradle to 7.2.2
franck-x Sep 2, 2022
ff9acda
build: upgrade compileSdkVersion and targetSdkVersion to 33
franck-x Sep 2, 2022
f42949b
build: upgrade dependencies
franck-x Sep 2, 2022
eab826e
added dockerbuild.yaml (https://github.com/bilde2910/Hauk/commit/5a11…
TheCataliasTNT2k Apr 1, 2023
4f36d9b
Merge remote-tracking branch 'franck-x/hauk/build/upgrade_to_sdk33_gr…
TheCataliasTNT2k Apr 2, 2023
3af47da
changes for android 13 and gradle
TheCataliasTNT2k Apr 4, 2023
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
63 changes: 63 additions & 0 deletions .github/workflows/dockerbuild.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
---
name: ci

on:
workflow_dispatch:
pull_request:
branches:
- 'master'
push:
branches:
- master
tags:
- 'v*'

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}

jobs:
docker:
runs-on: ubuntu-latest
permissions:
packages: write
contents: read
steps:
- name: Checkout
uses: actions/checkout@v3

- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@v4
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=raw,value=latest,enable={{is_default_branch}}

- name: set up qemu
uses: docker/setup-qemu-action@v2

- name: set up docker buildx
uses: docker/setup-buildx-action@v2

- name: Login to GitHub Container Registry
if: github.event_name != 'pull_request'
uses: docker/login-action@v2
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Build and push
id: docker_build
uses: docker/build-push-action@v3
with:
platforms: linux/amd64, linux/arm64
context: .
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
9 changes: 5 additions & 4 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
FROM php:apache
COPY backend-php/ /var/www/html/
COPY frontend/ /var/www/html/
COPY docker/start.sh .

RUN apt-get update && \
apt-get install -y memcached libmemcached-dev zlib1g-dev libldap2-dev && \
Expand All @@ -12,7 +9,11 @@ RUN apt-get update && \

EXPOSE 80/tcp
VOLUME /etc/hauk

STOPSIGNAL SIGINT

COPY docker/start.sh .
RUN chmod +x ./start.sh
COPY backend-php/ /var/www/html/
COPY frontend/ /var/www/html/

CMD ["./start.sh"]
2 changes: 1 addition & 1 deletion android/.idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 13 additions & 10 deletions android/app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
apply plugin: 'com.android.application'

android {
compileSdkVersion 29
buildToolsVersion "29.0.2"
namespace 'info.varden.hauk'

compileSdkVersion 33
defaultConfig {
applicationId "info.varden.hauk"
minSdkVersion 23
targetSdkVersion 29
targetSdkVersion 33
versionCode 13
versionName "1.6.1"
versionName "1.6.2"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
}
buildTypes {
release {
Expand All @@ -21,10 +23,11 @@ android {

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.preference:preference:1.1.1'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test:runner:1.2.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation 'androidx.appcompat:appcompat:1.5.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1'
implementation 'androidx.preference:preference:1.2.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test:runner:1.4.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}
26 changes: 22 additions & 4 deletions android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="info.varden.hauk">
xmlns:tools="http://schemas.android.com/tools">

<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.INTERNET" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>


<application
android:allowBackup="true"
Expand All @@ -31,7 +34,8 @@
android:launchMode="singleTop"
android:screenOrientation="portrait"
android:windowSoftInputMode="stateHidden"
android:theme="@style/HomeTheme">
android:theme="@style/HomeTheme"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
Expand All @@ -45,14 +49,28 @@
</activity>

<receiver
android:name=".global.Receiver"
android:name=".global.ExportedReceiver"
android:exported="true"
tools:ignore="ExportedReceiver">
<intent-filter>
<action android:name="info.varden.hauk.START_ALONE_THEN_SHARE_VIA" />
<action android:name="info.varden.hauk.START_ALONE_THEN_MAKE_TOAST" />
</intent-filter>
</receiver>

<receiver
android:name=".global.RebootReceiver"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED"
android:exported="true">

<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>

</receiver>

<receiver
android:name=".notify.CopyLinkReceiver"
android:exported="false">
Expand Down
2 changes: 2 additions & 0 deletions android/app/src/main/java/info/varden/hauk/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public enum Constants {
public static final Preference<String> PREF_NICKNAME = new Preference.String("nickname", "");
public static final Preference<Integer> PREF_DURATION_UNIT = new Preference.Integer("durUnit", Constants.DURATION_UNIT_MINUTES);
public static final Preference<Boolean> PREF_ALLOW_ADOPTION = new Preference.Boolean("allowAdoption", true);
public static final Preference<Boolean> PREF_RESTART_ON_BOOT = new Preference.Boolean("restartOnBoot", true);
public static final Preference<NightModeStyle> PREF_NIGHT_MODE = new Preference.Enum<>("nightMode", NightModeStyle.FOLLOW_SYSTEM);
public static final Preference<Boolean> PREF_CONFIRM_STOP = new Preference.Boolean("confirmStop", true);
public static final Preference<Boolean> PREF_HIDE_LOGO = new Preference.Boolean("hideLogo", false);
Expand Down Expand Up @@ -122,6 +123,7 @@ public enum Constants {
public static final String PACKET_PARAM_SPEED = "spd";
public static final String PACKET_PARAM_TIMESTAMP = "time";
public static final String PACKET_PARAM_USERNAME = "usr";
public static final String PACKET_PARAM_ALTITUDE = "alt";

// Packet OK response header. All valid packets start with this line.
public static final String PACKET_RESPONSE_OK = "OK";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
* @since 1.3
* @author Marius Lindvall
*/
public final class Receiver extends BroadcastReceiver {
public final class ExportedReceiver extends BroadcastReceiver {
@SuppressWarnings("HardCodedStringLiteral")
private static final String ACTION_START_SHARING_ALONE_WITH_MENU = "info.varden.hauk.START_ALONE_THEN_SHARE_VIA";
@SuppressWarnings("HardCodedStringLiteral")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package info.varden.hauk.global;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.widget.Toast;

import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.SocketAddress;

import info.varden.hauk.Constants;
import info.varden.hauk.R;
import info.varden.hauk.global.ui.AuthorizationActivity;
import info.varden.hauk.global.ui.DisplayShareDialogListener;
import info.varden.hauk.global.ui.toast.GNSSStatusUpdateListenerImpl;
import info.varden.hauk.global.ui.toast.SessionInitiationResponseHandlerImpl;
import info.varden.hauk.global.ui.toast.ShareListenerImpl;
import info.varden.hauk.http.ConnectionParameters;
import info.varden.hauk.http.SessionInitiationPacket;
import info.varden.hauk.http.security.CertificateValidationPolicy;
import info.varden.hauk.manager.SessionManager;
import info.varden.hauk.struct.AdoptabilityPreference;
import info.varden.hauk.system.LocationPermissionsNotGrantedException;
import info.varden.hauk.system.LocationServicesDisabledException;
import info.varden.hauk.system.preferences.PreferenceManager;
import info.varden.hauk.utils.DeprecationMigrator;
import info.varden.hauk.utils.Log;
import info.varden.hauk.utils.TimeUtils;
// Reboot broadcast receiver for Hauk. If enabled resumes a share session if one exists on device restart
public final class RebootReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
// Subsequent calls may result in data being read from preferences. We should ensure that
// all deprecated preferences have been migrated before we continue.
new DeprecationMigrator(context).migrate();

PreferenceManager prefs = new PreferenceManager(context);
if(prefs.get(Constants.PREF_RESTART_ON_BOOT))
resumeShare(context,intent);
}
private void resumeShare(Context context, Intent intent) {
Log.d("Trying to resume shares...");
new BroadcastSessionManager(context).resumeShares();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,15 @@
import android.util.Base64;

import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;

import info.varden.hauk.Constants;
import info.varden.hauk.R;
Expand Down Expand Up @@ -48,36 +54,17 @@ protected LocationUpdatePacket(Context ctx, Session session, Location location,
super(ctx, session.getServerURL(), session.getConnectionParameters(), Constants.URL_PATH_POST_LOCATION);
setParameter(Constants.PACKET_PARAM_SESSION_ID, session.getID());

if (session.getDerivableE2EKey() == null) {
// If not using end-to-end encryption, send parameters in plain text.
setParameter(Constants.PACKET_PARAM_LATITUDE, String.valueOf(location.getLatitude()));
setParameter(Constants.PACKET_PARAM_LONGITUDE, String.valueOf(location.getLongitude()));
setParameter(Constants.PACKET_PARAM_PROVIDER_ACCURACY, String.valueOf(accuracy.getMode()));
setParameter(Constants.PACKET_PARAM_TIMESTAMP, String.valueOf(System.currentTimeMillis() / (double) TimeUtils.MILLIS_PER_SECOND));
Cipher cipher = initCipher(session);

// Not all devices provide these parameters:
if (location.hasSpeed()) setParameter(Constants.PACKET_PARAM_SPEED, String.valueOf(location.getSpeed()));
if (location.hasAccuracy()) setParameter(Constants.PACKET_PARAM_ACCURACY, String.valueOf(location.getAccuracy()));
} else {
// We're using end-to-end encryption - generate an IV and encrypt all parameters.
try {
Cipher cipher = Cipher.getInstance(Constants.E2E_TRANSFORMATION);
cipher.init(Cipher.ENCRYPT_MODE, session.getDerivableE2EKey().deriveSpec(), new SecureRandom());
byte[] iv = cipher.getIV();
setParameter(Constants.PACKET_PARAM_INIT_VECTOR, Base64.encodeToString(iv, Base64.DEFAULT));
encryptAndSetParameter(Constants.PACKET_PARAM_LATITUDE, location.getLatitude(), cipher);
encryptAndSetParameter(Constants.PACKET_PARAM_LONGITUDE, location.getLongitude(), cipher);
encryptAndSetParameter(Constants.PACKET_PARAM_PROVIDER_ACCURACY, accuracy.getMode(), cipher);
encryptAndSetParameter(Constants.PACKET_PARAM_TIMESTAMP, System.currentTimeMillis() / (double) TimeUtils.MILLIS_PER_SECOND, cipher);

setParameter(Constants.PACKET_PARAM_LATITUDE, Base64.encodeToString(cipher.doFinal(String.valueOf(location.getLatitude()).getBytes(StandardCharsets.UTF_8)), Base64.DEFAULT));
setParameter(Constants.PACKET_PARAM_LONGITUDE, Base64.encodeToString(cipher.doFinal(String.valueOf(location.getLongitude()).getBytes(StandardCharsets.UTF_8)), Base64.DEFAULT));
setParameter(Constants.PACKET_PARAM_PROVIDER_ACCURACY, Base64.encodeToString(cipher.doFinal(String.valueOf(accuracy.getMode()).getBytes(StandardCharsets.UTF_8)), Base64.DEFAULT));
setParameter(Constants.PACKET_PARAM_TIMESTAMP, Base64.encodeToString(cipher.doFinal(String.valueOf(System.currentTimeMillis() / (double) TimeUtils.MILLIS_PER_SECOND).getBytes(StandardCharsets.UTF_8)), Base64.DEFAULT));

// Not all devices provide these parameters:
if (location.hasSpeed()) setParameter(Constants.PACKET_PARAM_SPEED, Base64.encodeToString(cipher.doFinal(String.valueOf(location.getSpeed()).getBytes(StandardCharsets.UTF_8)), Base64.DEFAULT));
if (location.hasAccuracy()) setParameter(Constants.PACKET_PARAM_ACCURACY, Base64.encodeToString(cipher.doFinal(String.valueOf(location.getAccuracy()).getBytes(StandardCharsets.UTF_8)), Base64.DEFAULT));
} catch (Exception e) {
Log.e("Error was thrown when encrypting location data", e); //NON-NLS
}
}
// Not all devices provide these parameters:
if (location.hasSpeed()) encryptAndSetParameter(Constants.PACKET_PARAM_SPEED, location.getSpeed(), cipher);
if (location.hasAccuracy()) encryptAndSetParameter(Constants.PACKET_PARAM_ACCURACY, location.getAccuracy(), cipher);
if (location.hasAltitude()) encryptAndSetParameter(Constants.PACKET_PARAM_ALTITUDE, location.getAltitude(), cipher);
}

@SuppressWarnings("DesignForExtension")
Expand Down Expand Up @@ -113,4 +100,33 @@ protected void onSuccess(String[] data, Version backendVersion) throws ServerExc
throw new ServerException(err.toString());
}
}

private Cipher initCipher(Session session) {
Cipher cipher = null;
if (session.getDerivableE2EKey() != null) {
try {
cipher = Cipher.getInstance(Constants.E2E_TRANSFORMATION);
cipher.init(Cipher.ENCRYPT_MODE, session.getDerivableE2EKey().deriveSpec(), new SecureRandom());
byte[] iv = cipher.getIV();
setParameter(Constants.PACKET_PARAM_INIT_VECTOR, Base64.encodeToString(iv, Base64.DEFAULT));
} catch (NoSuchAlgorithmException | InvalidKeyException | InvalidKeySpecException | NoSuchPaddingException exception) {
Log.e("Error was thrown while initializing E2E encryption", exception); //NON-NLS
}
}
return cipher;
}

private <V> void encryptAndSetParameter(String key, V value, Cipher cipher) {
if (cipher != null) {
// We're using end-to-end encryption - generate an IV and encrypt all parameters.
try {
setParameter(key, Base64.encodeToString(cipher.doFinal(String.valueOf(value).getBytes(StandardCharsets.UTF_8)), Base64.DEFAULT));
} catch (BadPaddingException | IllegalBlockSizeException exception) {
Log.e("Error was thrown while encrypting location data", exception); //NON-NLS
}
} else {
// If not using end-to-end encryption, send parameters in plain text.
setParameter(key, String.valueOf(value));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,15 @@ public final void resumeShares(ResumePrompt prompt) {
}
}

public final void resumeShares() {
if (pusher != null) {
Log.d("Pusher is non-null (%s), stopping and nulling it before calling service relauncher", pusher); //NON-NLS
this.ctx.stopService(pusher);
pusher = null;
}
this.resumable.tryResumeShare(new ServiceRelauncher(this, this.resumable));
}

/**
* A preparation step for initiating sessions. Checks location services status and instantiates
* a response handler for the session initiation packet.
Expand Down Expand Up @@ -448,6 +457,7 @@ private boolean hasLocationPermission() {
}
}


/**
* The GNSS status handler that the {@link SessionManager} itself uses to receive status updates
* from the GNSS listeners. Used to propagate events further upstream.
Expand Down
3 changes: 2 additions & 1 deletion android/app/src/main/res/values-ca/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<resources>
<string name="pref_cryptUsername_title">Nom d\'usuari</string>
<string name="pref_cryptUsername_hint">&lt;opcional&gt;</string>
<string name="action_settings">Configuracions</string>
<string name="pref_cryptPassword_title">Password:</string>
<string name="label_duration">Durada de la compartició:</string>
<string name="pref_interval_title">Interval d\'actualització (s):</string>
Expand Down Expand Up @@ -115,4 +116,4 @@
\n
\nSi activeu aquesta opció i compartiu la vostra ubicació amb un grup d’amics i algú altre també vol compartir la seva ubicació, pot crear un grup compartit i afegir-lo al seu mapa, de manera que tots dos aparegueu al mateix mapa d’ubicació compartit. Això és útil si és conduir i no es pot utilitzar el telèfon, ja que l\'adopció de la seva participació per part d\'altres persones no requereix cap interacció per part seva.</string>
<string name="err_ver_group">El servidor no admet comparticions de grup. Les accions del grup són compatibles amb la versió %s i superiors; actualment el servidor està executant la versió %s. La vostra participació s\'ha convertit en una participació individual.</string>
</resources>
</resources>
Loading