chromium/chrome/services/mac_notifications/public/mojom/mac_notifications.mojom

// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

module mac_notifications.mojom;

import "mojo/public/mojom/base/string16.mojom";
import "sandbox/policy/mojom/sandbox.mojom";
import "ui/gfx/image/mojom/image.mojom";
import "url/mojom/url.mojom";

// Represents a profile being used to display notifications. A profile with a
// given |id| might have another child profile with the same |id| but with
// incognito set to true. This tuple uniquely identifies a profile.
struct ProfileIdentifier {
  // Identifies a profile. Usually the name of a profile but should be treated
  // as an opaque string.
  string id;
  // Whether this profile is the incognito profile for |id|.
  bool incognito;
};

// Represents a unique identifier for a notification. Notifications might have
// the same |id| if they belong to different |profile|s but the tuple of both
// uniquely identifies a notification.
struct NotificationIdentifier {
  // Notification id that might contain some developer controlled parts. Should
  // always be treated as an opaque string.
  string id;
  // Profile for which this notification is being shown for.
  ProfileIdentifier profile;
};

// Metadata about a notification. This data is passed into the helper process
// when displaying a new notifications and returned back to the browser process
// when the user takes an action on that notification.
struct NotificationMetadata {
  // Unique notification identifier.
  NotificationIdentifier id;
  // Notification type as defined in NotificationHandler::Type. We're treating
  // this as an opaque integer as we don't care about its value in the helper
  // process but simply want to pass it back to the browser process.
  int32 type;
  // The origin URL of the script which requested the notification. Can be empty
  // if requested through a chrome app or extension or if it's a system
  // notification.
  url.mojom.Url origin_url;
  // The user data dir for the browser process that created this
  // notification. We use this to make sure we handle notification events in the
  // correct browser instance as multiple may run with different user data dirs.
  string user_data_dir;
};

// The operation taken on a notification.
enum NotificationOperation {
  // The user clicked on the notification body or a user action button. The
  // |button_index| of NotificationActionInfo distinguishes between those two.
  kClick,
  // The user closed the notification. Note that this signal may not be reliable
  // and there are cases when a notification gets closed without this event
  // firing (e.g. via the Close All button in the notification center).
  kClose,
  // The user clicked on the settings buttons of a notification.
  kSettings,
};

// Represents a notification and the action taken on it by the user.
struct NotificationActionInfo {
  // Metadata about this notification as passed in via DisplayNotification().
  NotificationMetadata meta;
  // The operation taken on this notification.
  NotificationOperation operation;
  // The clicked user button index or -1 if it's a different action.
  int32 button_index;
  // Contains the text reply for inline reply actions if available.
  mojo_base.mojom.String16? reply;
};

// Represents a notification action button to be shown to the user.
struct NotificationActionButton {
  // The title of this action button.
  mojo_base.mojom.String16 title;
  // The placeholder value for inline reply action buttons if set.
  mojo_base.mojom.String16? placeholder;
};

// Represents a notification to be shown to the user via the helper app.
struct Notification {
  // Metadata about this notification.
  NotificationMetadata meta;
  // The title of this notification shown as the first row.
  mojo_base.mojom.String16 title;
  // The subtitle of this notification shown as the second row. Typically shows
  // the origin of the notification.
  mojo_base.mojom.String16 subtitle;
  // The body of this notification shown as the third and final row.
  mojo_base.mojom.String16 body;
  // If true we should close and show the notification again if one with the
  // same identifier already exists. Otherwise just update its content.
  bool renotify;
  // Whether this notification should show a settings button to the user.
  bool show_settings_button;
  // Additional action buttons to be shown to the user.
  array<NotificationActionButton> buttons;
  // An optional icon shown on the right hand side of the notification.
  gfx.mojom.ImageSkia? icon;
};

// This enum is used in UMA. Do not delete or re-order entries. New entries
// should only be added at the end.
enum RequestPermissionResult {
  kRequestFailed = 0,
  kPermissionDenied = 1,
  kPermissionGranted = 2,
  kPermissionPreviouslyDenied = 3,
  kPermissionPreviouslyGranted = 4,
};

// This enum is persisted to disk. Do not delete or re-order entries. New
// entries should only be added at the end.
enum PermissionStatus {
  // A permission prompt has never been shown for this application.
  kNotDetermined = 1,
  // A permission prompt is currently showing.
  kPromptPending = 2,
  // A permission prompt has been denied, or the application quit with a pending
  // permission prompt.
  kDenied = 3,
  // A permission prompt has been accepted.
  kGranted = 4,
};

// Interface to control notifications shown by the helper app. Implemented by
// the helper app and called from the browser process.
interface MacNotificationService {
  // Display the |notification| via the system notification center.
  DisplayNotification(Notification notification);

  // Gets a list of notification ids that are currently shown in the system
  // notification center. If a `profile` is passed, the list is filtered to only
  // include notification ids for that profile. Otherwise this will return all
  // displayed notification ids for all profiles. If an `origin` is passed, the
  // list is also filtered to only include notifications for that origin.
  GetDisplayedNotifications(
      ProfileIdentifier? profile, url.mojom.Url? origin)
      => (array<NotificationIdentifier> notifications);

  // Closes the notification identified by |identifier|.
  CloseNotification(NotificationIdentifier identifier);

  // Closes all notifications shown for |profile|.
  CloseNotificationsForProfile(ProfileIdentifier profile);

  // Closes all notifications shown by the helper app in the system notification
  // center for all profiles.
  CloseAllNotifications();

  // Checks if it is okay to terminate this service. Returns false if for
  // example there are still displayed notifications, or if terminating the
  // service would interrupt/abort any pending permission requests.
  OkayToTerminateService() => (bool can_terminate);
};

// Handles notification actions such as click or close. Implemented in the
// browser process and called from the helper app.
interface MacNotificationActionHandler {
  // Called when there has been an action on a notification. An example is a
  // user clicking on a notification or when a notification got closed.
  OnNotificationAction(NotificationActionInfo info);
};

// Main entrypoint for the system notification service. Implemented in a helper
// app so we can set a custom alert style different from the main app. This
// allows us to show both banner and alert style notifications on macOS.
[ServiceSandbox=sandbox.mojom.Sandbox.kNoSandbox]
interface MacNotificationProvider {
  // Called from the browser process to connect to the helper app. Further calls
  // are made on the |service| interface and actions will be handled by the
  // passed |handler|.
  BindNotificationService(
      pending_receiver<MacNotificationService> service,
      pending_remote<MacNotificationActionHandler> handler);
};