Commit 948b6550 authored by Steven Bingler's avatar Steven Bingler Committed by Commit Bot

Create an class so native code can query Java's EnterpriseInfo

Create a native class that other classes can use to query ownership
state of the Android device from the Java side EnterpriseInfo.

This class provides a function that accepts a callback. When this
function is called the callback is stored in a list and a request to
the Java side is made. If any more requests are received they are stored
in the list while we wait on the response from the Java side.

Once the Java side response is received all callbacks stored in the list
are run.

Bug: 1085168
Change-Id: I49429d13f9a407e3650fe265d4e010e7e169ee68
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2268657
Commit-Queue: Steven Bingler <bingler@chromium.org>
Reviewed-by: default avatarTheresa  <twellington@chromium.org>
Reviewed-by: default avatarEric Orth <ericorth@chromium.org>
Cr-Commit-Position: refs/heads/master@{#782997}
parent 76320e2a
......@@ -14,6 +14,8 @@ import org.chromium.base.Callback;
import org.chromium.base.ContextUtils;
import org.chromium.base.Log;
import org.chromium.base.ThreadUtils;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.base.annotations.NativeMethods;
import org.chromium.base.metrics.RecordHistogram;
import org.chromium.base.task.AsyncTask;
import org.chromium.base.task.TaskTraits;
......@@ -45,6 +47,24 @@ public final class EnterpriseInfo {
}
}
/**
* Returns, via callback, whether the device has a device owner or a profile owner for native.
*/
@CalledByNative
public static void getManagedStateForNative() {
Callback<OwnedState> callback = (result) -> {
if (result == null) {
// Unable to determine the owned state, assume it's not owned.
EnterpriseInfoJni.get().updateNativeOwnedState(false, false);
}
EnterpriseInfoJni.get().updateNativeOwnedState(
result.mDeviceOwned, result.mProfileOwned);
};
getDeviceEnterpriseInfo(callback);
}
/**
* Records metrics regarding whether the device has a device owner or a profile owner.
*/
......@@ -141,4 +161,9 @@ public final class EnterpriseInfo {
RecordHistogram.recordBooleanHistogram(
"EnterpriseCheck.IsFullyManaged", state.mDeviceOwned);
}
@NativeMethods
interface Natives {
void updateNativeOwnedState(boolean hasProfileOwnerApp, boolean hasDeviceOwnerApp);
}
}
......@@ -2688,6 +2688,8 @@ static_library("browser") {
"download/download_crx_util_android.cc",
"engagement/site_engagement_service_android.cc",
"engagement/site_engagement_service_android.h",
"enterprise/util/android_enterprise_info.cc",
"enterprise/util/android_enterprise_info.h",
"file_select_helper_contacts_android.cc",
"file_select_helper_contacts_android.h",
"first_run/android/first_run_utils.cc",
......
......@@ -2,8 +2,8 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#import("//build/config/android/config.gni")
import("//build/config/android/rules.gni")
android_library("java") {
sources = [ "android/java/src/org/chromium/chrome/browser/enterprise/util/ManagedBrowserUtils.java" ]
deps = [
......@@ -15,5 +15,8 @@ android_library("java") {
}
generate_jni("jni_headers") {
sources = [ "android/java/src/org/chromium/chrome/browser/enterprise/util/ManagedBrowserUtils.java" ]
sources = [
"../../../android/java/src/org/chromium/chrome/browser/policy/EnterpriseInfo.java",
"android/java/src/org/chromium/chrome/browser/enterprise/util/ManagedBrowserUtils.java",
]
}
// Copyright 2020 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/enterprise/util/android_enterprise_info.h"
#include <jni.h>
#include "base/android/jni_android.h"
#include "chrome/browser/enterprise/util/jni_headers/EnterpriseInfo_jni.h"
namespace chrome {
namespace enterprise_util {
AndroidEnterpriseInfo::AndroidEnterpriseInfo() = default;
AndroidEnterpriseInfo::~AndroidEnterpriseInfo() = default;
void AndroidEnterpriseInfo::GetAndroidEnterpriseInfoState(
EnterpriseInfoCallback callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
callback_queue_.push(std::move(callback));
// If there is already a callback in the queue then that means we're already
// waiting on a response. No need to initiate another request.
if (callback_queue_.size() > 1)
return;
Java_EnterpriseInfo_getManagedStateForNative(
base::android::AttachCurrentThread());
}
void AndroidEnterpriseInfo::ServiceCallbacks(bool profile_owned,
bool device_owned) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// Move the queue to a local so that we can handle re-entrancy.
std::queue<EnterpriseInfoCallback> local_queue;
local_queue.swap(callback_queue_);
while (local_queue.size() > 0) {
std::move(local_queue.front()).Run(profile_owned, device_owned);
local_queue.pop();
}
}
// JNI_EnterpriseInfo_UpdateNativeOwnedState() is static function, this makes
// friending it a hassle because it must be declared in the file that the friend
// declaration is in, but it's declaration can't be included in multiple places
// or things get messy and the linker gets mad. This helper class exists only to
// friend the JNI function and is, in turn, friended by AndroidEnterpriseInfo
// which allows for the private ServiceCallbacks() to be reached.
class AndroidEnterpriseInfoFriendHelper {
private:
friend void ::JNI_EnterpriseInfo_UpdateNativeOwnedState(
JNIEnv* env,
jboolean hasProfileOwnerApp,
jboolean hasDeviceOwnerApp);
static void ForwardToServiceCallbacks(bool profile_owned, bool device_owned) {
AndroidEnterpriseInfo::GetInstance()->ServiceCallbacks(profile_owned,
device_owned);
}
};
} // namespace enterprise_util
} // namespace chrome
void JNI_EnterpriseInfo_UpdateNativeOwnedState(JNIEnv* env,
jboolean hasProfileOwnerApp,
jboolean hasDeviceOwnerApp) {
chrome::enterprise_util::AndroidEnterpriseInfoFriendHelper::
ForwardToServiceCallbacks(static_cast<bool>(hasProfileOwnerApp),
static_cast<bool>(hasDeviceOwnerApp));
}
// Copyright 2020 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.
#ifndef CHROME_BROWSER_ENTERPRISE_UTIL_ANDROID_ENTERPRISE_INFO_H_
#define CHROME_BROWSER_ENTERPRISE_UTIL_ANDROID_ENTERPRISE_INFO_H_
#include <queue>
#include "base/callback.h"
#include "base/macros.h"
#include "base/no_destructor.h"
#include "base/sequence_checker.h"
#include "build/build_config.h"
// Class to connect native calls to
// org.chromium.chrome.browser.policy.EnterpriseInfo. This class is only usable
// for Android and is only built for Android.
// Only use from the UI Thread.
namespace chrome {
namespace enterprise_util {
class AndroidEnterpriseInfoFriendHelper;
class AndroidEnterpriseInfo {
public:
using EnterpriseInfoCallback = base::OnceCallback<void(bool, bool)>;
~AndroidEnterpriseInfo();
static AndroidEnterpriseInfo* GetInstance() {
static base::NoDestructor<AndroidEnterpriseInfo> instance;
return instance.get();
}
// Request the owned state from
// org.chromium.chrome.browser.policy.EnterpriseInfo and notify |callback|
// when the request is complete. |callback| is added to a list of callbacks
// and they are notified in the order they were received.
// Use from the UI thread.
void GetAndroidEnterpriseInfoState(EnterpriseInfoCallback callback);
private:
friend base::NoDestructor<AndroidEnterpriseInfo>;
friend AndroidEnterpriseInfoFriendHelper;
AndroidEnterpriseInfo();
// This function is for the Java side code to return its result.
// Calls are made on the UI thread.
void ServiceCallbacks(bool profile_owned, bool device_owned);
std::queue<EnterpriseInfoCallback> callback_queue_;
SEQUENCE_CHECKER(sequence_checker_);
DISALLOW_COPY_AND_ASSIGN(AndroidEnterpriseInfo);
};
} // namespace enterprise_util
} // namespace chrome
#endif // CHROME_BROWSER_ENTERPRISE_UTIL_ANDROID_ENTERPRISE_INFO_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment