// Copyright 2016 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/chromeos/note_taking_helper.h"

#include <algorithm>
#include <utility>

#include "apps/launcher.h"
#include "ash/public/cpp/stylus_utils.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/metrics/histogram_macros.h"
#include "base/stl_util.h"
#include "base/strings/string_split.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/chromeos/arc/arc_util.h"
#include "chrome/browser/chromeos/file_manager/path_util.h"
#include "chrome/browser/chromeos/lock_screen_apps/state_controller.h"
#include "chrome/browser/chromeos/note_taking_controller_client.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/common/pref_names.h"
#include "chromeos/chromeos_switches.h"
#include "components/arc/arc_bridge_service.h"
#include "components/arc/arc_service_manager.h"
#include "components/arc/intent_helper/arc_intent_helper_bridge.h"
#include "components/arc/metrics/arc_metrics_constants.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/scoped_user_pref_update.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/notification_service.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/common/api/app_runtime.h"
#include "extensions/common/extension.h"
#include "extensions/common/manifest_handlers/action_handlers_handler.h"
#include "extensions/common/permissions/api_permission.h"
#include "extensions/common/permissions/permissions_data.h"
#include "url/gurl.h"

namespace app_runtime = extensions::api::app_runtime;

namespace chromeos {
namespace {

// Pointer to singleton instance.
NoteTakingHelper* g_helper = nullptr;

// Whitelisted Chrome note-taking apps.
const char* const kExtensionIds[] = {
    // TODO(jdufault): Remove dev version? See crbug.com/640828.
    NoteTakingHelper::kDevKeepExtensionId,
    NoteTakingHelper::kProdKeepExtensionId,
};

// Returns true if |app_id|, a value from prefs::kNoteTakingAppId, looks like
// it's probably an Android package name rather than a Chrome extension ID.
bool LooksLikeAndroidPackageName(const std::string& app_id) {
  // Android package names are required to contain at least one period (see
  // validateName() in PackageParser.java), while Chrome extension IDs contain
  // only characters in [a-p].
  return app_id.find(".") != std::string::npos;
}

// Creates a new Mojo IntentInfo struct for launching an Android note-taking app
// with an optional ClipData URI.
arc::mojom::IntentInfoPtr CreateIntentInfo(const GURL& clip_data_uri) {
  arc::mojom::IntentInfoPtr intent = arc::mojom::IntentInfo::New();
  intent->action = NoteTakingHelper::kIntentAction;
  if (!clip_data_uri.is_empty())
    intent->clip_data_uri = clip_data_uri.spec();
  return intent;
}

// Whether the app's manifest indicates that the app supports note taking on the
// lock screen.
bool IsLockScreenEnabled(const extensions::Extension* app) {
  if (!app->permissions_data()->HasAPIPermission(
          extensions::APIPermission::kLockScreen)) {
    return false;
  }

  return extensions::ActionHandlersInfo::HasLockScreenActionHandler(
      app, app_runtime::ACTION_TYPE_NEW_NOTE);
}

// Gets the set of apps (more specifically, their app IDs) that are allowed to
// be launched on the lock screen, if the feature is whitelisted using
// |prefs::kNoteTakingAppsLockScreenWhitelist| preference. If the pref is not
// set, this method will return null (in which case the white-list should not be
// checked).
// Note that |prefs::kNoteTakingrAppsAllowedOnLockScreen| is currently only
// expected to be set by policy (if it's set at all).
std::unique_ptr<std::set<std::string>> GetAllowedLockScreenApps(
    PrefService* prefs) {
  const PrefService::Preference* allowed_lock_screen_apps_pref =
      prefs->FindPreference(prefs::kNoteTakingAppsLockScreenWhitelist);
  if (!allowed_lock_screen_apps_pref ||
      allowed_lock_screen_apps_pref->IsDefaultValue()) {
    return nullptr;
  }

  const base::Value* allowed_lock_screen_apps_value =
      allowed_lock_screen_apps_pref->GetValue();

  const base::ListValue* allowed_apps_list = nullptr;
  if (!allowed_lock_screen_apps_value ||
      !allowed_lock_screen_apps_value->GetAsList(&allowed_apps_list)) {
    return nullptr;
  }

  auto allowed_apps = std::make_unique<std::set<std::string>>();
  for (const base::Value& app_value : allowed_apps_list->GetList()) {
    if (!app_value.is_string()) {
      LOG(ERROR) << "Invalid app ID value " << app_value;
      continue;
    }

    allowed_apps->insert(app_value.GetString());
  }
  return allowed_apps;
}

}  // namespace

const char NoteTakingHelper::kIntentAction[] =
    "org.chromium.arc.intent.action.CREATE_NOTE";
const char NoteTakingHelper::kDevKeepExtensionId[] =
    "ogfjaccbdfhecploibfbhighmebiffla";
const char NoteTakingHelper::kProdKeepExtensionId[] =
    "hmjkmjkepdijhoojdojkdfohbdgmmhki";
const char NoteTakingHelper::kPreferredLaunchResultHistogramName[] =
    "Apps.NoteTakingApp.PreferredLaunchResult";
const char NoteTakingHelper::kDefaultLaunchResultHistogramName[] =
    "Apps.NoteTakingApp.DefaultLaunchResult";

// static
void NoteTakingHelper::Initialize() {
  DCHECK(!g_helper);
  g_helper = new NoteTakingHelper();
}

// static
void NoteTakingHelper::Shutdown() {
  DCHECK(g_helper);
  delete g_helper;
  g_helper = nullptr;
}

// static
NoteTakingHelper* NoteTakingHelper::Get() {
  DCHECK(g_helper);
  return g_helper;
}

void NoteTakingHelper::AddObserver(Observer* observer) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  DCHECK(observer);
  observers_.AddObserver(observer);
}

void NoteTakingHelper::RemoveObserver(Observer* observer) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  DCHECK(observer);
  observers_.RemoveObserver(observer);
}

NoteTakingAppInfos NoteTakingHelper::GetAvailableApps(Profile* profile) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  NoteTakingAppInfos infos;

  const std::vector<const extensions::Extension*> chrome_apps =
      GetChromeApps(profile);
  for (const auto* app : chrome_apps) {
    NoteTakingLockScreenSupport lock_screen_support =
        GetLockScreenSupportForChromeApp(profile, app);
    infos.push_back(
        NoteTakingAppInfo{app->name(), app->id(), false, lock_screen_support});
  }

  if (arc::IsArcAllowedForProfile(profile))
    infos.insert(infos.end(), android_apps_.begin(), android_apps_.end());

  // Determine which app, if any, is preferred and whether it is enabled on
  // lock screen.
  const std::string pref_app_id =
      profile->GetPrefs()->GetString(prefs::kNoteTakingAppId);
  for (auto& info : infos) {
    if (info.app_id == pref_app_id) {
      info.preferred = true;
      break;
    }
  }

  return infos;
}

std::unique_ptr<NoteTakingAppInfo> NoteTakingHelper::GetPreferredChromeAppInfo(
    Profile* profile) {
  std::string preferred_app_id =
      profile->GetPrefs()->GetString(prefs::kNoteTakingAppId);
  if (LooksLikeAndroidPackageName(preferred_app_id))
    return nullptr;

  if (preferred_app_id.empty())
    preferred_app_id = kProdKeepExtensionId;

  const extensions::Extension* preferred_app =
      extensions::ExtensionRegistry::Get(profile)->GetExtensionById(
          preferred_app_id, extensions::ExtensionRegistry::ENABLED);
  if (!preferred_app)
    return nullptr;

  if (!IsWhitelistedChromeApp(preferred_app) &&
      !extensions::ActionHandlersInfo::HasActionHandler(
          preferred_app, app_runtime::ACTION_TYPE_NEW_NOTE)) {
    return nullptr;
  }

  std::unique_ptr<NoteTakingAppInfo> info =
      std::make_unique<NoteTakingAppInfo>();
  info->name = preferred_app->name();
  info->app_id = preferred_app->id();
  info->preferred = true;
  info->lock_screen_support =
      GetLockScreenSupportForChromeApp(profile, preferred_app);
  return info;
}

void NoteTakingHelper::SetPreferredApp(Profile* profile,
                                       const std::string& app_id) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  DCHECK(profile);

  if (app_id == profile->GetPrefs()->GetString(prefs::kNoteTakingAppId))
    return;

  profile->GetPrefs()->SetString(prefs::kNoteTakingAppId, app_id);

  for (Observer& observer : observers_)
    observer.OnPreferredNoteTakingAppUpdated(profile);
}

bool NoteTakingHelper::SetPreferredAppEnabledOnLockScreen(Profile* profile,
                                                          bool enabled) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  DCHECK(profile);
  if (profile != profile_with_enabled_lock_screen_apps_)
    return false;

  std::string app_id = profile->GetPrefs()->GetString(prefs::kNoteTakingAppId);
  const extensions::Extension* app =
      extensions::ExtensionRegistry::Get(profile)->GetExtensionById(
          app_id, extensions::ExtensionRegistry::ENABLED);
  if (!app)
    return false;

  NoteTakingLockScreenSupport current_state =
      GetLockScreenSupportForChromeApp(profile, app);

  if ((enabled && current_state != NoteTakingLockScreenSupport::kSupported) ||
      (!enabled && current_state != NoteTakingLockScreenSupport::kEnabled)) {
    return false;
  }

  profile->GetPrefs()->SetBoolean(prefs::kNoteTakingAppEnabledOnLockScreen,
                                  enabled);

  for (Observer& observer : observers_)
    observer.OnPreferredNoteTakingAppUpdated(profile);

  return true;
}

bool NoteTakingHelper::IsAppAvailable(Profile* profile) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  DCHECK(profile);
  return ash::stylus_utils::HasStylusInput() &&
         !GetAvailableApps(profile).empty();
}

void NoteTakingHelper::LaunchAppForNewNote(Profile* profile,
                                           const base::FilePath& path) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  DCHECK(profile);

  LaunchResult result = LaunchResult::NO_APP_SPECIFIED;
  std::string app_id = profile->GetPrefs()->GetString(prefs::kNoteTakingAppId);
  if (!app_id.empty())
    result = LaunchAppInternal(profile, app_id, path);
  UMA_HISTOGRAM_ENUMERATION(kPreferredLaunchResultHistogramName,
                            static_cast<int>(result),
                            static_cast<int>(LaunchResult::MAX));
  if (result == LaunchResult::CHROME_SUCCESS ||
      result == LaunchResult::ANDROID_SUCCESS) {
    return;
  }

  // If the user hasn't chosen an app or we were unable to launch the one that
  // they've chosen, just launch the first one we see.
  result = LaunchResult::NO_APPS_AVAILABLE;
  NoteTakingAppInfos infos = GetAvailableApps(profile);
  if (infos.empty())
    LOG(WARNING) << "Unable to launch note-taking app; none available";
  else
    result = LaunchAppInternal(profile, infos[0].app_id, path);
  UMA_HISTOGRAM_ENUMERATION(kDefaultLaunchResultHistogramName,
                            static_cast<int>(result),
                            static_cast<int>(LaunchResult::MAX));
}

void NoteTakingHelper::OnIntentFiltersUpdated() {
  if (play_store_enabled_)
    UpdateAndroidApps();
}

void NoteTakingHelper::OnArcPlayStoreEnabledChanged(bool enabled) {
  play_store_enabled_ = enabled;
  if (!enabled) {
    android_apps_.clear();
    android_apps_received_ = false;
  }
  for (Observer& observer : observers_)
    observer.OnAvailableNoteTakingAppsUpdated();
}

void NoteTakingHelper::SetProfileWithEnabledLockScreenApps(Profile* profile) {
  DCHECK(!profile_with_enabled_lock_screen_apps_);
  profile_with_enabled_lock_screen_apps_ = profile;

  pref_change_registrar_.Init(profile->GetPrefs());
  pref_change_registrar_.Add(
      prefs::kNoteTakingAppsLockScreenWhitelist,
      base::Bind(&NoteTakingHelper::OnAllowedNoteTakingAppsChanged,
                 base::Unretained(this)));
  OnAllowedNoteTakingAppsChanged();
}

NoteTakingHelper::NoteTakingHelper()
    : launch_chrome_app_callback_(
          base::Bind(&apps::LaunchPlatformAppWithAction)),
      extension_registry_observer_(this),
      note_taking_controller_client_(
          std::make_unique<NoteTakingControllerClient>(this)),
      weak_ptr_factory_(this) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  const std::string switch_value =
      base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
          switches::kNoteTakingAppIds);
  if (!switch_value.empty()) {
    whitelisted_chrome_app_ids_ = base::SplitString(
        switch_value, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
  }
  whitelisted_chrome_app_ids_.insert(whitelisted_chrome_app_ids_.end(),
                                     kExtensionIds,
                                     kExtensionIds + base::size(kExtensionIds));

  // Track profiles so we can observe their extension registries.
  registrar_.Add(this, chrome::NOTIFICATION_PROFILE_ADDED,
                 content::NotificationService::AllBrowserContextsAndSources());
  play_store_enabled_ = false;
  for (Profile* profile :
       g_browser_process->profile_manager()->GetLoadedProfiles()) {
    extension_registry_observer_.Add(
        extensions::ExtensionRegistry::Get(profile));
    // Check if the profile has already enabled Google Play Store.
    // IsArcPlayStoreEnabledForProfile() can return true only for the primary
    // profile.
    play_store_enabled_ |= arc::IsArcPlayStoreEnabledForProfile(profile);

    // ArcIntentHelperBridge will notify us about changes to the list of
    // available Android apps.
    auto* intent_helper_bridge =
        arc::ArcIntentHelperBridge::GetForBrowserContext(profile);
    if (intent_helper_bridge)
      intent_helper_bridge->AddObserver(this);
  }

  // Watch for changes of Google Play Store enabled state.
  auto* session_manager = arc::ArcSessionManager::Get();
  session_manager->AddObserver(this);

  // If the ARC intent helper is ready, get the Android apps. Otherwise,
  // UpdateAndroidApps() will be called when ArcServiceManager calls
  // OnIntentFiltersUpdated().
  if (play_store_enabled_ && arc::ArcServiceManager::Get()
                                 ->arc_bridge_service()
                                 ->intent_helper()
                                 ->IsConnected()) {
    UpdateAndroidApps();
  }
}

NoteTakingHelper::~NoteTakingHelper() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  // ArcSessionManagerTest shuts down ARC before NoteTakingHelper.
  if (arc::ArcSessionManager::Get())
    arc::ArcSessionManager::Get()->RemoveObserver(this);
  for (Profile* profile :
       g_browser_process->profile_manager()->GetLoadedProfiles()) {
    auto* intent_helper_bridge =
        arc::ArcIntentHelperBridge::GetForBrowserContext(profile);
    if (intent_helper_bridge)
      intent_helper_bridge->RemoveObserver(this);
  }
}

bool NoteTakingHelper::IsWhitelistedChromeApp(
    const extensions::Extension* extension) const {
  DCHECK(extension);
  return base::ContainsValue(whitelisted_chrome_app_ids_, extension->id());
}

std::vector<const extensions::Extension*> NoteTakingHelper::GetChromeApps(
    Profile* profile) const {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  const extensions::ExtensionRegistry* extension_registry =
      extensions::ExtensionRegistry::Get(profile);
  const extensions::ExtensionSet& enabled_extensions =
      extension_registry->enabled_extensions();

  std::vector<const extensions::Extension*> extensions;
  for (const auto& id : whitelisted_chrome_app_ids_) {
    if (enabled_extensions.Contains(id)) {
      extensions.push_back(extension_registry->GetExtensionById(
          id, extensions::ExtensionRegistry::ENABLED));
    }
  }

  // Add any extensions which have a "note" action in their manifest
  // "action_handler" entry.
  for (const auto& extension : enabled_extensions) {
    if (base::ContainsValue(extensions, extension.get()))
      continue;

    if (extensions::ActionHandlersInfo::HasActionHandler(
            extension.get(), app_runtime::ACTION_TYPE_NEW_NOTE)) {
      extensions.push_back(extension.get());
    }
  }

  return extensions;
}

void NoteTakingHelper::UpdateAndroidApps() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  auto* helper = ARC_GET_INSTANCE_FOR_METHOD(
      arc::ArcServiceManager::Get()->arc_bridge_service()->intent_helper(),
      RequestIntentHandlerList);
  if (!helper)
    return;
  helper->RequestIntentHandlerList(
      CreateIntentInfo(GURL()), base::Bind(&NoteTakingHelper::OnGotAndroidApps,
                                           weak_ptr_factory_.GetWeakPtr()));
}

void NoteTakingHelper::OnGotAndroidApps(
    std::vector<arc::mojom::IntentHandlerInfoPtr> handlers) {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  if (!play_store_enabled_)
    return;

  android_apps_.clear();
  android_apps_.reserve(handlers.size());
  for (const auto& it : handlers) {
    android_apps_.emplace_back(
        NoteTakingAppInfo{it->name, it->package_name, false,
                          NoteTakingLockScreenSupport::kNotSupported});
  }
  android_apps_received_ = true;

  for (Observer& observer : observers_)
    observer.OnAvailableNoteTakingAppsUpdated();
}

NoteTakingHelper::LaunchResult NoteTakingHelper::LaunchAppInternal(
    Profile* profile,
    const std::string& app_id,
    const base::FilePath& path) {
  DCHECK(profile);

  if (LooksLikeAndroidPackageName(app_id)) {
    // Android app.
    if (!arc::IsArcAllowedForProfile(profile)) {
      LOG(WARNING) << "Can't launch Android app " << app_id << " for profile";
      return LaunchResult::ANDROID_NOT_SUPPORTED_BY_PROFILE;
    }
    auto* helper = ARC_GET_INSTANCE_FOR_METHOD(
        arc::ArcServiceManager::Get()->arc_bridge_service()->intent_helper(),
        HandleIntent);
    if (!helper)
      return LaunchResult::ANDROID_NOT_RUNNING;

    GURL clip_data_uri;
    if (!path.empty()) {
      if (!file_manager::util::ConvertPathToArcUrl(path, &clip_data_uri) ||
          !clip_data_uri.is_valid()) {
        LOG(WARNING) << "Failed to convert " << path.value() << " to ARC URI";
        return LaunchResult::ANDROID_FAILED_TO_CONVERT_PATH;
      }
    }

    // Only set the package name: leaving the activity name unset enables the
    // app to rename its activities.
    arc::mojom::ActivityNamePtr activity = arc::mojom::ActivityName::New();
    activity->package_name = app_id;

    // TODO(derat): Is there some way to detect whether this fails due to the
    // package no longer being available?
    helper->HandleIntent(CreateIntentInfo(clip_data_uri), std::move(activity));

    UMA_HISTOGRAM_ENUMERATION(
        "Arc.UserInteraction",
        arc::UserInteractionType::APP_STARTED_FROM_STYLUS_TOOLS);

    return LaunchResult::ANDROID_SUCCESS;
  } else {
    // Chrome app.
    const extensions::ExtensionRegistry* extension_registry =
        extensions::ExtensionRegistry::Get(profile);
    const extensions::Extension* app = extension_registry->GetExtensionById(
        app_id, extensions::ExtensionRegistry::ENABLED);
    if (!app) {
      LOG(WARNING) << "Failed to find Chrome note-taking app " << app_id;
      return LaunchResult::CHROME_APP_MISSING;
    }
    auto action_data = std::make_unique<app_runtime::ActionData>();
    action_data->action_type = app_runtime::ActionType::ACTION_TYPE_NEW_NOTE;
    launch_chrome_app_callback_.Run(profile, app, std::move(action_data), path);
    return LaunchResult::CHROME_SUCCESS;
  }
  NOTREACHED();
}

void NoteTakingHelper::Observe(int type,
                               const content::NotificationSource& source,
                               const content::NotificationDetails& details) {
  DCHECK_EQ(type, chrome::NOTIFICATION_PROFILE_ADDED);
  Profile* profile = content::Source<Profile>(source).ptr();
  DCHECK(profile);

  auto* registry = extensions::ExtensionRegistry::Get(profile);
  DCHECK(!extension_registry_observer_.IsObserving(registry));
  extension_registry_observer_.Add(registry);

  // TODO(derat): Remove this once OnArcPlayStoreEnabledChanged() is always
  // called after an ARC-enabled user logs in: http://b/36655474
  if (!play_store_enabled_ && arc::IsArcPlayStoreEnabledForProfile(profile)) {
    play_store_enabled_ = true;
    for (Observer& observer : observers_)
      observer.OnAvailableNoteTakingAppsUpdated();
  }

  auto* bridge = arc::ArcIntentHelperBridge::GetForBrowserContext(profile);
  if (bridge)
    bridge->AddObserver(this);
}

void NoteTakingHelper::OnExtensionLoaded(
    content::BrowserContext* browser_context,
    const extensions::Extension* extension) {
  if (IsWhitelistedChromeApp(extension) ||
      extensions::ActionHandlersInfo::HasActionHandler(
          extension, app_runtime::ACTION_TYPE_NEW_NOTE)) {
    for (Observer& observer : observers_)
      observer.OnAvailableNoteTakingAppsUpdated();
  }
}

void NoteTakingHelper::OnExtensionUnloaded(
    content::BrowserContext* browser_context,
    const extensions::Extension* extension,
    extensions::UnloadedExtensionReason reason) {
  if (IsWhitelistedChromeApp(extension) ||
      extensions::ActionHandlersInfo::HasActionHandler(
          extension, app_runtime::ACTION_TYPE_NEW_NOTE)) {
    for (Observer& observer : observers_)
      observer.OnAvailableNoteTakingAppsUpdated();
  }
}

void NoteTakingHelper::OnShutdown(extensions::ExtensionRegistry* registry) {
  extension_registry_observer_.Remove(registry);
}

NoteTakingLockScreenSupport NoteTakingHelper::GetLockScreenSupportForChromeApp(
    Profile* profile,
    const extensions::Extension* app) {
  if (profile != profile_with_enabled_lock_screen_apps_)
    return NoteTakingLockScreenSupport::kNotSupported;

  if (!IsLockScreenEnabled(app))
    return NoteTakingLockScreenSupport::kNotSupported;

  if (lock_screen_whitelist_state_ == AppWhitelistState::kUndetermined)
    UpdateLockScreenAppsWhitelistState();

  if (lock_screen_whitelist_state_ == AppWhitelistState::kAppsWhitelisted &&
      !lock_screen_apps_allowed_by_policy_.count(app->id())) {
    return NoteTakingLockScreenSupport::kNotAllowedByPolicy;
  }

  if (profile->GetPrefs()->GetBoolean(prefs::kNoteTakingAppEnabledOnLockScreen))
    return NoteTakingLockScreenSupport::kEnabled;

  return NoteTakingLockScreenSupport::kSupported;
}

void NoteTakingHelper::OnAllowedNoteTakingAppsChanged() {
  if (lock_screen_whitelist_state_ == AppWhitelistState::kUndetermined)
    return;

  std::unique_ptr<NoteTakingAppInfo> preferred_app =
      GetPreferredChromeAppInfo(profile_with_enabled_lock_screen_apps_);
  NoteTakingLockScreenSupport lock_screen_value_before_update =
      preferred_app ? preferred_app->lock_screen_support
                    : NoteTakingLockScreenSupport::kNotSupported;

  UpdateLockScreenAppsWhitelistState();

  preferred_app =
      GetPreferredChromeAppInfo(profile_with_enabled_lock_screen_apps_);
  NoteTakingLockScreenSupport lock_screen_value_after_update =
      preferred_app ? preferred_app->lock_screen_support
                    : NoteTakingLockScreenSupport::kNotSupported;

  // Do not notify observers about preferred app change if its lock screen
  // support status has not actually changed.
  if (lock_screen_value_before_update != lock_screen_value_after_update) {
    for (Observer& observer : observers_) {
      observer.OnPreferredNoteTakingAppUpdated(
          profile_with_enabled_lock_screen_apps_);
    }
  }
}

void NoteTakingHelper::UpdateLockScreenAppsWhitelistState() {
  std::unique_ptr<std::set<std::string>> whitelist = GetAllowedLockScreenApps(
      profile_with_enabled_lock_screen_apps_->GetPrefs());

  if (whitelist) {
    lock_screen_whitelist_state_ = AppWhitelistState::kAppsWhitelisted;
    lock_screen_apps_allowed_by_policy_.swap(*whitelist);
  } else {
    lock_screen_whitelist_state_ = AppWhitelistState::kNoAppWhitelist;
    lock_screen_apps_allowed_by_policy_.clear();
  }
}

}  // namespace chromeos
