diff --git a/mobile/android/base/sync/CommandProcessor.java b/mobile/android/base/sync/CommandProcessor.java index 5d79b624eb6..718c80efb85 100644 --- a/mobile/android/base/sync/CommandProcessor.java +++ b/mobile/android/base/sync/CommandProcessor.java @@ -7,11 +7,21 @@ package org.mozilla.gecko.sync; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; import org.json.simple.JSONArray; +import org.mozilla.gecko.R; + +import android.app.Notification; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; public class CommandProcessor { private static final String LOG_TAG = "Command"; + private static AtomicInteger currentId = new AtomicInteger(); protected ConcurrentHashMap commands = new ConcurrentHashMap(); private final static CommandProcessor processor = new CommandProcessor(); @@ -80,4 +90,39 @@ public class CommandProcessor { return null; } } + + public void displayURI(List args, Context context) { + // These two args are guaranteed to exist by trusting the client sender. + String uri = args.get(0); + String clientId = args.get(1); + + Logger.info(LOG_TAG, "Received a URI for display: " + uri + " from " + clientId); + + String title = null; + if (args.size() == 3) { + title = args.get(2); + } + + // Get NotificationManager. + String ns = Context.NOTIFICATION_SERVICE; + NotificationManager mNotificationManager = (NotificationManager)context.getSystemService(ns); + + // Create a Notficiation. + int icon = R.drawable.sync_ic_launcher; + String notificationTitle = context.getString(R.string.sync_new_tab); + if (title != null) { + notificationTitle = notificationTitle.concat(": " + title); + } + long when = System.currentTimeMillis(); + Notification notification = new Notification(icon, notificationTitle, when); + notification.flags = Notification.FLAG_AUTO_CANCEL; + + // Set pending intent associated with the notification. + Intent notificationIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri)); + PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0); + notification.setLatestEventInfo(context, notificationTitle, uri, contentIntent); + + // Send notification. + mNotificationManager.notify(currentId.getAndIncrement(), notification); + } } diff --git a/mobile/android/base/sync/GlobalSession.java b/mobile/android/base/sync/GlobalSession.java index 4d193a3af4d..a1012094289 100644 --- a/mobile/android/base/sync/GlobalSession.java +++ b/mobile/android/base/sync/GlobalSession.java @@ -176,6 +176,13 @@ public class GlobalSession implements CredentialsSource, PrefsSource, HttpRespon resetClient(null); } }); + + processor.registerCommand("displayURI", new CommandRunner() { + @Override + public void executeCommand(List args) { + CommandProcessor.getProcessor().displayURI(args, getContext()); + } + }); } protected void prepareStages() { diff --git a/mobile/android/base/sync/syncadapter/SyncAdapter.java b/mobile/android/base/sync/syncadapter/SyncAdapter.java index 538bfe7f94c..a1457f33879 100644 --- a/mobile/android/base/sync/syncadapter/SyncAdapter.java +++ b/mobile/android/base/sync/syncadapter/SyncAdapter.java @@ -7,16 +7,11 @@ package org.mozilla.gecko.sync.syncadapter; import java.io.IOException; import java.net.URI; import java.security.NoSuchAlgorithmException; -import java.util.List; import java.util.concurrent.TimeUnit; - import org.json.simple.parser.ParseException; import org.mozilla.gecko.sync.AlreadySyncingException; -import org.mozilla.gecko.sync.CommandRunner; -import org.mozilla.gecko.sync.CommandProcessor; import org.mozilla.gecko.sync.GlobalConstants; import org.mozilla.gecko.sync.GlobalSession; -import org.mozilla.gecko.sync.Logger; import org.mozilla.gecko.sync.NonObjectJSONException; import org.mozilla.gecko.sync.SyncConfiguration; import org.mozilla.gecko.sync.SyncConfigurationException; @@ -66,15 +61,6 @@ public class SyncAdapter extends AbstractThreadedSyncAdapter implements GlobalSe mContext = context; Log.d(LOG_TAG, "AccountManager.get(" + mContext + ")"); mAccountManager = AccountManager.get(context); - - // Register the displayURI command here so our SyncService - // can receive notifications to open a URI. - CommandProcessor.getProcessor().registerCommand("displayURI", new CommandRunner() { - @Override - public void executeCommand(List args) { - displayURI(args.get(0), args.get(1)); - } - }); } private SharedPreferences getGlobalPrefs() { @@ -493,9 +479,4 @@ public class SyncAdapter extends AbstractThreadedSyncAdapter implements GlobalSe public void informUnauthorizedResponse(GlobalSession session, URI oldClusterURL) { setClusterURLIsStale(true); } - - public void displayURI(String uri, String clientId) { - Logger.info(LOG_TAG, "Received a URI for display: " + uri + " from " + clientId); - // TODO: Bug 732147 - Send tab to device: receiving pushed tabs - } } diff --git a/mobile/android/sync/strings.xml.in b/mobile/android/sync/strings.xml.in index 17c04a93f91..72cb3ca6fc3 100644 --- a/mobile/android/sync/strings.xml.in +++ b/mobile/android/sync/strings.xml.in @@ -61,3 +61,5 @@ &sync.notification.oneaccount.label; + + &new_tab;