reader/android: add device meta-data
- add DeviceType to the Device schema (e.g., "Android", "Web")
- add DeviceInfoFactory class, which creates a Device object with the
correct information for the current Android device.
Change-Id: I639e07d3c4c4a7ea1fe7b946d11baf7c885131e1
diff --git a/android/app/src/main/java/io/v/android/apps/reader/db/DB.java b/android/app/src/main/java/io/v/android/apps/reader/db/DB.java
index 87cdeab..38a2e37 100644
--- a/android/app/src/main/java/io/v/android/apps/reader/db/DB.java
+++ b/android/app/src/main/java/io/v/android/apps/reader/db/DB.java
@@ -9,6 +9,7 @@
import android.content.Intent;
import io.v.android.apps.reader.model.Listener;
+import io.v.android.apps.reader.vdl.Device;
import io.v.android.apps.reader.vdl.DeviceSet;
import io.v.android.apps.reader.vdl.File;
@@ -90,6 +91,12 @@
DBList<File> getFileList();
/**
+ * Gets the list of devices of this user.
+ * @return a list of devices.
+ */
+ DBList<Device> getDeviceList();
+
+ /**
* Gets the list of currently active device sets.
* @return a list of device sets.
*/
diff --git a/android/app/src/main/java/io/v/android/apps/reader/db/FakeDB.java b/android/app/src/main/java/io/v/android/apps/reader/db/FakeDB.java
index 8d4e4e8..4ca5244 100644
--- a/android/app/src/main/java/io/v/android/apps/reader/db/FakeDB.java
+++ b/android/app/src/main/java/io/v/android/apps/reader/db/FakeDB.java
@@ -7,11 +7,14 @@
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
+import android.util.Log;
import java.util.ArrayList;
import java.util.List;
+import io.v.android.apps.reader.model.DeviceInfoFactory;
import io.v.android.apps.reader.model.Listener;
+import io.v.android.apps.reader.vdl.Device;
import io.v.android.apps.reader.vdl.DeviceSet;
import io.v.android.apps.reader.vdl.File;
@@ -31,17 +34,37 @@
};
private FakeFileList mFileList;
+ private FakeDeviceList mDeviceList;
private FakeDeviceSetList mDeviceSetList;
public FakeDB(Context context) {
mFileList = new FakeFileList();
+ mDeviceList = new FakeDeviceList(context);
mDeviceSetList = new FakeDeviceSetList();
}
- static class FakeFileList implements DBList<File> {
+ static abstract class BaseFakeList<E> implements DBList<E> {
+
+ private Listener mListener;
+
+ @Override
+ public void setListener(Listener listener) {
+ // This fake list never calls the notify methods.
+ // Just check if the listener is set only once.
+ assert mListener == null;
+ mListener = listener;
+ }
+
+ @Override
+ public void discard() {
+ // Nothing to do.
+ }
+
+ }
+
+ static class FakeFileList extends BaseFakeList<File> {
private List<File> mFiles;
- private Listener mListener;
public FakeFileList() {
mFiles = new ArrayList<>();
@@ -69,25 +92,33 @@
public File getItem(int position) {
return mFiles.get(position);
}
+ }
- @Override
- public void setListener(Listener listener) {
- // This fake list never calls the notify methods.
- // Just check if the listener is set only once.
- assert mListener == null;
- mListener = listener;
+ static class FakeDeviceList extends BaseFakeList<Device> {
+
+ private static final String TAG = FakeDeviceList.class.getSimpleName();
+
+ private Context mContext;
+
+ public FakeDeviceList(Context context) {
+ mContext = context;
+ Log.i(TAG, "Device Info: " + getItem(0));
}
@Override
- public void discard() {
- // Nothing to do.
+ public int getItemCount() {
+ return 1;
+ }
+
+ @Override
+ public Device getItem(int position) {
+ return DeviceInfoFactory.get(mContext);
}
}
- static class FakeDeviceSetList implements DBList<DeviceSet> {
+ static class FakeDeviceSetList extends BaseFakeList<DeviceSet> {
private List<DeviceSet> mDeviceSets;
- private Listener mListener;
public FakeDeviceSetList() {
mDeviceSets = new ArrayList<>();
@@ -113,19 +144,6 @@
public DeviceSet getItem(int position) {
return mDeviceSets.get(position);
}
-
- @Override
- public void setListener(Listener listener) {
- // This fake list never calls the notify methods.
- // Just check if the listener is set only once.
- assert mListener == null;
- mListener = listener;
- }
-
- @Override
- public void discard() {
- // Nothing to do.
- }
}
public void init(Activity activity) {
@@ -144,6 +162,11 @@
}
@Override
+ public DBList<Device> getDeviceList() {
+ return mDeviceList;
+ }
+
+ @Override
public DBList<DeviceSet> getDeviceSetList() {
return mDeviceSetList;
}
diff --git a/android/app/src/main/java/io/v/android/apps/reader/db/SyncbaseDB.java b/android/app/src/main/java/io/v/android/apps/reader/db/SyncbaseDB.java
index c72045c..1f9b636 100644
--- a/android/app/src/main/java/io/v/android/apps/reader/db/SyncbaseDB.java
+++ b/android/app/src/main/java/io/v/android/apps/reader/db/SyncbaseDB.java
@@ -14,6 +14,7 @@
import com.google.common.collect.ImmutableMap;
import io.v.android.apps.reader.model.Listener;
+import io.v.android.apps.reader.vdl.Device;
import io.v.android.apps.reader.vdl.DeviceSet;
import io.v.android.apps.reader.vdl.File;
import io.v.android.libs.security.BlessingsManager;
@@ -52,12 +53,18 @@
private static final int BLESSING_REQUEST = 200;
private static final String SYNCBASE_APP = "reader";
private static final String SYNCBASE_DB = "db";
+
private static final String FILES_TABLE = "files";
+ private static final String DEVICES_TABLE = "devices";
+ private static final String DEVICE_SETS_TABLE = "deviceSets";
private Permissions mPermissions;
private Context mContext;
private VContext vContext;
+
private Table mFiles;
+ private Table mDevices;
+ private Table mDeviceSets;
SyncbaseDB(Context context) {
mContext = context;
@@ -182,6 +189,16 @@
if (!mFiles.exists(vContext)) {
mFiles.create(vContext, mPermissions);
}
+
+ mDevices = db.getTable(DEVICES_TABLE);
+ if (!mDevices.exists(vContext)) {
+ mDevices.create(vContext, mPermissions);
+ }
+
+ mDeviceSets = db.getTable(DEVICE_SETS_TABLE);
+ if (!mDeviceSets.exists(vContext)) {
+ mDeviceSets.create(vContext, mPermissions);
+ }
} catch (VException e) {
handleError("Couldn't setup syncbase service: " + e.getMessage());
}
@@ -214,6 +231,11 @@
}
@Override
+ public DBList<Device> getDeviceList() {
+ return new EmptyList<Device>();
+ }
+
+ @Override
public DBList<DeviceSet> getDeviceSetList() {
return new EmptyList<DeviceSet>();
}
diff --git a/android/app/src/main/java/io/v/android/apps/reader/model/DeviceInfoFactory.java b/android/app/src/main/java/io/v/android/apps/reader/model/DeviceInfoFactory.java
new file mode 100644
index 0000000..1f067f7
--- /dev/null
+++ b/android/app/src/main/java/io/v/android/apps/reader/model/DeviceInfoFactory.java
@@ -0,0 +1,74 @@
+// Copyright 2015 The Vanadium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package io.v.android.apps.reader.model;
+
+import android.content.Context;
+import android.graphics.Point;
+import android.os.Build;
+import android.provider.Settings;
+import android.view.Display;
+import android.view.WindowManager;
+
+import io.v.android.apps.reader.vdl.Device;
+import io.v.android.apps.reader.vdl.Screen;
+
+/**
+ * A factory class that provides the information of the current device.
+ */
+public class DeviceInfoFactory {
+
+ private static final String DEVICE_TYPE = "Android";
+
+ private static volatile Device instance;
+
+ /**
+ * Singleton method for getting the Device object that represents this device.
+ *
+ * @param context Android context
+ * @return Device object representing this device.
+ */
+ public static Device get(Context context) {
+ Device result = instance;
+ if (instance == null) {
+ synchronized (DeviceInfoFactory.class) {
+ result = instance;
+ if (result == null) {
+ String id = Settings.Secure.getString(
+ context.getContentResolver(),
+ Settings.Secure.ANDROID_ID);
+
+ String name = Build.MODEL;
+
+ String arch = System.getProperty("os.arch");
+
+ Point size = getScreenSize(context);
+ Screen screen = new Screen(size.x, size.y);
+
+ instance = result = new Device(id, DEVICE_TYPE, name, arch, screen);
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /**
+ * Gets the screen size.
+ */
+ private static Point getScreenSize(Context context) {
+ WindowManager wm = (WindowManager) context
+ .getSystemService(Context.WINDOW_SERVICE);
+ Display display = wm.getDefaultDisplay();
+ Point size = new Point();
+ display.getSize(size);
+
+ // Make width <= height, regardless of the current screen orientation.
+ if (size.x > size.y) {
+ size.set(size.y, size.x);
+ }
+
+ return size;
+ }
+}
diff --git a/vdl/device.vdl b/vdl/device.vdl
index d742693..dd9cfe0 100644
--- a/vdl/device.vdl
+++ b/vdl/device.vdl
@@ -11,6 +11,7 @@
type Device struct {
Id string
+ DeviceType string
Name string
Arch string
Screen Screen