diff --git a/infer/src/checkers/ThreadSafety.ml b/infer/src/checkers/ThreadSafety.ml index ace1e5435..ee15d7ee0 100644 --- a/infer/src/checkers/ThreadSafety.ml +++ b/infer/src/checkers/ThreadSafety.ml @@ -296,6 +296,9 @@ module TransferFunctions (CFG : ProcCfg.S) = struct | "java.lang.ThreadLocal", "get" -> (* ThreadLocal prevents sharing between threads behind the scenes *) true + | ("android.app.Activity" | "android.view.View"), "findViewById" -> + (* assume findViewById creates fresh View's (note: not always true) *) + true | "android.support.v4.util.Pools$SynchronizedPool", "acquire" -> (* a pool should own all of its objects *) true diff --git a/infer/tests/codetoanalyze/java/threadsafety/AndroidModels.java b/infer/tests/codetoanalyze/java/threadsafety/AndroidModels.java index 703952df2..818713e2b 100644 --- a/infer/tests/codetoanalyze/java/threadsafety/AndroidModels.java +++ b/infer/tests/codetoanalyze/java/threadsafety/AndroidModels.java @@ -11,11 +11,18 @@ package codetoanalyze.java.checkers; import javax.annotation.concurrent.ThreadSafe; +import android.app.Activity; +import android.content.Context; import android.content.res.AssetManager; import android.content.res.Configuration; import android.content.res.Resources; +import android.view.View; import android.util.DisplayMetrics; +class MyActivity extends Activity { + +} + class MyResources extends Resources { public MyResources(AssetManager assets, DisplayMetrics metrics, Configuration config) { @@ -24,6 +31,16 @@ class MyResources extends Resources { } +class MyView extends View { + + boolean mField; + + public MyView(Context c) { + super(c); + } + +} + @ThreadSafe public class AndroidModels { @@ -48,4 +65,14 @@ public class AndroidModels { mField = mResources.getConfiguration(); } + public void findViewByIdOk1(MyView view) { + MyView subview = (MyView) view.findViewById(-1); + subview.mField = true; // ok; + } + + public void findViewByIdOk2(MyActivity activity) { + MyView view = (MyView) activity.findViewById(-1); + view.mField = true; // ok; + } + }