1*6777b538SAndroid Build Coastguard Worker# Lint 2*6777b538SAndroid Build Coastguard Worker 3*6777b538SAndroid Build Coastguard Worker[Android Lint] is [one of the static analysis tools] that Chromium uses to catch 4*6777b538SAndroid Build Coastguard Workerpossible issues in Java code. 5*6777b538SAndroid Build Coastguard Worker 6*6777b538SAndroid Build Coastguard WorkerThis is a [list of checks] that you might encounter. 7*6777b538SAndroid Build Coastguard Worker 8*6777b538SAndroid Build Coastguard Worker[Android Lint]: https://googlesamples.github.io/android-custom-lint-rules/book.md.html 9*6777b538SAndroid Build Coastguard Worker[one of the static analysis tools]: static_analysis.md 10*6777b538SAndroid Build Coastguard Worker[list of checks]: https://googlesamples.github.io/android-custom-lint-rules/checks/index.md.html 11*6777b538SAndroid Build Coastguard Worker 12*6777b538SAndroid Build Coastguard Worker[TOC] 13*6777b538SAndroid Build Coastguard Worker 14*6777b538SAndroid Build Coastguard Worker## How Chromium uses lint 15*6777b538SAndroid Build Coastguard Worker 16*6777b538SAndroid Build Coastguard WorkerChromium only runs lint on apk or bundle targets that explicitly set 17*6777b538SAndroid Build Coastguard Worker`enable_lint = true`. You can run lint by compiling the apk or bundle target 18*6777b538SAndroid Build Coastguard Workerwith ninja; once the code finishes compiling, ninja will automatically run lint 19*6777b538SAndroid Build Coastguard Workeron the code. 20*6777b538SAndroid Build Coastguard Worker 21*6777b538SAndroid Build Coastguard WorkerSome example targets that have lint enabled are: 22*6777b538SAndroid Build Coastguard Worker 23*6777b538SAndroid Build Coastguard Worker - `//chrome/android:monochrome_public_bundle` 24*6777b538SAndroid Build Coastguard Worker - `//android_webview/support_library/boundary_interfaces:boundary_interface_example_apk` 25*6777b538SAndroid Build Coastguard Worker - Other targets with `enable_lint` enabled: https://source.chromium.org/search?q=lang:gn%20enable_lint%5C%20%3D%5C%20true&ss=chromium 26*6777b538SAndroid Build Coastguard Worker 27*6777b538SAndroid Build Coastguard WorkerIf you think lint is not running and already verified your GN 28*6777b538SAndroid Build Coastguard Workertarget has `enable_lint = true`, then you can double check that 29*6777b538SAndroid Build Coastguard Worker`android_static_analysis` is set to `"on"` (this is the default value): 30*6777b538SAndroid Build Coastguard Worker 31*6777b538SAndroid Build Coastguard Worker```shell 32*6777b538SAndroid Build Coastguard Worker$ gn args out/Default --list=android_static_analysis 33*6777b538SAndroid Build Coastguard Workerandroid_static_analysis 34*6777b538SAndroid Build Coastguard Worker Current value (from the default) = "on" 35*6777b538SAndroid Build Coastguard Worker From //build/config/android/config.gni:85 36*6777b538SAndroid Build Coastguard Worker``` 37*6777b538SAndroid Build Coastguard Worker 38*6777b538SAndroid Build Coastguard Worker## My code has a lint error 39*6777b538SAndroid Build Coastguard Worker 40*6777b538SAndroid Build Coastguard WorkerIf lint reports an issue in your code, there are several possible remedies. 41*6777b538SAndroid Build Coastguard WorkerIn descending order of preference: 42*6777b538SAndroid Build Coastguard Worker 43*6777b538SAndroid Build Coastguard Worker### Fix it 44*6777b538SAndroid Build Coastguard Worker 45*6777b538SAndroid Build Coastguard WorkerWhile this isn't always the right response, fixing the lint error or warning 46*6777b538SAndroid Build Coastguard Workershould be the default. 47*6777b538SAndroid Build Coastguard Worker 48*6777b538SAndroid Build Coastguard Worker### Suppress it locally 49*6777b538SAndroid Build Coastguard Worker 50*6777b538SAndroid Build Coastguard WorkerJava provides an annotation, 51*6777b538SAndroid Build Coastguard Worker[`@SuppressWarnings`](https://developer.android.com/reference/java/lang/SuppressWarnings), 52*6777b538SAndroid Build Coastguard Workerthat tells lint to ignore the annotated element. It can be used on classes, 53*6777b538SAndroid Build Coastguard Workerconstructors, methods, parameters, fields, or local variables, though usage in 54*6777b538SAndroid Build Coastguard WorkerChromium is typically limited to the first three. You do not need to import it 55*6777b538SAndroid Build Coastguard Workersince it is in the `java.lang` package. 56*6777b538SAndroid Build Coastguard Worker 57*6777b538SAndroid Build Coastguard WorkerLike many suppression annotations, `@SuppressWarnings` takes a value that tells 58*6777b538SAndroid Build Coastguard Worker**lint** what to ignore. It can be a single `String`: 59*6777b538SAndroid Build Coastguard Worker 60*6777b538SAndroid Build Coastguard Worker```java 61*6777b538SAndroid Build Coastguard Worker@SuppressWarnings("NewApi") 62*6777b538SAndroid Build Coastguard Workerpublic void foo() { 63*6777b538SAndroid Build Coastguard Worker a.methodThatRequiresHighSdkLevel(); 64*6777b538SAndroid Build Coastguard Worker} 65*6777b538SAndroid Build Coastguard Worker``` 66*6777b538SAndroid Build Coastguard Worker 67*6777b538SAndroid Build Coastguard WorkerIt can also be a list of `String`s: 68*6777b538SAndroid Build Coastguard Worker 69*6777b538SAndroid Build Coastguard Worker```java 70*6777b538SAndroid Build Coastguard Worker@SuppressWarnings({ 71*6777b538SAndroid Build Coastguard Worker "NewApi", 72*6777b538SAndroid Build Coastguard Worker "UseSparseArrays" 73*6777b538SAndroid Build Coastguard Worker }) 74*6777b538SAndroid Build Coastguard Workerpublic Map<Integer, FakeObject> bar() { 75*6777b538SAndroid Build Coastguard Worker Map<Integer, FakeObject> shouldBeASparseArray = new HashMap<Integer, FakeObject>(); 76*6777b538SAndroid Build Coastguard Worker another.methodThatRequiresHighSdkLevel(shouldBeASparseArray); 77*6777b538SAndroid Build Coastguard Worker return shouldBeASparseArray; 78*6777b538SAndroid Build Coastguard Worker} 79*6777b538SAndroid Build Coastguard Worker``` 80*6777b538SAndroid Build Coastguard Worker 81*6777b538SAndroid Build Coastguard WorkerFor resource xml files you can use `tools:ignore`: 82*6777b538SAndroid Build Coastguard Worker 83*6777b538SAndroid Build Coastguard Worker```xml 84*6777b538SAndroid Build Coastguard Worker<?xml version="1.0" encoding="utf-8"?> 85*6777b538SAndroid Build Coastguard Worker<resources xmlns:tools="http://schemas.android.com/tools"> 86*6777b538SAndroid Build Coastguard Worker <!-- TODO(crbug/###): remove tools:ignore once these colors are used --> 87*6777b538SAndroid Build Coastguard Worker <color name="hi" tools:ignore="NewApi,UnusedResources">@color/unused</color> 88*6777b538SAndroid Build Coastguard Worker</resources> 89*6777b538SAndroid Build Coastguard Worker``` 90*6777b538SAndroid Build Coastguard Worker 91*6777b538SAndroid Build Coastguard WorkerThe examples above are the recommended ways of suppressing lint warnings. 92*6777b538SAndroid Build Coastguard Worker 93*6777b538SAndroid Build Coastguard Worker### Suppress it in a `lint-suppressions.xml` file 94*6777b538SAndroid Build Coastguard Worker 95*6777b538SAndroid Build Coastguard Worker**lint** can be given a per-target XML configuration file containing warnings or 96*6777b538SAndroid Build Coastguard Workererrors that should be ignored. Each target defines its own configuration file 97*6777b538SAndroid Build Coastguard Workervia the `lint_suppressions_file` gn variable. It is usually defined near its 98*6777b538SAndroid Build Coastguard Worker`enable_lint` gn variable. 99*6777b538SAndroid Build Coastguard Worker 100*6777b538SAndroid Build Coastguard WorkerThese suppressions files should only be used for temporarily ignoring warnings 101*6777b538SAndroid Build Coastguard Workerthat are too hard (or not possible) to suppress locally, and permanently 102*6777b538SAndroid Build Coastguard Workerignoring warnings only for this target. To permanently ignore a warning for all 103*6777b538SAndroid Build Coastguard Workertargets, add the warning to the `_DISABLED_ALWAYS` list in 104*6777b538SAndroid Build Coastguard Worker[build/android/gyp/lint.py](https://source.chromium.org/chromium/chromium/src/+/main:build/android/gyp/lint.py). 105*6777b538SAndroid Build Coastguard WorkerDisabling globally makes lint a bit faster. 106*6777b538SAndroid Build Coastguard Worker 107*6777b538SAndroid Build Coastguard WorkerThe exception to the above rule is for warnings that affect multiple languages. 108*6777b538SAndroid Build Coastguard WorkerFeel free to suppress those in lint-suppressions.xml files since it is not 109*6777b538SAndroid Build Coastguard Workerpractical to suppress them in each language file and it is a lot of extra bloat 110*6777b538SAndroid Build Coastguard Workerto list out every language for every violation in lint-baseline.xml files. 111*6777b538SAndroid Build Coastguard Worker 112*6777b538SAndroid Build Coastguard WorkerHere is an example of how to structure a suppressions XML file: 113*6777b538SAndroid Build Coastguard Worker 114*6777b538SAndroid Build Coastguard Worker```xml 115*6777b538SAndroid Build Coastguard Worker<?xml version="1.0" encoding="utf-8" ?> 116*6777b538SAndroid Build Coastguard Worker<lint> 117*6777b538SAndroid Build Coastguard Worker <!-- Chrome is a system app. --> 118*6777b538SAndroid Build Coastguard Worker <issue id="ProtectedPermissions" severity="ignore"/> 119*6777b538SAndroid Build Coastguard Worker <issue id="UnusedResources"> 120*6777b538SAndroid Build Coastguard Worker <!-- 1 raw resources are accessed by URL in various places. --> 121*6777b538SAndroid Build Coastguard Worker <ignore regexp="gen/remoting/android/.*/res/raw/credits.*"/> 122*6777b538SAndroid Build Coastguard Worker <!-- TODO(crbug.com/###): Remove the following line. --> 123*6777b538SAndroid Build Coastguard Worker <ignore regexp="The resource `R.string.soon_to_be_used` appears to be unused"/> 124*6777b538SAndroid Build Coastguard Worker </issue> 125*6777b538SAndroid Build Coastguard Worker</lint> 126*6777b538SAndroid Build Coastguard Worker``` 127*6777b538SAndroid Build Coastguard Worker 128*6777b538SAndroid Build Coastguard Worker## What are `lint-baseline.xml` files for? 129*6777b538SAndroid Build Coastguard Worker 130*6777b538SAndroid Build Coastguard WorkerBaseline files are to help us introduce new lint warnings and errors without 131*6777b538SAndroid Build Coastguard Workerblocking on fixing all our existing code that violate these new errors. Since 132*6777b538SAndroid Build Coastguard Workerthey are generated files, they should **not** be used to suppress lint warnings. 133*6777b538SAndroid Build Coastguard WorkerOne of the approaches above should be used instead. Eventually all the errors in 134*6777b538SAndroid Build Coastguard Workerbaseline files should be either fixed or ignored permanently. 135*6777b538SAndroid Build Coastguard Worker 136*6777b538SAndroid Build Coastguard WorkerMost devs do not need to update baseline files and should not need the script 137*6777b538SAndroid Build Coastguard Workerbelow. Occasionally when making large build configuration changes it may be 138*6777b538SAndroid Build Coastguard Workernecessary to update baseline files (e.g. increasing the min_sdk_version). 139*6777b538SAndroid Build Coastguard Worker 140*6777b538SAndroid Build Coastguard WorkerBaseline files are defined via the `lint_baseline_file` gn variable. It is 141*6777b538SAndroid Build Coastguard Workerusually defined near a target's `enable_lint` gn variable. To regenerate all 142*6777b538SAndroid Build Coastguard Workerbaseline files, run: 143*6777b538SAndroid Build Coastguard Worker 144*6777b538SAndroid Build Coastguard Worker``` 145*6777b538SAndroid Build Coastguard Worker$ third_party/android_build_tools/lint/rebuild_baselines.py 146*6777b538SAndroid Build Coastguard Worker``` 147*6777b538SAndroid Build Coastguard Worker 148*6777b538SAndroid Build Coastguard WorkerThis script will also update baseline files in downstream //clank if needed. 149*6777b538SAndroid Build Coastguard WorkerSince downstream and upstream use separate lint binaries, it is usually safe 150*6777b538SAndroid Build Coastguard Workerto simply land the update CLs in any order. 151