chromium/chrome/browser/feedback/android/family_info_feedback_source.cc

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

#include "chrome/browser/feedback/android/family_info_feedback_source.h"

#include "base/android/jni_string.h"
#include "base/android/jni_weak_ref.h"
#include "base/android/scoped_java_ref.h"
#include "base/notreached.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/signin/identity_manager_factory.h"
#include "chrome/browser/supervised_user/supervised_user_service_factory.h"
#include "components/supervised_user/core/browser/proto/families_common.pb.h"
#include "components/supervised_user/core/browser/supervised_user_utils.h"
#include "content/public/browser/storage_partition.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"

// Must come after all headers that specialize FromJniType() / ToJniType().
#include "chrome/browser/feedback/android/jni_headers/FamilyInfoFeedbackSource_jni.h"

using base::android::AttachCurrentThread;
using base::android::ConvertUTF8ToJavaString;
using base::android::JavaParamRef;
using base::android::ScopedJavaLocalRef;

namespace chrome::android {

void JNI_FamilyInfoFeedbackSource_Start(JNIEnv* env,
                                        const JavaParamRef<jobject>& obj,
                                        Profile* profile) {
  FamilyInfoFeedbackSource* feedback_source =
      new FamilyInfoFeedbackSource(obj, profile);
  feedback_source->GetFamilyMembers();
}

FamilyInfoFeedbackSource::FamilyInfoFeedbackSource(
    const JavaParamRef<jobject>& obj,
    Profile* profile)
    : supervised_user_service_(
          SupervisedUserServiceFactory::GetForProfile(profile)),
      identity_manager_(IdentityManagerFactory::GetForProfile(profile)),
      url_loader_factory_(profile->GetDefaultStoragePartition()
                              ->GetURLLoaderFactoryForBrowserProcess()),
      java_ref_(obj) {}
FamilyInfoFeedbackSource::~FamilyInfoFeedbackSource() = default;

void FamilyInfoFeedbackSource::GetFamilyMembers() {
  list_family_members_fetcher_ = FetchListFamilyMembers(
      *identity_manager_, url_loader_factory_,
      base::BindOnce(
          &FamilyInfoFeedbackSource::OnResponse,
          base::Unretained(this)));  // Unretained(.) is safe because `this`
                                     // owns `list_family_members_fetcher_`.
}

void FamilyInfoFeedbackSource::OnResponse(
    const supervised_user::ProtoFetcherStatus& status,
    std::unique_ptr<kidsmanagement::ListMembersResponse> response) {
  if (!status.IsOk()) {
    OnFailure(status);
    return;
  }
  OnSuccess(*response);
  // Release response.
}

void FamilyInfoFeedbackSource::OnSuccess(
    const kidsmanagement::ListMembersResponse& response) {
  std::string primary_account_gaia =
      identity_manager_->GetPrimaryAccountInfo(signin::ConsentLevel::kSignin)
          .gaia;

  JNIEnv* env = AttachCurrentThread();
  for (const kidsmanagement::FamilyMember& member : response.members()) {
    // Store the family member role for the primary account of the profile.
    if (primary_account_gaia == member.user_id()) {
      // If a child is signed-in, report the parental control web filter.
      ScopedJavaLocalRef<jstring> child_web_filter_type = nullptr;
      if (member.role() == kidsmanagement::CHILD) {
        supervised_user::WebFilterType web_filter_type =
            supervised_user_service_->GetURLFilter()->GetWebFilterType();
        child_web_filter_type = ConvertUTF8ToJavaString(
            env,
            supervised_user::WebFilterTypeToDisplayString(web_filter_type));
      }
      Java_FamilyInfoFeedbackSource_processPrimaryAccountFamilyInfo(
          env, java_ref_,
          ConvertUTF8ToJavaString(
              env, supervised_user::FamilyRoleToString(member.role())),
          child_web_filter_type);
    }
  }
  OnComplete();
}

void FamilyInfoFeedbackSource::OnFailure(
    const supervised_user::ProtoFetcherStatus& status) {
  DLOG(WARNING) << "ListFamilyMembers failed with status: "
                << status.ToString();
  OnComplete();
}

void FamilyInfoFeedbackSource::OnComplete() {
  // Object will delete itself following the fetch to ListFamilyMembers.
  delete this;
}

}  // namespace chrome::android