blob: 523cc113b4c981af2e759ac4469728081414d855 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
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"));
}
}
}
|