package yuku.alkitabfeedback;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Build;
import android.os.Build.VERSION;
import android.util.Log;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
public class FeedbackSender {
public static final String TAG = FeedbackSender.class.getSimpleName();
public interface OnSuccessListener {
void onSuccess(byte[] response);
}
static class Entry {
int timestamp;
String feedback_id;
String feedback_from_name;
String feedback_from_email;
String feedback_body;
int package_versionCode;
int build_version_sdk;
}
static final OkHttpClient client = new OkHttpClient();
String overrideInstallationId_;
final Context context_;
final SharedPreferences pref_;
List<Entry> entries_;
OnSuccessListener onSuccessListener_ = null;
boolean sending_ = false;
private static FeedbackSender instance;
public static FeedbackSender getInstance(Context context) {
if (instance == null) {
instance = new FeedbackSender(context);
}
return instance;
}
private FeedbackSender(Context context) {
context_ = context;
pref_ = context.getSharedPreferences("FeedbackSender", 0);
}
public void setOnSuccessListener(OnSuccessListener onSuccessListener) {
onSuccessListener_ = onSuccessListener;
}
public void addEntry(String feedback_from_name, String feedback_from_email, String feedback_body) {
load();
Entry e = new Entry();
e.timestamp = getTimestamp();
e.feedback_id = "u2:" + UUID.randomUUID().toString();
e.feedback_from_name = feedback_from_name;
e.feedback_from_email = feedback_from_email;
e.feedback_body = feedback_body;
e.package_versionCode = getPackageVersionCode();
e.build_version_sdk = getBuildVersionSdk();
entries_.add(e);
save();
}
synchronized void load() {
if (entries_ == null) {
final String base = "feedback/";
entries_ = new ArrayList<>();
int nfeedback = pref_.getInt(base + "n", 0);
for (int i = 0; i < nfeedback; i++) {
Entry e = new Entry();
e.timestamp = pref_.getInt(base + i + "/timestamp", 0);
e.feedback_id = pref_.getString(base + i + "/feedback_id", null);
e.feedback_from_name = pref_.getString(base + i + "/feedback_from_name", null);
e.feedback_from_email = pref_.getString(base + i + "/feedback_from_email", null);
e.feedback_body = pref_.getString(base + i + "/feedback_body", null);
e.package_versionCode = pref_.getInt(base + i + "/package_versionCode", 0);
e.build_version_sdk = pref_.getInt(base + i + "/build_version_sdk", 0);
entries_.add(e);
}
}
}
synchronized void save() {
if (entries_ == null) return;
final String base = "feedback/";
Editor editor = pref_.edit();
{
editor.putInt(base + "n", entries_.size());
for (int i = 0; i < entries_.size(); i++) {
Entry entry = entries_.get(i);
editor.putInt(base + i + "/timestamp", entry.timestamp);
editor.putString(base + i + "/feedback_id", entry.feedback_id);
editor.putString(base + i + "/feedback_from_name", entry.feedback_from_name);
editor.putString(base + i + "/feedback_from_email", entry.feedback_from_email);
editor.putString(base + i + "/feedback_body", entry.feedback_body);
editor.putInt(base + i + "/package_versionCode", entry.package_versionCode);
editor.putInt(base + i + "/build_version_sdk", entry.build_version_sdk);
}
}
editor.apply();
}
public synchronized void trySend() {
load();
if (sending_ || entries_.size() == 0) return;
sending_ = true;
new Sender().start();
}
class Sender extends Thread {
@Override public void run() {
boolean success = false;
Log.d(TAG, "feedback sending thread started");
try {
final FormBody.Builder form = new FormBody.Builder();
for (Entry e : entries_) {
form.add("timestamp[]", "" + e.timestamp);
form.add("installationId[]", "" + getInstallationId());
form.add("feedback_id[]", "" + e.feedback_id);
form.add("feedback_from_name[]", "" + e.feedback_from_name);
form.add("feedback_from_email[]", "" + e.feedback_from_email);
form.add("feedback_body[]", "" + e.feedback_body);
form.add("package_name[]", "" + context_.getPackageName());
form.add("package_versionCode[]", "" + e.package_versionCode);
form.add("build_product[]", "" + getBuildProduct());
form.add("build_device[]", "" + getBuildDevice());
form.add("build_model[]", "" + getBuildModel());
form.add("build_version_sdk[]", "" + e.build_version_sdk);
}
final Response resp = client.newCall(new Request.Builder().url(BuildConfig.SERVER_HOST + "laban/submit").post(form.build()).build()).execute();
final byte[] out = resp.body().bytes();
if (out.length >= 2 && out[0] == 'O' && out[1] == 'K') {
success = true;
}
if (onSuccessListener_ != null) {
onSuccessListener_.onSuccess(out);
}
if (success) {
synchronized (FeedbackSender.this) {
entries_.clear();
}
save();
}
} catch (IOException e) {
Log.w(TAG, "when posting feedback", e);
} finally {
Log.d(TAG, "feedback sending thread ended. success = " + success);
sending_ = false;
}
}
}
int getTimestamp() {
return (int) (new Date().getTime() / 1000L);
}
int getPackageVersionCode() {
int versionCode = 0;
try {
versionCode = context_.getPackageManager().getPackageInfo(context_.getPackageName(), 0).versionCode;
} catch (NameNotFoundException e) {
Log.w(TAG, "package get versioncode", e);
}
return versionCode;
}
String getBuildProduct() {
return Build.PRODUCT;
}
String getBuildDevice() {
return Build.DEVICE;
}
String getBuildModel() {
return Build.MODEL;
}
int getBuildVersionSdk() {
return VERSION.SDK_INT;
}
String getInstallationId() {
if (overrideInstallationId_ != null) return overrideInstallationId_;
String installationId = pref_.getString("installationId", null);
if (installationId == null) {
installationId = "u2:" + UUID.randomUUID().toString();
pref_.edit().putString("installationId", installationId).apply();
}
return installationId;
}
/**
* Set the uniqueId to use rather than the generated one
*/
public void setOverrideInstallationId(String installationId) {
overrideInstallationId_ = installationId;
}
}