forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Android] Adding content settings provider for notification channels
- Right now it just attempts to create channels on grant, and delete them on resetting the permission. - Java side is not yet implemented so this is actually a no-op. BUG=700377 Review-Url: https://codereview.chromium.org/2886433002 Cr-Commit-Position: refs/heads/master@{#478267}
- Loading branch information
awdf
authored and
Commit Bot
committed
Jun 9, 2017
1 parent
b706bcf
commit 338aa5e
Showing
14 changed files
with
433 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
44 changes: 44 additions & 0 deletions
44
...ndroid/java/src/org/chromium/chrome/browser/notifications/NotificationSettingsBridge.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
// Copyright 2017 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 org.chromium.base.BuildInfo; | ||
import org.chromium.base.annotations.CalledByNative; | ||
|
||
/** | ||
* Interface for native code to interact with Android notification channels. | ||
*/ | ||
public class NotificationSettingsBridge { | ||
// TODO(awdf): Remove this and check BuildInfo.sdk_int() from native instead, once SdkVersion | ||
// enum includes Android O. | ||
@CalledByNative | ||
static boolean shouldUseChannelSettings() { | ||
return BuildInfo.isAtLeastO(); | ||
} | ||
|
||
/** | ||
* Creates a notification channel for the given origin. | ||
* @param origin The site origin to be used as the channel name. | ||
* @param enabled True if the channel should be initially enabled, false if | ||
* it should start off as blocked. | ||
* @return true if the channel was successfully created, false otherwise. | ||
*/ | ||
@CalledByNative | ||
static boolean createChannel(String origin, boolean enabled) { | ||
// TODO(crbug.com/700377) Actually construct a channel. | ||
return false; | ||
} | ||
|
||
@CalledByNative | ||
static @NotificationChannelStatus int getChannelStatus(String origin) { | ||
// TODO(crbug.com/700377) Actually check channel status. | ||
return NotificationChannelStatus.UNAVAILABLE; | ||
} | ||
|
||
@CalledByNative | ||
static void deleteChannel(String origin) { | ||
// TODO(crbug.com/700377) Actually delete channel. | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
147 changes: 147 additions & 0 deletions
147
chrome/browser/notifications/notification_channels_provider_android.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
// Copyright 2017 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. | ||
|
||
#include "chrome/browser/notifications/notification_channels_provider_android.h" | ||
|
||
#include "base/android/jni_android.h" | ||
#include "base/android/jni_string.h" | ||
#include "base/logging.h" | ||
#include "base/strings/string_util.h" | ||
#include "chrome/browser/content_settings/host_content_settings_map_factory.h" | ||
#include "chrome/browser/profiles/profile.h" | ||
#include "components/content_settings/core/browser/content_settings_details.h" | ||
#include "components/content_settings/core/browser/content_settings_utils.h" | ||
#include "components/content_settings/core/browser/host_content_settings_map.h" | ||
#include "components/content_settings/core/common/content_settings.h" | ||
#include "components/content_settings/core/common/content_settings_pattern.h" | ||
#include "jni/NotificationSettingsBridge_jni.h" | ||
#include "url/gurl.h" | ||
#include "url/origin.h" | ||
#include "url/url_constants.h" | ||
|
||
using base::android::AttachCurrentThread; | ||
using base::android::ConvertUTF8ToJavaString; | ||
using base::android::ScopedJavaLocalRef; | ||
|
||
namespace { | ||
|
||
class NotificationChannelsBridgeImpl | ||
: public NotificationChannelsProviderAndroid::NotificationChannelsBridge { | ||
public: | ||
NotificationChannelsBridgeImpl() = default; | ||
~NotificationChannelsBridgeImpl() override = default; | ||
|
||
bool ShouldUseChannelSettings() override { | ||
return Java_NotificationSettingsBridge_shouldUseChannelSettings( | ||
AttachCurrentThread()); | ||
} | ||
|
||
void CreateChannel(const std::string& origin, bool enabled) override { | ||
JNIEnv* env = AttachCurrentThread(); | ||
Java_NotificationSettingsBridge_createChannel( | ||
env, ConvertUTF8ToJavaString(env, origin), enabled); | ||
} | ||
|
||
NotificationChannelStatus GetChannelStatus( | ||
const std::string& origin) override { | ||
JNIEnv* env = AttachCurrentThread(); | ||
return static_cast<NotificationChannelStatus>( | ||
Java_NotificationSettingsBridge_getChannelStatus( | ||
env, ConvertUTF8ToJavaString(env, origin))); | ||
} | ||
|
||
void DeleteChannel(const std::string& origin) override { | ||
JNIEnv* env = AttachCurrentThread(); | ||
Java_NotificationSettingsBridge_deleteChannel( | ||
env, ConvertUTF8ToJavaString(env, origin)); | ||
} | ||
}; | ||
|
||
} // anonymous namespace | ||
|
||
NotificationChannelsProviderAndroid::NotificationChannelsProviderAndroid() | ||
: NotificationChannelsProviderAndroid( | ||
base::MakeUnique<NotificationChannelsBridgeImpl>()) {} | ||
|
||
NotificationChannelsProviderAndroid::NotificationChannelsProviderAndroid( | ||
std::unique_ptr<NotificationChannelsBridge> bridge) | ||
: bridge_(std::move(bridge)), | ||
should_use_channels_(bridge_->ShouldUseChannelSettings()) {} | ||
|
||
NotificationChannelsProviderAndroid::~NotificationChannelsProviderAndroid() = | ||
default; | ||
|
||
std::unique_ptr<content_settings::RuleIterator> | ||
NotificationChannelsProviderAndroid::GetRuleIterator( | ||
ContentSettingsType content_type, | ||
const content_settings::ResourceIdentifier& resource_identifier, | ||
bool incognito) const { | ||
// TODO(crbug.com/700377) return rule iterator over all channels | ||
return nullptr; | ||
} | ||
|
||
bool NotificationChannelsProviderAndroid::SetWebsiteSetting( | ||
const ContentSettingsPattern& primary_pattern, | ||
const ContentSettingsPattern& secondary_pattern, | ||
ContentSettingsType content_type, | ||
const content_settings::ResourceIdentifier& resource_identifier, | ||
base::Value* value) { | ||
if (content_type != CONTENT_SETTINGS_TYPE_NOTIFICATIONS || | ||
!should_use_channels_) { | ||
return false; | ||
} | ||
// This provider only handles settings for specific origins. | ||
if (primary_pattern == ContentSettingsPattern::Wildcard() && | ||
secondary_pattern == ContentSettingsPattern::Wildcard() && | ||
resource_identifier.empty()) { | ||
return false; | ||
} | ||
url::Origin origin = url::Origin(GURL(primary_pattern.ToString())); | ||
DCHECK(!origin.unique()); | ||
const std::string origin_string = origin.Serialize(); | ||
ContentSetting setting = content_settings::ValueToContentSetting(value); | ||
switch (setting) { | ||
case CONTENT_SETTING_ALLOW: | ||
CreateChannelIfRequired(origin_string, | ||
NotificationChannelStatus::ENABLED); | ||
break; | ||
case CONTENT_SETTING_BLOCK: | ||
CreateChannelIfRequired(origin_string, | ||
NotificationChannelStatus::BLOCKED); | ||
break; | ||
case CONTENT_SETTING_DEFAULT: | ||
bridge_->DeleteChannel(origin_string); | ||
break; | ||
default: | ||
// We rely on notification settings being one of ALLOW/BLOCK/DEFAULT. | ||
NOTREACHED(); | ||
break; | ||
} | ||
return true; | ||
} | ||
|
||
void NotificationChannelsProviderAndroid::ClearAllContentSettingsRules( | ||
ContentSettingsType content_type) { | ||
// TODO(crbug.com/700377): If |content_type| == NOTIFICATIONS, delete | ||
// all channels. | ||
} | ||
|
||
void NotificationChannelsProviderAndroid::ShutdownOnUIThread() { | ||
RemoveAllObservers(); | ||
} | ||
|
||
void NotificationChannelsProviderAndroid::CreateChannelIfRequired( | ||
const std::string& origin_string, | ||
NotificationChannelStatus new_channel_status) { | ||
auto old_channel_status = bridge_->GetChannelStatus(origin_string); | ||
if (old_channel_status == NotificationChannelStatus::UNAVAILABLE) { | ||
bridge_->CreateChannel( | ||
origin_string, | ||
new_channel_status == NotificationChannelStatus::ENABLED); | ||
} else { | ||
// TODO(awdf): Maybe remove this DCHECK - channel status could change any | ||
// time so this may be vulnerable to a race condition. | ||
DCHECK(old_channel_status == new_channel_status); | ||
} | ||
} |
75 changes: 75 additions & 0 deletions
75
chrome/browser/notifications/notification_channels_provider_android.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
// Copyright 2017 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. | ||
|
||
#ifndef CHROME_BROWSER_NOTIFICATIONS_NOTIFICATION_CHANNELS_PROVIDER_ANDROID_H_ | ||
#define CHROME_BROWSER_NOTIFICATIONS_NOTIFICATION_CHANNELS_PROVIDER_ANDROID_H_ | ||
|
||
#include <string> | ||
|
||
#include "base/macros.h" | ||
#include "components/content_settings/core/browser/content_settings_observable_provider.h" | ||
#include "components/content_settings/core/browser/content_settings_observer.h" | ||
#include "components/content_settings/core/browser/content_settings_rule.h" | ||
#include "components/content_settings/core/common/content_settings.h" | ||
#include "components/content_settings/core/common/content_settings_types.h" | ||
#include "components/keyed_service/core/keyed_service.h" | ||
|
||
namespace { | ||
|
||
// A Java counterpart will be generated for this enum. | ||
// GENERATED_JAVA_ENUM_PACKAGE: org.chromium.chrome.browser.notifications | ||
enum NotificationChannelStatus { ENABLED, BLOCKED, UNAVAILABLE }; | ||
|
||
} // anonymous namespace | ||
|
||
// This class provides notification content settings from system notification | ||
// channels on Android O+. This provider takes precedence over pref-provided | ||
// content settings, but defers to supervised user and policy settings - see | ||
// ordering of the ProviderType enum values in HostContentSettingsMap. | ||
class NotificationChannelsProviderAndroid | ||
: public content_settings::ObservableProvider { | ||
public: | ||
// Helper class to make the JNI calls. | ||
class NotificationChannelsBridge { | ||
public: | ||
virtual ~NotificationChannelsBridge() = default; | ||
virtual bool ShouldUseChannelSettings() = 0; | ||
virtual void CreateChannel(const std::string& origin, bool enabled) = 0; | ||
virtual NotificationChannelStatus GetChannelStatus( | ||
const std::string& origin) = 0; | ||
virtual void DeleteChannel(const std::string& origin) = 0; | ||
}; | ||
|
||
NotificationChannelsProviderAndroid(); | ||
~NotificationChannelsProviderAndroid() override; | ||
|
||
// ProviderInterface methods: | ||
std::unique_ptr<content_settings::RuleIterator> GetRuleIterator( | ||
ContentSettingsType content_type, | ||
const content_settings::ResourceIdentifier& resource_identifier, | ||
bool incognito) const override; | ||
bool SetWebsiteSetting( | ||
const ContentSettingsPattern& primary_pattern, | ||
const ContentSettingsPattern& secondary_pattern, | ||
ContentSettingsType content_type, | ||
const content_settings::ResourceIdentifier& resource_identifier, | ||
base::Value* value) override; | ||
void ClearAllContentSettingsRules(ContentSettingsType content_type) override; | ||
void ShutdownOnUIThread() override; | ||
|
||
private: | ||
explicit NotificationChannelsProviderAndroid( | ||
std::unique_ptr<NotificationChannelsBridge> bridge); | ||
friend class NotificationChannelsProviderAndroidTest; | ||
|
||
void CreateChannelIfRequired(const std::string& origin_string, | ||
NotificationChannelStatus new_channel_status); | ||
|
||
std::unique_ptr<NotificationChannelsBridge> bridge_; | ||
bool should_use_channels_; | ||
|
||
DISALLOW_COPY_AND_ASSIGN(NotificationChannelsProviderAndroid); | ||
}; | ||
|
||
#endif // CHROME_BROWSER_NOTIFICATIONS_NOTIFICATION_CHANNELS_PROVIDER_ANDROID_H_ |
Oops, something went wrong.