diff options
author | peter <peter@chromium.org> | 2014-11-08 09:06:52 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2014-11-08 17:07:19 +0000 |
commit | 28dd519cf008574cc7e5dd5bf3b0984682e275af (patch) | |
tree | 3cd61e4aab3e173f5cb58e5fac72c2170dff4ed8 | |
parent | 1c62eeb1968b8da5bd44fac51a66949d67a999cc (diff) | |
download | chromium_src-28dd519cf008574cc7e5dd5bf3b0984682e275af.zip chromium_src-28dd519cf008574cc7e5dd5bf3b0984682e275af.tar.gz chromium_src-28dd519cf008574cc7e5dd5bf3b0984682e275af.tar.bz2 |
Be able to display very basic notifications on Android.
These are the very early beginnings of fully implementing the intended
Notification UX we have in mind.
BUG=90795
Review URL: https://codereview.chromium.org/696583003
Cr-Commit-Position: refs/heads/master@{#303389}
-rw-r--r-- | build/config/features.gni | 5 | ||||
-rw-r--r-- | chrome/android/java/src/org/chromium/chrome/browser/NotificationUIManager.java | 67 | ||||
-rw-r--r-- | chrome/browser/android/chrome_jni_registrar.cc | 3 | ||||
-rw-r--r-- | chrome/browser/notifications/notification_ui_manager_android.cc | 47 | ||||
-rw-r--r-- | chrome/browser/notifications/notification_ui_manager_android.h | 11 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 1 | ||||
-rw-r--r-- | ui/message_center/BUILD.gn | 6 |
7 files changed, 130 insertions, 10 deletions
diff --git a/build/config/features.gni b/build/config/features.gni index a395b40..5060d5e 100644 --- a/build/config/features.gni +++ b/build/config/features.gni @@ -77,9 +77,8 @@ enable_print_preview = !is_android use_seccomp_bpf = (is_linux || is_android) && (cpu_arch == "x86" || cpu_arch == "x64" || cpu_arch == "arm") -# Enable notifications everywhere except Android/iOS. -# Android is http://crbug.com/115320 -enable_notifications = !is_android && !is_ios +# Enable notifications everywhere except iOS. +enable_notifications = !is_ios # TODO(brettw) this should be moved to net and only dependents get this define. disable_ftp_support = is_ios diff --git a/chrome/android/java/src/org/chromium/chrome/browser/NotificationUIManager.java b/chrome/android/java/src/org/chromium/chrome/browser/NotificationUIManager.java new file mode 100644 index 0000000..f3bd971 --- /dev/null +++ b/chrome/android/java/src/org/chromium/chrome/browser/NotificationUIManager.java @@ -0,0 +1,67 @@ +// 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; + +import android.app.Notification; +import android.app.NotificationManager; +import android.content.Context; +import android.graphics.Bitmap; + +import org.chromium.base.CalledByNative; + +/** + * Provides the ability for the NotificationUIManagerAndroid to talk to the Android platform + * notification manager. + * + * This class should only be used on the UI thread. + */ +public class NotificationUIManager { + private final long mNativeNotificationManager; + + private final Context mAppContext; + private final NotificationManager mNotificationManager; + + private int mLastNotificationId; + + private NotificationUIManager(long nativeNotificationManager, Context context) { + mNativeNotificationManager = nativeNotificationManager; + mAppContext = context.getApplicationContext(); + + mNotificationManager = (NotificationManager) + mAppContext.getSystemService(Context.NOTIFICATION_SERVICE); + + mLastNotificationId = 0; + } + + /** + * Displays a notification with the given |title|, |body| and |icon|. + * + * @returns The id using which the notification can be identified. + */ + @CalledByNative + private int displayNotification(String title, String body, Bitmap icon) { + Notification notification = new Notification.Builder(mAppContext) + .setContentTitle(title) + .setContentText(body) + .setLargeIcon(icon) + .build(); + mNotificationManager.notify(mLastNotificationId, notification); + + return mLastNotificationId++; + } + + /** + * Closes the notification identified by |notificationId|. + */ + @CalledByNative + private void closeNotification(int notificationId) { + mNotificationManager.cancel(notificationId); + } + + @CalledByNative + private static NotificationUIManager create(long nativeNotificationManager, Context context) { + return new NotificationUIManager(nativeNotificationManager, context); + } +} diff --git a/chrome/browser/android/chrome_jni_registrar.cc b/chrome/browser/android/chrome_jni_registrar.cc index aabbb57..bcfcdec 100644 --- a/chrome/browser/android/chrome_jni_registrar.cc +++ b/chrome/browser/android/chrome_jni_registrar.cc @@ -49,6 +49,7 @@ #include "chrome/browser/invalidation/invalidation_service_factory_android.h" #include "chrome/browser/lifetime/application_lifetime_android.h" #include "chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.h" +#include "chrome/browser/notifications/notification_ui_manager_android.h" #include "chrome/browser/prerender/external_prerender_handler_android.h" #include "chrome/browser/profiles/profile_android.h" #include "chrome/browser/search_engines/template_url_service_android.h" @@ -169,6 +170,8 @@ static base::android::RegistrationMethod kChromeRegisteredMethods[] = { { "NavigationPopup", NavigationPopup::RegisterNavigationPopup }, { "NewTabPagePrefs", NewTabPagePrefs::RegisterNewTabPagePrefs }, + { "NotificationUIManager", + NotificationUIManagerAndroid::RegisterNotificationUIManager }, { "OmniboxPrerender", RegisterOmniboxPrerender }, { "OmniboxViewUtil", OmniboxViewUtil::RegisterOmniboxViewUtil }, { "PasswordGenerationPopup", diff --git a/chrome/browser/notifications/notification_ui_manager_android.cc b/chrome/browser/notifications/notification_ui_manager_android.cc index b440197..03f534d 100644 --- a/chrome/browser/notifications/notification_ui_manager_android.cc +++ b/chrome/browser/notifications/notification_ui_manager_android.cc @@ -4,9 +4,13 @@ #include "chrome/browser/notifications/notification_ui_manager_android.h" +#include "base/android/jni_string.h" #include "base/logging.h" #include "base/strings/string16.h" #include "chrome/browser/notifications/profile_notification.h" +#include "jni/NotificationUIManager_jni.h" +#include "ui/gfx/android/java_bitmap.h" +#include "ui/gfx/image/image.h" // static NotificationUIManager* NotificationUIManager::Create(PrefService* local_state) { @@ -14,6 +18,12 @@ NotificationUIManager* NotificationUIManager::Create(PrefService* local_state) { } NotificationUIManagerAndroid::NotificationUIManagerAndroid() { + JNIEnv* env = base::android::AttachCurrentThread(); + java_object_.Reset( + Java_NotificationUIManager_create( + env, + reinterpret_cast<intptr_t>(this), + base::android::GetApplicationContext())); } NotificationUIManagerAndroid::~NotificationUIManagerAndroid() { @@ -30,7 +40,21 @@ void NotificationUIManagerAndroid::Add(const Notification& notification, // Takes ownership of |profile_notification|. AddProfileNotification(profile_notification); - // TODO(peter): Display the notification on the Android system. + JNIEnv* env = base::android::AttachCurrentThread(); + + ScopedJavaLocalRef<jstring> title = base::android::ConvertUTF16ToJavaString( + env, notification.title()); + ScopedJavaLocalRef<jstring> body = base::android::ConvertUTF16ToJavaString( + env, notification.message()); + + SkBitmap icon_bitmap = notification.icon().AsBitmap(); + ScopedJavaLocalRef<jobject> icon = gfx::ConvertToJavaBitmap(&icon_bitmap); + + int platform_id = Java_NotificationUIManager_displayNotification( + env, java_object_.obj(), title.obj(), body.obj(), icon.obj()); + + std::string notification_id = profile_notification->notification().id(); + platform_notifications_[notification_id] = platform_id; } bool NotificationUIManagerAndroid::Update(const Notification& notification, @@ -152,9 +176,25 @@ void NotificationUIManagerAndroid::CancelAll() { profile_notifications_.clear(); } +bool NotificationUIManagerAndroid::RegisterNotificationUIManager(JNIEnv* env) { + return RegisterNativesImpl(env); +} + void NotificationUIManagerAndroid::PlatformCloseNotification( - ProfileNotification* notification) const { - // TODO(peter): Remove the notification from the Android system. + ProfileNotification* profile_notification) { + std::string id = profile_notification->notification().id(); + + auto iterator = platform_notifications_.find(id); + if (iterator == platform_notifications_.end()) + return; + + int platform_id = iterator->second; + platform_notifications_.erase(id); + + JNIEnv* env = base::android::AttachCurrentThread(); + Java_NotificationUIManager_closeNotification(env, + java_object_.obj(), + platform_id); } void NotificationUIManagerAndroid::AddProfileNotification( @@ -184,3 +224,4 @@ ProfileNotification* NotificationUIManagerAndroid::FindProfileNotification( return iter->second; } + diff --git a/chrome/browser/notifications/notification_ui_manager_android.h b/chrome/browser/notifications/notification_ui_manager_android.h index 7d37e24..6b853dd 100644 --- a/chrome/browser/notifications/notification_ui_manager_android.h +++ b/chrome/browser/notifications/notification_ui_manager_android.h @@ -5,10 +5,12 @@ #ifndef CHROME_BROWSER_NOTIFICATIONS_NOTIFICATION_UI_MANAGER_ANDROID_H_ #define CHROME_BROWSER_NOTIFICATIONS_NOTIFICATION_UI_MANAGER_ANDROID_H_ +#include <jni.h> #include <map> #include <set> #include <string> +#include "base/android/scoped_java_ref.h" #include "chrome/browser/notifications/notification_ui_manager.h" class ProfileNotification; @@ -35,9 +37,11 @@ class NotificationUIManagerAndroid : public NotificationUIManager { bool CancelAllByProfile(ProfileID profile_id) override; void CancelAll() override; + static bool RegisterNotificationUIManager(JNIEnv* env); + private: // Closes the Notification as displayed on the Android system. - void PlatformCloseNotification(ProfileNotification* notification) const; + void PlatformCloseNotification(ProfileNotification* profile_notification); // Helpers that add/remove the notification from local map. // The local map takes ownership of profile_notification object. @@ -51,6 +55,11 @@ class NotificationUIManagerAndroid : public NotificationUIManager { // Map from a notification id to the associated ProfileNotification*. std::map<std::string, ProfileNotification*> profile_notifications_; + // Map from notification id to the associated platform Id. + std::map<std::string, int> platform_notifications_; + + base::android::ScopedJavaGlobalRef<jobject> java_object_; + DISALLOW_COPY_AND_ASSIGN(NotificationUIManagerAndroid); }; diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 98ba522..5a72406 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -2766,6 +2766,7 @@ 'android/java/src/org/chromium/chrome/browser/JavascriptAppModalDialog.java', 'android/java/src/org/chromium/chrome/browser/NavigationPopup.java', 'android/java/src/org/chromium/chrome/browser/net/spdyproxy/DataReductionProxySettings.java', + 'android/java/src/org/chromium/chrome/browser/NotificationUIManager.java', 'android/java/src/org/chromium/chrome/browser/omnibox/AnswersImage.java', 'android/java/src/org/chromium/chrome/browser/omnibox/AutocompleteController.java', 'android/java/src/org/chromium/chrome/browser/omnibox/OmniboxPrerender.java', diff --git a/ui/message_center/BUILD.gn b/ui/message_center/BUILD.gn index 19f7ccd..31e9a89 100644 --- a/ui/message_center/BUILD.gn +++ b/ui/message_center/BUILD.gn @@ -24,7 +24,7 @@ component("message_center") { defines = [ "MESSAGE_CENTER_IMPLEMENTATION" ] - if (enable_notifications) { + if (enable_notifications && !is_android) { sources = [ "cocoa/notification_controller.h", "cocoa/notification_controller.mm", @@ -197,7 +197,7 @@ test("message_center_unittests") { "//url", ] - if (enable_notifications) { + if (enable_notifications && !is_android) { sources += [ "cocoa/notification_controller_unittest.mm", "cocoa/popup_collection_unittest.mm", @@ -232,5 +232,5 @@ test("message_center_unittests") { "//ui/views:test_support", ] } - } # enable_notifications + } # enable_notifications && !is_android } |