Bug 1244071 - Move reading of restrictions to dedicated cache class. r=mcomella

MozReview-Commit-ID: 7u40m0Wdusi

--HG--
extra : rebase_source : 135c9af9820277f7b910722510fe6a470300f31b
extra : amend_source : 4ab9ee588b09cce10b29d851e9915ac8a35f1a38
This commit is contained in:
Sebastian Kaspari 2016-02-01 22:14:16 +01:00
Родитель b77d966c3d
Коммит 40d294de36
5 изменённых файлов: 113 добавлений и 59 удалений

Просмотреть файл

@ -5,21 +5,21 @@
package org.mozilla.gecko; package org.mozilla.gecko;
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.util.Log;
import org.mozilla.gecko.AppConstants.Versions;
import org.mozilla.gecko.annotation.RobocopTarget; import org.mozilla.gecko.annotation.RobocopTarget;
import org.mozilla.gecko.annotation.WrapForJNI; import org.mozilla.gecko.annotation.WrapForJNI;
import org.mozilla.gecko.AppConstants.Versions;
import org.mozilla.gecko.restrictions.DefaultConfiguration; import org.mozilla.gecko.restrictions.DefaultConfiguration;
import org.mozilla.gecko.restrictions.GuestProfileConfiguration; import org.mozilla.gecko.restrictions.GuestProfileConfiguration;
import org.mozilla.gecko.restrictions.Restrictable; import org.mozilla.gecko.restrictions.Restrictable;
import org.mozilla.gecko.restrictions.RestrictedProfileConfiguration; import org.mozilla.gecko.restrictions.RestrictedProfileConfiguration;
import org.mozilla.gecko.restrictions.RestrictionCache;
import org.mozilla.gecko.restrictions.RestrictionConfiguration; import org.mozilla.gecko.restrictions.RestrictionConfiguration;
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.os.UserManager;
import android.util.Log;
@RobocopTarget @RobocopTarget
public class Restrictions { public class Restrictions {
private static final String LOGTAG = "GeckoRestrictedProfiles"; private static final String LOGTAG = "GeckoRestrictedProfiles";
@ -74,8 +74,7 @@ public class Restrictions {
} }
// The user is on a restricted profile if, and only if, we injected application restrictions during account setup. // The user is on a restricted profile if, and only if, we injected application restrictions during account setup.
final UserManager mgr = (UserManager) context.getSystemService(Context.USER_SERVICE); return RestrictionCache.hasApplicationRestrictions(context);
return !mgr.getApplicationRestrictions(context.getPackageName()).isEmpty();
} }
public static void update(Context context) { public static void update(Context context) {

Просмотреть файл

@ -66,9 +66,6 @@ public class RestrictedProfileConfiguration implements RestrictionConfiguration
} }
private Context context; private Context context;
private Bundle cachedAppRestrictions;
private Bundle cachedUserRestrictions;
private boolean isCacheInvalid = true;
public RestrictedProfileConfiguration(Context context) { public RestrictedProfileConfiguration(Context context) {
this.context = context.getApplicationContext(); this.context = context.getApplicationContext();
@ -76,38 +73,17 @@ public class RestrictedProfileConfiguration implements RestrictionConfiguration
@Override @Override
public synchronized boolean isAllowed(Restrictable restrictable) { public synchronized boolean isAllowed(Restrictable restrictable) {
if (isCacheInvalid || !ThreadUtils.isOnUiThread()) {
readRestrictions();
isCacheInvalid = false;
}
// Special casing system/user restrictions // Special casing system/user restrictions
if (restrictable == Restrictable.INSTALL_APPS || restrictable == Restrictable.MODIFY_ACCOUNTS) { if (restrictable == Restrictable.INSTALL_APPS || restrictable == Restrictable.MODIFY_ACCOUNTS) {
return !cachedUserRestrictions.getBoolean(restrictable.name); return RestrictionCache.getUserRestriction(context, restrictable.name);
} }
if (!cachedAppRestrictions.containsKey(restrictable.name) && !configuration.containsKey(restrictable)) { if (!RestrictionCache.hasApplicationRestriction(context, restrictable.name) && !configuration.containsKey(restrictable)) {
// Always allow features that are not in the configuration // Always allow features that are not in the configuration
return true; return true;
} }
return cachedAppRestrictions.getBoolean(restrictable.name, configuration.get(restrictable)); return RestrictionCache.getApplicationRestriction(context, restrictable.name, configuration.get(restrictable));
}
private void readRestrictions() {
final UserManager mgr = (UserManager) context.getSystemService(Context.USER_SERVICE);
StrictMode.ThreadPolicy policy = StrictMode.allowThreadDiskReads();
try {
Bundle appRestrictions = mgr.getApplicationRestrictions(context.getPackageName());
migrateRestrictionsIfNeeded(appRestrictions);
cachedAppRestrictions = appRestrictions;
cachedUserRestrictions = mgr.getUserRestrictions();
} finally {
StrictMode.setThreadPolicy(policy);
}
} }
@Override @Override
@ -135,7 +111,7 @@ public class RestrictedProfileConfiguration implements RestrictionConfiguration
@Override @Override
public synchronized void update() { public synchronized void update() {
isCacheInvalid = true; RestrictionCache.invalidate();
} }
public static List<Restrictable> getVisibleRestrictions() { public static List<Restrictable> getVisibleRestrictions() {
@ -150,25 +126,4 @@ public class RestrictedProfileConfiguration implements RestrictionConfiguration
return visibleList; return visibleList;
} }
/**
* This method migrates the old set of DISALLOW_ restrictions to the new restrictable feature ones (Bug 1189336).
*/
public static void migrateRestrictionsIfNeeded(Bundle bundle) {
if (!bundle.containsKey(Restrictable.INSTALL_EXTENSION.name) && bundle.containsKey("no_install_extensions")) {
bundle.putBoolean(Restrictable.INSTALL_EXTENSION.name, !bundle.getBoolean("no_install_extensions"));
}
if (!bundle.containsKey(Restrictable.PRIVATE_BROWSING.name) && bundle.containsKey("no_private_browsing")) {
bundle.putBoolean(Restrictable.PRIVATE_BROWSING.name, !bundle.getBoolean("no_private_browsing"));
}
if (!bundle.containsKey(Restrictable.CLEAR_HISTORY.name) && bundle.containsKey("no_clear_history")) {
bundle.putBoolean(Restrictable.CLEAR_HISTORY.name, !bundle.getBoolean("no_clear_history"));
}
if (!bundle.containsKey(Restrictable.ADVANCED_SETTINGS.name) && bundle.containsKey("no_advanced_settings")) {
bundle.putBoolean(Restrictable.ADVANCED_SETTINGS.name, !bundle.getBoolean("no_advanced_settings"));
}
}
} }

Просмотреть файл

@ -0,0 +1,99 @@
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: nil; -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.gecko.restrictions;
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.os.StrictMode;
import android.os.UserManager;
import org.mozilla.gecko.util.ThreadUtils;
/**
* Cache for user and application restrictions.
*/
public class RestrictionCache {
private static Bundle cachedAppRestrictions;
private static Bundle cachedUserRestrictions;
private static boolean isCacheInvalid = true;
private RestrictionCache() {}
public static synchronized boolean getUserRestriction(Context context, String restriction) {
updateCacheIfNeeded(context);
return cachedUserRestrictions.getBoolean(restriction);
}
public static synchronized boolean hasApplicationRestriction(Context context, String restriction) {
updateCacheIfNeeded(context);
return cachedAppRestrictions.containsKey(restriction);
}
public static synchronized boolean getApplicationRestriction(Context context, String restriction, boolean defaultValue) {
updateCacheIfNeeded(context);
return cachedAppRestrictions.getBoolean(restriction, defaultValue);
}
public static synchronized boolean hasApplicationRestrictions(Context context) {
updateCacheIfNeeded(context);
return !cachedAppRestrictions.isEmpty();
}
public static synchronized void invalidate() {
isCacheInvalid = true;
}
private static void updateCacheIfNeeded(Context context) {
// If we are not on the UI thread then we can just go ahead and read the values (Bug 1189347).
// Otherwise we read from the cache to avoid blocking the UI thread. If the cache is invalid
// then we hazard the consequences and just do the read.
if (isCacheInvalid || !ThreadUtils.isOnUiThread()) {
readRestrictions(context);
isCacheInvalid = false;
}
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
private static void readRestrictions(Context context) {
final UserManager mgr = (UserManager) context.getSystemService(Context.USER_SERVICE);
// If we do not have anything in the cache yet then this read might happen on the UI thread (Bug 1189347).
final StrictMode.ThreadPolicy policy = StrictMode.allowThreadDiskReads();
try {
Bundle appRestrictions = mgr.getApplicationRestrictions(context.getPackageName());
migrateRestrictionsIfNeeded(appRestrictions);
cachedAppRestrictions = appRestrictions;
cachedUserRestrictions = mgr.getUserRestrictions(); // Always implies disk read
} finally {
StrictMode.setThreadPolicy(policy);
}
}
/**
* This method migrates the old set of DISALLOW_ restrictions to the new restrictable feature ones (Bug 1189336).
*/
/* package-private */ static void migrateRestrictionsIfNeeded(Bundle bundle) {
if (!bundle.containsKey(Restrictable.INSTALL_EXTENSION.name) && bundle.containsKey("no_install_extensions")) {
bundle.putBoolean(Restrictable.INSTALL_EXTENSION.name, !bundle.getBoolean("no_install_extensions"));
}
if (!bundle.containsKey(Restrictable.PRIVATE_BROWSING.name) && bundle.containsKey("no_private_browsing")) {
bundle.putBoolean(Restrictable.PRIVATE_BROWSING.name, !bundle.getBoolean("no_private_browsing"));
}
if (!bundle.containsKey(Restrictable.CLEAR_HISTORY.name) && bundle.containsKey("no_clear_history")) {
bundle.putBoolean(Restrictable.CLEAR_HISTORY.name, !bundle.getBoolean("no_clear_history"));
}
if (!bundle.containsKey(Restrictable.ADVANCED_SETTINGS.name) && bundle.containsKey("no_advanced_settings")) {
bundle.putBoolean(Restrictable.ADVANCED_SETTINGS.name, !bundle.getBoolean("no_advanced_settings"));
}
}
}

Просмотреть файл

@ -38,7 +38,7 @@ public class RestrictionProvider extends BroadcastReceiver {
@Override @Override
public void run() { public void run() {
final Bundle oldRestrictions = intent.getBundleExtra(Intent.EXTRA_RESTRICTIONS_BUNDLE); final Bundle oldRestrictions = intent.getBundleExtra(Intent.EXTRA_RESTRICTIONS_BUNDLE);
RestrictedProfileConfiguration.migrateRestrictionsIfNeeded(oldRestrictions); RestrictionCache.migrateRestrictionsIfNeeded(oldRestrictions);
final Bundle extras = new Bundle(); final Bundle extras = new Bundle();

Просмотреть файл

@ -505,6 +505,7 @@ gbjar.sources += ['java/org/mozilla/gecko/' + x for x in [
'restrictions/GuestProfileConfiguration.java', 'restrictions/GuestProfileConfiguration.java',
'restrictions/Restrictable.java', 'restrictions/Restrictable.java',
'restrictions/RestrictedProfileConfiguration.java', 'restrictions/RestrictedProfileConfiguration.java',
'restrictions/RestrictionCache.java',
'restrictions/RestrictionConfiguration.java', 'restrictions/RestrictionConfiguration.java',
'restrictions/RestrictionProvider.java', 'restrictions/RestrictionProvider.java',
'ScreenshotObserver.java', 'ScreenshotObserver.java',