You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
74 lines
3.4 KiB
Kotlin
74 lines
3.4 KiB
Kotlin
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
package org.mozilla.fenix.perf
|
|
|
|
import android.os.Build
|
|
import android.os.StrictMode
|
|
import android.os.strictmode.Violation
|
|
import androidx.annotation.RequiresApi
|
|
import mozilla.components.support.base.log.logger.Logger
|
|
import org.mozilla.fenix.utils.ManufacturerCodes
|
|
|
|
private const val FCQN_EDM_STORAGE_PROVIDER_BASE = "com.android.server.enterprise.storage.EdmStorageProviderBase"
|
|
|
|
/**
|
|
* A [StrictMode.OnThreadViolationListener] that recreates
|
|
* [StrictMode.ThreadPolicy.Builder.penaltyDeath] but will ignore some violations. For example,
|
|
* sometimes OEMs will add code that violates StrictMode so we can ignore them here instead of
|
|
* cluttering up our code with resetAfter.
|
|
*
|
|
* This class can only be used with Android P+ so we'd have to implement workarounds if the
|
|
* violations we want to ignore affect older devices.
|
|
*/
|
|
@RequiresApi(Build.VERSION_CODES.P)
|
|
class ThreadPenaltyDeathWithIgnoresListener(
|
|
private val logger: Logger = Performance.logger
|
|
) : StrictMode.OnThreadViolationListener {
|
|
|
|
override fun onThreadViolation(violation: Violation?) {
|
|
if (violation == null) return
|
|
|
|
// Unfortunately, this method gets called many (~5+) times with the same violation so we end
|
|
// up logging/throwing redundantly.
|
|
if (shouldViolationBeIgnored(violation)) {
|
|
logger.debug("Ignoring StrictMode ThreadPolicy violation", violation)
|
|
} else {
|
|
penaltyDeath(violation)
|
|
}
|
|
}
|
|
|
|
@Suppress("TooGenericExceptionThrown") // we throw what StrictMode's penaltyDeath throws.
|
|
private fun penaltyDeath(violation: Violation) {
|
|
throw RuntimeException("StrictMode ThreadPolicy violation", violation)
|
|
}
|
|
|
|
private fun shouldViolationBeIgnored(violation: Violation): Boolean =
|
|
isSamsungLgEdmStorageProviderStartupViolation(violation)
|
|
|
|
private fun isSamsungLgEdmStorageProviderStartupViolation(violation: Violation): Boolean {
|
|
// Root issue: https://github.com/mozilla-mobile/fenix/issues/17920
|
|
//
|
|
// This fix may address the issues seen in this bug:
|
|
// https://github.com/mozilla-mobile/fenix/issues/15430
|
|
// So we might be able to back out the changes made there. However, I don't have a device to
|
|
// test so I didn't bother.
|
|
//
|
|
// This issue occurs on the Galaxy S10e, Galaxy A50, Note 10, and LG G7 FIT but not the S7:
|
|
// I'm guessing it's just a problem on recent Samsungs and LGs so it's okay being in this P+
|
|
// listener.
|
|
if (!ManufacturerCodes.isSamsung && !ManufacturerCodes.isLG) {
|
|
return false
|
|
}
|
|
|
|
// To ignore this warning, we can inspect the stack trace. There are no parts of the
|
|
// violation stack trace that are clearly unique to this violation but
|
|
// EdmStorageProviderBase doesn't appear in Android code search so we match against it.
|
|
// This class may be used in other violations that we're capable of fixing but this
|
|
// code may ignore them. I think it's okay - we keep this code simple and if it was a serious
|
|
// issue, we'd catch it on other manufacturers.
|
|
return violation.stackTrace.any { it.className == FCQN_EDM_STORAGE_PROVIDER_BASE }
|
|
}
|
|
}
|