Bug 1320889 - Tapping the notification for a downloaded file shouldn't open firefox. r?sebastian draft
authorNevin Chen <cnevinchen@gmail.com>
Fri, 16 Dec 2016 16:30:19 +0800
changeset 450896 e4a0308380b5bc1f8988c4650f86b62bab10541a
parent 446144 27449c736a04eec8c9033d70697747fce3a3c13d
child 539866 113840fa316be6e976b9c392a721004541626dd6
push id38988
push userbmo:cnevinchen@gmail.com
push dateMon, 19 Dec 2016 07:39:02 +0000
reviewerssebastian
bugs1320889
milestone53.0a1
Bug 1320889 - Tapping the notification for a downloaded file shouldn't open firefox. r?sebastian MozReview-Commit-ID: FzBk0TmVlm0
mobile/android/base/java/org/mozilla/gecko/notifications/NotificationHelper.java
--- a/mobile/android/base/java/org/mozilla/gecko/notifications/NotificationHelper.java
+++ b/mobile/android/base/java/org/mozilla/gecko/notifications/NotificationHelper.java
@@ -1,33 +1,39 @@
 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 package org.mozilla.gecko.notifications;
 
+import java.io.File;
+import java.io.UnsupportedEncodingException;
+import java.net.URLConnection;
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.List;
 
 import org.json.JSONArray;
 import org.json.JSONException;
 import org.json.JSONObject;
 import org.mozilla.gecko.AppConstants;
 import org.mozilla.gecko.EventDispatcher;
 import org.mozilla.gecko.GeckoAppShell;
 import org.mozilla.gecko.R;
 import org.mozilla.gecko.gfx.BitmapUtils;
 import org.mozilla.gecko.mozglue.SafeIntent;
 import org.mozilla.gecko.util.GeckoEventListener;
 
 import android.app.PendingIntent;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
 import android.graphics.Bitmap;
 import android.net.Uri;
 import android.support.v4.app.NotificationCompat;
 import android.util.Log;
 
 public final class NotificationHelper implements GeckoEventListener {
     public static final String HELPER_BROADCAST_ACTION = AppConstants.ANDROID_PACKAGE_NAME + ".helperBroadcastAction";
 
@@ -296,31 +302,80 @@ public final class NotificationHelper im
                                       actionTitle,
                                       pending);
                 }
             } catch (JSONException ex) {
                 Log.i(LOGTAG, "Error parsing", ex);
             }
         }
 
-        PendingIntent pi = buildNotificationPendingIntent(message, CLICK_EVENT);
-        builder.setContentIntent(pi);
-        PendingIntent deletePendingIntent = buildNotificationPendingIntent(message, CLEARED_EVENT);
-        builder.setDeleteIntent(deletePendingIntent);
+        // Bug 1320889 - Tapping the notification for a downloaded file shouldn't open firefox.
+        // If the gecko event is for download completion, we create another intent with different
+        // scheme to prevent Fennec from popping up.
+        final Intent viewFileIntent = createIntentIfDownloadCompleted(message);
+        if (builder != null && viewFileIntent != null && mContext != null) {
+            PendingIntent pIntent = PendingIntent.getActivity(mContext, 0, viewFileIntent, PendingIntent.FLAG_UPDATE_CURRENT);
+            builder.setAutoCancel(true);
+            builder.setContentIntent(pIntent);
+
+        } else {
+            PendingIntent pi = buildNotificationPendingIntent(message, CLICK_EVENT);
+            builder.setContentIntent(pi);
+            PendingIntent deletePendingIntent = buildNotificationPendingIntent(message, CLEARED_EVENT);
+            builder.setDeleteIntent(deletePendingIntent);
+
+        }
 
         ((NotificationClient) GeckoAppShell.getNotificationListener()).add(id, builder.build());
 
         boolean persistent = message.optBoolean(PERSISTENT_ATTR);
         // We add only not persistent notifications to the list since we want to purge only
         // them when geckoapp is destroyed.
         if (!persistent && !mClearableNotifications.containsKey(id)) {
             mClearableNotifications.put(id, message.toString());
         }
     }
 
+
+    private Intent createIntentIfDownloadCompleted(JSONObject message) {
+        try {
+            if (message.has(HANDLER_ATTR) && message.get(HANDLER_ATTR).equals("downloads") &&
+                    message.has(ONGOING_ATTR) && !message.optBoolean(ONGOING_ATTR) &&
+                    message.has(COOKIE_ATTR) && message.getString(COOKIE_ATTR).split("http").length > 0) {
+
+                String fileName = message.getString(TEXT_ATTR);
+                String cookie = message.getString(COOKIE_ATTR);
+                if (cookie.contains(fileName)) {
+                    String filePath = cookie.substring(0, cookie.indexOf(fileName)).replace("\"", "");
+                    String filePathDecode = java.net.URLDecoder.decode(filePath, "UTF-8");
+                    Uri uri = Uri.fromFile(new File(filePathDecode + fileName));
+                    Intent intent = new Intent();
+                    intent.setAction(Intent.ACTION_VIEW);
+                    intent.setDataAndType(uri, URLConnection.guessContentTypeFromName(uri.toString()));
+
+                    // if no one can handle this intent, let the user decides
+                    PackageManager manager = mContext.getPackageManager();
+                    List<ResolveInfo> infos = manager.queryIntentActivities(intent, 0);
+                    if (infos.size() == 0) {
+                        intent.setDataAndType(uri, "*/*");
+                    }
+
+                    return intent;
+                }
+            }
+        } catch (JSONException je) {
+            Log.e(LOGTAG, "Error while parsing download complete event.", je);
+            return null;
+        } catch (UnsupportedEncodingException e) {
+            Log.e(LOGTAG, "Error while parsing download file path.", e);
+            return null;
+        }
+        return null;
+    }
+
     private void hideNotification(JSONObject message) {
         final String id;
         final String handler;
         final String cookie;
         try {
             id = message.getString("id");
             handler = message.optString("handlerKey");
             cookie  = message.optString("cookie");