Skip to content

Commit

Permalink
Switch to GSON and re-enable Proguard/R8
Browse files Browse the repository at this point in the history
  • Loading branch information
Florianisme committed Oct 15, 2023
1 parent 7ccfbe6 commit 8438553
Show file tree
Hide file tree
Showing 10 changed files with 111 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@
import androidx.activity.result.ActivityResultLauncher;
import androidx.fragment.app.Fragment;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.gson.Gson;

import java.io.OutputStream;
import java.lang.ref.WeakReference;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -49,7 +50,7 @@ public void onActivityResult(Uri uri) {
.stream().map(DeviceBackupModel::new)
.collect(Collectors.toList());

byte[] content = new ObjectMapper().writeValueAsBytes(devices);
byte[] content = new Gson().toJson(devices).getBytes(StandardCharsets.UTF_8);
writeDevicesToFile(uri, content, context);

Toast.makeText(context, context.getString(R.string.backup_message_export_success, devices.size()), Toast.LENGTH_SHORT).show();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@
import androidx.activity.result.ActivityResultLauncher;
import androidx.fragment.app.Fragment;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.common.io.ByteStreams;
import com.google.gson.Gson;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.ref.WeakReference;
import java.util.Arrays;

Expand Down Expand Up @@ -46,7 +48,8 @@ public void onActivityResult(Uri uri) {

try {
byte[] bytes = readContentFromFile(uri, context);
Device[] devices = Arrays.stream(new ObjectMapper().readValue(bytes, DeviceBackupModel[].class))
InputStreamReader inputStreamReader = new InputStreamReader(new ByteArrayInputStream(bytes));
Device[] devices = Arrays.stream(new Gson().fromJson(inputStreamReader, DeviceBackupModel[].class))
.map(DeviceBackupModel::toModel)
.toArray(Device[]::new);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
package de.florianisme.wakeonlan.ui.backup.model;

import com.fasterxml.jackson.annotation.JsonAlias;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.gson.annotations.SerializedName;

import de.florianisme.wakeonlan.persistence.models.Device;

@JsonIgnoreProperties(ignoreUnknown = true)
public class DeviceBackupModel {

/*
Expand All @@ -15,50 +12,43 @@ public class DeviceBackupModel {
to JSON with its obfuscated name ("a", "b", and so on).
*/

@JsonProperty("id")
@JsonAlias("a")
@SerializedName(value = "id", alternate = "a")
public int id;

@JsonProperty("name")
@JsonAlias("b")
@SerializedName(value = "name", alternate = "b")
public String name;

@JsonProperty("mac_address")
@JsonAlias("c")
@SerializedName(value = "mac_address", alternate = "c")
public String macAddress;

@JsonProperty("broadcast_address")
@JsonAlias("d")
@SerializedName(value = "broadcast_address", alternate = "d")
public String broadcastAddress;

@JsonProperty("port")
@JsonAlias("e")
@SerializedName(value = "port", alternate = "e")
public int port;

@JsonProperty("status_ip")
@JsonAlias("f")
@SerializedName(value = "status_ip", alternate = "f")
public String statusIp;

@JsonProperty("secure_on_password")
@JsonAlias("g")
@SerializedName(value = "secure_on_password", alternate = "g")
public String secureOnPassword;

@JsonProperty("remote_shutdown_enabled")
@SerializedName(value = "remote_shutdown_enabled")
public boolean remoteShutdownEnabled;

@JsonProperty("ssh_address")
@SerializedName(value = "ssh_address")
public String sshAddress;

@JsonProperty("ssh_port")
@SerializedName(value = "ssh_port")
public Integer sshPort;

@JsonProperty("ssh_username")
@SerializedName(value = "ssh_username")
public String sshUsername;

@JsonProperty("ssh_password")
@SerializedName(value = "ssh_password")
public String sshPassword;

@JsonProperty("ssh_command")
@SerializedName(value = "ssh_command")
public String sshCommand;

public DeviceBackupModel(Device device) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@
import android.content.Context;
import android.util.Log;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.android.gms.wearable.DataClient;
import com.google.android.gms.wearable.PutDataMapRequest;
import com.google.android.gms.wearable.PutDataRequest;
import com.google.android.gms.wearable.Wearable;
import com.google.gson.Gson;
import com.google.gson.JsonParseException;

import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -38,8 +39,8 @@ private byte[] buildDevicesListByteArray(List<Device> devices) {
List<DeviceDto> deviceDtos = devices.stream()
.map(device -> new DeviceDto(device.id, device.name))
.collect(Collectors.toList());
return new ObjectMapper().writeValueAsBytes(deviceDtos);
} catch (JsonProcessingException e) {
return new Gson().toJson(deviceDtos).getBytes(StandardCharsets.UTF_8);
} catch (JsonParseException e) {
Log.e(getClass().getSimpleName(), "Could not transform list of devices to byte array", e);
return new byte[0];
}
Expand Down
10 changes: 8 additions & 2 deletions ping/build.gradle
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
apply plugin: 'com.android.library'
apply from: "$rootProject.projectDir/shared-build.gradle"

android {
namespace 'de.florianisme.wakeonlan.ping'
compileSdk 34

defaultConfig {
applicationId null
minSdk 24
targetSdk 34
versionName "1.0"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
}

Expand Down
41 changes: 41 additions & 0 deletions proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
-dontobfuscate
-keepattributes SourceFile,LineNumberTable
-keep class de.florianisme.wakeonlan.BuildConfig { *; }
-dontwarn org.slf4j.**
-dontwarn sun.security.x509.**

-keep class de.florianisme.wakeonlan.models.DeviceDto { *; }


##---------------Begin: proguard configuration for Gson ----------
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature

# For using GSON @Expose annotation
-keepattributes *Annotation*

# Gson specific classes
-dontwarn sun.misc.**
#-keep class com.google.gson.stream.** { *; }

# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** { <fields>; }

# Prevent proguard from stripping interface information from TypeAdapter, TypeAdapterFactory,
# JsonSerializer, JsonDeserializer instances (so they can be used in @JsonAdapter)
-keep class * extends com.google.gson.TypeAdapter
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer

# Prevent R8 from leaving Data object members always null
-keepclassmembers,allowobfuscation class * {
@com.google.gson.annotations.SerializedName <fields>;
}

# Retain generic signatures of TypeToken and its subclasses with R8 version 3.0 and higher.
-keep,allowobfuscation,allowshrinking class com.google.gson.reflect.TypeToken
-keep,allowobfuscation,allowshrinking class * extends com.google.gson.reflect.TypeToken

##---------------End: proguard configuration for Gson ----------
18 changes: 16 additions & 2 deletions shared-build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,21 @@ android {
}
}

buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),
"$rootProject.projectDir/proguard-rules.pro"
}
debug {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'),
"$rootProject.projectDir/proguard-rules.pro"
}
}

defaultConfig {
applicationId "de.florianisme.wakeonlan"
minSdk 24
Expand Down Expand Up @@ -44,8 +59,7 @@ dependencies {

implementation 'com.google.guava:guava:31.0.1-jre'

//noinspection GradleDependency 2.15 required Java 19 which is not supported yet
implementation 'com.fasterxml.jackson.core:jackson-databind:2.14.2'
implementation 'com.google.code.gson:gson:2.10.1'

testImplementation 'junit:junit:4.13.2'
testImplementation 'org.mockito:mockito-core:5.3.1'
Expand Down
3 changes: 1 addition & 2 deletions shared-models/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,5 @@ java {
}

dependencies {
//noinspection GradleDependency 2.15 required Java 19 which is not supported yet
implementation 'com.fasterxml.jackson.core:jackson-annotations:2.14.2'
implementation 'com.google.code.gson:gson:2.10.1'
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,25 @@
package de.florianisme.wakeonlan.models;

import com.fasterxml.jackson.annotation.JsonProperty;

import com.google.gson.annotations.SerializedName;

public class DeviceDto {

@JsonProperty("id")
private final int id;
@SerializedName("id")
private int id;

@JsonProperty("name")
private final String name;
@SerializedName("name")
private String name;

public DeviceDto(@JsonProperty("id") int id, @JsonProperty("name") String name) {
public DeviceDto(int id, String name) {
this.id = id;
this.name = name;
}

@SuppressWarnings("unused")
public DeviceDto() {
}

public int getId() {
return id;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

import android.net.Uri;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.google.android.gms.wearable.DataClient;
import com.google.android.gms.wearable.DataItem;
import com.google.android.gms.wearable.DataMap;
Expand All @@ -11,8 +10,11 @@
import com.google.android.gms.wearable.Node;
import com.google.android.gms.wearable.NodeClient;
import com.google.android.gms.wearable.PutDataRequest;
import com.google.gson.Gson;
import com.google.gson.JsonParseException;

import java.io.IOException;
import java.io.ByteArrayInputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.List;

Expand Down Expand Up @@ -64,8 +66,9 @@ public static List<DeviceDto> buildDeviceList(DataMap dataMap) throws DeviceQuer
}

try {
return Arrays.asList(new ObjectMapper().readValue(deviceListBytes, DeviceDto[].class));
} catch (IOException e) {
InputStreamReader inputStreamReader = new InputStreamReader(new ByteArrayInputStream(deviceListBytes));
return Arrays.asList(new Gson().fromJson(inputStreamReader, DeviceDto[].class));
} catch (JsonParseException e) {
throw new DeviceQueryException("Devices can not be parsed", e);
}
}
Expand Down

0 comments on commit 8438553

Please sign in to comment.