// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/browser/content_notification/model/content_notification_client.h"
#import "base/metrics/histogram_functions.h"
#import "ios/chrome/browser/content_notification/model/content_notification_nau_configuration.h"
#import "ios/chrome/browser/content_notification/model/content_notification_service.h"
#import "ios/chrome/browser/content_notification/model/content_notification_service_factory.h"
#import "ios/chrome/browser/push_notification/model/constants.h"
#import "ios/chrome/browser/push_notification/model/push_notification_client_id.h"
#import "ios/chrome/grit/ios_branded_strings.h"
#import "ios/chrome/grit/ios_strings.h"
#import "ui/base/l10n/l10n_util.h"
#import "url/gurl.h"
ContentNotificationClient::ContentNotificationClient()
: PushNotificationClient(PushNotificationClientId::kContent) {}
ContentNotificationClient::~ContentNotificationClient() = default;
void ContentNotificationClient::HandleNotificationInteraction(
UNNotificationResponse* response) {
// Need to check if it is a content notification first to avoid conflicts with
// other clients.
if (![response.notification.request.content.categoryIdentifier
isEqualToString:kContentNotificationFeedbackCategoryIdentifier]) {
return;
}
// In order to send delivered NAUs, the payload has been modified for it to be
// processed on `HandleNotificationReception()`. Before reusing the payload,
// remove the NAU body paramater from the payload to return it to its normal
// state.
NSMutableDictionary<NSString*, id>* unprocessedPayload =
[response.notification.request.content.userInfo mutableCopy];
if ([unprocessedPayload objectForKey:kContentNotificationNAUBodyParameter]) {
[unprocessedPayload
removeObjectForKey:kContentNotificationNAUBodyParameter];
}
// Regenerate the regular payload as NSDictionary after removing the extra
// object.
NSDictionary<NSString*, id>* payload = [unprocessedPayload copy];
ContentNotificationService* contentNotificationService =
ContentNotificationServiceFactory::GetForBrowserState(GetAnyProfile());
ContentNotificationNAUConfiguration* config =
[[ContentNotificationNAUConfiguration alloc] init];
config.notification = response.notification;
if ([response.actionIdentifier
isEqualToString:kContentNotificationFeedbackActionIdentifier]) {
config.actionType = NAUActionTypeFeedbackClicked;
base::UmaHistogramEnumeration(
kContentNotificationActionHistogramName,
NotificationActionType::kNotificationActionTypeFeedbackClicked);
NSDictionary<NSString*, NSString*>* feedbackPayload =
contentNotificationService->GetFeedbackPayload(payload);
LoadFeedbackWithPayloadAndClientId(feedbackPayload,
PushNotificationClientId::kContent);
} else if ([response.actionIdentifier
isEqualToString:UNNotificationDefaultActionIdentifier]) {
config.actionType = NAUActionTypeOpened;
base::UmaHistogramEnumeration(
kContentNotificationActionHistogramName,
NotificationActionType::kNotificationActionTypeOpened);
const GURL& url = contentNotificationService->GetDestinationUrl(payload);
if (url.is_empty()) {
base::UmaHistogramBoolean("ContentNotifications.OpenURLAction.HasURL",
false);
return;
}
base::UmaHistogramBoolean("ContentNotifications.OpenURLAction.HasURL",
true);
LoadUrlInNewTab(url);
} else if ([response.actionIdentifier
isEqualToString:UNNotificationDismissActionIdentifier]) {
base::UmaHistogramBoolean("ContentNotifications.DismissAction", true);
config.actionType = NAUActionTypeDismissed;
base::UmaHistogramEnumeration(
kContentNotificationActionHistogramName,
NotificationActionType::kNotificationActionTypeDismissed);
}
// TODO(crbug.com/337871560): Three way patch NAU and adding completion
// handler.
contentNotificationService->SendNAUForConfiguration(config);
}
// TODO(crbug.com/338875261): Add background refresh support.
// Delivered NAUs are currently being sent from the push_notification_delegate,
// and in the future they should be here once background refresh is available.
UIBackgroundFetchResult ContentNotificationClient::HandleNotificationReception(
NSDictionary<NSString*, id>* payload) {
return UIBackgroundFetchResultNoData;
}
NSArray<UNNotificationCategory*>*
ContentNotificationClient::RegisterActionableNotifications() {
UNNotificationAction* feedbackAction = [UNNotificationAction
actionWithIdentifier:kContentNotificationFeedbackActionIdentifier
title:l10n_util::GetNSString(
IDS_IOS_CONTENT_NOTIFICATIONS_SEND_FEEDBACK)
options:UNNotificationActionOptionForeground];
UNNotificationCategory* contentNotificationCategory = [UNNotificationCategory
categoryWithIdentifier:kContentNotificationFeedbackCategoryIdentifier
actions:@[ feedbackAction ]
intentIdentifiers:@[]
options:UNNotificationCategoryOptionCustomDismissAction];
return @[ contentNotificationCategory ];
}