diff options
Diffstat (limited to 'core')
-rw-r--r-- | core/java/android/app/ContextImpl.java | 11 | ||||
-rw-r--r-- | core/java/android/content/Context.java | 26 | ||||
-rw-r--r-- | core/java/android/os/FileUtils.java | 7 | ||||
-rw-r--r-- | core/java/android/os/StrictMode.java | 78 | ||||
-rw-r--r-- | core/jni/android_os_FileUtils.cpp | 3 |
5 files changed, 106 insertions, 19 deletions
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java index 083612e..72f7286 100644 --- a/core/java/android/app/ContextImpl.java +++ b/core/java/android/app/ContextImpl.java @@ -554,10 +554,13 @@ class ContextImpl extends Context { return sp; } } - // If somebody else (some other process) changed the prefs - // file behind our back, we reload it. This has been the - // historical (if undocumented) behavior. - sp.startReloadIfChangedUnexpectedly(); + if ((mode & Context.MODE_MULTI_PROCESS) != 0 || + getApplicationInfo().targetSdkVersion < android.os.Build.VERSION_CODES.HONEYCOMB) { + // If somebody else (some other process) changed the prefs + // file behind our back, we reload it. This has been the + // historical (if undocumented) behavior. + sp.startReloadIfChangedUnexpectedly(); + } return sp; } diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java index 277dc2f..b128d31 100644 --- a/core/java/android/content/Context.java +++ b/core/java/android/content/Context.java @@ -80,6 +80,25 @@ public abstract class Context { public static final int MODE_APPEND = 0x8000; /** + * SharedPreference loading flag: when set, the file on disk will + * be checked for modification even if the shared preferences + * instance is already loaded in this process. This behavior is + * sometimes desired in cases where the application has multiple + * processes, all writing to the same SharedPreferences file. + * Generally there are better forms of communication between + * processes, though. + * + * <p>This was the legacy (but undocumented) behavior in and + * before Gingerbread (Android 2.3) and this flag is implied when + * targetting such releases. For applications targetting SDK + * versions <em>greater than</em> Android 2.3, this flag must be + * explicitly set if desired. + * + * @see #getSharedPreferences + */ + public static final int MODE_MULTI_PROCESS = 0x0004; + + /** * Flag for {@link #bindService}: automatically create the service as long * as the binding exists. Note that while this will create the service, * its {@link android.app.Service#onStartCommand} @@ -318,7 +337,11 @@ public abstract class Context { * editor (SharedPreferences.edit()) and then commit changes (Editor.commit()). * @param mode Operating mode. Use 0 or {@link #MODE_PRIVATE} for the * default operation, {@link #MODE_WORLD_READABLE} - * and {@link #MODE_WORLD_WRITEABLE} to control permissions. + * and {@link #MODE_WORLD_WRITEABLE} to control permissions. The bit + * {@link #MODE_MULTI_PROCESS} can also be used if multiple processes + * are mutating the same SharedPreferences file. {@link #MODE_MULTI_PROCESS} + * is always on in apps targetting Gingerbread (Android 2.3) and below, and + * off by default in later versions. * * @return Returns the single SharedPreferences instance that can be used * to retrieve and modify the preference values. @@ -326,6 +349,7 @@ public abstract class Context { * @see #MODE_PRIVATE * @see #MODE_WORLD_READABLE * @see #MODE_WORLD_WRITEABLE + * @see #MODE_MULTI_PROCESS */ public abstract SharedPreferences getSharedPreferences(String name, int mode); diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java index 9d50fd9..f56f6a9 100644 --- a/core/java/android/os/FileUtils.java +++ b/core/java/android/os/FileUtils.java @@ -76,7 +76,12 @@ public class FileUtils * @return true if the file exists and false if it does not exist. If you do not have * permission to stat the file, then this method will return false. */ - public static native boolean getFileStatus(String path, FileStatus status); + public static boolean getFileStatus(String path, FileStatus status) { + StrictMode.noteDiskRead(); + return getFileStatusNative(path, status); + } + + private static native boolean getFileStatusNative(String path, FileStatus status); /** Regular expression for safe filenames: no spaces or metacharacters */ private static final Pattern SAFE_FILENAME_PATTERN = Pattern.compile("[\\w%+,./=_-]+"); diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java index b00b9c9..e314fce 100644 --- a/core/java/android/os/StrictMode.java +++ b/core/java/android/os/StrictMode.java @@ -669,25 +669,46 @@ public final class StrictMode { CloseGuard.setEnabled(enabled); } - private static class StrictModeNetworkViolation extends BlockGuard.BlockGuardPolicyException { + /** + * @hide + */ + public static class StrictModeViolation extends BlockGuard.BlockGuardPolicyException { + public StrictModeViolation(int policyState, int policyViolated, String message) { + super(policyState, policyViolated, message); + } + } + + /** + * @hide + */ + public static class StrictModeNetworkViolation extends StrictModeViolation { public StrictModeNetworkViolation(int policyMask) { - super(policyMask, DETECT_NETWORK); + super(policyMask, DETECT_NETWORK, null); } } - private static class StrictModeDiskReadViolation extends BlockGuard.BlockGuardPolicyException { + /** + * @hide + */ + private static class StrictModeDiskReadViolation extends StrictModeViolation { public StrictModeDiskReadViolation(int policyMask) { - super(policyMask, DETECT_DISK_READ); + super(policyMask, DETECT_DISK_READ, null); } } - private static class StrictModeDiskWriteViolation extends BlockGuard.BlockGuardPolicyException { + /** + * @hide + */ + private static class StrictModeDiskWriteViolation extends StrictModeViolation { public StrictModeDiskWriteViolation(int policyMask) { - super(policyMask, DETECT_DISK_WRITE); + super(policyMask, DETECT_DISK_WRITE, null); } } - private static class StrictModeCustomViolation extends BlockGuard.BlockGuardPolicyException { + /** + * @hide + */ + private static class StrictModeCustomViolation extends StrictModeViolation { public StrictModeCustomViolation(int policyMask, String name) { super(policyMask, DETECT_CUSTOM, name); } @@ -1007,9 +1028,16 @@ public final class StrictMode { // thread, in "gather" mode. In this case, the duration // of the violation is computed by the ultimate caller and // its Looper, if any. + // + // Also, as a special short-cut case when the only penalty + // bit is death, we die immediately, rather than timing + // the violation's duration. This makes it convenient to + // use in unit tests too, rather than waiting on a Looper. + // // TODO: if in gather mode, ignore Looper.myLooper() and always // go into this immediate mode? - if (looper == null) { + if (looper == null || + (info.policy & PENALTY_MASK) == PENALTY_DEATH) { info.durationMillis = -1; // unknown (redundant, already set) handleViolation(info); return; @@ -1179,13 +1207,16 @@ public final class StrictMode { } if ((info.policy & PENALTY_DEATH) != 0) { - System.err.println("StrictMode policy violation with POLICY_DEATH; shutting down."); - Process.killProcess(Process.myPid()); - System.exit(10); + executeDeathPenalty(info); } } } + private static void executeDeathPenalty(ViolationInfo info) { + int violationBit = parseViolationFromMessage(info.crashInfo.exceptionMessage); + throw new StrictModeViolation(info.policy, violationBit, null); + } + /** * In the common case, as set by conditionallyEnableDebugLogging, * we're just dropboxing any violations but not showing a dialog, @@ -1597,6 +1628,31 @@ public final class StrictMode { } /** + * @hide + */ + public static void noteDiskRead() { + BlockGuard.Policy policy = BlockGuard.getThreadPolicy(); + Log.d(TAG, "noteDiskRead; policy=" + policy); + if (!(policy instanceof AndroidBlockGuardPolicy)) { + // StrictMode not enabled. + return; + } + ((AndroidBlockGuardPolicy) policy).onReadFromDisk(); + } + + /** + * @hide + */ + public static void noteDiskWrite() { + BlockGuard.Policy policy = BlockGuard.getThreadPolicy(); + if (!(policy instanceof AndroidBlockGuardPolicy)) { + // StrictMode not enabled. + return; + } + ((AndroidBlockGuardPolicy) policy).onWriteToDisk(); + } + + /** * Parcelable that gets sent in Binder call headers back to callers * to report violations that happened during a cross-process call. * diff --git a/core/jni/android_os_FileUtils.cpp b/core/jni/android_os_FileUtils.cpp index d3faa2f..d8a3db3 100644 --- a/core/jni/android_os_FileUtils.cpp +++ b/core/jni/android_os_FileUtils.cpp @@ -177,7 +177,7 @@ static const JNINativeMethod methods[] = { {"getPermissions", "(Ljava/lang/String;[I)I", (void*)android_os_FileUtils_getPermissions}, {"setUMask", "(I)I", (void*)android_os_FileUtils_setUMask}, {"getFatVolumeId", "(Ljava/lang/String;)I", (void*)android_os_FileUtils_getFatVolumeId}, - {"getFileStatus", "(Ljava/lang/String;Landroid/os/FileUtils$FileStatus;)Z", (void*)android_os_FileUtils_getFileStatus}, + {"getFileStatusNative", "(Ljava/lang/String;Landroid/os/FileUtils$FileStatus;)Z", (void*)android_os_FileUtils_getFileStatus}, }; static const char* const kFileUtilsPathName = "android/os/FileUtils"; @@ -211,4 +211,3 @@ int register_android_os_FileUtils(JNIEnv* env) } } - |