Add presubmit to prevent SharedPreferences misuse.
BUG=599284
Review-Url: https://codereview.chromium.org/1993243002
Cr-Commit-Position: refs/heads/master@{#395881}
diff --git a/PRESUBMIT.py b/PRESUBMIT.py
index 5fe8b53..0fb216c 100644
--- a/PRESUBMIT.py
+++ b/PRESUBMIT.py
@@ -25,6 +25,7 @@
r"^chrome[\\\/]browser[\\\/]resources[\\\/]pdf[\\\/]index.js",
)
+
# The NetscapePlugIn library is excluded from pan-project as it will soon
# be deleted together with the rest of the NPAPI and it's not worthwhile to
# update the coding style until then.
@@ -32,10 +33,12 @@
r"^content[\\\/]shell[\\\/]tools[\\\/]plugin[\\\/].*",
)
+
# Fragment of a regular expression that matches C++ and Objective-C++
# implementation files.
_IMPLEMENTATION_EXTENSIONS = r'\.(cc|cpp|cxx|mm)$'
+
# Regular expression that matches code only used for test binaries
# (best effort).
_TEST_CODE_EXCLUDED_PATHS = (
@@ -55,6 +58,7 @@
r'testing[\\\/]iossim[\\\/]iossim\.mm$',
)
+
_TEST_ONLY_WARNING = (
'You might be calling functions intended only for testing from\n'
'production code. It is OK to ignore this warning if you know what\n'
@@ -67,6 +71,7 @@
'collation (LC_COLLATE=C) and check\nhttps://google.github.io/styleguide/'
'cppguide.html#Names_and_Order_of_Includes')
+
_BANNED_OBJC_FUNCTIONS = (
(
'addTrackingRect:',
@@ -291,6 +296,7 @@
),
)
+
_IPC_ENUM_TRAITS_DEPRECATED = (
'You are using IPC_ENUM_TRAITS() in your code. It has been deprecated.\n'
'See http://www.chromium.org/Home/chromium-security/education/security-tips-for-ipc')
@@ -322,10 +328,12 @@
'net/tools/testserver/testserver.pydeps',
]
+
_GENERIC_PYDEPS_FILES = [
'build/secondary/tools/swarming_client/isolate.pydeps',
]
+
_ALL_PYDEPS_FILES = _ANDROID_SPECIFIC_PYDEPS_FILES + _GENERIC_PYDEPS_FILES
@@ -491,6 +499,7 @@
'been modified and the associated histogram name has no match in either '
'%s or the modifications of it:' % (histograms_xml_path), problems)]
+
def _CheckFlakyTestUsage(input_api, output_api):
"""Check that FlakyTest annotation is our own instead of the android one"""
pattern = input_api.re.compile(r'import android.test.FlakyTest;')
@@ -506,6 +515,7 @@
files)]
return []
+
def _CheckNoNewWStrings(input_api, output_api):
"""Checks to make sure we don't introduce use of wstrings."""
problems = []
@@ -566,51 +576,42 @@
warnings = []
errors = []
+ def IsBlacklisted(affected_file, blacklist):
+ local_path = affected_file.LocalPath()
+ for item in blacklist:
+ if input_api.re.match(item, local_path):
+ return True
+ return False
+
+ def CheckForMatch(affected_file, line_num, line, func_name, message, error):
+ matched = False
+ if func_name[0:1] == '/':
+ regex = func_name[1:]
+ if input_api.re.search(regex, line):
+ matched = True
+ elif func_name in line:
+ matched = True
+ if matched:
+ problems = warnings;
+ if error:
+ problems = errors;
+ problems.append(' %s:%d:' % (affected_file.LocalPath(), line_num))
+ for message_line in message:
+ problems.append(' %s' % message_line)
+
file_filter = lambda f: f.LocalPath().endswith(('.mm', '.m', '.h'))
for f in input_api.AffectedFiles(file_filter=file_filter):
for line_num, line in f.ChangedContents():
for func_name, message, error in _BANNED_OBJC_FUNCTIONS:
- matched = False
- if func_name[0:1] == '/':
- regex = func_name[1:]
- if input_api.re.search(regex, line):
- matched = True
- elif func_name in line:
- matched = True
- if matched:
- problems = warnings;
- if error:
- problems = errors;
- problems.append(' %s:%d:' % (f.LocalPath(), line_num))
- for message_line in message:
- problems.append(' %s' % message_line)
+ CheckForMatch(f, line_num, line, func_name, message, error)
file_filter = lambda f: f.LocalPath().endswith(('.cc', '.mm', '.h'))
for f in input_api.AffectedFiles(file_filter=file_filter):
for line_num, line in f.ChangedContents():
for func_name, message, error, excluded_paths in _BANNED_CPP_FUNCTIONS:
- def IsBlacklisted(affected_file, blacklist):
- local_path = affected_file.LocalPath()
- for item in blacklist:
- if input_api.re.match(item, local_path):
- return True
- return False
if IsBlacklisted(f, excluded_paths):
continue
- matched = False
- if func_name[0:1] == '/':
- regex = func_name[1:]
- if input_api.re.search(regex, line):
- matched = True
- elif func_name in line:
- matched = True
- if matched:
- problems = warnings;
- if error:
- problems = errors;
- problems.append(' %s:%d:' % (f.LocalPath(), line_num))
- for message_line in message:
- problems.append(' %s' % message_line)
+ CheckForMatch(f, line_num, line, func_name, message, error)
result = []
if (warnings):
@@ -1862,6 +1863,7 @@
results.extend(_CheckSingletonInHeaders(input_api, output_api))
results.extend(_CheckNoDeprecatedCompiledResourcesGYP(input_api, output_api))
results.extend(_CheckPydepsNeedsUpdating(input_api, output_api))
+ results.extend(_CheckJavaStyle(input_api, output_api))
if any('PRESUBMIT.py' == f.LocalPath() for f in input_api.AffectedFiles()):
results.extend(input_api.canned_checks.RunUnitTestsInDirectory(
@@ -2085,7 +2087,6 @@
results = []
results.extend(_CommonChecks(input_api, output_api))
results.extend(_CheckValidHostsInDEPS(input_api, output_api))
- results.extend(_CheckJavaStyle(input_api, output_api))
results.extend(
input_api.canned_checks.CheckGNFormatted(input_api, output_api))
results.extend(_CheckUmaHistogramChanges(input_api, output_api))
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeBackupAgent.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeBackupAgent.java
index a95ec53..172cf787 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeBackupAgent.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeBackupAgent.java
@@ -11,8 +11,8 @@
import android.content.SharedPreferences;
import android.os.Build;
import android.os.ParcelFileDescriptor;
-import android.preference.PreferenceManager;
+import org.chromium.base.ContextUtils;
import org.chromium.base.Log;
import org.chromium.chrome.browser.firstrun.FirstRunSignInProcessor;
import org.chromium.chrome.browser.firstrun.FirstRunStatus;
@@ -62,8 +62,7 @@
@Override
public void onRestoreFinished() {
- SharedPreferences sharedPrefs =
- PreferenceManager.getDefaultSharedPreferences(ChromeBackupAgent.this);
+ SharedPreferences sharedPrefs = ContextUtils.getAppSharedPreferences();
Set<String> prefNames = sharedPrefs.getAll().keySet();
// Save the user name for later restoration.
String userName = sharedPrefs.getString(ChromeSigninController.SIGNED_IN_ACCOUNT_KEY, null);
diff --git a/chrome/android/javatests/src/org/chromium/chrome/browser/ChromeBackupIntegrationTest.java b/chrome/android/javatests/src/org/chromium/chrome/browser/ChromeBackupIntegrationTest.java
index 11b8bfd..d90896a3 100644
--- a/chrome/android/javatests/src/org/chromium/chrome/browser/ChromeBackupIntegrationTest.java
+++ b/chrome/android/javatests/src/org/chromium/chrome/browser/ChromeBackupIntegrationTest.java
@@ -9,9 +9,9 @@
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Build;
-import android.preference.PreferenceManager;
import android.test.suitebuilder.annotation.SmallTest;
+import org.chromium.base.ContextUtils;
import org.chromium.base.test.util.CommandLineFlags;
import org.chromium.base.test.util.MinAndroidSdkLevel;
import org.chromium.chrome.browser.firstrun.FirstRunSignInProcessor;
@@ -63,7 +63,7 @@
Context targetContext = getInstrumentation().getTargetContext();
// Fake having previously gone through FRE and signed in.
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(targetContext);
+ SharedPreferences prefs = ContextUtils.getAppSharedPreferences();
SharedPreferences.Editor preferenceEditor = prefs.edit();
preferenceEditor.putBoolean(FirstRunStatus.FIRST_RUN_FLOW_COMPLETE, true);
preferenceEditor.putBoolean(FirstRunSignInProcessor.FIRST_RUN_FLOW_SIGNIN_SETUP, true);
@@ -93,7 +93,7 @@
Context targetContext = getInstrumentation().getTargetContext();
// Fake having previously gone through FRE and signed in.
- SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(targetContext);
+ SharedPreferences prefs = ContextUtils.getAppSharedPreferences();
SharedPreferences.Editor preferenceEditor = prefs.edit();
preferenceEditor.putBoolean(FirstRunStatus.FIRST_RUN_FLOW_COMPLETE, true);
preferenceEditor.putBoolean(FirstRunSignInProcessor.FIRST_RUN_FLOW_SIGNIN_SETUP, true);
diff --git a/chrome/android/junit/src/org/chromium/chrome/browser/ChromeBackupAgentTest.java b/chrome/android/junit/src/org/chromium/chrome/browser/ChromeBackupAgentTest.java
index 20e1cb0..62853b63 100644
--- a/chrome/android/junit/src/org/chromium/chrome/browser/ChromeBackupAgentTest.java
+++ b/chrome/android/junit/src/org/chromium/chrome/browser/ChromeBackupAgentTest.java
@@ -9,9 +9,10 @@
import static org.junit.Assert.assertThat;
import android.content.SharedPreferences;
-import android.preference.PreferenceManager;
+import org.chromium.base.ContextUtils;
import org.chromium.testing.local.LocalRobolectricTestRunner;
+import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.Robolectric;
@@ -32,10 +33,14 @@
}
}
+ @Before
+ public void setUp() throws Exception {
+ ContextUtils.initApplicationContextForTests(Robolectric.application);
+ }
+
@Test
public void testOnRestoreFinished() {
- SharedPreferences sharedPrefs =
- PreferenceManager.getDefaultSharedPreferences(Robolectric.application);
+ SharedPreferences sharedPrefs = ContextUtils.getAppSharedPreferences();
SharedPreferences.Editor editor = sharedPrefs.edit();
editor.putBoolean("crash_dump_upload", false);
editor.putString("google.services.username", "user1");
diff --git a/tools/android/checkstyle/chromium-style-5.0.xml b/tools/android/checkstyle/chromium-style-5.0.xml
index 6557f61..700f449a 100644
--- a/tools/android/checkstyle/chromium-style-5.0.xml
+++ b/tools/android/checkstyle/chromium-style-5.0.xml
@@ -7,6 +7,9 @@
<module name="Checker">
<property name="severity" value="warning"/>
<property name="charset" value="UTF-8"/>
+ <module name="SuppressionFilter">
+ <property name="file" value="tools/android/checkstyle/suppressions.xml"/>
+ </module>
<module name="TreeWalker">
<module name="AvoidStarImport">
<property name="severity" value="error"/>
@@ -208,6 +211,13 @@
<property name="ignoreComments" value="true"/>
<property name="message" value="Avoid android.app.AlertDialog; if possible, use android.support.v7.app.AlertDialog instead, which has a Material look on all devices. (Some parts of the codebase can’t depend on the support library, in which case android.app.AlertDialog is the only option)"/>
</module>
+ <module name="RegexpSinglelineJava">
+ <property name="id" value="SharedPreferencesCheck"/>
+ <property name="severity" value="error"/>
+ <property name="format" value="getDefaultSharedPreferences"/>
+ <property name="ignoreComments" value="true"/>
+ <property name="message" value="Use ContextUtils.getAppSharedPreferences() instead to access app-wide SharedPreferences."/>
+ </module>
</module>
<!-- Non-TreeWalker modules -->
diff --git a/tools/android/checkstyle/suppressions.xml b/tools/android/checkstyle/suppressions.xml
new file mode 100644
index 0000000..850d7d4
--- /dev/null
+++ b/tools/android/checkstyle/suppressions.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE suppressions PUBLIC "-//Puppy Crawl//DTD Suppressions 1.1//EN" "http://www.puppycrawl.com/dtds/suppressions_1_1.dtd">
+
+<suppressions>
+ <suppress id="SharedPreferencesCheck" files="ContextUtils.java"/>
+</suppressions>