• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2017 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 package org.chromium.base;
6 
7 import android.os.Build;
8 import android.os.StrictMode;
9 
10 import java.io.Closeable;
11 
12 /**
13  * Enables try-with-resources compatible StrictMode violation allowlisting.
14  *
15  * Prefer "ignored" as the variable name to appease Android Studio's "Unused symbol" inspection.
16  *
17  * Example:
18  * <pre>
19  *     try (StrictModeContext ignored = StrictModeContext.allowDiskWrites()) {
20  *         return Example.doThingThatRequiresDiskWrites();
21  *     }
22  * </pre>
23  *
24  */
25 public final class StrictModeContext implements Closeable {
26     private final StrictMode.ThreadPolicy mThreadPolicy;
27     private final StrictMode.VmPolicy mVmPolicy;
28 
StrictModeContext(StrictMode.ThreadPolicy threadPolicy, StrictMode.VmPolicy vmPolicy)29     private StrictModeContext(StrictMode.ThreadPolicy threadPolicy, StrictMode.VmPolicy vmPolicy) {
30         // TODO(crbug/1475610): Determine after auditing strict mode context usage if we should keep
31         // or remove these trace events.
32         TraceEvent.startAsync("StrictModeContext", hashCode());
33         mThreadPolicy = threadPolicy;
34         mVmPolicy = vmPolicy;
35     }
36 
StrictModeContext(StrictMode.ThreadPolicy threadPolicy)37     private StrictModeContext(StrictMode.ThreadPolicy threadPolicy) {
38         this(threadPolicy, null);
39     }
40 
StrictModeContext(StrictMode.VmPolicy vmPolicy)41     private StrictModeContext(StrictMode.VmPolicy vmPolicy) {
42         this(null, vmPolicy);
43     }
44 
45     /**
46      * Convenience method for disabling all VM-level StrictMode checks with try-with-resources.
47      * Includes everything listed here:
48      *     https://developer.android.com/reference/android/os/StrictMode.VmPolicy.Builder.html
49      */
allowAllVmPolicies()50     public static StrictModeContext allowAllVmPolicies() {
51         try (TraceEvent e = TraceEvent.scoped("StrictModeContext.allowAllVmPolicies")) {
52             StrictMode.VmPolicy oldPolicy = StrictMode.getVmPolicy();
53             StrictMode.setVmPolicy(StrictMode.VmPolicy.LAX);
54             return new StrictModeContext(oldPolicy);
55         }
56     }
57 
58     /**
59      * Convenience method for disabling all thread-level StrictMode checks with try-with-resources.
60      * Includes everything listed here:
61      *     https://developer.android.com/reference/android/os/StrictMode.ThreadPolicy.Builder.html
62      */
allowAllThreadPolicies()63     public static StrictModeContext allowAllThreadPolicies() {
64         try (TraceEvent e = TraceEvent.scoped("StrictModeContext.allowAllThreadPolicies")) {
65             StrictMode.ThreadPolicy oldPolicy = StrictMode.getThreadPolicy();
66             StrictMode.setThreadPolicy(StrictMode.ThreadPolicy.LAX);
67             return new StrictModeContext(oldPolicy);
68         }
69     }
70 
71     /** Convenience method for disabling StrictMode for disk-writes with try-with-resources. */
allowDiskWrites()72     public static StrictModeContext allowDiskWrites() {
73         try (TraceEvent e = TraceEvent.scoped("StrictModeContext.allowDiskWrites")) {
74             StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
75             return new StrictModeContext(oldPolicy);
76         }
77     }
78 
79     /** Convenience method for disabling StrictMode for disk-reads with try-with-resources. */
allowDiskReads()80     public static StrictModeContext allowDiskReads() {
81         try (TraceEvent e = TraceEvent.scoped("StrictModeContext.allowDiskReads")) {
82             StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
83             return new StrictModeContext(oldPolicy);
84         }
85     }
86 
87     /** Convenience method for disabling StrictMode for slow calls with try-with-resources. */
allowSlowCalls()88     public static StrictModeContext allowSlowCalls() {
89         try (TraceEvent e = TraceEvent.scoped("StrictModeContext.allowSlowCalls")) {
90             StrictMode.ThreadPolicy oldPolicy = StrictMode.getThreadPolicy();
91             StrictMode.setThreadPolicy(
92                     new StrictMode.ThreadPolicy.Builder(oldPolicy).permitCustomSlowCalls().build());
93             return new StrictModeContext(oldPolicy);
94         }
95     }
96 
97     /**
98      * Convenience method for disabling StrictMode for unbuffered input/output operations with
99      * try-with-resources.
100      * For API level 25- this method will do nothing;
101      * because StrictMode.ThreadPolicy.Builder#permitUnbufferedIo is added in API level 26.
102      */
allowUnbufferedIo()103     public static StrictModeContext allowUnbufferedIo() {
104         try (TraceEvent e = TraceEvent.scoped("StrictModeContext.allowUnbufferedIo")) {
105             StrictMode.ThreadPolicy oldPolicy = StrictMode.getThreadPolicy();
106             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
107                 StrictMode.setThreadPolicy(
108                         new StrictMode.ThreadPolicy.Builder(oldPolicy)
109                                 .permitUnbufferedIo()
110                                 .build());
111             }
112             return new StrictModeContext(oldPolicy);
113         }
114     }
115 
116     @Override
close()117     public void close() {
118         if (mThreadPolicy != null) {
119             StrictMode.setThreadPolicy(mThreadPolicy);
120         }
121         if (mVmPolicy != null) {
122             StrictMode.setVmPolicy(mVmPolicy);
123         }
124         TraceEvent.finishAsync("StrictModeContext", hashCode());
125     }
126 }
127