summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--errorprone/java/com/google/errorprone/bugpatterns/android/ContextUserIdChecker.java42
-rw-r--r--errorprone/java/com/google/errorprone/bugpatterns/android/UidChecker.java8
-rw-r--r--errorprone/tests/java/com/google/errorprone/bugpatterns/android/ContextUserIdCheckerTest.java13
-rw-r--r--errorprone/tests/res/android/os/UserHandle.java4
4 files changed, 40 insertions, 27 deletions
diff --git a/errorprone/java/com/google/errorprone/bugpatterns/android/ContextUserIdChecker.java b/errorprone/java/com/google/errorprone/bugpatterns/android/ContextUserIdChecker.java
index 7f2cce6ea7f0..4f1af3e9bea2 100644
--- a/errorprone/java/com/google/errorprone/bugpatterns/android/ContextUserIdChecker.java
+++ b/errorprone/java/com/google/errorprone/bugpatterns/android/ContextUserIdChecker.java
@@ -17,6 +17,7 @@
package com.google.errorprone.bugpatterns.android;
import static com.google.errorprone.BugPattern.SeverityLevel.WARNING;
+import static com.google.errorprone.bugpatterns.android.UidChecker.getFlavor;
import static com.google.errorprone.matchers.Matchers.enclosingClass;
import static com.google.errorprone.matchers.Matchers.hasAnnotation;
import static com.google.errorprone.matchers.Matchers.instanceMethod;
@@ -27,17 +28,17 @@ import com.google.errorprone.BugPattern;
import com.google.errorprone.VisitorState;
import com.google.errorprone.bugpatterns.BugChecker;
import com.google.errorprone.bugpatterns.BugChecker.MethodInvocationTreeMatcher;
+import com.google.errorprone.bugpatterns.android.UidChecker.Flavor;
import com.google.errorprone.matchers.Description;
import com.google.errorprone.matchers.Matcher;
import com.google.errorprone.util.ASTHelpers;
import com.sun.source.tree.ExpressionTree;
+import com.sun.source.tree.IdentifierTree;
import com.sun.source.tree.MethodInvocationTree;
import com.sun.source.tree.Tree;
import com.sun.tools.javac.code.Symbol.VarSymbol;
import java.util.List;
-import java.util.Locale;
-import java.util.function.Predicate;
/**
* To avoid an explosion of {@code startActivityForUser} style methods, we've
@@ -62,39 +63,34 @@ public final class ContextUserIdChecker extends BugChecker implements MethodInvo
private static final Matcher<ExpressionTree> GET_USER_ID_CALL = methodInvocation(
instanceMethod().onDescendantOf("android.content.Context").named("getUserId"));
+ private static final Matcher<ExpressionTree> USER_ID_FIELD = new Matcher<ExpressionTree>() {
+ @Override
+ public boolean matches(ExpressionTree tree, VisitorState state) {
+ if (tree instanceof IdentifierTree) {
+ return "mUserId".equals((((IdentifierTree) tree).getName().toString()));
+ }
+ return false;
+ }
+ };
+
@Override
public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState state) {
if (INSIDE_MANAGER.matches(tree, state)
&& BINDER_CALL.matches(tree, state)) {
final List<VarSymbol> vars = ASTHelpers.getSymbol(tree).params();
for (int i = 0; i < vars.size(); i++) {
- if (USER_ID_VAR.test(vars.get(i)) &&
- !GET_USER_ID_CALL.matches(tree.getArguments().get(i), state)) {
+ final Flavor varFlavor = getFlavor(vars.get(i));
+ final ExpressionTree arg = tree.getArguments().get(i);
+ if (varFlavor == Flavor.USER_ID &&
+ !GET_USER_ID_CALL.matches(arg, state) &&
+ !USER_ID_FIELD.matches(arg, state)) {
return buildDescription(tree)
.setMessage("Must pass Context.getUserId() as user ID"
- + "to enable createContextAsUser()")
+ + " to enable createContextAsUser()")
.build();
}
}
}
return Description.NO_MATCH;
}
-
- private static final UserIdMatcher USER_ID_VAR = new UserIdMatcher();
-
- private static class UserIdMatcher implements Predicate<VarSymbol> {
- @Override
- public boolean test(VarSymbol t) {
- if ("int".equals(t.type.toString())) {
- switch (t.name.toString().toLowerCase(Locale.ROOT)) {
- case "user":
- case "userid":
- case "userhandle":
- case "user_id":
- return true;
- }
- }
- return false;
- }
- }
}
diff --git a/errorprone/java/com/google/errorprone/bugpatterns/android/UidChecker.java b/errorprone/java/com/google/errorprone/bugpatterns/android/UidChecker.java
index 533586f65c61..3ffb8ea40789 100644
--- a/errorprone/java/com/google/errorprone/bugpatterns/android/UidChecker.java
+++ b/errorprone/java/com/google/errorprone/bugpatterns/android/UidChecker.java
@@ -63,7 +63,7 @@ public final class UidChecker extends BugChecker implements MethodInvocationTree
return Description.NO_MATCH;
}
- private static enum Flavor {
+ public static enum Flavor {
UNKNOWN(null),
PID(Pattern.compile("(^pid$|Pid$)")),
UID(Pattern.compile("(^uid$|Uid$)")),
@@ -78,7 +78,7 @@ public final class UidChecker extends BugChecker implements MethodInvocationTree
}
}
- private static Flavor getFlavor(String name) {
+ public static Flavor getFlavor(String name) {
for (Flavor f : Flavor.values()) {
if (f.matches(name)) {
return f;
@@ -87,7 +87,7 @@ public final class UidChecker extends BugChecker implements MethodInvocationTree
return Flavor.UNKNOWN;
}
- private static Flavor getFlavor(VarSymbol symbol) {
+ public static Flavor getFlavor(VarSymbol symbol) {
final String type = symbol.type.toString();
if ("int".equals(type)) {
return getFlavor(symbol.name.toString());
@@ -95,7 +95,7 @@ public final class UidChecker extends BugChecker implements MethodInvocationTree
return Flavor.UNKNOWN;
}
- private static Flavor getFlavor(ExpressionTree tree) {
+ public static Flavor getFlavor(ExpressionTree tree) {
if (tree instanceof IdentifierTree) {
return getFlavor(((IdentifierTree) tree).getName().toString());
} else if (tree instanceof MemberSelectTree) {
diff --git a/errorprone/tests/java/com/google/errorprone/bugpatterns/android/ContextUserIdCheckerTest.java b/errorprone/tests/java/com/google/errorprone/bugpatterns/android/ContextUserIdCheckerTest.java
index 46a24d16f35a..c0b8cd745afc 100644
--- a/errorprone/tests/java/com/google/errorprone/bugpatterns/android/ContextUserIdCheckerTest.java
+++ b/errorprone/tests/java/com/google/errorprone/bugpatterns/android/ContextUserIdCheckerTest.java
@@ -49,9 +49,16 @@ public class ContextUserIdCheckerTest {
"@SystemService(\"foo\") public class FooManager {",
" Context mContext;",
" IFooService mService;",
+ " final int mUserId;",
+ " FooManager(Context context) {",
+ " mUserId = mContext.getUserId();",
+ " }",
" void bar() throws RemoteException {",
" mService.baz(null, mContext.getUserId());",
" }",
+ " void baz() throws RemoteException {",
+ " mService.baz(null, mUserId);",
+ " }",
"}")
.doTest();
}
@@ -63,11 +70,13 @@ public class ContextUserIdCheckerTest {
.addSourceFile("/android/content/Context.java")
.addSourceFile("/android/foo/IFooService.java")
.addSourceFile("/android/os/IInterface.java")
+ .addSourceFile("/android/os/UserHandle.java")
.addSourceFile("/android/os/RemoteException.java")
.addSourceLines("FooManager.java",
"import android.annotation.SystemService;",
"import android.content.Context;",
"import android.foo.IFooService;",
+ "import android.os.UserHandle;",
"import android.os.RemoteException;",
"@SystemService(\"foo\") public class FooManager {",
" Context mContext;",
@@ -76,6 +85,10 @@ public class ContextUserIdCheckerTest {
" // BUG: Diagnostic contains:",
" mService.baz(null, 0);",
" }",
+ " void baz() throws RemoteException {",
+ " // BUG: Diagnostic contains:",
+ " mService.baz(null, UserHandle.myUserId());",
+ " }",
"}")
.doTest();
}
diff --git a/errorprone/tests/res/android/os/UserHandle.java b/errorprone/tests/res/android/os/UserHandle.java
index a05fb9e42efa..c58d661fad08 100644
--- a/errorprone/tests/res/android/os/UserHandle.java
+++ b/errorprone/tests/res/android/os/UserHandle.java
@@ -28,4 +28,8 @@ public class UserHandle {
public static int getUid(int userId, int appId) {
throw new UnsupportedOperationException();
}
+
+ public static int myUserId() {
+ throw new UnsupportedOperationException();
+ }
}