Closed Bug 2055298 Opened 2 months ago Closed 1 month ago

Eliminate remaining NoSystemCurrentTimeMillis lint baseline entries in mobile/android

Categories

(Firefox for Android :: General, task)

All
Android
task

Tracking

()

RESOLVED FIXED
155 Branch
Tracking Status
firefox155 --- fixed

People

(Reporter: RyanVM, Assigned: RyanVM)

References

(Blocks 1 open bug)

Details

Attachments

(13 files)

48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review
48 bytes, text/x-phabricator-request
Details | Review

Follow-up to bug 2039540, which introduced the NoSystemCurrentTimeMillis Android Lint detector and recorded the pre-existing violations in per-module lint-baseline.xml files. Currently there are 97 such baselined violations across the tree.

This bug removes those baseline entries by making each System.currentTimeMillis() call injectable, so the check is enforced with an empty baseline across mobile/android.

Approach:

  • Route System.currentTimeMillis() through the form the detector permits: a default-valued () -> Long (or Long) parameter on a class constructor or a top-level function, so tests can supply a fake clock.
  • For call sites with no injectable seam (framework-instantiated singletons/objects, the sanctioned DefaultDateTimeProvider wrapper, and the sample apps), annotate with a justified @Suppress("NoSystemCurrentTimeMillis") carrying the rationale inline.
  • Drop the now-empty NoSystemCurrentTimeMillis entries from each module's lint-baseline.xml.

Result: no remaining NoSystemCurrentTimeMillis findings or baseline entries in mobile/android.

Try push: https://treeherder.mozilla.org/jobs?repo=try&revision=0e682d89a945869d4206febee84e8d19b96af8ec (the Fenix unit test failure is already fixed and verified locally)

The Bugbug bot thinks this bug should belong to the 'Firefox for Android::Tooling' component, and is moving the bug to that component. Please correct in case you think the bot is wrong.

Component: General → Tooling
Component: Tooling → General

Route direct System.currentTimeMillis() calls in android-components and fenix classes through an
injectable currentTimeMillis provider defaulted in the primary constructor, the form accepted by the
NoSystemCurrentTimeMillis lint check, and drop the corresponding baseline entries. Also removes a
stale baseline entry for a since-deleted file.

Route direct System.currentTimeMillis() calls in top-level functions through an injectable default
parameter, the form accepted by the NoSystemCurrentTimeMillis lint check, and drop the corresponding
baseline entries. One-shot functions take a Long value default matching existing convention, while
functions that read the clock repeatedly take a () -> Long provider.

Move the System.currentTimeMillis() default out of the injectable provider property initializer and
into a primary-constructor parameter default, the form accepted by the NoSystemCurrentTimeMillis lint
check, while keeping the existing mutable test seam intact.

DefaultDateTimeProvider is the sanctioned wrapper around System.currentTimeMillis() that exists so
the clock can be injected everywhere else, so annotate its override with a justified suppression
rather than routing it through yet another provider.

Relocate SponsoredContentImpressionEntity.impressionDateInSeconds from a body-property initializer to
a primary-constructor parameter default, the form accepted by the NoSystemCurrentTimeMillis lint
check. This pulls the field into the data class's generated equals/copy, so SponsoredContentsRepositoryTest
now compares recorded impressions by url rather than by whole-entity equality, which would otherwise
depend on which wall-clock second the entities were constructed. Room still populates the column via
the constructor.

Object, companion, and singleton members give the lint check no constructor or top-level function to
attach an injectable default to. Move each System.currentTimeMillis() into an accepted form: a
top-level bundle-reading helper for the Crash companion factories, a constructor-defaulted
DefaultStartTimeProvider class in place of the object, and an AnnouncementDebouncer class backing
AccessibilityUtils.

The lint check only accepts a System.currentTimeMillis() default on a top-level function or a class
constructor, not on interface methods. Remove the current-time defaults from the PrivacyNoticeBanner,
TermsOfUsePrompt, and onboarding terms-of-service interfaces and have their implementations read the
time from an injected constructor provider instead. Production callers already invoke these with no
argument; the affected tests inject a fixed clock through the constructor.

The lint check does not accept a System.currentTimeMillis() default on interface, Dao, or data-class
methods. The sponsored-content impressions Dao now takes the timestamp explicitly, since its one
production caller already supplies it. SitePermissions gains a savedAt constructor default, so both
SitePermissionsRules.toSitePermissions and SitePermissionsFeature can drop their own clocks, and
BookmarksStorage.getRecentBookmarks drops its currentTime parameter while PlacesBookmarksStorage
reads its injected constructor clock instead.

Fragments cannot take an injectable constructor parameter because the framework instantiates them
reflectively. Move the settings.<timestamp> = System.currentTimeMillis() stamps out of
BrowserFragment, HomeFragment, and OnboardingFragment into Settings recorder methods that use the
clock Settings already holds in its constructor, so the call sites carry no direct clock read.

The sync worker and the account-settings observer are framework-instantiated and can't inject a
clock. Give the top-level setLastSynced() a current-time default so both drop their direct
System.currentTimeMillis() reads, and route the worker's stagger-buffer check and timestamp store
through top-level helpers with the same default.

FenixApplication and GrowthDataWorker are framework-instantiated, so their time-based cutoffs move
into top-level functions with a current-time default parameter: historyMetadataCleanupCutoff() for
the history-metadata cleanup age, and isAfterFirstWeekFromInstall() for the growth-data first-week
check.

The browser and sync sample apps reach System.currentTimeMillis() through framework entry points (an
Application.onCreate and a lazily-built FxaAccountManager) that offer no injectable clock seam and no
time-dependent behavior worth testing. Annotate both with a justified suppression rather than
restructuring sample-only code.

LensCameraFragment uses System.currentTimeMillis() only to make a captured-image filename unique;
there is no time-dependent behavior to test, so the call is annotated with a justified suppression
rather than injected.

Pushed by rvandermeulen@mozilla.com: https://github.com/mozilla-firefox/firefox/commit/fdbfe93ba5f1 https://hg.mozilla.org/integration/autoland/rev/cd5624cb7783 Inject a currentTimeMillis provider into classes r=android-reviewers,mcarare https://github.com/mozilla-firefox/firefox/commit/2f816fb61462 https://hg.mozilla.org/integration/autoland/rev/4d95c3d9d360 Inject a currentTimeMillis parameter into top-level functions r=android-reviewers,mcarare https://github.com/mozilla-firefox/firefox/commit/c205c10dd104 https://hg.mozilla.org/integration/autoland/rev/8a669d3b3d6b Relocate currentTimeMillis providers into constructors r=android-reviewers,mcarare https://github.com/mozilla-firefox/firefox/commit/1ab6874ef887 https://hg.mozilla.org/integration/autoland/rev/00d265828f91 Suppress NoSystemCurrentTimeMillis on the DateTimeProvider implementation r=android-reviewers,mcarare https://github.com/mozilla-firefox/firefox/commit/271c68706127 https://hg.mozilla.org/integration/autoland/rev/e34d0be9816b Move the impression timestamp default into the entity constructor r=android-reviewers,mcarare https://github.com/mozilla-firefox/firefox/commit/001c05b36f28 https://hg.mozilla.org/integration/autoland/rev/6bf269fff594 Restructure object and companion members r=android-reviewers,mcarare https://github.com/mozilla-firefox/firefox/commit/8e2d10312e79 https://hg.mozilla.org/integration/autoland/rev/7f57ddd8d195 Drop method-parameter clock defaults from repository interfaces r=android-reviewers,mcarare https://github.com/mozilla-firefox/firefox/commit/3dfc66f569ca https://hg.mozilla.org/integration/autoland/rev/fd775ec088a3 Drop method-parameter clock defaults for bookmarks, site permissions, and impressions r=android-reviewers,mcarare https://github.com/mozilla-firefox/firefox/commit/0f7aded49cd3 https://hg.mozilla.org/integration/autoland/rev/10013dadf42d Record activity timestamps through Settings r=android-reviewers,mcarare https://github.com/mozilla-firefox/firefox/commit/4668a5577ecb https://hg.mozilla.org/integration/autoland/rev/3710c98efd99 Default the sync last-synced timestamp r=android-reviewers,mcarare https://github.com/mozilla-firefox/firefox/commit/077889fc7cd7 https://hg.mozilla.org/integration/autoland/rev/121cd0f9c897 Extract framework-class time cutoffs to top-level functions r=android-reviewers,mcarare https://github.com/mozilla-firefox/firefox/commit/da4924962d93 https://hg.mozilla.org/integration/autoland/rev/548516b47e8d Suppress NoSystemCurrentTimeMillis in sample apps r=android-reviewers,mcarare https://github.com/mozilla-firefox/firefox/commit/4b4ed5d5a6a3 https://hg.mozilla.org/integration/autoland/rev/d45e17686707 Suppress NoSystemCurrentTimeMillis for the capture-image filename r=android-reviewers,mcarare
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: