From ccff3e1718565f4f59d854a54769844d2f3a25e4 Mon Sep 17 00:00:00 2001 From: Felix Ableitner Date: Tue, 16 Sep 2014 11:29:00 +0300 Subject: [PATCH] Use notification instead of dialog if syncthing binary crashes. This also gets rid of the SYSTEM_ALERT_WINDOW permission. --- src/main/AndroidManifest.xml | 1 - .../fragments/NodeSettingsFragment.java | 8 +-- .../syncthingandroid/syncthing/RestApi.java | 31 +++++------ .../syncthing/SyncthingRunnable.java | 53 ++++++------------- .../syncthing/SyncthingService.java | 2 +- 5 files changed, 36 insertions(+), 59 deletions(-) diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml index b8e8cf53..5852ba61 100644 --- a/src/main/AndroidManifest.xml +++ b/src/main/AndroidManifest.xml @@ -12,7 +12,6 @@ - diff --git a/src/main/java/com/nutomic/syncthingandroid/fragments/NodeSettingsFragment.java b/src/main/java/com/nutomic/syncthingandroid/fragments/NodeSettingsFragment.java index b646b101..42f25b3b 100644 --- a/src/main/java/com/nutomic/syncthingandroid/fragments/NodeSettingsFragment.java +++ b/src/main/java/com/nutomic/syncthingandroid/fragments/NodeSettingsFragment.java @@ -151,7 +151,7 @@ public class NodeSettingsFragment extends PreferenceFragment implements .show(); return true; } - mSyncthingService.getApi().editNode(mNode, this); + mSyncthingService.getApi().editNode(mNode, getActivity(), this); return true; case R.id.share_node_id: RestApi.shareNodeId(getActivity(), mNode.NodeID); @@ -211,7 +211,7 @@ public class NodeSettingsFragment extends PreferenceFragment implements /** * Sets version and current address of the node. - *

+ * * NOTE: This is only called once on startup, should be called more often to properly display * version/address changes. */ @@ -228,7 +228,7 @@ public class NodeSettingsFragment extends PreferenceFragment implements */ private void nodeUpdated() { if (!mIsCreate) { - mSyncthingService.getApi().editNode(mNode, this); + mSyncthingService.getApi().editNode(mNode, getActivity(), this); } } @@ -261,7 +261,7 @@ public class NodeSettingsFragment extends PreferenceFragment implements } /** - * Callback for {@link RestApi#editNode(RestApi.Node, RestApi.OnNodeIdNormalizedListener)}. + * Callback for {@link RestApi#editNode}. * Displays an error message if present, or finishes the Activity on success in edit mode. * * @param normalizedId The normalized node ID, or null on error. diff --git a/src/main/java/com/nutomic/syncthingandroid/syncthing/RestApi.java b/src/main/java/com/nutomic/syncthingandroid/syncthing/RestApi.java index 2248a47f..db3ebbce 100644 --- a/src/main/java/com/nutomic/syncthingandroid/syncthing/RestApi.java +++ b/src/main/java/com/nutomic/syncthingandroid/syncthing/RestApi.java @@ -14,7 +14,6 @@ import android.content.Intent; import android.os.Build; import android.support.v4.app.NotificationCompat; import android.util.Log; -import android.view.WindowManager; import android.widget.Toast; import com.nutomic.syncthingandroid.BuildConfig; @@ -322,7 +321,7 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener { * Sends the updated mConfig via Rest API to syncthing and displays a "restart" notification. */ @TargetApi(11) - private void configUpdated(Context context) { + private void configUpdated(Activity activity) { new PostTask().execute(mUrl, PostTask.URI_CONFIG, mApiKey, mConfig.toString()); if (mRestartPostponed) @@ -332,9 +331,9 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener { .setAction(SyncthingService.ACTION_RESTART); AlertDialog.Builder builder = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) - ? new AlertDialog.Builder(context.getApplicationContext(), AlertDialog.THEME_HOLO_LIGHT) - : new AlertDialog.Builder(context.getApplicationContext()); - AlertDialog dialog = builder.setMessage(R.string.restart_title) + ? new AlertDialog.Builder(activity, AlertDialog.THEME_HOLO_LIGHT) + : new AlertDialog.Builder(activity); + builder.setMessage(R.string.restart_title) .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { @@ -353,9 +352,7 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener { createRestartNotification(); } }) - .create(); - dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); - dialog.show(); + .show(); } /** @@ -674,8 +671,8 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener { * @param node Settings of the node to edit. To create a node, pass a non-existant node ID. * @param listener {@link OnNodeIdNormalizedListener} for the normalized node ID. */ - public void editNode(final Node node, - final OnNodeIdNormalizedListener listener) { + public void editNode(final Node node, final Activity activity, + final OnNodeIdNormalizedListener listener) { normalizeNodeId(node.NodeID, new RestApi.OnNodeIdNormalizedListener() { @Override @@ -711,7 +708,7 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener { n.put("NodeID", node.NodeID); n.put("Name", node.Name); n.put("Addresses", listToJson(node.Addresses.split(" "))); - configUpdated(mContext); + configUpdated(activity); } catch (JSONException e) { Log.w(TAG, "Failed to read nodes", e); } @@ -723,7 +720,7 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener { /** * Deletes the given node from syncthing. */ - public boolean deleteNode(Node node, Context context) { + public boolean deleteNode(Node node, Activity activity) { try { JSONArray nodes = mConfig.getJSONArray("Nodes"); @@ -735,7 +732,7 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener { break; } } - configUpdated(context); + configUpdated(activity); } catch (JSONException e) { Log.w(TAG, "Failed to edit repo", e); return false; @@ -746,7 +743,7 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener { /** * Updates or creates the given node. */ - public boolean editRepo(Repo repo, boolean create, Context context) { + public boolean editRepo(Repo repo, boolean create, Activity activity) { try { JSONArray repos = mConfig.getJSONArray("Repositories"); JSONObject r = null; @@ -783,7 +780,7 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener { params.put(key, repo.Versioning.getParams().get(key)); } r.put("Versioning", versioning); - configUpdated(context); + configUpdated(activity); } catch (JSONException e) { Log.w(TAG, "Failed to edit repo " + repo.ID + " at " + repo.Directory, e); return false; @@ -794,7 +791,7 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener { /** * Deletes the given repository from syncthing. */ - public boolean deleteRepo(Repo repo, Context context) { + public boolean deleteRepo(Repo repo, Activity activity) { try { JSONArray repos = mConfig.getJSONArray("Repositories"); @@ -806,7 +803,7 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener { break; } } - configUpdated(context); + configUpdated(activity); } catch (JSONException e) { Log.w(TAG, "Failed to edit repo", e); return false; diff --git a/src/main/java/com/nutomic/syncthingandroid/syncthing/SyncthingRunnable.java b/src/main/java/com/nutomic/syncthingandroid/syncthing/SyncthingRunnable.java index 51658d0e..f6ceb955 100644 --- a/src/main/java/com/nutomic/syncthingandroid/syncthing/SyncthingRunnable.java +++ b/src/main/java/com/nutomic/syncthingandroid/syncthing/SyncthingRunnable.java @@ -1,11 +1,10 @@ package com.nutomic.syncthingandroid.syncthing; -import android.app.AlertDialog; +import android.app.Notification; +import android.app.NotificationManager; import android.content.Context; -import android.content.DialogInterface; -import android.os.Handler; +import android.support.v4.app.NotificationCompat; import android.util.Log; -import android.view.WindowManager; import com.nutomic.syncthingandroid.R; @@ -25,12 +24,12 @@ public class SyncthingRunnable implements Runnable { private static final String TAG_NATIVE = "SyncthingNativeCode"; + private static final int NOTIFICATION_CRASHED = 3; + private final Context mContext; private final String mCommand; - private final Handler mHandler; - private final String mApiKey; /** @@ -41,7 +40,6 @@ public class SyncthingRunnable implements Runnable { public SyncthingRunnable(Context context, String command) { mContext = context; mCommand = command; - mHandler = new Handler(); char[] chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".toCharArray(); StringBuilder sb = new StringBuilder(); @@ -84,41 +82,24 @@ public class SyncthingRunnable implements Runnable { Log.w(TAG, "Failed to close shell stream", e); } process.destroy(); - final int retVal = ret; if (ret != 0) { Log.w(TAG_NATIVE, "Syncthing binary crashed with error code " + - Integer.toString(retVal)); - postCrashDialog(retVal); + Integer.toString(ret)); + NotificationCompat.Builder b = new NotificationCompat.Builder(mContext) + .setContentTitle(mContext.getString(R.string.binary_crashed_title)) + .setContentText(mContext.getString(R.string.binary_crashed_message, ret)) + .setSmallIcon(R.drawable.ic_launcher) + .setAutoCancel(true) + .setOnlyAlertOnce(true); + Notification n = new NotificationCompat.BigTextStyle(b) + .bigText(mContext.getString(R.string.binary_crashed_message, ret)).build(); + NotificationManager mNotificationManager = (NotificationManager) + mContext.getSystemService(Context.NOTIFICATION_SERVICE); + mNotificationManager.notify(NOTIFICATION_CRASHED, n); } } } - /** - * Displays a dialog with an info message and the return value. - * - * @param retVal - */ - private void postCrashDialog(final int retVal) { - mHandler.post(new Runnable() { - public void run() { - AlertDialog dialog = new AlertDialog.Builder(mContext) - .setTitle(R.string.binary_crashed_title) - .setMessage(mContext.getString(R.string.binary_crashed_message, retVal)) - .setPositiveButton(android.R.string.ok, - new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialogInterface, int i) { - System.exit(0); - } - } - ) - .create(); - dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); - dialog.show(); - } - }); - } - /** * Logs the outputs of a stream to logcat and mNativeLog. * diff --git a/src/main/java/com/nutomic/syncthingandroid/syncthing/SyncthingService.java b/src/main/java/com/nutomic/syncthingandroid/syncthing/SyncthingService.java index 52d04242..e2f57e12 100644 --- a/src/main/java/com/nutomic/syncthingandroid/syncthing/SyncthingService.java +++ b/src/main/java/com/nutomic/syncthingandroid/syncthing/SyncthingService.java @@ -205,7 +205,7 @@ public class SyncthingService extends Service { } /** - * Creates notification, starts native binary. + * Starts the native binary. */ @Override public void onCreate() {