Movatterモバイル変換


[0]ホーム

URL:


Google Git
Sign in
chromium /chromium /src /refs/heads/main /. /styleguide /java /java.md
blob: 9c7f234e17877487bf5af341e5bc694f9a91f3bc [file] [log] [blame] [view]
Andrew Grieve8d9e40f2023-03-15 21:04:42[diff] [blame]1# Chromium Java Style Guide
nyquist9d61f982017-02-10 00:29:08[diff] [blame]2
3_For other languages, please see the [Chromium style
John Palmerbe051302021-05-19 11:48:35[diff] [blame]4guides](https://chromium.googlesource.com/chromium/src/+/main/styleguide/styleguide.md)._
nyquist9d61f982017-02-10 00:29:08[diff] [blame]5
6Chromium follows the [Android Open Source style
7guide](http://source.android.com/source/code-style.html) unless an exception
8is listed below.
9
nyquistaae4c7c2017-02-15 20:41:42[diff] [blame]10You can propose changes to this style guide by sending an email to
11`java@chromium.org`. Ideally, the list will arrive at some consensus and you can
12request review for a change to this file. If there's no consensus,
John Palmerbe051302021-05-19 11:48:35[diff] [blame]13[`//styleguide/java/OWNERS`](https://chromium.googlesource.com/chromium/src/+/main/styleguide/java/OWNERS)
nyquistaae4c7c2017-02-15 20:41:42[diff] [blame]14get to decide.
15
agrieve0e6bdf22018-08-03 14:25:24[diff] [blame]16[TOC]
17
Andrew Grieve99e388f2023-11-02 20:46:51[diff] [blame]18## Java Language Features
Nate Fischer03308e92022-11-07 18:14:59[diff] [blame]19
Andrew Grieve99e388f2023-11-02 20:46:51[diff] [blame]20### Type Deduction using "var" {#var}
Nate Fischer03308e92022-11-07 18:14:59[diff] [blame]21
22A variable declaration can use the `var` keyword in place of the type (similar
23to the `auto` keyword in C++). In line with the [guidance for
24C++](https://google.github.io/styleguide/cppguide.html#Type_deduction), the
25`var` keyword may be used when it aids readability and the type of the value is
26already clear (ex. `var bundle = new Bundle()` is OK, but `var something =
27returnValueIsNotObvious()` may be unclear to readers who are new to this part of
28the code).
29
30The `var` keyword may also be used in try-with-resources when the resource is
31not directly accessed (or when it falls under the previous guidance), such as:
32
33```java
34try (var ignored = StrictModeContext.allowDiskWrites()) {
35 // 'var' is permitted so long as the 'ignored' variable is not used directly
36 // in the code.
37}
38```
39
agrieve398286b2018-08-15 01:44:45[diff] [blame]40### Exceptions
Andrew Grieve99e388f2023-11-02 20:46:51[diff] [blame]41
Andrew Grieve1210d142024-06-06 16:31:47[diff] [blame]42A quick primer:
43
44* `Throwable`: Base class for all exceptions
45 * `Error`: Base class for exceptions which are meant to crash the app.
46 * `Exception`: Base class for exceptions that make sense the `catch`.
47 * `RuntimeException`: Base class for exceptions that do not need to be
48 declared as `throws` ("unchecked exceptions").
49
50#### Broad Catch Handlers {#broad-catches}
51
52Use catch statements that do not catch exceptions they are not meant to.
53 * There is rarely a valid reason to `catch (Throwable t)`, since that
54 includes the (generally unrecoverable) `Error` types.
55
56Use `catch (Exception e)` when working with OS APIs that might throw
57(assuming the program can recover from them).
Andrew Grieve318b35322023-01-13 16:03:23[diff] [blame]58 * There have been many cases of crashes caused by `IllegalStateException` /
59 `IllegalArgumentException` / `SecurityException` being thrown where only
Andrew Grieve1210d142024-06-06 16:31:47[diff] [blame]60 `RemoteException` was being caught. Unless catch handlers will differ
61 based on exception type, just catch `Exception`.
62
63Do not use `catch (RuntimeException e)`.
64 * It is useful to extend `RuntimeException` to make unchecked exception
65 types, but the type does not make much sense in `catch` clauses, as
66 there are not times when you'd want to catch all unchecked exceptions,
67 but not also want to catch all checked exceptions.
68
69#### Exception Messages {#exception-messages}
agrieve398286b2018-08-15 01:44:45[diff] [blame]70
Andrew Grieve318b35322023-01-13 16:03:23[diff] [blame]71Avoid adding messages to exceptions that do not aid in debugging. For example:
agrieve398286b2018-08-15 01:44:45[diff] [blame]72
agrieve50430de2018-08-15 17:49:16[diff] [blame]73```java
74try {
Nate Fischerfc38dc812024-04-24 17:07:26[diff] [blame]75 somethingThatThrowsIOException();
agrieve50430de2018-08-15 17:49:16[diff] [blame]76} catch (IOException e) {
Nate Fischerfc38dc812024-04-24 17:07:26[diff] [blame]77 // Bad - message does not tell you more than the stack trace does:
78 throw new RuntimeException("Failed to parse a file.", e);
79 // Good - conveys that this block failed along with the "caused by" exception.
80 throw new RuntimeException(e);
81 // Good - adds useful information.
82 throw new RuntimeException(String.format("Failed to parse %s", fileName), e);
agrieve50430de2018-08-15 17:49:16[diff] [blame]83}
84```
85
Andrew Grieve1210d142024-06-06 16:31:47[diff] [blame]86#### Wrapping with RuntimeException {#throw-unchecked}
87
88It is common to wrap a checked exception with a RuntimeException for cases
89where a checked exception is not recoverable, or not possible. In order to
90reduce the number of stack trace "caused by" clauses, and to save on binary
91size, use [`JavaUtils.throwUnchecked()`] instead.
92
93```java
94try {
95 somethingThatThrowsIOException();
96} catch (IOException e) {
97 // Bad - RuntimeException adds no context and creates longer stack traces.
98 throw new RuntimeException(e);
99 // Good - Original exception is preserved.
100 throw JavaUtils.throwUnchecked(e);
101}
102```
103
104*** note
105Do not use `throwUnchecked()` when the exception may want to be caught.
106***
107
108
109[`JavaUtils.throwUnchecked()`]: https://source.chromium.org/search?q=symbol:JavaUtils.throwUnchecked
110
agrieve398286b2018-08-15 01:44:45[diff] [blame]111### Asserts
Andrew Grieve8d9e40f2023-03-15 21:04:42[diff] [blame]112
Andrew Grieve087342762023-07-25 01:14:25[diff] [blame]113The build system:
114 * strips asserts in release builds (via R8),
115 * enables them in debug builds,
116 * and enables them in report-only mode for Canary builds.
agrieve398286b2018-08-15 01:44:45[diff] [blame]117
118```java
Andrew Grieve087342762023-07-25 01:14:25[diff] [blame]119// Code for assert expressions & messages is removed when asserts are disabled.
120assert someCallWithoutSideEffects(param) : "Call failed with: " + param;
agrieve398286b2018-08-15 01:44:45[diff] [blame]121```
122
Andrew Grieve087342762023-07-25 01:14:25[diff] [blame]123Use your judgement for when to use asserts vs exceptions. Generally speaking,
124use asserts to check program invariants (e.g. parameter constraints) and
125exceptions for unrecoverable error conditions (e.g. OS errors). You should tend
126to use exceptions more in privacy / security-sensitive code.
127
128Do not add checks when the code will crash anyways. E.g.:
129
130```java
131// Don't do this.
132assert(foo != null);
133foo.method(); // This will throw anyways.
134```
135
136For multi-statement asserts, use [`BuildConfig.ENABLE_ASSERTS`] to guard your
137code (similar to `#if DCHECK_IS_ON()` in C++). E.g.:
agrieve398286b2018-08-15 01:44:45[diff] [blame]138
139```java
Nate Fischer4570ebc32021-06-04 00:44:45[diff] [blame]140import org.chromium.build.BuildConfig;
141
142...
143
144if (BuildConfig.ENABLE_ASSERTS) {
Nate Fischerfc38dc812024-04-24 17:07:26[diff] [blame]145 // Any code here will be stripped in release builds by R8.
146 ...
agrieve398286b2018-08-15 01:44:45[diff] [blame]147}
148```
149
Andrew Grieve087342762023-07-25 01:14:25[diff] [blame]150[`BuildConfig.ENABLE_ASSERTS`]: https://source.chromium.org/search?q=symbol:BuildConfig%5C.ENABLE_ASSERTS
151
Andrew Grieve99e388f2023-11-02 20:46:51[diff] [blame]152#### DCHECKS vs Java Asserts {#asserts}
Andrew Grieve087342762023-07-25 01:14:25[diff] [blame]153
154`DCHECK` and `assert` are similar, but our guidance for them differs:
155 * CHECKs are preferred in C++, whereas asserts are preferred in Java.
156
157This is because as a memory-safe language, logic bugs in Java are much less
158likely to be exploitable.
159
Andrew Grieve99e388f2023-11-02 20:46:51[diff] [blame]160### toString() {#toString}
Andrew Grieve8d9e40f2023-03-15 21:04:42[diff] [blame]161
Andrew Grieve99e388f2023-11-02 20:46:51[diff] [blame]162Use explicit serialization methods (e.g. `toDebugString()` or `getDescription()`)
163instead of `toString()` when dynamic dispatch is not required.
Andrew Grieve8d9e40f2023-03-15 21:04:42[diff] [blame]164
Andrew Grieve99e388f2023-11-02 20:46:51[diff] [blame]1651. R8 cannot detect when `toString()` is unused, so overrides will not be stripped
166 when unused.
1672. R8 cannot optimize / inline these calls as well as non-overriding methods.
Andrew Grieve8d9e40f2023-03-15 21:04:42[diff] [blame]168
Andrew Grieve99e388f2023-11-02 20:46:51[diff] [blame]169### Records & AutoValue {#records}
170
171```java
172// Banned.
173record Rectangle(float length, float width) {}
174```
175
176**Rationale:**
177 * To avoid dead code:
178 * Records and `@AutoValue` generate `equals()`, `hashCode()`, and `toString()`,
179 which `R8` is unable to remove when unused.
180 * When these methods are required, implement them explicitly so that the
181 intention is clear.
182 * Also - supporting `record` requires build system work ([crbug/1493366]).
183
184Example with `equals()` and `hashCode()`:
185
186```java
187public class ValueClass {
188 private final SomeClass mObjMember;
189 private final int mIntMember;
190
191 @Override
192 public boolean equals(Object o) {
193 return o instanceof ValueClass vc
194 && Objects.equals(mObjMember, vc.mObjMember)
195 && mIntMember == vc.mIntMember;
196 }
197
198 @Override
199 public int hashCode() {
200 return Objects.hash(mObjMember, mIntMember);
201 }
202}
203```
204
205[crbug/1493366]: https://crbug.com/1493366
206
207### Enums
208
Andrew Grieveec66d8532025-10-08 16:59:45[diff] [blame]209Banned. Use [`@IntDef`](#intdefs) / `@LongDef` / `@StringDef` instead.
Andrew Grieve99e388f2023-11-02 20:46:51[diff] [blame]210
211**Rationale:**
212
Andrew Grieveec66d8532025-10-08 16:59:45[diff] [blame]213Java enums generate a lot of bytecode and some of their APIs rely on reflection
214under-the-hood. They also implement `Serializable`, which can lead to the
215inability to every change them.
216
217* Use constants where possible.
218* When a custom type is required, use explicit classes with inheritance.
219* When serialization is required, use explicit serialization / deserialization
220 logic.
Andrew Grieve8d9e40f2023-03-15 21:04:42[diff] [blame]221
Andrew Grieve9d2a5eab2025-10-01 17:25:46[diff] [blame]222### Optional
223
224Avoid it if possible. Use `@Nullable` instead.
225
226## Rationale:
227
228`Optional` adds binary size overhead and requires an extra allocation for each
229use. It may still be a good choice if you need to distinguish between "null"
230and "unset", but prefer `null` or a sentinel value when possible. The same
231applies to `OptionalInt`, etc.
232
233[NullAway](#Nullability-Annotations) warnings will ensure that null checks are
234not missed.
235
agrieve16c6fe82018-11-27 17:47:49[diff] [blame]236### Finalizers
Andrew Grieve8d9e40f2023-03-15 21:04:42[diff] [blame]237
Andrew Grieveec8284602023-10-16 15:53:25[diff] [blame]238In line with [Google's Java style guide] and [Android's Java style guide],
agrieve16c6fe82018-11-27 17:47:49[diff] [blame]239never override `Object.finalize()`.
240
241Custom finalizers:
242* are called on a background thread, and at an unpredicatble point in time,
243* swallow all exceptions (asserts won't work),
244* causes additional garbage collector jank.
245
246Classes that need destructor logic should provide an explicit `destroy()`
Sky Malice667b2c22025-05-12 19:14:18[diff] [blame]247method. Use [LifetimeAssert](https://chromium.googlesource.com/chromium/src/+/main/base/android/java/src/org/chromium/base/lifetime/LifetimeAssert.java)
Bo Liu9bb53ca2020-09-22 00:48:10[diff] [blame]248to ensure in debug builds and tests that `destroy()` is called.
agrieve16c6fe82018-11-27 17:47:49[diff] [blame]249
Andrew Grieveec8284602023-10-16 15:53:25[diff] [blame]250[Google's Java style guide]: https://google.github.io/styleguide/javaguide.html#s6.4-finalizers
251[Android's Java style guide]: https://source.android.com/docs/setup/contribute/code-style#dont-use-finalizers
252
Andrew Grieve19c214d2025-01-14 20:50:06[diff] [blame]253## Nullability Annotations
254
Andrew Grieve9d2a5eab2025-10-01 17:25:46[diff] [blame]255All non-test Java files within the main repository should use `@NullMarked`.
256Tests are encouraged to use them, but there is currently no effort to annotate
257existing ones.
Andrew Grieve19c214d2025-01-14 20:50:06[diff] [blame]258
Andrew Grieve9d2a5eab2025-10-01 17:25:46[diff] [blame]259See [nullaway.md] for how to use `@Nullable` and related annotations.
260
Andrew Grieve19c214d2025-01-14 20:50:06[diff] [blame]261[nullaway.md]: nullaway.md
262
Andrew Grieve99e388f2023-11-02 20:46:51[diff] [blame]263## Java Library APIs
Andrew Grieve8d9e40f2023-03-15 21:04:42[diff] [blame]264
Andrew Grieve99e388f2023-11-02 20:46:51[diff] [blame]265Android provides the ability to bundle copies of `java.*` APIs alongside
266application code, known as [Java Library Desugaring]. However, since this
267bundling comes with a performance cost, Chrome does not use it. Treat `java.*`
268APIs the same as you would `android.*` ones and guard them with
269`Build.VERSION.SDK_INT` checks [when necessary]. The one exception is if the
270method is [directly backported by D8] (these are okay to use, since they are
271lightweight). Android Lint will fail if you try to use an API without a
272corresponding `Build.VERSION.SDK_INT` guard or `@RequiresApi` annotation.
273
274[Java Library Desugaring]: https://developer.android.com/studio/write/java8-support-table
275[when necessary]: https://developer.android.com/reference/packages
276[directly backported by D8]: https://source.chromium.org/chromium/chromium/src/+/main:third_party/r8/backported_methods.txt
277
278### Logging
279
280* Use `org.chromium.base.Log` instead of `android.util.Log`.
281 * It provides `%s` support, and ensures log stripping works correctly.
282* Minimize the use of `Log.w()` and `Log.e()`.
283 * Debug and Info log levels are stripped by ProGuard in release builds, and
284 so have no performance impact for shipping builds. However, Warning and
285 Error log levels are not stripped.
286* Function calls in log parameters are *not* stripped by ProGuard.
287
288```java
289Log.d(TAG, "There are %d cats", countCats()); // countCats() not stripped.
290```
291
292### Streams
293
Andrew Grieve31928c92024-11-27 21:00:13[diff] [blame]294Using [Java streams] outside of tests is strongly discouraged. If you can write
295your code as an explicit loop, then do so. The primary reason for this guidance
296is because the lambdas and method references needed for streams almost always
297result in larger binary size than their loop equivalents (see
298[crbug.com/344943957] for examples).
Andrew Grieve99e388f2023-11-02 20:46:51[diff] [blame]299
300The `parallel()` and `parallelStream()` APIs are simpler than their loop
Andrew Grieve31928c92024-11-27 21:00:13[diff] [blame]301equivalents, but are banned due to a lack of a compelling use case in Chrome.
302If you find one, please discuss on `java@chromium.org`.
303
304Use of `stream()` without a lambda / method reference is allowed. E.g.:
305
306```java
307@SuppressWarnings("NoStreams")
308private static List<Integer> boxInts(int[] arr) {
309 return Arrays.stream(arr).boxed().collect(Collectors.toList());
310}
311
312@SuppressWarnings("NoStreams")
313private static List<String> readLines(BufferedReader bufferedReader) {
314 return bufferedReader.lines().collect(Collectors.toList());
315}
316```
Andrew Grieve99e388f2023-11-02 20:46:51[diff] [blame]317
318[Java streams]: https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html
Andrew Grieve31928c92024-11-27 21:00:13[diff] [blame]319[crbug.com/344943957]: https://crbug.com/344943957
Andrew Grieve99e388f2023-11-02 20:46:51[diff] [blame]320
321### AndroidX Annotations {#annotations}
322
323* Use them liberally. They are [documented here](https://developer.android.com/studio/write/annotations).
agrieve398286b2018-08-15 01:44:45[diff] [blame]324 * They generally improve readability.
Andrew Grieve99e388f2023-11-02 20:46:51[diff] [blame]325 * Many make lint more useful.
Andrew Grieve506d5622025-01-29 21:15:55[diff] [blame]326* What about `androidx.annotation.Nullable`?
327 * We are migrating away from it (see [nullaway.md]).
328 * Keep using it in files that have not yet been migrated.
agrieve398286b2018-08-15 01:44:45[diff] [blame]329
Andrew Grieve99e388f2023-11-02 20:46:51[diff] [blame]330#### IntDefs {#intdefs}
Carlos Knippschildf2e58c12021-06-03 01:43:37[diff] [blame]331
Andrew Grieve99e388f2023-11-02 20:46:51[diff] [blame]332Values can be declared outside or inside the `@interface`. Chromium style is
333to declare inside.
Carlos Knippschildf2e58c12021-06-03 01:43:37[diff] [blame]334
335```java
336@IntDef({ContactsPickerAction.CANCEL, ContactsPickerAction.CONTACTS_SELECTED,
337 ContactsPickerAction.SELECT_ALL, ContactsPickerAction.UNDO_SELECT_ALL})
338@Retention(RetentionPolicy.SOURCE)
339public @interface ContactsPickerAction {
340 int CANCEL = 0;
341 int CONTACTS_SELECTED = 1;
342 int SELECT_ALL = 2;
343 int UNDO_SELECT_ALL = 3;
344 int NUM_ENTRIES = 4;
345}
346// ...
347void onContactsPickerUserAction(@ContactsPickerAction int action, ...);
348```
349
350Values of `Integer` type are also supported, which allows using a sentinel
351`null` if needed.
352
353[@IntDef annotation]: https://developer.android.com/studio/write/annotations#enum-annotations
354[Android lint]: https://chromium.googlesource.com/chromium/src/+/HEAD/build/android/docs/lint.md
355
Andrew Grieve99e388f2023-11-02 20:46:51[diff] [blame]356
357## Style / Formatting {#style}
nyquistaae4c7c2017-02-15 20:41:42[diff] [blame]358
agrieve398286b2018-08-15 01:44:45[diff] [blame]359### File Headers
John Palmerbe051302021-05-19 11:48:35[diff] [blame]360* Use the same format as in the [C++ style guide](https://chromium.googlesource.com/chromium/src/+/main/styleguide/c++/c++.md#File-headers).
nyquistaae4c7c2017-02-15 20:41:42[diff] [blame]361
agrieve398286b2018-08-15 01:44:45[diff] [blame]362### TODOs
Andrew Grieve8d9e40f2023-03-15 21:04:42[diff] [blame]363
Alison Gale37015772024-06-28 19:47:48[diff] [blame]364* TODO should follow chromium convention. Examples:
365 * `TODO(username): Some sentence here.`
366 * `TODO(crbug.com/40192027): Even better to use a bug for context.`
nyquistaae4c7c2017-02-15 20:41:42[diff] [blame]367
Andrew Grieved99e3c02023-10-25 14:56:48[diff] [blame]368### Parameter Comments
369
370Use [parameter comments] when they aid in the readability of a function call.
371
372E.g.:
373
374```java
375someMethod(/* enabled= */ true, /* target= */ null, defaultValue);
376```
377
378[parameter comments]: https://errorprone.info/bugpattern/ParameterName
379
380### Default Field Initializers
Andrew Grieve8d9e40f2023-03-15 21:04:42[diff] [blame]381
nyquist9d61f982017-02-10 00:29:08[diff] [blame]382* Fields should not be explicitly initialized to default values (see
383 [here](https://groups.google.com/a/chromium.org/d/topic/chromium-dev/ylbLOvLs0bs/discussion)).
nyquistaae4c7c2017-02-15 20:41:42[diff] [blame]384
Andrew Grieve8d9e40f2023-03-15 21:04:42[diff] [blame]385### Curly Braces
386
nyquistaae4c7c2017-02-15 20:41:42[diff] [blame]387Conditional braces should be used, but are optional if the conditional and the
388statement can be on a single line.
389
390Do:
391
392```java
393if (someConditional) return false;
394for (int i = 0; i < 10; ++i) callThing(i);
395```
396
397or
398
399```java
400if (someConditional) {
Nate Fischerfc38dc812024-04-24 17:07:26[diff] [blame]401 return false;
nyquistaae4c7c2017-02-15 20:41:42[diff] [blame]402}
403```
404
405Do NOT do:
406
407```java
408if (someConditional)
Nate Fischerfc38dc812024-04-24 17:07:26[diff] [blame]409 return false;
nyquistaae4c7c2017-02-15 20:41:42[diff] [blame]410```
411
nyquist2d192c4c2017-03-06 21:36:51[diff] [blame]412### Import Order
Andrew Grieve8d9e40f2023-03-15 21:04:42[diff] [blame]413
nyquist2d192c4c2017-03-06 21:36:51[diff] [blame]414* Static imports go before other imports.
415* Each import group must be separated by an empty line.
416
417This is the order of the import groups:
418
4191. android
Yun Liuf40227d92019-04-04 17:37:46[diff] [blame]4201. androidx
nyquist2d192c4c2017-03-06 21:36:51[diff] [blame]4211. com (except com.google.android.apps.chrome)
4221. dalvik
4231. junit
4241. org
4251. com.google.android.apps.chrome
4261. org.chromium
4271. java
4281. javax
429
Andrew Grieve11c370072023-07-18 13:46:46[diff] [blame]430## Testing
431
432Googlers, see [go/clank-test-strategy](http://go/clank-test-strategy).
433
434In summary:
435
436* Use real dependencies when feasible and fast. Use Mockito’s `@Mock` most
437 of the time, but write fakes for frequently used dependencies.
438
Andrew Grievef8a603ce2024-05-21 20:09:24[diff] [blame]439* Do not use Robolectric Shadows for Chromium code.
440 * Shadows make code harder to refactor.
441 * Prefer to refactor code to make it more testable.
442 * When you really need to use a test double for a static method, add a
443 `setFooForTesting() [...]` method to make the test contract explicit.
444 * Use [`ResettersForTesting.register()`] from within `ForTesting()`
445 methods to ensure that state is reset between tests.
Andrew Grieve11c370072023-07-18 13:46:46[diff] [blame]446
447* Use Robolectric when possible (when tests do not require native). Other
448 times, use on-device tests with one of the following annotations:
449 * [`@Batch(UNIT_TESTS)`] for unit tests
450 * [`@Batch(PER_CLASS)`] for integration tests
451 * [`@DoNotBatch`] for when each test method requires an app restart
452
453[`ResettersForTesting.register()`]: https://source.chromium.org/search?q=symbol:ResettersForTesting.register
454[`@Batch(UNIT_TESTS)`]: https://source.chromium.org/search?q=symbol:Batch.UNIT_TESTS
455[`@Batch(PER_CLASS)`]: https://source.chromium.org/search?q=symbol:Batch.PER_CLASS
456[`@DoNotBatch`]: https://source.chromium.org/search?q=symbol:DoNotBatch
457
458### Test-only Code
Andrew Grieve8d9e40f2023-03-15 21:04:42[diff] [blame]459
Andrew Grieve0872aad2023-06-26 14:16:31[diff] [blame]460Functions and fields used only for testing should have `ForTesting` as a
461suffix so that:
Caitlin Fischer210cfab2020-05-07 20:04:30[diff] [blame]462
Andrew Grieve0872aad2023-06-26 14:16:31[diff] [blame]4631. The `android-binary-size` trybot can [ensure they are removed] in
464 non-test optimized builds (by R8).
4652. [`PRESUMBIT.py`] can ensure no calls are made to such methods outside of
466 tests, and
467
468`ForTesting` methods that are `@CalledByNative` should use
469`@CalledByNativeForTesting` instead.
470
471Symbols that are made public (or package-private) for the sake of tests
472should be annotated with [`@VisibleForTesting`]. Android Lint will check
473that calls from non-test code respect the "otherwise" visibility.
474
Andrew Grievee27a4f712023-07-04 15:16:35[diff] [blame]475Symbols with a `ForTesting` suffix **should not** be annotated with
Andrew Grieve0872aad2023-06-26 14:16:31[diff] [blame]476`@VisibleForTesting`. While `otherwise=VisibleForTesting.NONE` exists, it
477is redundant given the "ForTesting" suffix and the associated lint check
Andrew Grievee27a4f712023-07-04 15:16:35[diff] [blame]478is redundant given our trybot check. You should, however, use it for
479test-only constructors.
Andrew Grieve0872aad2023-06-26 14:16:31[diff] [blame]480
481[ensure they are removed]: /docs/speed/binary_size/android_binary_size_trybot.md#Added-Symbols-named-ForTest
482[`PRESUMBIT.py`]: https://chromium.googlesource.com/chromium/src/+/main/PRESUBMIT.py
483[`@VisibleForTesting`]: https://developer.android.com/reference/androidx/annotation/VisibleForTesting
Sam Maier7452a0d2022-07-20 18:24:35[diff] [blame]484
nyquist9d61f982017-02-10 00:29:08[diff] [blame]485## Location
Andrew Grieve8d9e40f2023-03-15 21:04:42[diff] [blame]486
nyquist9d61f982017-02-10 00:29:08[diff] [blame]487"Top level directories" are defined as directories with a GN file, such as
John Palmerbe051302021-05-19 11:48:35[diff] [blame]488[//base](https://chromium.googlesource.com/chromium/src/+/main/base/)
nyquist9d61f982017-02-10 00:29:08[diff] [blame]489and
John Palmerbe051302021-05-19 11:48:35[diff] [blame]490[//content](https://chromium.googlesource.com/chromium/src/+/main/content/),
nyquist9d61f982017-02-10 00:29:08[diff] [blame]491Chromium Java should live in a directory named
492`<top level directory>/android/java`, with a package name
493`org.chromium.<top level directory>`. Each top level directory's Java should
494build into a distinct JAR that honors the abstraction specified in a native
John Palmerbe051302021-05-19 11:48:35[diff] [blame]495[checkdeps](https://chromium.googlesource.com/chromium/buildtools/+/main/checkdeps/checkdeps.py)
nyquist9d61f982017-02-10 00:29:08[diff] [blame]496(e.g. `org.chromium.base` does not import `org.chromium.content`). The full
497path of any java file should contain the complete package name.
498
499For example, top level directory `//base` might contain a file named
500`base/android/java/org/chromium/base/Class.java`. This would get compiled into a
501`chromium_base.jar` (final JAR name TBD).
502
503`org.chromium.chrome.browser.foo.Class` would live in
504`chrome/android/java/org/chromium/chrome/browser/foo/Class.java`.
505
506New `<top level directory>/android` directories should have an `OWNERS` file
507much like
John Palmerbe051302021-05-19 11:48:35[diff] [blame]508[//base/android/OWNERS](https://chromium.googlesource.com/chromium/src/+/main/base/android/OWNERS).
nyquist9d61f982017-02-10 00:29:08[diff] [blame]509
Andrew Grieve0872aad2023-06-26 14:16:31[diff] [blame]510## Tools
511
Andrew Grieveec8284602023-10-16 15:53:25[diff] [blame]512`google-java-format` is used to auto-format Java files. Formatting of its code
513should be accepted in code reviews.
Andrew Grieve0872aad2023-06-26 14:16:31[diff] [blame]514
515You can run `git cl format` to apply the automatic formatting.
516
Andrew Grieveec8284602023-10-16 15:53:25[diff] [blame]517Chromium also makes use of several [static analysis] tools.
Andrew Grieve0872aad2023-06-26 14:16:31[diff] [blame]518
Andrew Grieveec8284602023-10-16 15:53:25[diff] [blame]519[static analysis]: /build/android/docs/static_analysis.md
Andrew Grieve0872aad2023-06-26 14:16:31[diff] [blame]520
nyquistaae4c7c2017-02-15 20:41:42[diff] [blame]521## Miscellany
Andrew Grieve8d9e40f2023-03-15 21:04:42[diff] [blame]522
nyquistaae4c7c2017-02-15 20:41:42[diff] [blame]523* Use UTF-8 file encodings and LF line endings.

[8]ページ先頭

©2009-2025 Movatter.jp