Bug 1189347 - RestrictedProfileConfiguration: Cache restrictions to avoid unnecessary disk reads. r=ally,rnewman
authorSebastian Kaspari <s.kaspari@gmail.com>
Fri, 21 Aug 2015 12:14:12 +0200
changeset 291227 0fd54ce01b937c51891b2f43a1810e28e8032f2b
parent 291226 f876d7b28d81fe7e60a382d09633e4797a58a6c3
child 291260 22c34579ae0720e7d3dc39a22b9d33f13bc0198b
child 291304 ccbc6bf48ad2ce4b9bc6d9a694e8afe723716f65
push id5245
push userraliiev@mozilla.com
push dateThu, 29 Oct 2015 11:30:51 +0000
treeherdermozilla-beta@dac831dc1bd0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersally, rnewman
bugs1189347
milestone43.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1189347 - RestrictedProfileConfiguration: Cache restrictions to avoid unnecessary disk reads. r=ally,rnewman
mobile/android/base/GeckoApp.java
mobile/android/base/RestrictedProfiles.java
mobile/android/base/restrictions/DefaultConfiguration.java
mobile/android/base/restrictions/GuestProfileConfiguration.java
mobile/android/base/restrictions/RestrictedProfileConfiguration.java
mobile/android/base/restrictions/RestrictionConfiguration.java
--- a/mobile/android/base/GeckoApp.java
+++ b/mobile/android/base/GeckoApp.java
@@ -1957,16 +1957,18 @@ public abstract class GeckoApp
                 if (rec != null) {
                     rec.setCurrentSession(currentSession);
                     rec.processDelayed();
                 } else {
                     Log.w(LOGTAG, "Can't record session: rec is null.");
                 }
             }
         });
+
+        RestrictedProfiles.update(this);
     }
 
     @Override
     public void onWindowFocusChanged(boolean hasFocus) {
         super.onWindowFocusChanged(hasFocus);
 
         if (!mWindowFocusInitialized && hasFocus) {
             mWindowFocusInitialized = true;
--- a/mobile/android/base/RestrictedProfiles.java
+++ b/mobile/android/base/RestrictedProfiles.java
@@ -84,16 +84,20 @@ public class RestrictedProfiles {
                 // At least one restriction is enabled -> We are a restricted profile
                 return true;
             }
         }
 
         return false;
     }
 
+    public static void update(Context context) {
+        getConfiguration(context).update();
+    }
+
     private static Restriction geckoActionToRestriction(int action) {
         for (Restriction rest : Restriction.values()) {
             if (rest.id == action) {
                 return rest;
             }
         }
 
         throw new IllegalArgumentException("Unknown action " + action);
--- a/mobile/android/base/restrictions/DefaultConfiguration.java
+++ b/mobile/android/base/restrictions/DefaultConfiguration.java
@@ -19,9 +19,12 @@ public class DefaultConfiguration implem
     public boolean canLoadUrl(String url) {
         return true;
     }
 
     @Override
     public boolean isRestricted() {
         return false;
     }
+
+    @Override
+    public void update() {}
 }
--- a/mobile/android/base/restrictions/GuestProfileConfiguration.java
+++ b/mobile/android/base/restrictions/GuestProfileConfiguration.java
@@ -67,9 +67,12 @@ public class GuestProfileConfiguration i
 
         return true;
     }
 
     @Override
     public boolean isRestricted() {
         return true;
     }
+
+    @Override
+    public void update() {}
 }
--- a/mobile/android/base/restrictions/RestrictedProfileConfiguration.java
+++ b/mobile/android/base/restrictions/RestrictedProfileConfiguration.java
@@ -1,57 +1,74 @@
 /* -*- 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 org.mozilla.gecko.AboutPages;
+import org.mozilla.gecko.util.ThreadUtils;
 
 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 java.util.Arrays;
 import java.util.List;
 
+@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
 public class RestrictedProfileConfiguration implements RestrictionConfiguration {
     static List<Restriction> DEFAULT_RESTRICTIONS = Arrays.asList(
             Restriction.DISALLOW_INSTALL_EXTENSION,
             Restriction.DISALLOW_IMPORT_SETTINGS,
             Restriction.DISALLOW_DEVELOPER_TOOLS,
             Restriction.DISALLOW_CUSTOMIZE_HOME,
             Restriction.DISALLOW_PRIVATE_BROWSING,
             Restriction.DISALLOW_LOCATION_SERVICE,
             Restriction.DISALLOW_DISPLAY_SETTINGS,
             Restriction.DISALLOW_CLEAR_HISTORY,
             Restriction.DISALLOW_MASTER_PASSWORD,
             Restriction.DISALLOW_GUEST_BROWSING
     );
 
     private Context context;
+    private Bundle cachedRestrictions;
+    private boolean isCacheInvalid = true;
 
     public RestrictedProfileConfiguration(Context context) {
         this.context = context.getApplicationContext();
     }
 
     @Override
-    public boolean isAllowed(Restriction restriction) {
-        boolean isAllowed = !getAppRestrictions(context).getBoolean(restriction.name, DEFAULT_RESTRICTIONS.contains(restriction));
-
-        if (isAllowed) {
-            // If this restriction is not enforced by the app setup then check wether this is a restriction that is
-            // enforced by the system.
-            isAllowed = !getUserRestrictions(context).getBoolean(restriction.name, false);
+    public synchronized boolean isAllowed(Restriction restriction) {
+        if (isCacheInvalid || !ThreadUtils.isOnUiThread()) {
+            cachedRestrictions = readRestrictions();
+            isCacheInvalid = false;
         }
 
-        return isAllowed;
+        return !cachedRestrictions.getBoolean(restriction.name, DEFAULT_RESTRICTIONS.contains(restriction));
+    }
+
+    private Bundle readRestrictions() {
+        final UserManager mgr = (UserManager) context.getSystemService(Context.USER_SERVICE);
+
+        StrictMode.ThreadPolicy policy = StrictMode.allowThreadDiskReads();
+
+        try {
+            Bundle restrictions = new Bundle();
+            restrictions.putAll(mgr.getApplicationRestrictions(context.getPackageName()));
+            restrictions.putAll(mgr.getUserRestrictions());
+            return restrictions;
+        } finally {
+            StrictMode.setThreadPolicy(policy);
+        }
     }
 
     @Override
     public boolean canLoadUrl(String url) {
         if (!isAllowed(Restriction.DISALLOW_INSTALL_EXTENSION) && AboutPages.isAboutAddons(url)) {
             return false;
         }
 
@@ -67,20 +84,13 @@ public class RestrictedProfileConfigurat
         return true;
     }
 
     @Override
     public boolean isRestricted() {
         return true;
     }
 
-    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
-    private Bundle getAppRestrictions(final Context context) {
-        final UserManager mgr = (UserManager) context.getSystemService(Context.USER_SERVICE);
-        return mgr.getApplicationRestrictions(context.getPackageName());
-    }
-
-    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
-    private Bundle getUserRestrictions(final Context context) {
-        final UserManager mgr = (UserManager) context.getSystemService(Context.USER_SERVICE);
-        return mgr.getUserRestrictions();
+    @Override
+    public synchronized void update() {
+        isCacheInvalid = true;
     }
 }
--- a/mobile/android/base/restrictions/RestrictionConfiguration.java
+++ b/mobile/android/base/restrictions/RestrictionConfiguration.java
@@ -18,9 +18,14 @@ public interface RestrictionConfiguratio
      * Is the user allowed to load the given URL?
      */
     boolean canLoadUrl(String url);
 
     /**
      * Is this user restricted in any way?
      */
     boolean isRestricted();
+
+    /**
+     * Update restrictions if needed.
+     */
+    void update();
 }