910e62b5创建于 1月15日历史提交
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_UI_PROMOS_IOS_PROMO_TRIGGER_SERVICE_H_
#define CHROME_BROWSER_UI_PROMOS_IOS_PROMO_TRIGGER_SERVICE_H_

#include "base/callback_list.h"
#include "components/desktop_to_mobile_promos/promos_types.h"
#include "components/keyed_service/core/keyed_service.h"

class Profile;

namespace syncer {
class DeviceInfo;
}  // namespace syncer

// Service that acts as a communication bridge between different UI components
// to manage and trigger iOS promos.
class IOSPromoTriggerService : public KeyedService {
 public:
  using PromoCallback =
      base::RepeatingCallback<void(desktop_to_mobile_promos::PromoType)>;

  explicit IOSPromoTriggerService(Profile* profile);
  ~IOSPromoTriggerService() override;

  IOSPromoTriggerService(const IOSPromoTriggerService&) = delete;
  IOSPromoTriggerService& operator=(const IOSPromoTriggerService&) = delete;

  // Notifies observers that a promo should be shown.
  // TODO(crbug.com/446944658): The NotifyPromoShouldBeShown API is a temporary
  // solution for triggering promos. The long-term plan is to migrate the
  // presentation logic to the Browser User Education system. Once that is
  // complete, it can be removed.
  virtual void NotifyPromoShouldBeShown(
      desktop_to_mobile_promos::PromoType promo_type);

  // Returns a synced iOS device to show a reminder on. This method prioritizes
  // the most recently active iPhone. If no iPhone is found, it falls back to
  // the most recently active iPad. If no iOS devices are found, it returns
  // nullptr.
  virtual const syncer::DeviceInfo* GetIOSDeviceToRemind();

  // Sets a preference to show a reminder for `promo_type` on a synced iOS
  // device with guid `device_guid`.
  virtual void SetReminderForIOSDevice(
      desktop_to_mobile_promos::PromoType promo_type,
      const std::string& device_guid);

  // Registers a callback to be notified when a promo should be shown.
  [[nodiscard]] base::CallbackListSubscription RegisterPromoCallback(
      PromoCallback callback);

 private:
  // Returns true if `current_preference` is a more preferred device than
  // `another_device`. Prioritizes iPhones over iPads, and more recently
  // updated devices if form factors are the same.
  bool IsMorePreferredDevice(const syncer::DeviceInfo* current_preference,
                             const syncer::DeviceInfo* another_device);

  base::RepeatingCallbackList<void(desktop_to_mobile_promos::PromoType)>
      callback_list_;
  raw_ptr<Profile> profile_;
};

#endif  // CHROME_BROWSER_UI_PROMOS_IOS_PROMO_TRIGGER_SERVICE_H_