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

#include "extensions/browser/api/device_permissions_manager.h"

#include <stddef.h>

#include <optional>
#include <utility>

#include "base/functional/bind.h"
#include "base/memory/scoped_refptr.h"
#include "base/no_destructor.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
#include "content/public/browser/browser_thread.h"
#include "extensions/browser/api/hid/hid_device_manager.h"
#include "extensions/browser/api/usb/usb_device_manager.h"
#include "extensions/browser/extension_host.h"
#include "extensions/browser/extension_prefs.h"
#include "extensions/browser/extensions_browser_client.h"
#include "extensions/common/extension_id.h"
#include "extensions/common/permissions/api_permission.h"
#include "extensions/strings/grit/extensions_strings.h"
#include "services/device/public/cpp/usb/usb_ids.h"
#include "ui/base/l10n/l10n_util.h"

namespace extensions {

using content::BrowserContext;
using content::BrowserThread;
using extensions::APIPermission;
using extensions::Extension;
using extensions::ExtensionHost;
using extensions::ExtensionPrefs;

namespace {

// Preference keys

// The device that the app has permission to access.
const char kDevices[] = "devices";

// The type of device saved.
const char kDeviceType[] = "type";

// Type identifier for USB devices.
const char kDeviceTypeUsb[] = "usb";

// Type identifier for HID devices.
const char kDeviceTypeHid[] = "hid";

// The vendor ID of the device that the app had permission to access.
const char kDeviceVendorId[] = "vendor_id";

// The product ID of the device that the app had permission to access.
const char kDeviceProductId[] = "product_id";

// The serial number of the device that the app has permission to access.
const char kDeviceSerialNumber[] = "serial_number";

// The manufacturer string read from the device that the app has permission to
// access.
const char kDeviceManufacturerString[] = "manufacturer_string";

// The product string read from the device that the app has permission to
// access.
const char kDeviceProductString[] = "product_string";

// Serialized timestamp of the last time when the device was opened by the app.
const char kDeviceLastUsed[] = "last_used_time";

// Converts a DevicePermissionEntry::Type to a string for the prefs file.
const char* TypeToString(DevicePermissionEntry::Type type) {
  switch (type) {
    case DevicePermissionEntry::Type::USB:
      return kDeviceTypeUsb;
    case DevicePermissionEntry::Type::HID:
      return kDeviceTypeHid;
  }
  NOTREACHED();
}

// Persists a DevicePermissionEntry in ExtensionPrefs.
void SaveDevicePermissionEntry(BrowserContext* context,
                               const ExtensionId& extension_id,
                               scoped_refptr<DevicePermissionEntry> entry) {
  ExtensionPrefs* prefs = ExtensionPrefs::Get(context);
  ExtensionPrefs::ScopedListUpdate update(prefs, extension_id, kDevices);
  base::ListValue* devices = update.Ensure();

  base::DictValue device_entry(entry->ToValue());
  DCHECK(!devices->contains(device_entry));
  devices->Append(std::move(device_entry));
}

bool MatchesDevicePermissionEntry(const base::DictValue& value,
                                  scoped_refptr<DevicePermissionEntry> entry) {
  const std::string* type = value.FindString(kDeviceType);
  if (!type || *type != TypeToString(entry->type())) {
    return false;
  }
  std::optional<int> vendor_id = value.FindInt(kDeviceVendorId);
  if (!vendor_id || vendor_id.value() != entry->vendor_id()) {
    return false;
  }
  std::optional<int> product_id = value.FindInt(kDeviceProductId);
  if (!product_id || product_id.value() != entry->product_id()) {
    return false;
  }
  const std::string* serial_number = value.FindString(kDeviceSerialNumber);
  if (!serial_number ||
      base::UTF8ToUTF16(*serial_number) != entry->serial_number()) {
    return false;
  }
  return true;
}

// Updates the timestamp stored in ExtensionPrefs for the given
// DevicePermissionEntry.
void UpdateDevicePermissionEntry(BrowserContext* context,
                                 const ExtensionId& extension_id,
                                 scoped_refptr<DevicePermissionEntry> entry) {
  ExtensionPrefs* prefs = ExtensionPrefs::Get(context);
  ExtensionPrefs::ScopedListUpdate update(prefs, extension_id, kDevices);
  base::ListValue* devices = update.Ensure();

  for (auto& value : *devices) {
    if (!value.is_dict())
      continue;
    if (!MatchesDevicePermissionEntry(value.GetDict(), entry)) {
      continue;
    }

    value = base::Value(entry->ToValue());
    break;
  }
}

// Removes the given DevicePermissionEntry from ExtensionPrefs.
void RemoveDevicePermissionEntry(BrowserContext* context,
                                 const ExtensionId& extension_id,
                                 scoped_refptr<DevicePermissionEntry> entry) {
  ExtensionPrefs* prefs = ExtensionPrefs::Get(context);
  ExtensionPrefs::ScopedListUpdate update(prefs, extension_id, kDevices);
  base::ListValue* devices = update.Get();
  if (!devices) {
    return;
  }

  for (auto it = devices->begin(); it != devices->end(); ++it) {
    if (!it->is_dict())
      continue;
    if (!MatchesDevicePermissionEntry(it->GetDict(), entry)) {
      continue;
    }
    devices->erase(it);
    break;
  }
}

// Clears all DevicePermissionEntries for the app from ExtensionPrefs.
void ClearDevicePermissionEntries(ExtensionPrefs* prefs,
                                  const ExtensionId& extension_id) {
  prefs->UpdateExtensionPref(extension_id, kDevices, std::nullopt);
}

scoped_refptr<DevicePermissionEntry> ReadDevicePermissionEntry(
    const base::DictValue& entry) {
  std::optional<int> vendor_id = entry.FindInt(kDeviceVendorId);
  if (!vendor_id || vendor_id.value() < 0 ||
      vendor_id.value() > static_cast<int>(UINT16_MAX)) {
    return nullptr;
  }

  std::optional<int> product_id = entry.FindInt(kDeviceProductId);
  if (!product_id || product_id.value() < 0 ||
      product_id.value() > static_cast<int>(UINT16_MAX)) {
    return nullptr;
  }

  const std::string* serial_number_ptr = entry.FindString(kDeviceSerialNumber);
  if (!serial_number_ptr)
    return nullptr;
  std::u16string serial_number = base::UTF8ToUTF16(*serial_number_ptr);
  std::u16string manufacturer_string;
  // Ignore failure as this string is optional.
  const std::string* manufacturer_ptr =
      entry.FindString(kDeviceManufacturerString);
  if (manufacturer_ptr) {
    manufacturer_string = base::UTF8ToUTF16(*manufacturer_ptr);
  }

  std::u16string product_string;
  // Ignore failure as this string is optional.
  const std::string* product_ptr = entry.FindString(kDeviceProductString);
  if (product_ptr) {
    product_string = base::UTF8ToUTF16(*product_ptr);
  }

  // If a last used time is not stored in ExtensionPrefs last_used.is_null()
  // will be true.
  const std::string* last_used_ptr = entry.FindString(kDeviceLastUsed);
  int64_t last_used_i64 = 0;
  base::Time last_used;
  if (last_used_ptr && base::StringToInt64(*last_used_ptr, &last_used_i64)) {
    last_used = base::Time::FromInternalValue(last_used_i64);
  }

  const std::string* device_type_ptr = entry.FindString(kDeviceType);
  if (!device_type_ptr)
    return nullptr;

  if (*device_type_ptr == kDeviceTypeUsb) {
    return base::MakeRefCounted<DevicePermissionEntry>(
        DevicePermissionEntry::Type::USB, vendor_id.value(), product_id.value(),
        serial_number, manufacturer_string, product_string, last_used);
  } else if (*device_type_ptr == kDeviceTypeHid) {
    return base::MakeRefCounted<DevicePermissionEntry>(
        DevicePermissionEntry::Type::HID, vendor_id.value(), product_id.value(),
        serial_number, std::u16string(), product_string, last_used);
  }
  return nullptr;
}

// Returns all DevicePermissionEntries for the app.
std::set<scoped_refptr<DevicePermissionEntry>> GetDevicePermissionEntries(
    ExtensionPrefs* prefs,
    const ExtensionId& extension_id) {
  std::set<scoped_refptr<DevicePermissionEntry>> result;
  const base::ListValue* devices =
      prefs->ReadPrefAsList(extension_id, kDevices);
  if (!devices) {
    return result;
  }

  for (const auto& entry : *devices) {
    if (entry.is_dict()) {
      scoped_refptr<DevicePermissionEntry> device_entry =
          ReadDevicePermissionEntry(entry.GetDict());
      result.insert(device_entry);
    }
  }
  return result;
}

}  // namespace

DevicePermissionEntry::DevicePermissionEntry(
    const device::mojom::UsbDeviceInfo& device)
    : device_guid_(device.guid),
      type_(Type::USB),
      vendor_id_(device.vendor_id),
      product_id_(device.product_id) {
  if (device.serial_number)
    serial_number_ = *device.serial_number;

  if (device.manufacturer_name)
    manufacturer_string_ = *device.manufacturer_name;

  if (device.product_name)
    product_string_ = *device.product_name;
}

DevicePermissionEntry::DevicePermissionEntry(
    const device::mojom::HidDeviceInfo& device)
    : device_guid_(device.guid),
      type_(Type::HID),
      vendor_id_(device.vendor_id),
      product_id_(device.product_id),
      serial_number_(base::UTF8ToUTF16(device.serial_number)),
      product_string_(base::UTF8ToUTF16(device.product_name)) {}

DevicePermissionEntry::DevicePermissionEntry(
    Type type,
    uint16_t vendor_id,
    uint16_t product_id,
    const std::u16string& serial_number,
    const std::u16string& manufacturer_string,
    const std::u16string& product_string,
    const base::Time& last_used)
    : type_(type),
      vendor_id_(vendor_id),
      product_id_(product_id),
      serial_number_(serial_number),
      manufacturer_string_(manufacturer_string),
      product_string_(product_string),
      last_used_(last_used) {}

DevicePermissionEntry::~DevicePermissionEntry() {
}

bool DevicePermissionEntry::IsPersistent() const {
  return !serial_number_.empty();
}

base::DictValue DevicePermissionEntry::ToValue() const {
  if (!IsPersistent()) {
    return base::DictValue();
  }

  DCHECK(!serial_number_.empty());
  base::DictValue entry_dict;
  entry_dict.Set(kDeviceType, TypeToString(type_));
  entry_dict.Set(kDeviceVendorId, vendor_id_);
  entry_dict.Set(kDeviceProductId, product_id_);
  entry_dict.Set(kDeviceSerialNumber, serial_number_);

  if (!manufacturer_string_.empty()) {
    entry_dict.Set(kDeviceManufacturerString, manufacturer_string_);
  }
  if (!product_string_.empty()) {
    entry_dict.Set(kDeviceProductString, product_string_);
  }
  if (!last_used_.is_null()) {
    entry_dict.Set(kDeviceLastUsed,
                   base::NumberToString(last_used_.ToInternalValue()));
  }

  return entry_dict;
}

std::u16string DevicePermissionEntry::GetPermissionMessageString() const {
  return DevicePermissionsManager::GetPermissionMessage(
      vendor_id_, product_id_, manufacturer_string_, product_string_,
      serial_number_, type_ == Type::USB);
}

DevicePermissions::~DevicePermissions() {
}

scoped_refptr<DevicePermissionEntry> DevicePermissions::FindUsbDeviceEntry(
    const device::mojom::UsbDeviceInfo& device) const {
  const auto& ephemeral_device_entry = ephemeral_usb_devices_.find(device.guid);
  if (ephemeral_device_entry != ephemeral_usb_devices_.end()) {
    return ephemeral_device_entry->second;
  }

  if (!device.serial_number || device.serial_number->empty()) {
    return nullptr;
  }

  for (const auto& entry : entries_) {
    if (entry->IsPersistent() && entry->vendor_id() == device.vendor_id &&
        entry->product_id() == device.product_id &&
        entry->serial_number() == *device.serial_number) {
      return entry;
    }
  }
  return nullptr;
}

scoped_refptr<DevicePermissionEntry> DevicePermissions::FindHidDeviceEntry(
    const device::mojom::HidDeviceInfo& device) const {
  const auto& ephemeral_device_entry = ephemeral_hid_devices_.find(device.guid);
  if (ephemeral_device_entry != ephemeral_hid_devices_.end()) {
    return ephemeral_device_entry->second;
  }

  if (device.serial_number.empty()) {
    return nullptr;
  }

  std::u16string serial_number = base::UTF8ToUTF16(device.serial_number);
  for (const auto& entry : entries_) {
    if (entry->IsPersistent() && entry->vendor_id() == device.vendor_id &&
        entry->product_id() == device.product_id &&
        entry->serial_number() == serial_number) {
      return entry;
    }
  }
  return nullptr;
}

DevicePermissions::DevicePermissions(BrowserContext* context,
                                     const ExtensionId& extension_id) {
  ExtensionPrefs* prefs = ExtensionPrefs::Get(context);
  entries_ = GetDevicePermissionEntries(prefs, extension_id);
}

// static
DevicePermissionsManager* DevicePermissionsManager::Get(
    BrowserContext* context) {
  return DevicePermissionsManagerFactory::GetForBrowserContext(context);
}

// static
std::u16string DevicePermissionsManager::GetPermissionMessage(
    uint16_t vendor_id,
    uint16_t product_id,
    const std::u16string& manufacturer_string,
    const std::u16string& product_string,
    const std::u16string& serial_number,
    bool always_include_manufacturer) {
  std::u16string product = product_string;
  if (product.empty()) {
    const char* product_name =
        device::UsbIds::GetProductName(vendor_id, product_id);
    if (product_name) {
      product = base::UTF8ToUTF16(product_name);
    }
  }

  std::u16string manufacturer = manufacturer_string;
  if (manufacturer_string.empty()) {
    const char* vendor_name = device::UsbIds::GetVendorName(vendor_id);
    if (vendor_name) {
      manufacturer = base::UTF8ToUTF16(vendor_name);
    }
  }

  if (serial_number.empty()) {
    if (product.empty()) {
      product = base::ASCIIToUTF16(base::StringPrintf("%04x", product_id));
      if (manufacturer.empty()) {
        manufacturer =
            base::ASCIIToUTF16(base::StringPrintf("%04x", vendor_id));
        return l10n_util::GetStringFUTF16(
            IDS_DEVICE_NAME_WITH_UNKNOWN_PRODUCT_UNKNOWN_VENDOR, product,
            manufacturer);
      } else {
        return l10n_util::GetStringFUTF16(
            IDS_DEVICE_NAME_WITH_UNKNOWN_PRODUCT_VENDOR, product, manufacturer);
      }
    } else {
      if (always_include_manufacturer) {
        if (manufacturer.empty()) {
          manufacturer =
              base::ASCIIToUTF16(base::StringPrintf("%04x", vendor_id));
          return l10n_util::GetStringFUTF16(
              IDS_DEVICE_NAME_WITH_PRODUCT_UNKNOWN_VENDOR, product,
              manufacturer);
        } else {
          return l10n_util::GetStringFUTF16(IDS_DEVICE_NAME_WITH_PRODUCT_VENDOR,
                                            product, manufacturer);
        }
      } else {
        return product;
      }
    }
  } else {
    if (product.empty()) {
      product = base::ASCIIToUTF16(base::StringPrintf("%04x", product_id));
      if (manufacturer.empty()) {
        manufacturer =
            base::ASCIIToUTF16(base::StringPrintf("%04x", vendor_id));
        return l10n_util::GetStringFUTF16(
            IDS_DEVICE_NAME_WITH_UNKNOWN_PRODUCT_UNKNOWN_VENDOR_SERIAL, product,
            manufacturer, serial_number);
      } else {
        return l10n_util::GetStringFUTF16(
            IDS_DEVICE_NAME_WITH_UNKNOWN_PRODUCT_VENDOR_SERIAL, product,
            manufacturer, serial_number);
      }
    } else {
      if (always_include_manufacturer) {
        if (manufacturer.empty()) {
          manufacturer =
              base::ASCIIToUTF16(base::StringPrintf("%04x", vendor_id));
          return l10n_util::GetStringFUTF16(
              IDS_DEVICE_NAME_WITH_PRODUCT_UNKNOWN_VENDOR_SERIAL, product,
              manufacturer, serial_number);
        } else {
          return l10n_util::GetStringFUTF16(
              IDS_DEVICE_NAME_WITH_PRODUCT_VENDOR_SERIAL, product, manufacturer,
              serial_number);
        }
      } else {
        return l10n_util::GetStringFUTF16(IDS_DEVICE_NAME_WITH_PRODUCT_SERIAL,
                                          product, serial_number);
      }
    }
  }
}

DevicePermissions* DevicePermissionsManager::GetForExtension(
    const ExtensionId& extension_id) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DevicePermissions* device_permissions = GetInternal(extension_id);
  if (!device_permissions) {
    device_permissions = new DevicePermissions(context_, extension_id);
    extension_id_to_device_permissions_[extension_id] = device_permissions;
  }

  return device_permissions;
}

std::vector<std::u16string>
DevicePermissionsManager::GetPermissionMessageStrings(
    const ExtensionId& extension_id) const {
  DCHECK(thread_checker_.CalledOnValidThread());
  std::vector<std::u16string> messages;
  const DevicePermissions* device_permissions = GetInternal(extension_id);
  if (device_permissions) {
    for (const scoped_refptr<DevicePermissionEntry>& entry :
         device_permissions->entries()) {
      messages.push_back(entry->GetPermissionMessageString());
    }
  }
  return messages;
}

void DevicePermissionsManager::AllowUsbDevice(
    const ExtensionId& extension_id,
    const device::mojom::UsbDeviceInfo& device_info) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DevicePermissions* device_permissions = GetForExtension(extension_id);
  auto device_entry = base::MakeRefCounted<DevicePermissionEntry>(device_info);

  if (device_entry->IsPersistent()) {
    for (const auto& entry : device_permissions->entries()) {
      if (entry->vendor_id() == device_entry->vendor_id() &&
          entry->product_id() == device_entry->product_id() &&
          entry->serial_number() == device_entry->serial_number()) {
        return;
      }
    }

    device_permissions->entries_.insert(device_entry);
    SaveDevicePermissionEntry(context_, extension_id, device_entry);
  } else if (!device_permissions->ephemeral_usb_devices_.contains(
                 device_info.guid)) {
    // Non-persistent devices cannot be reliably identified when they are
    // reconnected so such devices are only remembered until disconnect.
    // Register an observer here so that this set doesn't grow undefinitely.
    device_permissions->entries_.insert(device_entry);
    device_permissions->ephemeral_usb_devices_[device_info.guid] = device_entry;

    // Make sure the UsbDeviceManager has been connected to the DeviceService.
    // UsbDeviceManager is responsible for removing the permission entry for
    // an ephemeral USB device. Only do this when an ephemeral device has been
    // added.
    UsbDeviceManager* device_manager = UsbDeviceManager::Get(context_);
    DCHECK(device_manager);
    device_manager->EnsureConnectionWithDeviceManager();
  }
}

void DevicePermissionsManager::AllowHidDevice(
    const ExtensionId& extension_id,
    const device::mojom::HidDeviceInfo& device) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DevicePermissions* device_permissions = GetForExtension(extension_id);

  auto device_entry = base::MakeRefCounted<DevicePermissionEntry>(device);

  if (device_entry->IsPersistent()) {
    for (const auto& entry : device_permissions->entries()) {
      if (entry->vendor_id() == device_entry->vendor_id() &&
          entry->product_id() == device_entry->product_id() &&
          entry->serial_number() == device_entry->serial_number()) {
        return;
      }
    }

    device_permissions->entries_.insert(device_entry);
    SaveDevicePermissionEntry(context_, extension_id, device_entry);
  } else if (!device_permissions->ephemeral_hid_devices_.contains(
                 device.guid)) {
    // Non-persistent devices cannot be reliably identified when they are
    // reconnected so such devices are only remembered until disconnect.
    // Register an observer here so that this set doesn't grow undefinitely.
    device_permissions->entries_.insert(device_entry);
    device_permissions->ephemeral_hid_devices_[device.guid] = device_entry;

    // Make sure the HidDeviceManager is active. HidDeviceManager is
    // responsible for removing the permission entry for an ephemeral hid
    // device. Only do this when an ephemeral device has been added.
    HidDeviceManager* device_manager = HidDeviceManager::Get(context_);
    DCHECK(device_manager);
    device_manager->LazyInitialize();
  }
}

void DevicePermissionsManager::UpdateLastUsed(
    const ExtensionId& extension_id,
    scoped_refptr<DevicePermissionEntry> entry) {
  DCHECK(thread_checker_.CalledOnValidThread());
  entry->set_last_used(base::Time::Now());
  if (entry->IsPersistent()) {
    UpdateDevicePermissionEntry(context_, extension_id, entry);
  }
}

void DevicePermissionsManager::RemoveEntry(
    const ExtensionId& extension_id,
    scoped_refptr<DevicePermissionEntry> entry) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DevicePermissions* device_permissions = GetInternal(extension_id);
  DCHECK(device_permissions);
  DCHECK(device_permissions->entries_.contains(entry));
  device_permissions->entries_.erase(entry);
  if (entry->IsPersistent()) {
    RemoveDevicePermissionEntry(context_, extension_id, entry);
  } else if (entry->type_ == DevicePermissionEntry::Type::USB) {
    device_permissions->ephemeral_usb_devices_.erase(entry->device_guid_);
  } else if (entry->type_ == DevicePermissionEntry::Type::HID) {
    device_permissions->ephemeral_hid_devices_.erase(entry->device_guid_);
  } else {
    NOTREACHED();
  }
}

void DevicePermissionsManager::Clear(const ExtensionId& extension_id) {
  DCHECK(thread_checker_.CalledOnValidThread());

  ClearDevicePermissionEntries(ExtensionPrefs::Get(context_), extension_id);
  DevicePermissions* device_permissions = GetInternal(extension_id);
  if (device_permissions) {
    extension_id_to_device_permissions_.erase(extension_id);
    delete device_permissions;
  }
}

DevicePermissionsManager::DevicePermissionsManager(
    content::BrowserContext* context)
    : context_(context) {}

DevicePermissionsManager::~DevicePermissionsManager() {
  for (const auto& map_entry : extension_id_to_device_permissions_) {
    DevicePermissions* device_permissions = map_entry.second;
    delete device_permissions;
  }
}

DevicePermissions* DevicePermissionsManager::GetInternal(
    const ExtensionId& extension_id) const {
  auto it = extension_id_to_device_permissions_.find(extension_id);
  if (it != extension_id_to_device_permissions_.end()) {
    return it->second;
  }

  return nullptr;
}

void DevicePermissionsManager::RemoveEntryByDeviceGUID(
    DevicePermissionEntry::Type type,
    const std::string& guid) {
  DCHECK(thread_checker_.CalledOnValidThread());
  for (const auto& map_entry : extension_id_to_device_permissions_) {
    // An ephemeral device cannot be identified if it is reconnected and so
    // permission to access it is cleared on disconnect.
    DevicePermissions* device_permissions = map_entry.second;
    auto& devices = (type == DevicePermissionEntry::Type::HID)
                        ? device_permissions->ephemeral_hid_devices_
                        : device_permissions->ephemeral_usb_devices_;
    const auto& device_entry = devices.find(guid);
    if (device_entry != devices.end()) {
      device_permissions->entries_.erase(device_entry->second);
      devices.erase(device_entry);
    }
  }
}

// static
DevicePermissionsManager* DevicePermissionsManagerFactory::GetForBrowserContext(
    content::BrowserContext* context) {
  return static_cast<DevicePermissionsManager*>(
      GetInstance()->GetServiceForBrowserContext(context, true));
}

// static
DevicePermissionsManagerFactory*
DevicePermissionsManagerFactory::GetInstance() {
  static base::NoDestructor<DevicePermissionsManagerFactory> instance;
  return instance.get();
}

DevicePermissionsManagerFactory::DevicePermissionsManagerFactory()
    : BrowserContextKeyedServiceFactory(
          "DevicePermissionsManager",
          BrowserContextDependencyManager::GetInstance()) {
}

DevicePermissionsManagerFactory::~DevicePermissionsManagerFactory() = default;

std::unique_ptr<KeyedService>
DevicePermissionsManagerFactory::BuildServiceInstanceForBrowserContext(
    content::BrowserContext* context) const {
  return std::make_unique<DevicePermissionsManager>(context);
}

BrowserContext* DevicePermissionsManagerFactory::GetBrowserContextToUse(
    BrowserContext* context) const {
  // Return the original (possibly off-the-record) browser context so that a
  // separate instance of the DevicePermissionsManager is used in incognito
  // mode. The parent class's implementation returns null.
  return ExtensionsBrowserClient::Get()->GetContextOwnInstance(context);
}

}  // namespace extensions
