diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 8fafe4b..49a0551 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -14,6 +14,7 @@
+
diff --git a/app/src/main/java/com/github/ma1co/openmemories/tweak/BackupInfoAdapter.java b/app/src/main/java/com/github/ma1co/openmemories/tweak/BackupInfoAdapter.java
new file mode 100644
index 0000000..94bd095
--- /dev/null
+++ b/app/src/main/java/com/github/ma1co/openmemories/tweak/BackupInfoAdapter.java
@@ -0,0 +1,27 @@
+package com.github.ma1co.openmemories.tweak;
+
+public class BackupInfoAdapter implements ItemActivity.InfoItem.Adapter {
+ private final BackupProperty property;
+
+ public BackupInfoAdapter(BackupProperty property) {
+ this.property = property;
+ }
+
+ public BackupProperty getProperty() {
+ return property;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return property.exists();
+ }
+
+ @Override
+ public String getValue() {
+ try {
+ return property.getValue().toString();
+ } catch (BackupProperty.BackupException e) {
+ return "";
+ }
+ }
+}
diff --git a/app/src/main/java/com/github/ma1co/openmemories/tweak/BackupKeys.java b/app/src/main/java/com/github/ma1co/openmemories/tweak/BackupKeys.java
index 67c2b4d..680289b 100644
--- a/app/src/main/java/com/github/ma1co/openmemories/tweak/BackupKeys.java
+++ b/app/src/main/java/com/github/ma1co/openmemories/tweak/BackupKeys.java
@@ -24,4 +24,10 @@ public class BackupKeys {
}
public static final BackupProperty.Byte PAL_NTSC_SELECTOR_ENABLED = new BackupProperty.Byte(0x01070148);
+
+ public static final BackupProperty.CString MODEL_NAME = new BackupProperty.CString(0x003e0005, 16);
+
+ public static final BackupProperty.ByteArray SERIAL_NUMBER = new BackupProperty.ByteArray(0x00e70003, 4);
+
+ public static final BackupProperty.CString PLATFORM_VERSION = new BackupProperty.CString(0x01660024, 8);
}
diff --git a/app/src/main/java/com/github/ma1co/openmemories/tweak/BackupProperty.java b/app/src/main/java/com/github/ma1co/openmemories/tweak/BackupProperty.java
index 9934e54..d927f75 100644
--- a/app/src/main/java/com/github/ma1co/openmemories/tweak/BackupProperty.java
+++ b/app/src/main/java/com/github/ma1co/openmemories/tweak/BackupProperty.java
@@ -16,6 +16,24 @@ public BackupProtectionException() {
}
}
+ public static class ByteArray extends BaseProperty {
+ public ByteArray(int id, int size) {
+ super(id, byte[].class, size);
+ }
+
+ @Override
+ protected byte[] toBytes(byte[] value) {
+ if (value.length != getSize())
+ throw new IllegalArgumentException("Wrong array length");
+ return value;
+ }
+
+ @Override
+ protected byte[] fromBytes(byte[] value) {
+ return value;
+ }
+ }
+
public static class Byte extends BaseProperty {
public Byte(int id) {
super(id, Integer.class, 1);
@@ -48,6 +66,29 @@ protected Integer fromBytes(byte[] value) {
}
}
+ public static class CString extends BaseProperty {
+ public CString(int id, int size) {
+ super(id, String.class, size);
+ }
+
+ @Override
+ protected byte[] toBytes(String value) {
+ byte[] bytes = value.getBytes();
+ if (bytes.length > getSize())
+ throw new IllegalArgumentException("String too long");
+ return Arrays.copyOf(bytes, getSize());
+ }
+
+ @Override
+ protected String fromBytes(byte[] value) {
+ String str = new String(value);
+ int length = str.indexOf('\u0000');
+ if (length == -1)
+ length = value.length;
+ return str.substring(0, length);
+ }
+ }
+
public static abstract class BaseProperty extends BackupProperty {
private final int id;
private final int size;
diff --git a/app/src/main/java/com/github/ma1co/openmemories/tweak/InfoActivity.java b/app/src/main/java/com/github/ma1co/openmemories/tweak/InfoActivity.java
new file mode 100644
index 0000000..d4927f5
--- /dev/null
+++ b/app/src/main/java/com/github/ma1co/openmemories/tweak/InfoActivity.java
@@ -0,0 +1,82 @@
+package com.github.ma1co.openmemories.tweak;
+
+import android.os.Bundle;
+
+import java.io.IOException;
+
+public class InfoActivity extends ItemActivity {
+ public static class LoggingInfoAdapter implements InfoItem.Adapter {
+ private final String key;
+ private final InfoItem.Adapter parent;
+
+ public LoggingInfoAdapter(String key, InfoItem.Adapter parent) {
+ this.key = key;
+ this.parent = parent;
+ }
+
+ @Override
+ public boolean isAvailable() {
+ return parent.isAvailable();
+ }
+
+ @Override
+ public String getValue() {
+ String value = parent.getValue();
+ Logger.info("InfoAdapter", String.format("%s: %s", key, value));
+ return value;
+ }
+ }
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ addLoggedInfo("Model", new BackupInfoAdapter<>(BackupKeys.MODEL_NAME));
+
+ addInfo("Serial number", new BackupInfoAdapter(BackupKeys.SERIAL_NUMBER) {
+ @Override
+ public String getValue() {
+ try {
+ byte[] serial = getProperty().getValue();
+ return String.format("%x%02x%02x%02x", serial[0], serial[1], serial[2], serial[3]);
+ } catch (BackupProperty.BackupException e) {
+ return "";
+ }
+ }
+ });
+
+ addLoggedInfo("Backup region", new InfoItem.Adapter() {
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+ @Override
+ public String getValue() {
+ try {
+ return Backup.readData().getRegion();
+ } catch (IOException | NativeException e) {
+ return "";
+ }
+ }
+ });
+
+ addLoggedInfo("Tweak app version", new InfoItem.Adapter() {
+ @Override
+ public boolean isAvailable() {
+ return true;
+ }
+
+ @Override
+ public String getValue() {
+ return BuildConfig.VERSION_NAME;
+ }
+ });
+
+ addLoggedInfo("Java API version", new BackupInfoAdapter<>(BackupKeys.PLATFORM_VERSION));
+ }
+
+ protected BaseItem addLoggedInfo(String title, InfoItem.Adapter adapter) {
+ return addInfo(title, new LoggingInfoAdapter(title, adapter));
+ }
+}
diff --git a/app/src/main/java/com/github/ma1co/openmemories/tweak/ItemActivity.java b/app/src/main/java/com/github/ma1co/openmemories/tweak/ItemActivity.java
index 0779b0a..a12aa45 100644
--- a/app/src/main/java/com/github/ma1co/openmemories/tweak/ItemActivity.java
+++ b/app/src/main/java/com/github/ma1co/openmemories/tweak/ItemActivity.java
@@ -106,6 +106,36 @@ public Adapter getAdapter() {
}
}
+ public static class InfoItem extends BaseItem {
+ public interface Adapter {
+ boolean isAvailable();
+ String getValue();
+ }
+
+ private final Adapter adapter;
+ private final TextView titleView;
+ private final TextView valueView;
+
+ public InfoItem(Context context, String title, Adapter adapter) {
+ super(context);
+ inflate(context, R.layout.view_info, this);
+ titleView = (TextView) findViewById(R.id.title);
+ valueView = (TextView) findViewById(R.id.value);
+
+ this.adapter = adapter;
+ titleView.setText(title);
+ }
+
+ public Adapter getAdapter() {
+ return adapter;
+ }
+
+ @Override
+ public void update() {
+ valueView.setText(adapter.isAvailable() ? adapter.getValue() : "(not available)");
+ }
+ }
+
private ViewGroup containerView;
@Override
@@ -143,4 +173,8 @@ protected BaseItem addSwitch(String title, SwitchItem.Adapter adapter) {
protected BaseItem addButton(String text, ButtonItem.Adapter adapter) {
return addItem(new ButtonItem(this, text, adapter));
}
+
+ protected BaseItem addInfo(String title, InfoItem.Adapter adapter) {
+ return addItem(new InfoItem(this, title, adapter));
+ }
}
diff --git a/app/src/main/java/com/github/ma1co/openmemories/tweak/MainActivity.java b/app/src/main/java/com/github/ma1co/openmemories/tweak/MainActivity.java
index 0473d36..f144283 100644
--- a/app/src/main/java/com/github/ma1co/openmemories/tweak/MainActivity.java
+++ b/app/src/main/java/com/github/ma1co/openmemories/tweak/MainActivity.java
@@ -25,6 +25,7 @@ public void uncaughtException(Thread thread, Throwable exp) {
}
});
+ addTab("info", "Info", android.R.drawable. ic_menu_info_details, InfoActivity.class);
addTab("video", "Video", android.R.drawable.ic_menu_camera, VideoActivity.class);
addTab("region", "Region", android.R.drawable.ic_menu_mapmode, RegionActivity.class);
addTab("protection", "Protection", android.R.drawable.ic_lock_lock, ProtectionActivity.class);
diff --git a/app/src/main/res/layout/view_info.xml b/app/src/main/res/layout/view_info.xml
new file mode 100644
index 0000000..60b9fcf
--- /dev/null
+++ b/app/src/main/res/layout/view_info.xml
@@ -0,0 +1,13 @@
+
+
+
+
+