// Copyright 2014 The Chromium 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 org.chromium.chrome.browser.notifications; import android.app.IntentService; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.util.Log; import org.chromium.base.ThreadUtils; import org.chromium.base.annotations.SuppressFBWarnings; import org.chromium.base.library_loader.ProcessInitException; import org.chromium.chrome.browser.init.ChromeBrowserInitializer; /** * The Notification service receives intents fired as responses to user actions issued on Android * notifications displayed in the notification tray. */ public class NotificationService extends IntentService { private static final String TAG = NotificationService.class.getSimpleName(); /** * The class which receives the intents from the Android framework. It initializes the * Notification service, and forward the intents there. Declared public as it needs to be * initialized by the Android framework. */ public static class Receiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Log.i(TAG, "Received a notification intent in the NotificationService's receiver."); // TODO(peter): Do we need to acquire a wake lock here? intent.setClass(context, NotificationService.class); context.startService(intent); } } public NotificationService() { super(TAG); } /** * Called when a Notification has been interacted with by the user. If we can verify that * the Intent has a notification Id, start Chrome (if needed) on the UI thread. * * @param intent The intent containing the specific information. */ @Override public void onHandleIntent(final Intent intent) { if (!intent.hasExtra(NotificationConstants.EXTRA_NOTIFICATION_ID) || !intent.hasExtra(NotificationConstants.EXTRA_NOTIFICATION_INFO_ORIGIN) || !intent.hasExtra(NotificationConstants.EXTRA_NOTIFICATION_INFO_TAG)) { return; } ThreadUtils.runOnUiThread(new Runnable() { @Override public void run() { dispatchIntentOnUIThread(intent); } }); } /** * Initializes Chrome and starts the browser process if it's not running as of yet, and * dispatch |intent| to the NotificationPlatformBridge once this is done. * * @param intent The intent containing the notification's information. */ @SuppressFBWarnings("DM_EXIT") private void dispatchIntentOnUIThread(Intent intent) { try { ChromeBrowserInitializer.getInstance(this).handleSynchronousStartup(); // Now that the browser process is initialized, we pass forward the call to the // NotificationPlatformBridge which will take care of delivering the appropriate events. if (!NotificationPlatformBridge.dispatchNotificationEvent(intent)) { Log.w(TAG, "Unable to dispatch the notification event to Chrome."); } // TODO(peter): Verify that the lifetime of the NotificationService is sufficient // when a notification event could be dispatched successfully. } catch (ProcessInitException e) { Log.e(TAG, "Unable to start the browser process.", e); System.exit(-1); } } }