diff options
36 files changed, 826 insertions, 626 deletions
diff --git a/chrome/android/BUILD.gn b/chrome/android/BUILD.gn index 2ae9301..b6fc990 100644 --- a/chrome/android/BUILD.gn +++ b/chrome/android/BUILD.gn @@ -614,6 +614,7 @@ android_library("chrome_shared_test_java") { "//components/invalidation/impl:java", "//components/invalidation/impl:javatests", "//components/navigation_interception/android:navigation_interception_java", + "//components/policy/android:policy_java", "//components/precache/android:precache_java", "//components/precache/android:precache_javatests", "//components/web_contents_delegate_android:web_contents_delegate_android_java", diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java index 2ecf575..3859e8c 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeActivity.java @@ -88,7 +88,6 @@ import org.chromium.chrome.browser.nfc.BeamController; import org.chromium.chrome.browser.nfc.BeamProvider; import org.chromium.chrome.browser.omaha.OmahaClient; import org.chromium.chrome.browser.partnercustomizations.PartnerBrowserCustomizations; -import org.chromium.chrome.browser.policy.PolicyManager.PolicyChangeListener; import org.chromium.chrome.browser.preferences.ChromePreferenceManager; import org.chromium.chrome.browser.preferences.PrefServiceBridge; import org.chromium.chrome.browser.preferences.PreferencesLauncher; @@ -121,6 +120,7 @@ import org.chromium.content.browser.ContentViewCore; import org.chromium.content.common.ContentSwitches; import org.chromium.content_public.browser.LoadUrlParams; import org.chromium.content_public.browser.readback_types.ReadbackResponse; +import org.chromium.policy.CombinedPolicyProvider.PolicyChangeListener; import org.chromium.printing.PrintManagerDelegateImpl; import org.chromium.printing.PrintingController; import org.chromium.ui.base.ActivityWindowAndroid; diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeApplication.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeApplication.java index 194bf1e..1bc6d27 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeApplication.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeApplication.java @@ -61,7 +61,6 @@ import org.chromium.chrome.browser.omaha.UpdateInfoBarHelper; import org.chromium.chrome.browser.partnercustomizations.PartnerBrowserCustomizations; import org.chromium.chrome.browser.policy.PolicyAuditor; import org.chromium.chrome.browser.policy.PolicyManager; -import org.chromium.chrome.browser.policy.PolicyManager.PolicyChangeListener; import org.chromium.chrome.browser.policy.providers.AppRestrictionsPolicyProvider; import org.chromium.chrome.browser.preferences.AccessibilityPreferences; import org.chromium.chrome.browser.preferences.LocationSettings; @@ -92,6 +91,8 @@ import org.chromium.content.browser.BrowserStartupController; import org.chromium.content.browser.ChildProcessLauncher; import org.chromium.content.browser.ContentViewStatics; import org.chromium.content.browser.DownloadController; +import org.chromium.policy.CombinedPolicyProvider; +import org.chromium.policy.CombinedPolicyProvider.PolicyChangeListener; import org.chromium.printing.PrintingController; import org.chromium.sync.signin.AccountManagerDelegate; import org.chromium.sync.signin.AccountManagerHelper; @@ -183,7 +184,6 @@ public class ChromeApplication extends ContentApplication { private ChromeLifetimeController mChromeLifetimeController; private PrintingController mPrintingController; - private PolicyManager mPolicyManager = new PolicyManager(); /** * This is called once per ChromeApplication instance, which get created per process @@ -319,8 +319,7 @@ public class ChromeApplication extends ContentApplication { stopApplicationActivityTracker(); PartnerBrowserCustomizations.destroy(); ShareHelper.clearSharedScreenshots(this); - mPolicyManager.destroy(); - mPolicyManager = null; + CombinedPolicyProvider.get().destroy(); } } @@ -476,9 +475,6 @@ public class ChromeApplication extends ContentApplication { AppBannerManager.setAppDetailsDelegate(createAppDetailsDelegate()); mChromeLifetimeController = new ChromeLifetimeController(this); - mPolicyManager.initializeNative(); - registerPolicyProviders(mPolicyManager); - PrefServiceBridge.getInstance().migratePreferences(this); } @@ -500,6 +496,9 @@ public class ChromeApplication extends ContentApplication { public void startChromeBrowserProcessesAsync(BrowserStartupController.StartupCallback callback) throws ProcessInitException { assert ThreadUtils.runningOnUiThread() : "Tried to start the browser on the wrong thread"; + // The policies are used by browser startup, so we need to register the policy providers + // before starting the browser process. + registerPolicyProviders(CombinedPolicyProvider.get()); Context applicationContext = getApplicationContext(); BrowserStartupController.get(applicationContext, LibraryProcessType.PROCESS_BROWSER) .startBrowserProcessesAsync(callback); @@ -520,6 +519,9 @@ public class ChromeApplication extends ContentApplication { LibraryLoader libraryLoader = LibraryLoader.get(LibraryProcessType.PROCESS_BROWSER); libraryLoader.ensureInitialized(context); libraryLoader.asyncPrefetchLibrariesToMemory(); + // The policies are used by browser startup, so we need to register the policy providers + // before starting the browser process. + registerPolicyProviders(CombinedPolicyProvider.get()); BrowserStartupController.get(context, LibraryProcessType.PROCESS_BROWSER) .startBrowserProcessesSync(false); if (initGoogleServicesManager) { @@ -698,33 +700,47 @@ public class ChromeApplication extends ContentApplication { return new GSAHelper(); } + // TODO(aberent): Change return type and remove cast once downstream CL has landed. @VisibleForTesting public PolicyManager getPolicyManagerForTesting() { - return mPolicyManager; + return (PolicyManager) CombinedPolicyProvider.get(); } /** * Registers various policy providers with the policy manager. * Providers are registered in increasing order of precedence so overrides should call this * method in the end for this method to maintain the highest precedence. - * @param manager The {@link PolicyManager} to register the providers with. + * @param combinedProvider The {@link CombinedPolicyProvider} to register the providers with. + */ + protected void registerPolicyProviders(CombinedPolicyProvider combinedProvider) { + combinedProvider.registerProvider( + new AppRestrictionsPolicyProvider(getApplicationContext())); + } + + /** + * Temp - for compatibility with existing downstream code, which overrides this. + * @param manager The {@link PolicyManager} to register the providers with + * + * TODO(aberent): Remove once the downstream CL lands. */ protected void registerPolicyProviders(PolicyManager manager) { - manager.registerProvider(new AppRestrictionsPolicyProvider(getApplicationContext())); + // Cast the manager's type to force a call to the other overload, avoiding infinite + // recursion + registerPolicyProviders((CombinedPolicyProvider) manager); } /** * Add a listener to be notified upon policy changes. */ public void addPolicyChangeListener(PolicyChangeListener listener) { - mPolicyManager.addPolicyChangeListener(listener); + CombinedPolicyProvider.get().addPolicyChangeListener(listener); } /** * Remove a listener to be notified upon policy changes. */ public void removePolicyChangeListener(PolicyChangeListener listener) { - mPolicyManager.removePolicyChangeListener(listener); + CombinedPolicyProvider.get().removePolicyChangeListener(listener); } /** diff --git a/chrome/android/java/src/org/chromium/chrome/browser/policy/PolicyManager.java b/chrome/android/java/src/org/chromium/chrome/browser/policy/PolicyManager.java index d4f1e20..2682024 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/policy/PolicyManager.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/policy/PolicyManager.java @@ -4,111 +4,10 @@ package org.chromium.chrome.browser.policy; -import android.os.Bundle; - -import org.chromium.base.CalledByNative; -import org.chromium.base.ThreadUtils; -import org.chromium.policy.PolicyConverter; - -import java.util.ArrayList; -import java.util.List; +import org.chromium.policy.CombinedPolicyProvider; /** - * Reads enterprise policies from one or more policy providers - * and plumbs them through to the policy subsystem. + * Temp version of old class to avoid breaking downstream builds + * TODO(aberent): Remove once downstream CL lands */ -public class PolicyManager { - private long mNativePolicyManager; - - private PolicyConverter mPolicyConverter; - private final List<PolicyProvider> mPolicyProviders = new ArrayList<>(); - private final List<Bundle> mCachedPolicies = new ArrayList<>(); - private final List<PolicyChangeListener> mPolicyChangeListeners = new ArrayList<>(); - - public void initializeNative() { - ThreadUtils.assertOnUiThread(); - mNativePolicyManager = nativeInit(); - mPolicyConverter = nativeCreatePolicyConverter(mNativePolicyManager); - } - - /** - * PolicyProviders are assigned a unique precedence based on their order of registration. - * Later Registration -> Higher Precedence. - * This precedence is also used as a 'source' tag for disambiguating updates. - */ - public void registerProvider(PolicyProvider provider) { - mPolicyProviders.add(provider); - mCachedPolicies.add(null); - provider.setManagerAndSource(this, mPolicyProviders.size() - 1); - provider.refresh(); - } - - public void destroy() { - // All the activities registered should have been destroyed by then. - assert mPolicyChangeListeners.isEmpty(); - - for (PolicyProvider provider : mPolicyProviders) { - provider.destroy(); - } - mPolicyProviders.clear(); - - nativeDestroy(mNativePolicyManager); - mNativePolicyManager = 0; - mPolicyConverter = null; - } - - void onSettingsAvailable(int source, Bundle newSettings) { - mCachedPolicies.set(source, newSettings); - // Check if we have policies from all the providers before applying them. - for (Bundle settings : mCachedPolicies) { - if (settings == null) return; - } - for (Bundle settings : mCachedPolicies) { - for (String key : settings.keySet()) { - mPolicyConverter.setPolicy(key, settings.get(key)); - } - } - nativeFlushPolicies(mNativePolicyManager); - } - - void terminateIncognitoSession() { - for (PolicyChangeListener listener : mPolicyChangeListeners) { - listener.terminateIncognitoSession(); - } - } - - public void addPolicyChangeListener(PolicyChangeListener listener) { - mPolicyChangeListeners.add(listener); - } - - public void removePolicyChangeListener(PolicyChangeListener listener) { - assert mPolicyChangeListeners.contains(listener); - mPolicyChangeListeners.remove(listener); - } - - @CalledByNative - private void refreshPolicies() { - assert mPolicyProviders.size() == mCachedPolicies.size(); - for (int i = 0; i < mCachedPolicies.size(); ++i) { - mCachedPolicies.set(i, null); - } - for (PolicyProvider provider : mPolicyProviders) { - provider.refresh(); - } - } - - /** - * Interface to handle actions related with policy changes. - */ - public interface PolicyChangeListener { - /** - * Call to notify the listener that incognito browsing is unavailable due to policy. - */ - void terminateIncognitoSession(); - } - - private native long nativeInit(); - private native PolicyConverter nativeCreatePolicyConverter(long nativePolicyManager); - private native void nativeDestroy(long nativePolicyManager); - private native void nativeFlushPolicies(long nativePolicyManager); -} +public class PolicyManager extends CombinedPolicyProvider {} diff --git a/chrome/android/java/src/org/chromium/chrome/browser/policy/PolicyProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/policy/PolicyProvider.java index f26e4de..0563ebf 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/policy/PolicyProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/policy/PolicyProvider.java @@ -5,55 +5,22 @@ package org.chromium.chrome.browser.policy; import android.content.Context; -import android.os.Bundle; + +import org.chromium.base.annotations.SuppressFBWarnings; /** - * Base class for Policy providers. + * Temp version of old class to avoid breaking downstream builds + * TODO(aberent): Remove once downstream CL lands. + * FB warnings suppressed because FB doesn't like the two classes having the + * same simple name, which I can't avoid here. */ -public abstract class PolicyProvider { - private PolicyManager mPolicyManager; - protected final Context mContext; - private int mSource = -1; - - protected PolicyProvider(Context context) { - mContext = context.getApplicationContext(); - } - - protected void notifySettingsAvailable(Bundle settings) { - mPolicyManager.onSettingsAvailable(mSource, settings); - } - - protected void terminateIncognitoSession() { - mPolicyManager.terminateIncognitoSession(); - } - +@SuppressFBWarnings +public abstract class PolicyProvider extends org.chromium.policy.PolicyProvider { /** - * Called to request a refreshed set of policies. - * This method must handle notifying the PolicyManager whenever applicable. + * @param context */ - public abstract void refresh(); - - /** - * Register the PolicyProvider for receiving policy changes. - */ - protected void startListeningForPolicyChanges() { - } - - /** - * Called by the {@link PolicyManager} to correctly hook it with the Policy system. - * @param policyManager reference to the PolicyManager to be used like a delegate. - * @param source tags the PolicyProvider with a source. - */ - final void setManagerAndSource(PolicyManager policyManager, int source) { - assert mSource < 0; - assert source >= 0; - mSource = source; - assert mPolicyManager == null; - mPolicyManager = policyManager; - startListeningForPolicyChanges(); + protected PolicyProvider(Context context) { + super(context); } - /** Called when the provider is unregistered */ - public void destroy() { - } } diff --git a/chrome/android/java/src/org/chromium/chrome/browser/policy/providers/AppRestrictionsPolicyProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/policy/providers/AppRestrictionsPolicyProvider.java index 35b9f8c..977fa28 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/policy/providers/AppRestrictionsPolicyProvider.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/policy/providers/AppRestrictionsPolicyProvider.java @@ -7,8 +7,8 @@ package org.chromium.chrome.browser.policy.providers; import android.content.Context; import android.os.Bundle; -import org.chromium.chrome.browser.policy.PolicyProvider; import org.chromium.policy.AppRestrictionsProvider; +import org.chromium.policy.PolicyProvider; /** * Policy provider for Android's App Restriction Schema. diff --git a/chrome/browser/android/chrome_jni_registrar.cc b/chrome/browser/android/chrome_jni_registrar.cc index 94e56b2..a541fc9 100644 --- a/chrome/browser/android/chrome_jni_registrar.cc +++ b/chrome/browser/android/chrome_jni_registrar.cc @@ -55,7 +55,6 @@ #include "chrome/browser/android/omnibox/autocomplete_controller_android.h" #include "chrome/browser/android/omnibox/omnibox_prerender.h" #include "chrome/browser/android/password_ui_view_android.h" -#include "chrome/browser/android/policy/policy_manager.h" #include "chrome/browser/android/precache/precache_launcher.h" #include "chrome/browser/android/preferences/autofill/autofill_profile_bridge.h" #include "chrome/browser/android/preferences/pref_service_bridge.h" @@ -270,7 +269,6 @@ static base::android::RegistrationMethod kChromeRegisteredMethods[] = { PermissionUpdateInfoBarDelegate::RegisterPermissionUpdateInfoBarDelegate}, {"PersonalDataManagerAndroid", autofill::PersonalDataManagerAndroid::Register}, - {"PolicyManager", RegisterPolicyManager}, {"PrecacheLauncher", RegisterPrecacheLauncher}, {"PrefServiceBridge", PrefServiceBridge::RegisterPrefServiceBridge}, {"ProfileAndroid", ProfileAndroid::RegisterProfileAndroid}, diff --git a/chrome/browser/android/chrome_main_delegate_staging_android.cc b/chrome/browser/android/chrome_main_delegate_staging_android.cc index 2f7ae53..2042718 100644 --- a/chrome/browser/android/chrome_main_delegate_staging_android.cc +++ b/chrome/browser/android/chrome_main_delegate_staging_android.cc @@ -8,7 +8,7 @@ #include "base/files/file_util.h" #include "base/logging.h" #include "base/path_service.h" -#include "components/policy/core/common/policy_provider_android.h" +#include "components/policy/core/browser/android/android_combined_policy_provider.h" #if defined(SAFE_BROWSING_DB_REMOTE) #include "chrome/browser/safe_browsing/safe_browsing_api_handler.h" @@ -36,7 +36,7 @@ bool ChromeMainDelegateStagingAndroid::BasicStartupComplete(int* exit_code) { SafeBrowsingResourceThrottleFactory::RegisterFactory( data_reduction_proxy_throttle_factory_.get()); #endif - policy::PolicyProviderAndroid::SetShouldWaitForPolicy(true); + policy::android::AndroidCombinedPolicyProvider::SetShouldWaitForPolicy(true); return ChromeMainDelegateAndroid::BasicStartupComplete(exit_code); } diff --git a/chrome/browser/android/policy/policy_manager.cc b/chrome/browser/android/policy/policy_manager.cc deleted file mode 100644 index 696f3a2..0000000 --- a/chrome/browser/android/policy/policy_manager.cc +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright 2015 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/android/policy/policy_manager.h" - -#include "base/android/jni_android.h" -#include "chrome/browser/browser_process.h" -#include "chrome/browser/browser_process_platform_part.h" -#include "components/policy/core/browser/android/policy_converter.h" -#include "components/policy/core/browser/browser_policy_connector.h" -#include "components/policy/core/common/policy_provider_android.h" -#include "components/policy/core/common/schema.h" -#include "jni/PolicyManager_jni.h" - -using base::android::AttachCurrentThread; -using base::android::ScopedJavaLocalRef; - -PolicyManager::PolicyManager(JNIEnv* env, jobject obj) - : weak_java_policy_manager_(env, obj) { - policy_provider_ = static_cast<policy::PolicyProviderAndroid*>( - g_browser_process->browser_policy_connector()->GetPlatformProvider()); - policy_provider_->SetDelegate(this); -} - -PolicyManager::~PolicyManager() {} - -ScopedJavaLocalRef<jobject> PolicyManager::CreatePolicyConverter(JNIEnv* env, - jobject obj) { - policy_converter_.reset(new policy::android::PolicyConverter( - policy_provider_->GetChromeSchema())); - return ScopedJavaLocalRef<jobject>(policy_converter_->GetJavaObject()); -} - -void PolicyManager::RefreshPolicies() { - JNIEnv* env = AttachCurrentThread(); - Java_PolicyManager_refreshPolicies( - env, weak_java_policy_manager_.get(env).obj()); -} - -void PolicyManager::PolicyProviderShutdown() { - policy_provider_ = nullptr; -} - -void PolicyManager::FlushPolicies(JNIEnv* env, jobject obj) { - if (!policy_provider_) - return; - - policy_provider_->SetPolicies(policy_converter_->GetPolicyBundle()); -} - -void PolicyManager::Destroy(JNIEnv* env, jobject obj) { - if (policy_provider_) - policy_provider_->SetDelegate(nullptr); - - delete this; -} - -static jlong Init(JNIEnv* env, jobject obj) { - return reinterpret_cast<intptr_t>(new PolicyManager(env, obj)); -} - -bool RegisterPolicyManager(JNIEnv* env) { - return RegisterNativesImpl(env); -} diff --git a/chrome/browser/android/policy/policy_manager.h b/chrome/browser/android/policy/policy_manager.h deleted file mode 100644 index 21c72be..0000000 --- a/chrome/browser/android/policy/policy_manager.h +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2015 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_ANDROID_POLICY_POLICY_MANAGER_H_ -#define CHROME_BROWSER_ANDROID_POLICY_POLICY_MANAGER_H_ - -#include <jni.h> - -#include "base/android/jni_weak_ref.h" -#include "base/macros.h" -#include "base/memory/scoped_ptr.h" -#include "components/policy/core/common/policy_provider_android_delegate.h" - -namespace policy { - -class PolicyProviderAndroid; - -namespace android { - -class PolicyConverter; - -} // namespace android -} // namespace policy - -class PolicyManager : public policy::PolicyProviderAndroidDelegate { - public: - PolicyManager(JNIEnv* env, jobject obj); - - void FlushPolicies(JNIEnv* env, jobject obj); - - void Destroy(JNIEnv* env, jobject obj); - - // Creates the native and java |PolicyConverter|, returns the reference to - // the java one. - base::android::ScopedJavaLocalRef<jobject> CreatePolicyConverter(JNIEnv* env, - jobject obj); - - // PolicyProviderAndroidDelegate: - void RefreshPolicies() override; - void PolicyProviderShutdown() override; - - private: - ~PolicyManager() override; - - JavaObjectWeakGlobalRef weak_java_policy_manager_; - - scoped_ptr<policy::android::PolicyConverter> policy_converter_; - policy::PolicyProviderAndroid* policy_provider_; - - DISALLOW_COPY_AND_ASSIGN(PolicyManager); -}; - -// Register native methods -bool RegisterPolicyManager(JNIEnv* env); - -#endif // CHROME_BROWSER_ANDROID_POLICY_POLICY_MANAGER_H_ diff --git a/chrome/browser/policy/chrome_browser_policy_connector.cc b/chrome/browser/policy/chrome_browser_policy_connector.cc index e27d38b..5f19b2a 100644 --- a/chrome/browser/policy/chrome_browser_policy_connector.cc +++ b/chrome/browser/policy/chrome_browser_policy_connector.cc @@ -37,7 +37,7 @@ #elif defined(OS_POSIX) && !defined(OS_ANDROID) #include "components/policy/core/common/config_dir_policy_loader.h" #elif defined(OS_ANDROID) -#include "components/policy/core/common/policy_provider_android.h" +#include "components/policy/core/browser/android/android_combined_policy_provider.h" #endif using content::BrowserThread; @@ -114,7 +114,8 @@ ConfigurationPolicyProvider* return NULL; } #elif defined(OS_ANDROID) - return new PolicyProviderAndroid(); + return new policy::android::AndroidCombinedPolicyProvider( + GetSchemaRegistry()); #else return NULL; #endif diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 3756b07..d547c5d 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -190,8 +190,6 @@ 'browser/android/omnibox/omnibox_prerender.h', 'browser/android/password_ui_view_android.cc', 'browser/android/password_ui_view_android.h', - 'browser/android/policy/policy_manager.cc', - 'browser/android/policy/policy_manager.h', 'browser/android/precache/precache_launcher.cc', 'browser/android/precache/precache_launcher.h', 'browser/android/preferences/autofill/autofill_profile_bridge.cc', @@ -1755,7 +1753,6 @@ 'android/java/src/org/chromium/chrome/browser/omnibox/OmniboxViewUtil.java', 'android/java/src/org/chromium/chrome/browser/partnerbookmarks/PartnerBookmarksReader.java', 'android/java/src/org/chromium/chrome/browser/password_manager/Credential.java', - 'android/java/src/org/chromium/chrome/browser/policy/PolicyManager.java', 'android/java/src/org/chromium/chrome/browser/PasswordUIView.java', 'android/java/src/org/chromium/chrome/browser/precache/PrecacheLauncher.java', 'android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillProfileBridge.java', diff --git a/chrome/test/android/BUILD.gn b/chrome/test/android/BUILD.gn index 7c09f5a..6f9e4bb 100644 --- a/chrome/test/android/BUILD.gn +++ b/chrome/test/android/BUILD.gn @@ -15,6 +15,7 @@ android_library("chrome_java_test_support") { "//chrome/android:chrome_java_resources", "//components/bookmarks/common/android:bookmarks_java", "//components/invalidation/impl:java", + "//components/policy/android:policy_java", "//components/web_contents_delegate_android:web_contents_delegate_android_java", "//content/public/android:content_java", "//content/public/test/android:content_java_test_support", diff --git a/components/components_tests.gyp b/components/components_tests.gyp index afa86ee..09d599f 100644 --- a/components/components_tests.gyp +++ b/components/components_tests.gyp @@ -396,6 +396,7 @@ 'password_manager/core/common/credential_manager_types_unittest.cc', ], 'policy_unittest_sources': [ + 'policy/core/browser/android/android_combined_policy_provider_unittest.cc', 'policy/core/browser/android/policy_converter_unittest.cc', 'policy/core/browser/autofill_policy_handler_unittest.cc', 'policy/core/browser/browser_policy_connector_unittest.cc', @@ -429,7 +430,6 @@ 'policy/core/common/policy_loader_mac_unittest.cc', 'policy/core/common/policy_loader_win_unittest.cc', 'policy/core/common/policy_map_unittest.cc', - 'policy/core/common/policy_provider_android_unittest.cc', 'policy/core/common/policy_service_impl_unittest.cc', 'policy/core/common/policy_statistics_collector_unittest.cc', 'policy/core/common/preg_parser_win_unittest.cc', @@ -990,6 +990,7 @@ 'conditions': [ ['OS=="android"', { 'dependencies': [ + 'components.gyp:policy_java', '../build/android/ndk.gyp:cpu_features', ], }], @@ -1556,6 +1557,25 @@ }, 'includes': [ '../build/apk_test.gypi' ], }, + { + 'target_name': 'components_junit_tests', + 'type': 'none', + 'dependencies': [ + 'components.gyp:invalidation_java', + 'components.gyp:policy_java', + '../base/base.gyp:base_java', + '../base/base.gyp:base_java_test_support', + '../testing/android/junit/junit_test.gyp:junit_test_support', + ], + 'variables': { + 'main_class': 'org.chromium.testing.local.JunitTestMain', + 'src_paths': [ + 'invalidation/impl/android/junit/', + 'policy/android/junit/' + ], + }, + 'includes': [ '../build/host_jar.gypi' ], + }, ], }], ], diff --git a/components/invalidation.gypi b/components/invalidation.gypi index 8329c8c..4e361f8 100644 --- a/components/invalidation.gypi +++ b/components/invalidation.gypi @@ -231,23 +231,6 @@ 'includes': [ '../build/java.gypi' ], }, { - 'target_name': 'invalidation_junit_tests', - 'type': 'none', - 'dependencies': [ - 'invalidation_java', - '../base/base.gyp:base_java', - '../base/base.gyp:base_java_test_support', - '../testing/android/junit/junit_test.gyp:junit_test_support', - ], - 'variables': { - 'main_class': 'org.chromium.testing.local.JunitTestMain', - 'src_paths': [ - 'invalidation/impl/android/junit/' - ], - }, - 'includes': [ '../build/host_jar.gypi' ], - }, - { 'target_name': 'invalidation_jni_headers', 'type': 'none', 'sources': [ diff --git a/components/policy.gypi b/components/policy.gypi index 2302487..d032ace 100644 --- a/components/policy.gypi +++ b/components/policy.gypi @@ -62,6 +62,11 @@ 'includes': [ 'policy/policy_browser.gypi', ], + 'conditions': [ + ['OS=="android"', { + 'dependencies': ['policy_jni_headers']}, + ], + ], }, ], }, { # component=="shared_library" @@ -82,6 +87,11 @@ 'dependencies': [ 'policy_component', ], + 'conditions': [ + ['OS=="android"', { + 'dependencies': ['policy_jni_headers']}, + ], + ], }, { # GN version: //components/policy:policy_component_browser @@ -339,6 +349,23 @@ }, ], }], + ['OS=="android"', + { + 'targets' : [ + { + 'target_name' : 'policy_jni_headers', + 'type': 'none', + 'sources': [ + 'policy/android/java/src/org/chromium/policy/CombinedPolicyProvider.java', + 'policy/android/java/src/org/chromium/policy/PolicyConverter.java', + ], + 'variables': { + 'jni_gen_package': 'policy', + }, + 'includes': [ '../build/jni_generator.gypi' ], + }, + ], + }], ['OS=="android" and configuration_policy==1', { 'targets': [ { @@ -395,18 +422,6 @@ }, 'includes': [ '../build/java.gypi' ], }, - { - # GN: //components/policy/android:jni_headers - 'target_name': 'policy_jni_headers', - 'type': 'none', - 'sources': [ - 'policy/android/java/src/org/chromium/policy/PolicyConverter.java', - ], - 'variables': { - 'jni_gen_package': 'policy', - }, - 'includes': [ '../build/jni_generator.gypi' ], - }, ], }], ['OS=="win" and target_arch=="ia32" and configuration_policy==1', { diff --git a/components/policy/android/BUILD.gn b/components/policy/android/BUILD.gn index 9784e36..3598072 100644 --- a/components/policy/android/BUILD.gn +++ b/components/policy/android/BUILD.gn @@ -4,15 +4,20 @@ import("//build/config/android/rules.gni") -_jni_sources = [ "java/src/org/chromium/policy/PolicyConverter.java" ] +_jni_sources = [ + "java/src/org/chromium/policy/PolicyConverter.java", + "java/src/org/chromium/policy/CombinedPolicyProvider.java", +] # GYP: //components/components.gyp:policy_java android_library("policy_java") { deps = [ "//base:base_java", ] - java_files = [ "java/src/org/chromium/policy/AppRestrictionsProvider.java" ] + - _jni_sources + java_files = [ + "java/src/org/chromium/policy/AppRestrictionsProvider.java", + "java/src/org/chromium/policy/PolicyProvider.java", + ] + _jni_sources } # GYP: //components/components.gyp:policy_jni_headers diff --git a/components/policy/android/java/src/org/chromium/policy/AppRestrictionsProvider.java b/components/policy/android/java/src/org/chromium/policy/AppRestrictionsProvider.java index cb4f8a0..dc3858e 100644 --- a/components/policy/android/java/src/org/chromium/policy/AppRestrictionsProvider.java +++ b/components/policy/android/java/src/org/chromium/policy/AppRestrictionsProvider.java @@ -9,14 +9,22 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.content.SharedPreferences; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; +import android.os.Parcel; import android.os.UserManager; +import android.preference.PreferenceManager; +import android.util.Base64; + +import org.chromium.base.metrics.RecordHistogram; + +import java.util.concurrent.TimeUnit; /** - * Retrieves app restrictions and provides them to a {@link Delegate} object as Bundles. - * Retrieving the restrictions is done asynchronously. + * Retrieves app restrictions and provides them to a {@link Delegate} object as Bundles. Retrieving + * the restrictions is done asynchronously. */ public class AppRestrictionsProvider { /** Delegate to notify when restrictions have been received. */ @@ -25,9 +33,12 @@ public class AppRestrictionsProvider { public void notifyNewAppRestrictionsAvailable(Bundle newAppRestrictions); } + private static final String PREFERENCE_KEY = "App Restrictions"; + private final UserManager mUserManager; private final Context mContext; private final Delegate mDelegate; + private final SharedPreferences mSharedPreferences; private final BroadcastReceiver mAppRestrictionsChangedReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { @@ -37,13 +48,14 @@ public class AppRestrictionsProvider { /** * @param context The application context. - * @param appRestrictionsProviderDelegate Object to be notified when new restrictions - * are available. + * @param appRestrictionsProviderDelegate Object to be notified when new restrictions are + * available. */ public AppRestrictionsProvider(Context context, Delegate appRestrictionsProviderDelegate) { mContext = context; mDelegate = appRestrictionsProviderDelegate; mUserManager = getUserManager(); + mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(mContext); } /** @@ -66,15 +78,24 @@ public class AppRestrictionsProvider { mDelegate.notifyNewAppRestrictionsAvailable(new Bundle()); return; } + final Bundle cachedResult = getCachedPolicies(); + if (cachedResult != null) { + mDelegate.notifyNewAppRestrictionsAvailable(cachedResult); + } new AsyncTask<Void, Void, Bundle>() { @Override protected Bundle doInBackground(Void... params) { - return getApplicationRestrictions(); + long startTime = System.currentTimeMillis(); + Bundle bundle = getApplicationRestrictions(); + RecordHistogram.recordTimesHistogram("Enterprise.AppRestrictionLoadTime", + System.currentTimeMillis() - startTime, TimeUnit.MILLISECONDS); + return bundle; } @Override protected void onPostExecute(Bundle result) { + cachePolicies(result); mDelegate.notifyNewAppRestrictionsAvailable(result); } }.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); @@ -105,8 +126,8 @@ public class AppRestrictionsProvider { } /** - * Wrap access to the Android UserManager to allow being swapped out in environments where it - * is not available yet. + * Wrap access to the Android UserManager to allow being swapped out in environments where it is + * not available yet. */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) private Bundle getApplicationRestrictions() { @@ -114,12 +135,45 @@ public class AppRestrictionsProvider { } /** - * Wrap access to the Android UserManager to allow being swapped out in environments where it - * is not available yet. + * Wrap access to the Android UserManager to allow being swapped out in environments where it is + * not available yet. */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) private UserManager getUserManager() { if (!isRestrictionsSupported()) return null; return (UserManager) mContext.getSystemService(Context.USER_SERVICE); } + + private void cachePolicies(Bundle policies) { + Parcel p = Parcel.obtain(); + p.writeBundle(policies); + byte bytes[] = p.marshall(); + String s = Base64.encodeToString(bytes, 0); + SharedPreferences.Editor ed = mSharedPreferences.edit(); + ed.putString(PREFERENCE_KEY, s); + ed.apply(); + } + + private Bundle getCachedPolicies() { + String s = mSharedPreferences.getString(PREFERENCE_KEY, null); + if (s == null) { + return null; + } + byte bytes[] = Base64.decode(s, 0); + Parcel p = Parcel.obtain(); + // Unmarshalling the parcel is, in theory, unsafe if the Android version or API version has + // changed, but the worst that is likely to happen is that the bundle comes back empty, and + // this will be corrected once the Android returns the real App Restrictions. + p.unmarshall(bytes, 0, bytes.length); + p.setDataPosition(0); + Bundle result = p.readBundle(); + try { + result = p.readBundle(); + } catch (IllegalStateException e) { + result = null; + } + RecordHistogram.recordBooleanHistogram( + "Enterprise.AppRestrictionsCacheLoad", result != null); + return result; + } } diff --git a/components/policy/android/java/src/org/chromium/policy/CombinedPolicyProvider.java b/components/policy/android/java/src/org/chromium/policy/CombinedPolicyProvider.java new file mode 100644 index 0000000..13991d9 --- /dev/null +++ b/components/policy/android/java/src/org/chromium/policy/CombinedPolicyProvider.java @@ -0,0 +1,148 @@ +// Copyright 2015 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. + +package org.chromium.policy; + +import android.os.Bundle; + +import org.chromium.base.CalledByNative; +import org.chromium.base.JNINamespace; +import org.chromium.base.ThreadUtils; +import org.chromium.base.VisibleForTesting; + +import java.util.ArrayList; +import java.util.List; + +/** + * Reads enterprise policies from one or more policy providers and plumbs them through to the policy + * subsystem. + */ +@JNINamespace("policy::android") +public class CombinedPolicyProvider { + private static CombinedPolicyProvider sInstance = null; + + private long mNativeCombinedPolicyProvider = 0; + + private PolicyConverter mPolicyConverter; + private final List<PolicyProvider> mPolicyProviders = new ArrayList<>(); + private final List<Bundle> mCachedPolicies = new ArrayList<>(); + private final List<PolicyChangeListener> mPolicyChangeListeners = new ArrayList<>(); + + public static CombinedPolicyProvider get() { + if (sInstance == null) { + sInstance = new CombinedPolicyProvider(); + } + return sInstance; + } + + private void linkNativeInternal( + long nativeCombinedPolicyProvider, PolicyConverter policyConverter) { + mNativeCombinedPolicyProvider = nativeCombinedPolicyProvider; + mPolicyConverter = policyConverter; + if (nativeCombinedPolicyProvider != 0) { + for (PolicyProvider provider : mPolicyProviders) { + provider.refresh(); + } + } + } + + @CalledByNative + public static CombinedPolicyProvider linkNative( + long nativeCombinedPolicyProvider, PolicyConverter policyConverter) { + ThreadUtils.assertOnUiThread(); + get().linkNativeInternal(nativeCombinedPolicyProvider, policyConverter); + return get(); + } + + /** + * PolicyProviders are assigned a unique precedence based on their order of registration. Later + * Registration -> Higher Precedence. This precedence is also used as a 'source' tag for + * disambiguating updates. + */ + public void registerProvider(PolicyProvider provider) { + mPolicyProviders.add(provider); + mCachedPolicies.add(null); + provider.setManagerAndSource(this, mPolicyProviders.size() - 1); + if (mNativeCombinedPolicyProvider != 0) provider.refresh(); + } + + public void destroy() { + // All the activities registered should have been destroyed by then. + assert mPolicyChangeListeners.isEmpty(); + + for (PolicyProvider provider : mPolicyProviders) { + provider.destroy(); + } + mPolicyProviders.clear(); + mPolicyConverter = null; + } + + void onSettingsAvailable(int source, Bundle newSettings) { + mCachedPolicies.set(source, newSettings); + // Check if we have policies from all the providers before applying them. + for (Bundle settings : mCachedPolicies) { + if (settings == null) return; + } + + if (mNativeCombinedPolicyProvider == 0) return; + + for (Bundle settings : mCachedPolicies) { + for (String key : settings.keySet()) { + mPolicyConverter.setPolicy(key, settings.get(key)); + } + } + nativeFlushPolicies(mNativeCombinedPolicyProvider); + } + + void terminateIncognitoSession() { + for (PolicyChangeListener listener : mPolicyChangeListeners) { + listener.terminateIncognitoSession(); + } + } + + public void addPolicyChangeListener(PolicyChangeListener listener) { + mPolicyChangeListeners.add(listener); + } + + public void removePolicyChangeListener(PolicyChangeListener listener) { + assert mPolicyChangeListeners.contains(listener); + mPolicyChangeListeners.remove(listener); + } + + @VisibleForTesting + @CalledByNative + void refreshPolicies() { + assert mPolicyProviders.size() == mCachedPolicies.size(); + for (int i = 0; i < mCachedPolicies.size(); ++i) { + mCachedPolicies.set(i, null); + } + for (PolicyProvider provider : mPolicyProviders) { + provider.refresh(); + } + } + + /** + * Interface to handle actions related with policy changes. + */ + public interface PolicyChangeListener { + /** + * Call to notify the listener that incognito browsing is unavailable due to policy. + */ + void terminateIncognitoSession(); + } + + @VisibleForTesting + public static void set(CombinedPolicyProvider p) { + sInstance = p; + } + + // Constructor needs to be public (temporarily) to so that PolicyManager can be derived from + // this class. Also needed, with package scope, for testing. + // TODO(aberent): Once upstream CL lands change to package scope. + // @VisibleForTesting + // CombinedPolicyProvider() {} + + @VisibleForTesting + protected native void nativeFlushPolicies(long nativeAndroidCombinedPolicyProvider); +} diff --git a/components/policy/android/java/src/org/chromium/policy/PolicyProvider.java b/components/policy/android/java/src/org/chromium/policy/PolicyProvider.java new file mode 100644 index 0000000..4375d24 --- /dev/null +++ b/components/policy/android/java/src/org/chromium/policy/PolicyProvider.java @@ -0,0 +1,59 @@ +// Copyright 2015 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. + +package org.chromium.policy; + +import android.content.Context; +import android.os.Bundle; + +/** + * Base class for Policy providers. + */ +public abstract class PolicyProvider { + private CombinedPolicyProvider mCombinedPolicyProvider; + protected final Context mContext; + private int mSource = -1; + + protected PolicyProvider(Context context) { + mContext = context.getApplicationContext(); + } + + protected void notifySettingsAvailable(Bundle settings) { + mCombinedPolicyProvider.onSettingsAvailable(mSource, settings); + } + + protected void terminateIncognitoSession() { + mCombinedPolicyProvider.terminateIncognitoSession(); + } + + /** + * Called to request a refreshed set of policies. This method must handle notifying the + * CombinedPolicyProvider whenever applicable. + */ + public abstract void refresh(); + + /** + * Register the PolicyProvider for receiving policy changes. + */ + protected void startListeningForPolicyChanges() {} + + /** + * Called by the {@link CombinedPolicyProvider} to correctly hook it with the Policy system. + * + * @param combinedPolicyProvider reference to the CombinedPolicyProvider to be used like a + * delegate. + * @param source tags the PolicyProvider with a source. + */ + final void setManagerAndSource(CombinedPolicyProvider combinedPolicyProvider, int source) { + assert mSource < 0; + assert source >= 0; + mSource = source; + assert mCombinedPolicyProvider == null; + mCombinedPolicyProvider = combinedPolicyProvider; + startListeningForPolicyChanges(); + } + + /** Called when the provider is unregistered */ + public void destroy() {} +} diff --git a/components/policy/android/junit/src/org/chromium/policy/CombinedPolicyProviderTest.java b/components/policy/android/junit/src/org/chromium/policy/CombinedPolicyProviderTest.java new file mode 100644 index 0000000..6d510a0 --- /dev/null +++ b/components/policy/android/junit/src/org/chromium/policy/CombinedPolicyProviderTest.java @@ -0,0 +1,189 @@ +// Copyright 2015 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. + +package org.chromium.policy; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyBoolean; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.anyLong; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; + +import android.os.Bundle; + +import org.chromium.testing.local.LocalRobolectricTestRunner; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.Robolectric; +import org.robolectric.annotation.Config; + +/** + * Robolectric tests for CombinedPolicyProvider + */ +@RunWith(LocalRobolectricTestRunner.class) +@Config(manifest = Config.NONE) +public class CombinedPolicyProviderTest { + private PolicyConverter mPolicyConverter; + + @Before + public void setup() { + // Stub out the native calls + CombinedPolicyProvider provider = spy(new CombinedPolicyProvider()); + mPolicyConverter = mock(PolicyConverter.class); + doNothing().when(mPolicyConverter).setPolicy(anyString(), any()); + doNothing().when(provider).nativeFlushPolicies(anyLong()); + CombinedPolicyProvider.set(provider); + } + + /** + * Dummy concrete class. Needed because PolicyProvider has final functions that cannot be + * stubbed and is abstract so can't be directly instantiated to be spied upon. + */ + class DummyPolicyProvider extends PolicyProvider { + public DummyPolicyProvider() { + super(Robolectric.application); + } + + @Override + public void refresh() { + // Do nothing + } + } + + @Test + public void testRegisterProvider() { + // Have to spy not mock here so that the real constructor gets called, hence avoiding + // an assert in PolicyProvider.setManagerAndSource. + PolicyProvider provider = spy(new DummyPolicyProvider()); + CombinedPolicyProvider.get().registerProvider(provider); + // Can't verify PolicyProvider.setManagerAndSource directly because it is final. + // This, at least, demonstrates that it has been called. + verify(provider).startListeningForPolicyChanges(); + verify(provider, never()).refresh(); + assertEquals(CombinedPolicyProvider.get(), + CombinedPolicyProvider.linkNative(1234, mPolicyConverter)); + verify(provider).refresh(); + PolicyProvider provider2 = spy(new DummyPolicyProvider()); + CombinedPolicyProvider.get().registerProvider(provider2); + verify(provider2).startListeningForPolicyChanges(); + verify(provider2).refresh(); + } + + @Test + public void testOnSettingsAvailable_noNative() { + // No native policy manager + PolicyProvider provider = new DummyPolicyProvider(); + CombinedPolicyProvider.get().registerProvider(provider); + Bundle b = new Bundle(); + b.putBoolean("BoolPolicy", true); + CombinedPolicyProvider.get().onSettingsAvailable(0, b); + verify(mPolicyConverter, never()).setPolicy(anyString(), any()); + verify(CombinedPolicyProvider.get(), never()).nativeFlushPolicies(anyInt()); + } + + @Test + public void testOnSettingsAvailable_oneProvider() { + CombinedPolicyProvider.linkNative(1234, mPolicyConverter); + PolicyProvider provider = new DummyPolicyProvider(); + CombinedPolicyProvider.get().registerProvider(provider); + Bundle b = new Bundle(); + b.putBoolean("BoolPolicy", false); + b.putInt("IntPolicy", 42); + b.putString("StringPolicy", "A string"); + b.putStringArray("StringArrayPolicy", new String[] {"String1", "String2"}); + CombinedPolicyProvider.get().onSettingsAvailable(0, b); + verify(mPolicyConverter).setPolicy("BoolPolicy", false); + verify(mPolicyConverter).setPolicy("IntPolicy", 42); + verify(mPolicyConverter).setPolicy("StringPolicy", "A string"); + verify(mPolicyConverter) + .setPolicy("StringArrayPolicy", new String[] {"String1", "String2"}); + verify(CombinedPolicyProvider.get()).nativeFlushPolicies(1234); + } + + @Test + public void testOnSettingsAvailable_secondProvider() { + CombinedPolicyProvider.linkNative(1234, mPolicyConverter); + PolicyProvider provider = new DummyPolicyProvider(); + CombinedPolicyProvider.get().registerProvider(provider); + Bundle b = new Bundle(); + CombinedPolicyProvider.get().onSettingsAvailable(0, b); + verify(CombinedPolicyProvider.get()).nativeFlushPolicies(1234); + + // Second policy provider registered but no settings. + PolicyProvider provider2 = new DummyPolicyProvider(); + CombinedPolicyProvider.get().registerProvider(provider2); + b = new Bundle(); + b.putBoolean("BoolPolicy", true); + CombinedPolicyProvider.get().onSettingsAvailable(0, b); + + // Second call should have been ignored, so nothing should have been set + verify(mPolicyConverter, never()).setPolicy(anyString(), anyBoolean()); + // and flush should have been called precisely once. + verify(CombinedPolicyProvider.get()).nativeFlushPolicies(1234); + + // Empty but valid bundle from second policy provider should set the policy and push it + // to the native code + b = new Bundle(); + CombinedPolicyProvider.get().onSettingsAvailable(1, b); + verify(mPolicyConverter).setPolicy("BoolPolicy", true); + verify(CombinedPolicyProvider.get(), times(2)).nativeFlushPolicies(1234); + } + + @Test + public void testRefreshPolicies() { + CombinedPolicyProvider.linkNative(1234, mPolicyConverter); + PolicyProvider provider = new DummyPolicyProvider(); + PolicyProvider provider2 = new DummyPolicyProvider(); + CombinedPolicyProvider.get().registerProvider(provider); + CombinedPolicyProvider.get().registerProvider(provider2); + Bundle b = new Bundle(); + b.putBoolean("BoolPolicy", true); + CombinedPolicyProvider.get().onSettingsAvailable(0, b); + CombinedPolicyProvider.get().onSettingsAvailable(1, b); + verify(CombinedPolicyProvider.get(), times(1)).nativeFlushPolicies(1234); + + CombinedPolicyProvider.get().refreshPolicies(); + // This should have cleared the cached policies, so onSettingsAvailable should now do + // nothing until both providers have settings. + CombinedPolicyProvider.get().onSettingsAvailable(0, b); + // Still only one call. + verify(CombinedPolicyProvider.get(), times(1)).nativeFlushPolicies(1234); + b = new Bundle(); + b.putBoolean("BoolPolicy", false); + CombinedPolicyProvider.get().onSettingsAvailable(1, b); + // That should have caused the second flush. + verify(CombinedPolicyProvider.get(), times(2)).nativeFlushPolicies(1234); + // And the policy should have been set to the new value. + verify(mPolicyConverter).setPolicy("BoolPolicy", false); + } + + @Test + public void testTerminateIncognitoSession() { + CombinedPolicyProvider.PolicyChangeListener l = + mock(CombinedPolicyProvider.PolicyChangeListener.class); + CombinedPolicyProvider.get().addPolicyChangeListener(l); + CombinedPolicyProvider.get().terminateIncognitoSession(); + verify(l).terminateIncognitoSession(); + CombinedPolicyProvider.get().removePolicyChangeListener(l); + CombinedPolicyProvider.get().terminateIncognitoSession(); + // Should still have only called the listener once + verify(l).terminateIncognitoSession(); + } + + @Test + public void testDestroy() { + PolicyProvider provider = spy(new DummyPolicyProvider()); + CombinedPolicyProvider.get().registerProvider(provider); + CombinedPolicyProvider.get().destroy(); + verify(provider).destroy(); + } +} diff --git a/components/policy/core/browser/BUILD.gn b/components/policy/core/browser/BUILD.gn index 89cd82c..03340d3 100644 --- a/components/policy/core/browser/BUILD.gn +++ b/components/policy/core/browser/BUILD.gn @@ -30,6 +30,18 @@ source_set("browser") { "//ui/base", ] + if (is_android) { + sources += [ + "android/android_combined_policy_provider.cc", + "android/android_combined_policy_provider.h", + "android/component_jni_registrar.cc", + "android/component_jni_registrar.h", + "android/policy_converter.cc", + "android/policy_converter.h", + ] + deps += [ "//components/policy/android:jni_headers" ] + } + if (enable_configuration_policy) { sources += [ "autofill_policy_handler.cc", @@ -60,15 +72,5 @@ source_set("browser") { "//components/policy/proto", "//third_party/icu", ] - - if (is_android) { - sources += [ - "android/component_jni_registrar.cc", - "android/component_jni_registrar.h", - "android/policy_converter.cc", - "android/policy_converter.h", - ] - deps += [ "//components/policy/android:jni_headers" ] - } } } diff --git a/components/policy/core/browser/android/android_combined_policy_provider.cc b/components/policy/core/browser/android/android_combined_policy_provider.cc new file mode 100644 index 0000000..c66f5ac --- /dev/null +++ b/components/policy/core/browser/android/android_combined_policy_provider.cc @@ -0,0 +1,66 @@ +// Copyright 2015 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 "components/policy/core/browser/android/android_combined_policy_provider.h" + +#include "base/android/jni_android.h" +#include "base/android/jni_string.h" +#include "components/policy/core/browser/android/policy_converter.h" +#include "jni/CombinedPolicyProvider_jni.h" + +using base::android::AttachCurrentThread; + +namespace { + +bool g_wait_for_policies = false; + +} // namespace + +namespace policy { +namespace android { + +AndroidCombinedPolicyProvider::AndroidCombinedPolicyProvider( + SchemaRegistry* registry) + : initialized_(!g_wait_for_policies) { + PolicyNamespace ns(POLICY_DOMAIN_CHROME, std::string()); + const Schema* schema = registry->schema_map()->GetSchema(ns); + policy_converter_.reset(new policy::android::PolicyConverter(schema)); + java_combined_policy_provider_.Reset(Java_CombinedPolicyProvider_linkNative( + AttachCurrentThread(), reinterpret_cast<intptr_t>(this), + policy_converter_->GetJavaObject().obj())); +} + +AndroidCombinedPolicyProvider::~AndroidCombinedPolicyProvider() { + Java_CombinedPolicyProvider_linkNative(AttachCurrentThread(), 0, jobject()); + java_combined_policy_provider_.Reset(); +} + +void AndroidCombinedPolicyProvider::RefreshPolicies() { + JNIEnv* env = AttachCurrentThread(); + Java_CombinedPolicyProvider_refreshPolicies( + env, java_combined_policy_provider_.obj()); +} + +void AndroidCombinedPolicyProvider::FlushPolicies(JNIEnv* env, jobject obj) { + initialized_ = true; + UpdatePolicy(policy_converter_->GetPolicyBundle().Pass()); +} + +// static +void AndroidCombinedPolicyProvider::SetShouldWaitForPolicy( + bool should_wait_for_policy) { + g_wait_for_policies = should_wait_for_policy; +} + +bool AndroidCombinedPolicyProvider::IsInitializationComplete( + PolicyDomain domain) const { + return initialized_; +} + +bool AndroidCombinedPolicyProvider::Register(JNIEnv* env) { + return RegisterNativesImpl(env); +} + +} // namespace android +} // namespace policy diff --git a/components/policy/core/browser/android/android_combined_policy_provider.h b/components/policy/core/browser/android/android_combined_policy_provider.h new file mode 100644 index 0000000..985d542 --- /dev/null +++ b/components/policy/core/browser/android/android_combined_policy_provider.h @@ -0,0 +1,67 @@ +// Copyright 2015 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 COMPONENTS_POLICY_CORE_BROWSER_ANDROID_ANDROID_COMBINED_POLICY_PROVIDER_H_ +#define COMPONENTS_POLICY_CORE_BROWSER_ANDROID_ANDROID_COMBINED_POLICY_PROVIDER_H_ + +#include <jni.h> + +#include "base/android/scoped_java_ref.h" +#include "base/macros.h" +#include "base/memory/scoped_ptr.h" +#include "components/policy/core/common/configuration_policy_provider.h" +#include "components/policy/core/common/policy_bundle.h" +#include "components/policy/policy_export.h" + +namespace policy { + +class SchemaRegistry; + +namespace android { + +class PolicyConverter; + +class POLICY_EXPORT AndroidCombinedPolicyProvider + : public ConfigurationPolicyProvider { + public: + explicit AndroidCombinedPolicyProvider(SchemaRegistry* registry); + + ~AndroidCombinedPolicyProvider() override; + + // Push the polices updated by the Java policy providers to the core policy + // system + void FlushPolicies(JNIEnv* env, jobject obj); + + // Call this method to tell the policy system whether it should wait for + // policies to be loaded by this provider. If this method is called, + // IsInitializationComplete() will only return true after SetPolicies() has + // been called at least once, otherwise it will return true immediately. + static void SetShouldWaitForPolicy(bool should_wait_for_policy); + + // ConfigurationPolicyProvider: + bool IsInitializationComplete(PolicyDomain domain) const override; + void RefreshPolicies() override; + + // For testing + PolicyConverter* GetPolicyConverterForTesting() { + return policy_converter_.get(); + } + + // Register the JNI methods + static bool Register(JNIEnv* env); + + private: + bool initialized_; + scoped_ptr<policy::android::PolicyConverter> policy_converter_; + base::android::ScopedJavaGlobalRef<jobject> java_combined_policy_provider_; + + + DISALLOW_COPY_AND_ASSIGN(AndroidCombinedPolicyProvider); +}; + +} // namespace android + +} // namespace policy + +#endif // COMPONENTS_POLICY_CORE_BROWSER_ANDROID_ANDROID_COMBINED_POLICY_PROVIDER_H_ diff --git a/components/policy/core/browser/android/android_combined_policy_provider_unittest.cc b/components/policy/core/browser/android/android_combined_policy_provider_unittest.cc new file mode 100644 index 0000000..b860f2b --- /dev/null +++ b/components/policy/core/browser/android/android_combined_policy_provider_unittest.cc @@ -0,0 +1,92 @@ +// Copyright 2015 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 <jni.h> + +#include "base/android/jni_android.h" +#include "base/android/jni_string.h" +#include "base/android/scoped_java_ref.h" +#include "base/values.h" +#include "components/policy/core/browser/android/android_combined_policy_provider.h" +#include "components/policy/core/browser/android/policy_converter.h" +#include "components/policy/core/common/policy_bundle.h" +#include "components/policy/core/common/schema.h" +#include "components/policy/core/common/schema_registry.h" +#include "testing/gtest/include/gtest/gtest.h" + +using base::android::ConvertUTF8ToJavaString; +using base::android::AttachCurrentThread; +using base::android::ScopedJavaLocalRef; + +namespace policy { + +namespace android { +class AndroidCombinedPolicyProviderTest : public ::testing::Test { + void TearDown() override; +}; + +void AndroidCombinedPolicyProviderTest::TearDown() { + AndroidCombinedPolicyProvider::SetShouldWaitForPolicy(false); +} + +TEST_F(AndroidCombinedPolicyProviderTest, InitializationCompleted) { + SchemaRegistry registry; + AndroidCombinedPolicyProvider manager(®istry); + EXPECT_TRUE(manager.IsInitializationComplete(POLICY_DOMAIN_CHROME)); + // If the manager is deleted (by going out of scope) without being shutdown + // first it DCHECKs. + manager.Shutdown(); +} + +TEST_F(AndroidCombinedPolicyProviderTest, SetShouldWaitForPolicy) { + AndroidCombinedPolicyProvider::SetShouldWaitForPolicy(true); + SchemaRegistry registry; + AndroidCombinedPolicyProvider manager(®istry); + EXPECT_FALSE(manager.IsInitializationComplete(POLICY_DOMAIN_CHROME)); + manager.FlushPolicies(nullptr, nullptr); + EXPECT_TRUE(manager.IsInitializationComplete(POLICY_DOMAIN_CHROME)); + // If the manager is deleted (by going out of scope) without being shutdown + // first it DCHECKs. + manager.Shutdown(); +} + +TEST_F(AndroidCombinedPolicyProviderTest, FlushPolices) { + const char kSchemaTemplate[] = + "{" + " \"type\": \"object\"," + " \"properties\": {" + " }" + "}"; + + PolicyNamespace ns(POLICY_DOMAIN_CHROME, std::string()); + std::string error; + Schema schema = Schema::Parse(kSchemaTemplate, &error); + SchemaRegistry registry; + registry.RegisterComponent(ns, schema); + AndroidCombinedPolicyProvider manager(®istry); + JNIEnv* env = AttachCurrentThread(); + ScopedJavaLocalRef<jstring> jpolicy = + ConvertUTF8ToJavaString(env, "TestPolicy"); + ScopedJavaLocalRef<jstring> jvalue = + ConvertUTF8ToJavaString(env, "TestValue"); + manager.GetPolicyConverterForTesting()->SetPolicyString(env, nullptr, + jpolicy.obj(), + jvalue.obj()); + manager.FlushPolicies(env, nullptr); + const PolicyBundle& bundle = manager.policies(); + const PolicyMap& map = bundle.Get(ns); + const base::Value* value = map.GetValue("TestPolicy"); + ASSERT_NE(nullptr, value); + EXPECT_EQ(base::Value::TYPE_STRING, value->GetType()); + std::string out_value; + EXPECT_TRUE(value->GetAsString(&out_value)); + EXPECT_EQ("TestValue", out_value); + // If the manager is deleted (by going out of scope) without being shutdown + // first it DCHECKs. + manager.Shutdown(); +} + +} // namespace android + +} // namespace policy diff --git a/components/policy/core/browser/android/component_jni_registrar.cc b/components/policy/core/browser/android/component_jni_registrar.cc index 985bcce..76c4c4d 100644 --- a/components/policy/core/browser/android/component_jni_registrar.cc +++ b/components/policy/core/browser/android/component_jni_registrar.cc @@ -7,6 +7,7 @@ #include "base/android/jni_android.h" #include "base/android/jni_registrar.h" #include "base/basictypes.h" +#include "components/policy/core/browser/android/android_combined_policy_provider.h" #include "components/policy/core/browser/android/policy_converter.h" namespace policy { @@ -14,6 +15,7 @@ namespace android { static base::android::RegistrationMethod kPolicyRegisteredMethods[] = { {"PolicyConverter", PolicyConverter::Register}, + {"AndroidCombinedPolicyProvider", AndroidCombinedPolicyProvider::Register}, }; bool RegisterPolicy(JNIEnv* env) { diff --git a/components/policy/core/common/BUILD.gn b/components/policy/core/common/BUILD.gn index 130f583..dc931e6 100644 --- a/components/policy/core/common/BUILD.gn +++ b/components/policy/core/common/BUILD.gn @@ -92,9 +92,6 @@ source_set("common") { "policy_namespace.h", "policy_pref_names.cc", "policy_pref_names.h", - "policy_provider_android.cc", - "policy_provider_android.h", - "policy_provider_android_delegate.h", "policy_service.cc", "policy_service.h", "policy_service_impl.cc", diff --git a/components/policy/core/common/policy_provider_android.cc b/components/policy/core/common/policy_provider_android.cc deleted file mode 100644 index d307661..0000000 --- a/components/policy/core/common/policy_provider_android.cc +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2014 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 "components/policy/core/common/policy_provider_android.h" -#include "components/policy/core/common/policy_provider_android_delegate.h" - -namespace policy { - -namespace { - -bool g_wait_for_policies = false; - -} // namespace - -PolicyProviderAndroid::PolicyProviderAndroid() - : delegate_(NULL), - initialized_(!g_wait_for_policies) {} - -PolicyProviderAndroid::~PolicyProviderAndroid() {} - -const Schema* PolicyProviderAndroid::GetChromeSchema() const { - PolicyNamespace ns(POLICY_DOMAIN_CHROME, std::string()); - return schema_map()->GetSchema(ns); -} - -// static -void PolicyProviderAndroid::SetShouldWaitForPolicy( - bool should_wait_for_policy) { - g_wait_for_policies = should_wait_for_policy; -} - -void PolicyProviderAndroid::SetDelegate( - PolicyProviderAndroidDelegate* delegate) { - DCHECK(!delegate || !delegate_); - delegate_ = delegate; -} - -void PolicyProviderAndroid::SetPolicies(scoped_ptr<PolicyBundle> policy) { - initialized_ = true; - UpdatePolicy(policy.Pass()); -} - -void PolicyProviderAndroid::Shutdown() { - if (delegate_) - delegate_->PolicyProviderShutdown(); - - ConfigurationPolicyProvider::Shutdown(); -} - -bool PolicyProviderAndroid::IsInitializationComplete( - PolicyDomain domain) const { - return initialized_; -} - -void PolicyProviderAndroid::RefreshPolicies() { - if (delegate_) { - delegate_->RefreshPolicies(); - } else { - // If we don't have a delegate, pass a copy of the current policies. - scoped_ptr<PolicyBundle> bundle(new PolicyBundle()); - bundle->CopyFrom(policies()); - UpdatePolicy(bundle.Pass()); - } -} - -} // namespace policy diff --git a/components/policy/core/common/policy_provider_android.h b/components/policy/core/common/policy_provider_android.h deleted file mode 100644 index 76bc515..0000000 --- a/components/policy/core/common/policy_provider_android.h +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2014 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 COMPONENTS_POLICY_CORE_COMMON_POLICY_PROVIDER_ANDROID_H_ -#define COMPONENTS_POLICY_CORE_COMMON_POLICY_PROVIDER_ANDROID_H_ - -#include "base/basictypes.h" -#include "base/compiler_specific.h" -#include "components/policy/core/common/configuration_policy_provider.h" - -namespace policy { - -class PolicyProviderAndroidDelegate; -class Schema; - -// Provider for policies set by the Android platform. -class POLICY_EXPORT PolicyProviderAndroid : public ConfigurationPolicyProvider { - public: - PolicyProviderAndroid(); - ~PolicyProviderAndroid() override; - - // Call this method to tell the policy system whether it should wait for - // policies to be loaded by this provider. If this method is called, - // IsInitializationComplete() will only return true after SetPolicies() has - // been called at least once, otherwise it will return true immediately. - static void SetShouldWaitForPolicy(bool should_wait_for_policy); - - // Returns the schema for Chrome policies. - const Schema* GetChromeSchema() const; - - void SetDelegate(PolicyProviderAndroidDelegate* delegate); - void SetPolicies(scoped_ptr<PolicyBundle> policy); - - // ConfigurationPolicyProvider: - void Shutdown() override; - bool IsInitializationComplete(PolicyDomain domain) const override; - void RefreshPolicies() override; - - private: - PolicyProviderAndroidDelegate* delegate_; - bool initialized_; - - DISALLOW_COPY_AND_ASSIGN(PolicyProviderAndroid); -}; - -} // namespace policy - -#endif // COMPONENTS_POLICY_CORE_COMMON_POLICY_PROVIDER_ANDROID_H_ diff --git a/components/policy/core/common/policy_provider_android_delegate.h b/components/policy/core/common/policy_provider_android_delegate.h deleted file mode 100644 index e5116f04..0000000 --- a/components/policy/core/common/policy_provider_android_delegate.h +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2014 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 COMPONENTS_POLICY_CORE_COMMON_POLICY_PROVIDER_ANDROID_DELEGATE_H_ -#define COMPONENTS_POLICY_CORE_COMMON_POLICY_PROVIDER_ANDROID_DELEGATE_H_ - -#include "base/compiler_specific.h" -#include "components/policy/policy_export.h" - -namespace policy { - -// A delegate for the Android policy provider. This class is responsible for -// setting policies on the PolicyProviderAndroid and refreshing them on demand. -class POLICY_EXPORT PolicyProviderAndroidDelegate { - public: - // Called to refresh policies. If this method is called, the delegate must - // eventually call SetPolicies on the provider. - virtual void RefreshPolicies() = 0; - - // Called before the provider is destroyed. - virtual void PolicyProviderShutdown() = 0; - - protected: - virtual ~PolicyProviderAndroidDelegate() {} -}; - -} // namespace policy - -#endif // COMPONENTS_POLICY_CORE_COMMON_POLICY_PROVIDER_ANDROID_DELEGATE_H_ diff --git a/components/policy/core/common/policy_provider_android_unittest.cc b/components/policy/core/common/policy_provider_android_unittest.cc deleted file mode 100644 index 12844f3..0000000 --- a/components/policy/core/common/policy_provider_android_unittest.cc +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright 2014 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 "base/memory/scoped_ptr.h" -#include "components/policy/core/common/policy_provider_android.h" -#include "components/policy/core/common/policy_provider_android_delegate.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace policy { - -namespace { - -// Helper to write a policy in |bundle| with less code. -void SetPolicy(PolicyBundle* bundle, - const std::string& name, - const std::string& value) { - bundle->Get(PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())) - .Set(name, - POLICY_LEVEL_MANDATORY, - POLICY_SCOPE_USER, - new base::StringValue(value), - NULL); -} - -class MockPolicyProviderAndroidDelegate : public PolicyProviderAndroidDelegate { - public: - MockPolicyProviderAndroidDelegate() {} - virtual ~MockPolicyProviderAndroidDelegate() {} - - MOCK_METHOD0(RefreshPolicies, void()); - MOCK_METHOD0(PolicyProviderShutdown, void()); - - private: - DISALLOW_COPY_AND_ASSIGN(MockPolicyProviderAndroidDelegate); -}; - -// Test fixture that makes sure that we always call Shutdown() before destroying -// the policy provider. Allocate this just like a PolicyProviderAndroid and use -// Get() to get the policy provider. -class PolicyProviderAndroidTestFixture { - public: - PolicyProviderAndroidTestFixture() {} - ~PolicyProviderAndroidTestFixture() { - provider_.Shutdown(); - } - - PolicyProviderAndroid* Get() { - return &provider_; - } - - private: - PolicyProviderAndroid provider_; - DISALLOW_COPY_AND_ASSIGN(PolicyProviderAndroidTestFixture); -}; - -} // namespace - -class PolicyProviderAndroidTest : public ::testing::Test { - protected: - PolicyProviderAndroidTest(); - ~PolicyProviderAndroidTest() override; - - void SetUp() override; - void TearDown() override; - - private: - DISALLOW_COPY_AND_ASSIGN(PolicyProviderAndroidTest); -}; - -PolicyProviderAndroidTest::PolicyProviderAndroidTest() {} -PolicyProviderAndroidTest::~PolicyProviderAndroidTest() {} - -void PolicyProviderAndroidTest::SetUp() {} - -void PolicyProviderAndroidTest::TearDown() { - PolicyProviderAndroid::SetShouldWaitForPolicy(false); -} - -TEST_F(PolicyProviderAndroidTest, InitializationCompleted) { - PolicyProviderAndroidTestFixture provider; - EXPECT_TRUE(provider.Get()->IsInitializationComplete(POLICY_DOMAIN_CHROME)); - - const PolicyBundle kEmptyBundle; - EXPECT_TRUE(provider.Get()->policies().Equals(kEmptyBundle)); -} - -TEST_F(PolicyProviderAndroidTest, WaitForInitialization) { - PolicyProviderAndroid::SetShouldWaitForPolicy(true); - PolicyProviderAndroidTestFixture provider; - EXPECT_FALSE(provider.Get()->IsInitializationComplete(POLICY_DOMAIN_CHROME)); - - scoped_ptr<PolicyBundle> policy_bundle(new PolicyBundle); - SetPolicy(policy_bundle.get(), "key", "value"); - PolicyBundle expected_policy_bundle; - expected_policy_bundle.CopyFrom(*policy_bundle); - provider.Get()->SetPolicies(policy_bundle.Pass()); - EXPECT_TRUE(provider.Get()->IsInitializationComplete(POLICY_DOMAIN_CHROME)); - EXPECT_TRUE(provider.Get()->policies().Equals(expected_policy_bundle)); -} - -TEST_F(PolicyProviderAndroidTest, RefreshPolicies) { - MockPolicyProviderAndroidDelegate delegate; - PolicyProviderAndroidTestFixture provider; - - provider.Get()->SetDelegate(&delegate); - - scoped_ptr<PolicyBundle> policy_bundle(new PolicyBundle); - SetPolicy(policy_bundle.get(), "key", "old_value"); - PolicyBundle expected_policy_bundle; - expected_policy_bundle.CopyFrom(*policy_bundle); - provider.Get()->SetPolicies(policy_bundle.Pass()); - EXPECT_TRUE(provider.Get()->policies().Equals(expected_policy_bundle)); - - EXPECT_CALL(delegate, RefreshPolicies()).Times(1); - provider.Get()->RefreshPolicies(); - - policy_bundle.reset(new PolicyBundle); - SetPolicy(policy_bundle.get(), "key", "new_value"); - expected_policy_bundle.CopyFrom(*policy_bundle); - provider.Get()->SetPolicies(policy_bundle.Pass()); - EXPECT_TRUE(provider.Get()->policies().Equals(expected_policy_bundle)); - - EXPECT_CALL(delegate, PolicyProviderShutdown()).Times(1); -} - -} // namespace policy diff --git a/components/policy/policy_browser.gypi b/components/policy/policy_browser.gypi index 17511d0..8f6ddb3 100644 --- a/components/policy/policy_browser.gypi +++ b/components/policy/policy_browser.gypi @@ -66,6 +66,8 @@ 'conditions': [ ['OS=="android"', { 'sources': [ + 'core/browser/android/android_combined_policy_provider.cc', + 'core/browser/android/android_combined_policy_provider.h', 'core/browser/android/component_jni_registrar.cc', 'core/browser/android/component_jni_registrar.h', 'core/browser/android/policy_converter.cc', diff --git a/components/policy/policy_common.gypi b/components/policy/policy_common.gypi index a1b570e..d2468ba 100644 --- a/components/policy/policy_common.gypi +++ b/components/policy/policy_common.gypi @@ -107,9 +107,6 @@ 'core/common/policy_namespace.h', 'core/common/policy_pref_names.cc', 'core/common/policy_pref_names.h', - 'core/common/policy_provider_android.cc', - 'core/common/policy_provider_android.h', - 'core/common/policy_provider_android_delegate.h', 'core/common/policy_service.cc', 'core/common/policy_service.h', 'core/common/policy_service_impl.cc', diff --git a/components/test/DEPS b/components/test/DEPS index 265c5f7..d36f58a 100644 --- a/components/test/DEPS +++ b/components/test/DEPS @@ -2,6 +2,7 @@ include_rules = [ # To initialize the global data of content_settings. "+components/content_settings/core/common", "+components/invalidation/impl/android/component_jni_registrar.h", + "+components/policy/core/browser/android/component_jni_registrar.h", "+components/safe_json/android/component_jni_registrar.h", "+content/public/android/java/src/org/chromium/content/browser", "+content/public/app/content_jni_onload.h", diff --git a/components/test/run_all_unittests.cc b/components/test/run_all_unittests.cc index fd327a1..4c29924 100644 --- a/components/test/run_all_unittests.cc +++ b/components/test/run_all_unittests.cc @@ -23,6 +23,7 @@ #if defined(OS_ANDROID) #include "base/android/jni_android.h" #include "components/invalidation/impl/android/component_jni_registrar.h" +#include "components/policy/core/browser/android/component_jni_registrar.h" #include "components/safe_json/android/component_jni_registrar.h" #include "ui/base/android/ui_base_jni_registrar.h" #include "ui/gfx/android/gfx_jni_registrar.h" @@ -52,6 +53,7 @@ class ComponentsTestSuite : public base::TestSuite { ASSERT_TRUE(gfx::android::RegisterJni(env)); ASSERT_TRUE(ui::android::RegisterJni(env)); ASSERT_TRUE(invalidation::android::RegisterInvalidationJni(env)); + ASSERT_TRUE(policy::android::RegisterPolicy(env)); ASSERT_TRUE(safe_json::android::RegisterSafeJsonJni(env)); #endif diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index f7a606b..6b96f77 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml @@ -8145,6 +8145,21 @@ http://cs/file:chrome/histograms.xml - but prefer this file for new entries. </summary> </histogram> +<histogram name="Enterprise.AppRestrictionLoadTime" units="milliseconds"> + <owner>aberent@chromium.org</owner> + <summary> + Android Only - Time to load the App Restrictions from the O.S.. + </summary> +</histogram> + +<histogram name="Enterprise.AppRestrictionsCacheLoad" enum="BooleanSuccess"> + <owner>aberent@chromium.org</owner> + <summary> + Android Only - Whether Chrome was able to read and decode the + AppRestrictions policy cache on startup. + </summary> +</histogram> + <histogram name="Enterprise.AttributesTPMConsistency" enum="EnterpriseAttributesTPMConsistencyType"> <owner>tnagel@chromium.org</owner> |