Convert FragmentStrictMode to Kotlin

We now have a Kotlin dependency and this is a new API so we can go ahead
and convert it to Kotlin as well.

RelNote: "FragmentStrictMode is now in Kotlin"
Test: ./gradlew checkApi
Bug: 199183506
Change-Id: I117679edc3af067bb0ef901714ace02712c97a40
diff --git a/fragment/fragment/api/current.txt b/fragment/fragment/api/current.txt
index fbeb1874..1d5f748 100644
--- a/fragment/fragment/api/current.txt
+++ b/fragment/fragment/api/current.txt
@@ -461,15 +461,20 @@
 
   public final class FragmentReuseViolation extends androidx.fragment.app.strictmode.Violation {
     method public String getPreviousFragmentId();
+    property public String message;
+    property public final String previousFragmentId;
   }
 
   public final class FragmentStrictMode {
-    method public static androidx.fragment.app.strictmode.FragmentStrictMode.Policy getDefaultPolicy();
-    method public static void setDefaultPolicy(androidx.fragment.app.strictmode.FragmentStrictMode.Policy);
+    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy getDefaultPolicy();
+    method @VisibleForTesting public void onPolicyViolation(androidx.fragment.app.strictmode.Violation violation);
+    method public void setDefaultPolicy(androidx.fragment.app.strictmode.FragmentStrictMode.Policy defaultPolicy);
+    property public final androidx.fragment.app.strictmode.FragmentStrictMode.Policy defaultPolicy;
+    field public static final androidx.fragment.app.strictmode.FragmentStrictMode INSTANCE;
   }
 
-  public static interface FragmentStrictMode.OnViolationListener {
-    method public void onViolation(androidx.fragment.app.strictmode.Violation);
+  public static fun interface FragmentStrictMode.OnViolationListener {
+    method public void onViolation(androidx.fragment.app.strictmode.Violation violation);
   }
 
   public static final class FragmentStrictMode.Policy {
@@ -478,7 +483,7 @@
 
   public static final class FragmentStrictMode.Policy.Builder {
     ctor public FragmentStrictMode.Policy.Builder();
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder allowViolation(Class<? extends androidx.fragment.app.Fragment>, Class<? extends androidx.fragment.app.strictmode.Violation>);
+    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder allowViolation(Class<? extends androidx.fragment.app.Fragment> fragmentClass, Class<? extends androidx.fragment.app.strictmode.Violation> violationClass);
     method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy build();
     method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder detectFragmentReuse();
     method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder detectFragmentTagUsage();
@@ -487,47 +492,61 @@
     method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder detectTargetFragmentUsage();
     method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder detectWrongFragmentContainer();
     method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder penaltyDeath();
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder penaltyListener(androidx.fragment.app.strictmode.FragmentStrictMode.OnViolationListener);
+    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder penaltyListener(androidx.fragment.app.strictmode.FragmentStrictMode.OnViolationListener listener);
     method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder penaltyLog();
   }
 
   public final class FragmentTagUsageViolation extends androidx.fragment.app.strictmode.Violation {
     method public android.view.ViewGroup? getParentContainer();
+    property public String message;
+    property public final android.view.ViewGroup? parentContainer;
   }
 
   public final class GetRetainInstanceUsageViolation extends androidx.fragment.app.strictmode.RetainInstanceUsageViolation {
+    property public String message;
   }
 
   public final class GetTargetFragmentRequestCodeUsageViolation extends androidx.fragment.app.strictmode.TargetFragmentUsageViolation {
+    property public String message;
   }
 
   public final class GetTargetFragmentUsageViolation extends androidx.fragment.app.strictmode.TargetFragmentUsageViolation {
+    property public String message;
   }
 
   public abstract class RetainInstanceUsageViolation extends androidx.fragment.app.strictmode.Violation {
   }
 
   public final class SetRetainInstanceUsageViolation extends androidx.fragment.app.strictmode.RetainInstanceUsageViolation {
+    property public String message;
   }
 
   public final class SetTargetFragmentUsageViolation extends androidx.fragment.app.strictmode.TargetFragmentUsageViolation {
     method public int getRequestCode();
     method public androidx.fragment.app.Fragment getTargetFragment();
+    property public String message;
+    property public final int requestCode;
+    property public final androidx.fragment.app.Fragment targetFragment;
   }
 
   public final class SetUserVisibleHintViolation extends androidx.fragment.app.strictmode.Violation {
     method public boolean isVisibleToUser();
+    property public final boolean isVisibleToUser;
+    property public String message;
   }
 
   public abstract class TargetFragmentUsageViolation extends androidx.fragment.app.strictmode.Violation {
   }
 
   public abstract class Violation extends java.lang.RuntimeException {
-    method public androidx.fragment.app.Fragment getFragment();
+    method public final androidx.fragment.app.Fragment getFragment();
+    property public final androidx.fragment.app.Fragment fragment;
   }
 
   public final class WrongFragmentContainerViolation extends androidx.fragment.app.strictmode.Violation {
     method public android.view.ViewGroup getContainer();
+    property public final android.view.ViewGroup container;
+    property public String message;
   }
 
 }
diff --git a/fragment/fragment/api/public_plus_experimental_current.txt b/fragment/fragment/api/public_plus_experimental_current.txt
index fbeb1874..1d5f748 100644
--- a/fragment/fragment/api/public_plus_experimental_current.txt
+++ b/fragment/fragment/api/public_plus_experimental_current.txt
@@ -461,15 +461,20 @@
 
   public final class FragmentReuseViolation extends androidx.fragment.app.strictmode.Violation {
     method public String getPreviousFragmentId();
+    property public String message;
+    property public final String previousFragmentId;
   }
 
   public final class FragmentStrictMode {
-    method public static androidx.fragment.app.strictmode.FragmentStrictMode.Policy getDefaultPolicy();
-    method public static void setDefaultPolicy(androidx.fragment.app.strictmode.FragmentStrictMode.Policy);
+    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy getDefaultPolicy();
+    method @VisibleForTesting public void onPolicyViolation(androidx.fragment.app.strictmode.Violation violation);
+    method public void setDefaultPolicy(androidx.fragment.app.strictmode.FragmentStrictMode.Policy defaultPolicy);
+    property public final androidx.fragment.app.strictmode.FragmentStrictMode.Policy defaultPolicy;
+    field public static final androidx.fragment.app.strictmode.FragmentStrictMode INSTANCE;
   }
 
-  public static interface FragmentStrictMode.OnViolationListener {
-    method public void onViolation(androidx.fragment.app.strictmode.Violation);
+  public static fun interface FragmentStrictMode.OnViolationListener {
+    method public void onViolation(androidx.fragment.app.strictmode.Violation violation);
   }
 
   public static final class FragmentStrictMode.Policy {
@@ -478,7 +483,7 @@
 
   public static final class FragmentStrictMode.Policy.Builder {
     ctor public FragmentStrictMode.Policy.Builder();
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder allowViolation(Class<? extends androidx.fragment.app.Fragment>, Class<? extends androidx.fragment.app.strictmode.Violation>);
+    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder allowViolation(Class<? extends androidx.fragment.app.Fragment> fragmentClass, Class<? extends androidx.fragment.app.strictmode.Violation> violationClass);
     method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy build();
     method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder detectFragmentReuse();
     method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder detectFragmentTagUsage();
@@ -487,47 +492,61 @@
     method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder detectTargetFragmentUsage();
     method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder detectWrongFragmentContainer();
     method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder penaltyDeath();
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder penaltyListener(androidx.fragment.app.strictmode.FragmentStrictMode.OnViolationListener);
+    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder penaltyListener(androidx.fragment.app.strictmode.FragmentStrictMode.OnViolationListener listener);
     method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder penaltyLog();
   }
 
   public final class FragmentTagUsageViolation extends androidx.fragment.app.strictmode.Violation {
     method public android.view.ViewGroup? getParentContainer();
+    property public String message;
+    property public final android.view.ViewGroup? parentContainer;
   }
 
   public final class GetRetainInstanceUsageViolation extends androidx.fragment.app.strictmode.RetainInstanceUsageViolation {
+    property public String message;
   }
 
   public final class GetTargetFragmentRequestCodeUsageViolation extends androidx.fragment.app.strictmode.TargetFragmentUsageViolation {
+    property public String message;
   }
 
   public final class GetTargetFragmentUsageViolation extends androidx.fragment.app.strictmode.TargetFragmentUsageViolation {
+    property public String message;
   }
 
   public abstract class RetainInstanceUsageViolation extends androidx.fragment.app.strictmode.Violation {
   }
 
   public final class SetRetainInstanceUsageViolation extends androidx.fragment.app.strictmode.RetainInstanceUsageViolation {
+    property public String message;
   }
 
   public final class SetTargetFragmentUsageViolation extends androidx.fragment.app.strictmode.TargetFragmentUsageViolation {
     method public int getRequestCode();
     method public androidx.fragment.app.Fragment getTargetFragment();
+    property public String message;
+    property public final int requestCode;
+    property public final androidx.fragment.app.Fragment targetFragment;
   }
 
   public final class SetUserVisibleHintViolation extends androidx.fragment.app.strictmode.Violation {
     method public boolean isVisibleToUser();
+    property public final boolean isVisibleToUser;
+    property public String message;
   }
 
   public abstract class TargetFragmentUsageViolation extends androidx.fragment.app.strictmode.Violation {
   }
 
   public abstract class Violation extends java.lang.RuntimeException {
-    method public androidx.fragment.app.Fragment getFragment();
+    method public final androidx.fragment.app.Fragment getFragment();
+    property public final androidx.fragment.app.Fragment fragment;
   }
 
   public final class WrongFragmentContainerViolation extends androidx.fragment.app.strictmode.Violation {
     method public android.view.ViewGroup getContainer();
+    property public final android.view.ViewGroup container;
+    property public String message;
   }
 
 }
diff --git a/fragment/fragment/api/restricted_current.txt b/fragment/fragment/api/restricted_current.txt
index 35e9eae..8b68506 100644
--- a/fragment/fragment/api/restricted_current.txt
+++ b/fragment/fragment/api/restricted_current.txt
@@ -491,15 +491,20 @@
 
   public final class FragmentReuseViolation extends androidx.fragment.app.strictmode.Violation {
     method public String getPreviousFragmentId();
+    property public String message;
+    property public final String previousFragmentId;
   }
 
   public final class FragmentStrictMode {
-    method public static androidx.fragment.app.strictmode.FragmentStrictMode.Policy getDefaultPolicy();
-    method public static void setDefaultPolicy(androidx.fragment.app.strictmode.FragmentStrictMode.Policy);
+    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy getDefaultPolicy();
+    method @VisibleForTesting public void onPolicyViolation(androidx.fragment.app.strictmode.Violation violation);
+    method public void setDefaultPolicy(androidx.fragment.app.strictmode.FragmentStrictMode.Policy defaultPolicy);
+    property public final androidx.fragment.app.strictmode.FragmentStrictMode.Policy defaultPolicy;
+    field public static final androidx.fragment.app.strictmode.FragmentStrictMode INSTANCE;
   }
 
-  public static interface FragmentStrictMode.OnViolationListener {
-    method public void onViolation(androidx.fragment.app.strictmode.Violation);
+  public static fun interface FragmentStrictMode.OnViolationListener {
+    method public void onViolation(androidx.fragment.app.strictmode.Violation violation);
   }
 
   public static final class FragmentStrictMode.Policy {
@@ -508,7 +513,7 @@
 
   public static final class FragmentStrictMode.Policy.Builder {
     ctor public FragmentStrictMode.Policy.Builder();
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder allowViolation(Class<? extends androidx.fragment.app.Fragment>, Class<? extends androidx.fragment.app.strictmode.Violation>);
+    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder allowViolation(Class<? extends androidx.fragment.app.Fragment> fragmentClass, Class<? extends androidx.fragment.app.strictmode.Violation> violationClass);
     method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy build();
     method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder detectFragmentReuse();
     method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder detectFragmentTagUsage();
@@ -517,47 +522,61 @@
     method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder detectTargetFragmentUsage();
     method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder detectWrongFragmentContainer();
     method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder penaltyDeath();
-    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder penaltyListener(androidx.fragment.app.strictmode.FragmentStrictMode.OnViolationListener);
+    method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder penaltyListener(androidx.fragment.app.strictmode.FragmentStrictMode.OnViolationListener listener);
     method public androidx.fragment.app.strictmode.FragmentStrictMode.Policy.Builder penaltyLog();
   }
 
   public final class FragmentTagUsageViolation extends androidx.fragment.app.strictmode.Violation {
     method public android.view.ViewGroup? getParentContainer();
+    property public String message;
+    property public final android.view.ViewGroup? parentContainer;
   }
 
   public final class GetRetainInstanceUsageViolation extends androidx.fragment.app.strictmode.RetainInstanceUsageViolation {
+    property public String message;
   }
 
   public final class GetTargetFragmentRequestCodeUsageViolation extends androidx.fragment.app.strictmode.TargetFragmentUsageViolation {
+    property public String message;
   }
 
   public final class GetTargetFragmentUsageViolation extends androidx.fragment.app.strictmode.TargetFragmentUsageViolation {
+    property public String message;
   }
 
   public abstract class RetainInstanceUsageViolation extends androidx.fragment.app.strictmode.Violation {
   }
 
   public final class SetRetainInstanceUsageViolation extends androidx.fragment.app.strictmode.RetainInstanceUsageViolation {
+    property public String message;
   }
 
   public final class SetTargetFragmentUsageViolation extends androidx.fragment.app.strictmode.TargetFragmentUsageViolation {
     method public int getRequestCode();
     method public androidx.fragment.app.Fragment getTargetFragment();
+    property public String message;
+    property public final int requestCode;
+    property public final androidx.fragment.app.Fragment targetFragment;
   }
 
   public final class SetUserVisibleHintViolation extends androidx.fragment.app.strictmode.Violation {
     method public boolean isVisibleToUser();
+    property public final boolean isVisibleToUser;
+    property public String message;
   }
 
   public abstract class TargetFragmentUsageViolation extends androidx.fragment.app.strictmode.Violation {
   }
 
   public abstract class Violation extends java.lang.RuntimeException {
-    method public androidx.fragment.app.Fragment getFragment();
+    method public final androidx.fragment.app.Fragment getFragment();
+    property public final androidx.fragment.app.Fragment fragment;
   }
 
   public final class WrongFragmentContainerViolation extends androidx.fragment.app.strictmode.Violation {
     method public android.view.ViewGroup getContainer();
+    property public final android.view.ViewGroup container;
+    property public String message;
   }
 
 }
diff --git a/fragment/fragment/src/androidTest/java/androidx/fragment/app/strictmode/FragmentStrictModeTest.kt b/fragment/fragment/src/androidTest/java/androidx/fragment/app/strictmode/FragmentStrictModeTest.kt
index 6b60563..2c4687b 100644
--- a/fragment/fragment/src/androidTest/java/androidx/fragment/app/strictmode/FragmentStrictModeTest.kt
+++ b/fragment/fragment/src/androidTest/java/androidx/fragment/app/strictmode/FragmentStrictModeTest.kt
@@ -42,12 +42,12 @@
 
     @Before
     public fun setup() {
-        originalPolicy = FragmentStrictMode.getDefaultPolicy()
+        originalPolicy = FragmentStrictMode.defaultPolicy
     }
 
     @After
     public fun teardown() {
-        FragmentStrictMode.setDefaultPolicy(originalPolicy)
+        FragmentStrictMode.defaultPolicy = originalPolicy
     }
 
     @Test
@@ -55,7 +55,7 @@
         val policy = FragmentStrictMode.Policy.Builder()
             .penaltyDeath()
             .build()
-        FragmentStrictMode.setDefaultPolicy(policy)
+        FragmentStrictMode.defaultPolicy = policy
 
         var violation: Violation? = null
         try {
@@ -92,7 +92,7 @@
 
             val violation = object : Violation(childFragment) {}
 
-            FragmentStrictMode.setDefaultPolicy(policy("Default policy"))
+            FragmentStrictMode.defaultPolicy = policy("Default policy")
             FragmentStrictMode.onPolicyViolation(violation)
             InstrumentationRegistry.getInstrumentation().waitForIdleSync()
             assertThat(lastTriggeredPolicy).isEqualTo("Default policy")
@@ -116,7 +116,7 @@
         val policy = FragmentStrictMode.Policy.Builder()
             .penaltyListener { thread = Thread.currentThread() }
             .build()
-        FragmentStrictMode.setDefaultPolicy(policy)
+        FragmentStrictMode.defaultPolicy = policy
 
         with(ActivityScenario.launch(FragmentTestActivity::class.java)) {
             val fragmentManager = withActivity { supportFragmentManager }
@@ -140,7 +140,7 @@
             .detectFragmentReuse()
             .penaltyListener { violation = it }
             .build()
-        FragmentStrictMode.setDefaultPolicy(policy)
+        FragmentStrictMode.defaultPolicy = policy
 
         with(ActivityScenario.launch(FragmentTestActivity::class.java)) {
             val fragmentManager = withActivity { supportFragmentManager }
@@ -176,7 +176,7 @@
             .detectFragmentReuse()
             .penaltyListener { violation = it }
             .build()
-        FragmentStrictMode.setDefaultPolicy(policy)
+        FragmentStrictMode.defaultPolicy = policy
 
         with(ActivityScenario.launch(FragmentTestActivity::class.java)) {
             val fragmentManager = withActivity { supportFragmentManager }
@@ -213,7 +213,7 @@
             .detectFragmentTagUsage()
             .penaltyListener { violation = it }
             .build()
-        FragmentStrictMode.setDefaultPolicy(policy)
+        FragmentStrictMode.defaultPolicy = policy
 
         with(ActivityScenario.launch(FragmentTestActivity::class.java)) {
             withActivity { setContentView(R.layout.activity_inflated_fragment) }
@@ -236,7 +236,7 @@
             .detectRetainInstanceUsage()
             .penaltyListener { violation = it }
             .build()
-        FragmentStrictMode.setDefaultPolicy(policy)
+        FragmentStrictMode.defaultPolicy = policy
 
         val fragment = StrictFragment()
         fragment.retainInstance = true
@@ -261,7 +261,7 @@
             .detectSetUserVisibleHint()
             .penaltyListener { violation = it }
             .build()
-        FragmentStrictMode.setDefaultPolicy(policy)
+        FragmentStrictMode.defaultPolicy = policy
 
         val fragment = StrictFragment()
         fragment.userVisibleHint = true
@@ -279,7 +279,7 @@
             .detectTargetFragmentUsage()
             .penaltyListener { violation = it }
             .build()
-        FragmentStrictMode.setDefaultPolicy(policy)
+        FragmentStrictMode.defaultPolicy = policy
 
         val fragment = StrictFragment()
         val targetFragment = StrictFragment()
@@ -313,7 +313,7 @@
             .detectWrongFragmentContainer()
             .penaltyListener { violation = it }
             .build()
-        FragmentStrictMode.setDefaultPolicy(policy)
+        FragmentStrictMode.defaultPolicy = policy
 
         with(ActivityScenario.launch(FragmentTestActivity::class.java)) {
             val fragmentManager = withActivity { supportFragmentManager }
@@ -361,7 +361,7 @@
         for (violationClass in violationClassList) {
             policyBuilder = policyBuilder.allowViolation(fragmentClass, violationClass)
         }
-        FragmentStrictMode.setDefaultPolicy(policyBuilder.build())
+        FragmentStrictMode.defaultPolicy = policyBuilder.build()
 
         StrictFragment().retainInstance = true
         assertThat(violation).isNotInstanceOf(violationClass1)
diff --git a/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/FragmentReuseViolation.kt b/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/FragmentReuseViolation.kt
index bd8d249..1082536 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/FragmentReuseViolation.kt
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/FragmentReuseViolation.kt
@@ -13,34 +13,20 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package androidx.fragment.app.strictmode
 
-package androidx.fragment.app.strictmode;
+import androidx.fragment.app.Fragment
 
-import androidx.annotation.NonNull;
-import androidx.fragment.app.Fragment;
-
-/** See #{@link FragmentStrictMode.Policy.Builder#detectFragmentReuse()}. */
-public final class FragmentReuseViolation extends Violation {
-
-    @NonNull
-    private final String mPreviousWho;
-
-    FragmentReuseViolation(@NonNull Fragment fragment, @NonNull String previousWho) {
-        super(fragment);
-        this.mPreviousWho = previousWho;
-    }
-
+/**
+ * See [FragmentStrictMode.Policy.Builder.detectFragmentReuse].
+ */
+class FragmentReuseViolation internal constructor(
+    fragment: Fragment,
+    val previousFragmentId: String
+) : Violation(fragment) {
     /**
-     * Gets the unique ID of the previous instance of the {@link Fragment} causing the Violation.
+     * Gets the unique ID of the previous instance of the [Fragment] causing the Violation.
      */
-    @NonNull
-    public String getPreviousFragmentId() {
-        return mPreviousWho;
-    }
-
-    @NonNull
-    @Override
-    public String getMessage() {
-        return "Attempting to reuse fragment " + mFragment + " with previous ID " + mPreviousWho;
-    }
+    override val message: String
+        get() = "Attempting to reuse fragment $fragment with previous ID $previousFragmentId"
 }
diff --git a/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/FragmentStrictMode.kt b/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/FragmentStrictMode.kt
index ac43754..f8f73b1 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/FragmentStrictMode.kt
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/FragmentStrictMode.kt
@@ -13,131 +13,330 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package androidx.fragment.app.strictmode
 
-package androidx.fragment.app.strictmode;
-
-import android.annotation.SuppressLint;
-import android.os.Handler;
-import android.os.Looper;
-import android.util.Log;
-import android.view.ViewGroup;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.annotation.RestrictTo;
-import androidx.annotation.VisibleForTesting;
-import androidx.fragment.app.Fragment;
-import androidx.fragment.app.FragmentContainerView;
-import androidx.fragment.app.FragmentManager;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
+import android.annotation.SuppressLint
+import android.os.Looper
+import android.util.Log
+import android.view.ViewGroup
+import androidx.annotation.RestrictTo
+import androidx.annotation.VisibleForTesting
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.FragmentManager
+import androidx.fragment.app.strictmode.FragmentStrictMode.Policy
 
 /**
  * FragmentStrictMode is a tool which detects things you might be doing by accident and brings
  * them to your attention so you can fix them. Basically, it's a version of
- * {@link android.os.StrictMode} specifically for fragment-related issues.
+ * [android.os.StrictMode] specifically for fragment-related issues.
  *
- * <p>You can decide what should happen when a violation is detected. For example, using {@link
- * Policy.Builder#penaltyLog} you can watch the output of <code>adb logcat</code> while you
+ * You can decide what should happen when a violation is detected. For example, using
+ * [Policy.Builder.penaltyLog] you can watch the output of `adb logcat` while you
  * use your application to see the violations as they happen.
  */
-@SuppressLint("SyntheticAccessor")
-public final class FragmentStrictMode {
-    private static final String TAG = "FragmentStrictMode";
-    private static Policy defaultPolicy = Policy.LAX;
+object FragmentStrictMode {
+    private const val TAG = "FragmentStrictMode"
+    /**
+     * The current policy for what actions should be detected, as well as the penalty if such
+     * actions occur.
+     */
+    var defaultPolicy = Policy.LAX
+    private fun getNearestPolicy(fragment: Fragment?): Policy {
+        var declaringFragment = fragment
+        while (declaringFragment != null) {
+            if (declaringFragment.isAdded) {
+                val fragmentManager = declaringFragment.parentFragmentManager
+                if (fragmentManager.strictModePolicy != null) {
+                    return fragmentManager.strictModePolicy!!
+                }
+            }
+            declaringFragment = declaringFragment.parentFragment
+        }
+        return defaultPolicy
+    }
 
-    private enum Flag {
+    /**
+     * @hide
+     */
+    @JvmStatic
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
+    fun onFragmentReuse(fragment: Fragment, previousFragmentId: String) {
+        val violation: Violation = FragmentReuseViolation(fragment, previousFragmentId)
+        logIfDebuggingEnabled(violation)
+        val policy = getNearestPolicy(fragment)
+        if (policy.flags.contains(Flag.DETECT_FRAGMENT_REUSE) &&
+            shouldHandlePolicyViolation(policy, fragment.javaClass, violation.javaClass)
+        ) {
+            handlePolicyViolation(policy, violation)
+        }
+    }
+
+    /**
+     * @hide
+     */
+    @JvmStatic
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
+    fun onFragmentTagUsage(
+        fragment: Fragment,
+        container: ViewGroup?
+    ) {
+        val violation: Violation = FragmentTagUsageViolation(fragment, container)
+        logIfDebuggingEnabled(violation)
+        val policy = getNearestPolicy(fragment)
+        if (policy.flags.contains(Flag.DETECT_FRAGMENT_TAG_USAGE) &&
+            shouldHandlePolicyViolation(policy, fragment.javaClass, violation.javaClass)
+        ) {
+            handlePolicyViolation(policy, violation)
+        }
+    }
+
+    /**
+     * @hide
+     */
+    @JvmStatic
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
+    fun onSetRetainInstanceUsage(fragment: Fragment) {
+        val violation: Violation = SetRetainInstanceUsageViolation(fragment)
+        logIfDebuggingEnabled(violation)
+        val policy = getNearestPolicy(fragment)
+        if (policy.flags.contains(Flag.DETECT_RETAIN_INSTANCE_USAGE) &&
+            shouldHandlePolicyViolation(policy, fragment.javaClass, violation.javaClass)
+        ) {
+            handlePolicyViolation(policy, violation)
+        }
+    }
+
+    /**
+     * @hide
+     */
+    @JvmStatic
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
+    fun onGetRetainInstanceUsage(fragment: Fragment) {
+        val violation: Violation = GetRetainInstanceUsageViolation(fragment)
+        logIfDebuggingEnabled(violation)
+        val policy = getNearestPolicy(fragment)
+        if (policy.flags.contains(Flag.DETECT_RETAIN_INSTANCE_USAGE) &&
+            shouldHandlePolicyViolation(policy, fragment.javaClass, violation.javaClass)
+        ) {
+            handlePolicyViolation(policy, violation)
+        }
+    }
+
+    /**
+     * @hide
+     */
+    @JvmStatic
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
+    fun onSetUserVisibleHint(fragment: Fragment, isVisibleToUser: Boolean) {
+        val violation: Violation = SetUserVisibleHintViolation(fragment, isVisibleToUser)
+        logIfDebuggingEnabled(violation)
+        val policy = getNearestPolicy(fragment)
+        if (policy.flags.contains(Flag.DETECT_SET_USER_VISIBLE_HINT) &&
+            shouldHandlePolicyViolation(policy, fragment.javaClass, violation.javaClass)
+        ) {
+            handlePolicyViolation(policy, violation)
+        }
+    }
+
+    /**
+     * @hide
+     */
+    @JvmStatic
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
+    fun onSetTargetFragmentUsage(
+        violatingFragment: Fragment,
+        targetFragment: Fragment,
+        requestCode: Int
+    ) {
+        val violation: Violation = SetTargetFragmentUsageViolation(
+            violatingFragment, targetFragment, requestCode
+        )
+        logIfDebuggingEnabled(violation)
+        val policy = getNearestPolicy(violatingFragment)
+        if (policy.flags.contains(Flag.DETECT_TARGET_FRAGMENT_USAGE) &&
+            shouldHandlePolicyViolation(policy, violatingFragment.javaClass, violation.javaClass)
+        ) {
+            handlePolicyViolation(policy, violation)
+        }
+    }
+
+    /**
+     * @hide
+     */
+    @JvmStatic
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
+    fun onGetTargetFragmentUsage(fragment: Fragment) {
+        val violation: Violation = GetTargetFragmentUsageViolation(fragment)
+        logIfDebuggingEnabled(violation)
+        val policy = getNearestPolicy(fragment)
+        if (policy.flags.contains(Flag.DETECT_TARGET_FRAGMENT_USAGE) &&
+            shouldHandlePolicyViolation(policy, fragment.javaClass, violation.javaClass)
+        ) {
+            handlePolicyViolation(policy, violation)
+        }
+    }
+
+    /**
+     * @hide
+     */
+    @JvmStatic
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
+    fun onGetTargetFragmentRequestCodeUsage(fragment: Fragment) {
+        val violation: Violation = GetTargetFragmentRequestCodeUsageViolation(fragment)
+        logIfDebuggingEnabled(violation)
+        val policy = getNearestPolicy(fragment)
+        if (policy.flags.contains(Flag.DETECT_TARGET_FRAGMENT_USAGE) &&
+            shouldHandlePolicyViolation(policy, fragment.javaClass, violation.javaClass)
+        ) {
+            handlePolicyViolation(policy, violation)
+        }
+    }
+
+    /**
+     * @hide
+     */
+    @JvmStatic
+    @RestrictTo(RestrictTo.Scope.LIBRARY)
+    fun onWrongFragmentContainer(
+        fragment: Fragment,
+        container: ViewGroup
+    ) {
+        val violation: Violation = WrongFragmentContainerViolation(fragment, container)
+        logIfDebuggingEnabled(violation)
+        val policy = getNearestPolicy(fragment)
+        if (policy.flags.contains(Flag.DETECT_WRONG_FRAGMENT_CONTAINER) &&
+            shouldHandlePolicyViolation(policy, fragment.javaClass, violation.javaClass)
+        ) {
+            handlePolicyViolation(policy, violation)
+        }
+    }
+
+    @VisibleForTesting
+    fun onPolicyViolation(violation: Violation) {
+        logIfDebuggingEnabled(violation)
+        val fragment: Fragment = violation.fragment
+        val policy = getNearestPolicy(fragment)
+        if (shouldHandlePolicyViolation(policy, fragment.javaClass, violation.javaClass)) {
+            handlePolicyViolation(policy, violation)
+        }
+    }
+
+    private fun logIfDebuggingEnabled(violation: Violation) {
+        if (FragmentManager.isLoggingEnabled(Log.DEBUG)) {
+            Log.d(
+                FragmentManager.TAG,
+                "StrictMode violation in ${violation.fragment.javaClass.name}",
+                violation
+            )
+        }
+    }
+
+    private fun shouldHandlePolicyViolation(
+        policy: Policy,
+        fragmentClass: Class<out Fragment>,
+        violationClass: Class<out Violation>
+    ): Boolean {
+        val violationsToBypass = policy.mAllowedViolations[fragmentClass] ?: return true
+        if (violationClass.superclass != Violation::class.java) {
+            if (violationsToBypass.contains(violationClass.superclass)) {
+                return false
+            }
+        }
+        return !violationsToBypass.contains(violationClass)
+    }
+
+    private fun handlePolicyViolation(
+        policy: Policy,
+        violation: Violation
+    ) {
+        val fragment: Fragment = violation.fragment
+        val fragmentName = fragment.javaClass.name
+        if (policy.flags.contains(Flag.PENALTY_LOG)) {
+            Log.d(TAG, "Policy violation in $fragmentName", violation)
+        }
+        if (policy.listener != null) {
+            runOnHostThread(fragment) { policy.listener.onViolation(violation) }
+        }
+        if (policy.flags.contains(Flag.PENALTY_DEATH)) {
+            runOnHostThread(fragment) {
+                Log.e(TAG, "Policy violation with PENALTY_DEATH in $fragmentName", violation)
+                throw violation
+            }
+        }
+    }
+
+    private fun runOnHostThread(fragment: Fragment, runnable: Runnable) {
+        if (fragment.isAdded) {
+            val handler = fragment.parentFragmentManager.host.handler
+            if (handler.looper == Looper.myLooper()) {
+                runnable.run() // Already on correct thread -> run synchronously
+            } else {
+                handler.post(runnable) // Switch to correct thread
+            }
+        } else {
+            runnable.run() // Fragment is not attached to any host -> run synchronously
+        }
+    }
+
+    internal enum class Flag {
         PENALTY_LOG,
         PENALTY_DEATH,
-
         DETECT_FRAGMENT_REUSE,
         DETECT_FRAGMENT_TAG_USAGE,
         DETECT_RETAIN_INSTANCE_USAGE,
         DETECT_SET_USER_VISIBLE_HINT,
         DETECT_TARGET_FRAGMENT_USAGE,
-        DETECT_WRONG_FRAGMENT_CONTAINER,
+        DETECT_WRONG_FRAGMENT_CONTAINER
     }
 
-    private FragmentStrictMode() {}
-
     /**
-     * When #{@link Policy.Builder#penaltyListener} is enabled, the listener is called when a
+     * When [Policy.Builder.penaltyListener] is enabled, the listener is called when a
      * violation occurs.
      */
-    public interface OnViolationListener {
-
-        /** Called on a policy violation. */
-        void onViolation(@NonNull Violation violation);
+    fun interface OnViolationListener {
+        /** Called on a policy violation.  */
+        fun onViolation(violation: Violation)
     }
 
     /**
-     * {@link FragmentStrictMode} policy applied to a certain {@link FragmentManager} (or globally).
+     * [FragmentStrictMode] policy applied to a certain [FragmentManager] (or globally).
      *
-     * <p>This policy can either be enabled globally using {@link #setDefaultPolicy} or for a
-     * specific {@link FragmentManager} using {@link FragmentManager#setStrictModePolicy(Policy)}.
-     * The current policy can be retrieved using {@link #getDefaultPolicy} and
-     * {@link FragmentManager#getStrictModePolicy} respectively.
+     * This policy can either be enabled globally using [defaultPolicy] or for a
+     * specific [FragmentManager] using [FragmentManager.setStrictModePolicy].
+     * The current policy can be retrieved using [defaultPolicy] and
+     * [FragmentManager.getStrictModePolicy] respectively.
      *
-     * <p>Note that multiple penalties may be provided and they're run in order from least to most
+     * Note that multiple penalties may be provided and they're run in order from least to most
      * severe (logging before process death, for example). There's currently no mechanism to choose
      * different penalties for different detected actions.
      */
-    public static final class Policy {
-        private final Set<Flag> mFlags;
-        private final OnViolationListener mListener;
-        private final Map<Class<? extends Fragment>,
-                Set<Class<? extends Violation>>> mAllowedViolations;
-
-        /** The default, lax policy which doesn't catch anything. */
-        @NonNull
-        public static final Policy LAX = new Policy(new HashSet<>(), null, new HashMap<>());
-
-        private Policy(
-                @NonNull Set<Flag> flags,
-                @Nullable OnViolationListener listener,
-                @NonNull Map<Class<? extends Fragment>,
-                        Set<Class<? extends Violation>>> allowedViolations) {
-            this.mFlags = new HashSet<>(flags);
-            this.mListener = listener;
-
-            Map<Class<? extends Fragment>, Set<Class<? extends Violation>>>
-                    newAllowedViolationsMap = new HashMap<>();
-            for (Map.Entry<Class<? extends Fragment>,
-                    Set<Class<? extends Violation>>> entry : allowedViolations.entrySet()) {
-                newAllowedViolationsMap.put(entry.getKey(), new HashSet<>(entry.getValue()));
-            }
-            this.mAllowedViolations = newAllowedViolationsMap;
-        }
+    class Policy internal constructor(
+        internal val flags: Set<Flag>,
+        listener: OnViolationListener?,
+        allowedViolations: Map<Class<out Fragment>, MutableSet<Class<out Violation>>>
+    ) {
+        internal val listener: OnViolationListener?
+        internal val mAllowedViolations: Map<Class<out Fragment>, Set<Class<out Violation>>>
 
         /**
-         * Creates {@link Policy} instances. Methods whose names start with {@code detect} specify
-         * what problems we should look for. Methods whose names start with {@code penalty} specify
+         * Creates [Policy] instances. Methods whose names start with `detect` specify
+         * what problems we should look for. Methods whose names start with `penalty` specify
          * what we should do when we detect a problem.
          *
-         * <p>You can call as many {@code detect} and {@code penalty} methods as you like. Currently
+         * You can call as many `detect` and `penalty` methods as you like. Currently
          * order is insignificant: all penalties apply to all detected problems.
          */
-        public static final class Builder {
-            private final Set<Flag> mFlags;
-            private OnViolationListener mListener;
-            private final Map<Class<? extends Fragment>,
-                    Set<Class<? extends Violation>>> mAllowedViolations;
+        class Builder {
+            private val flags: MutableSet<Flag> = mutableSetOf()
+            private var listener: OnViolationListener? = null
+            private val mAllowedViolations:
+                MutableMap<Class<out Fragment>, MutableSet<Class<out Violation>>> = mutableMapOf()
 
-            /** Create a Builder that detects nothing and has no violations. */
-            public Builder() {
-                mFlags = new HashSet<>();
-                mAllowedViolations = new HashMap<>();
-            }
-
-            /** Log detected violations to the system log. */
-            @NonNull
+            /** Log detected violations to the system log.  */
             @SuppressLint("BuilderSetStyle")
-            public Builder penaltyLog() {
-                mFlags.add(Flag.PENALTY_LOG);
-                return this;
+            fun penaltyLog(): Builder {
+                flags.add(Flag.PENALTY_LOG)
+                return this
             }
 
             /**
@@ -145,363 +344,123 @@
              * penalties so you'll still get to see logging or other violations before the exception
              * is thrown.
              */
-            @NonNull
             @SuppressLint("BuilderSetStyle")
-            public Builder penaltyDeath() {
-                mFlags.add(Flag.PENALTY_DEATH);
-                return this;
+            fun penaltyDeath(): Builder {
+                flags.add(Flag.PENALTY_DEATH)
+                return this
             }
 
             /**
-             * Call #{@link OnViolationListener#onViolation} for every violation. The listener will
+             * Call [OnViolationListener.onViolation] for every violation. The listener will
              * be called on the main thread of the fragment host.
              */
-            @NonNull
             @SuppressLint("BuilderSetStyle")
-            public Builder penaltyListener(@NonNull OnViolationListener listener) {
-                this.mListener = listener;
-                return this;
+            fun penaltyListener(listener: OnViolationListener): Builder {
+                this.listener = listener
+                return this
             }
 
             /**
-             * Detects cases, where a #{@link Fragment} instance is reused, after it was previously
-             * removed from a #{@link FragmentManager}.
+             * Detects cases, where a [Fragment] instance is reused, after it was previously
+             * removed from a [FragmentManager].
              */
-            @NonNull
             @SuppressLint("BuilderSetStyle")
-            public Builder detectFragmentReuse() {
-                mFlags.add(Flag.DETECT_FRAGMENT_REUSE);
-                return this;
+            fun detectFragmentReuse(): Builder {
+                flags.add(Flag.DETECT_FRAGMENT_REUSE)
+                return this
             }
 
-            /** Detects usage of the &lt;fragment&gt; tag inside XML layouts. */
-            @NonNull
+            /** Detects usage of the <fragment> tag inside XML layouts.  */
             @SuppressLint("BuilderSetStyle")
-            public Builder detectFragmentTagUsage() {
-                mFlags.add(Flag.DETECT_FRAGMENT_TAG_USAGE);
-                return this;
+            fun detectFragmentTagUsage(): Builder {
+                flags.add(Flag.DETECT_FRAGMENT_TAG_USAGE)
+                return this
             }
 
             /**
-             * Detects calls to #{@link Fragment#setRetainInstance} and
-             * #{@link Fragment#getRetainInstance()}.
+             * Detects calls to [Fragment.setRetainInstance] and [Fragment.getRetainInstance].
              */
-            @NonNull
             @SuppressLint("BuilderSetStyle")
-            public Builder detectRetainInstanceUsage() {
-                mFlags.add(Flag.DETECT_RETAIN_INSTANCE_USAGE);
-                return this;
+            fun detectRetainInstanceUsage(): Builder {
+                flags.add(Flag.DETECT_RETAIN_INSTANCE_USAGE)
+                return this
             }
 
-            /** Detects calls to #{@link Fragment#setUserVisibleHint}. */
-            @NonNull
+            /** Detects calls to [Fragment.setUserVisibleHint].  */
             @SuppressLint("BuilderSetStyle")
-            public Builder detectSetUserVisibleHint() {
-                mFlags.add(Flag.DETECT_SET_USER_VISIBLE_HINT);
-                return this;
+            fun detectSetUserVisibleHint(): Builder {
+                flags.add(Flag.DETECT_SET_USER_VISIBLE_HINT)
+                return this
             }
 
             /**
-             * Detects calls to #{@link Fragment#setTargetFragment},
-             * #{@link Fragment#getTargetFragment()} and #{@link Fragment#getTargetRequestCode()}.
+             * Detects calls to [Fragment.setTargetFragment], [Fragment.getTargetFragment] and
+             * [Fragment.getTargetRequestCode].
              */
-            @NonNull
             @SuppressLint("BuilderSetStyle")
-            public Builder detectTargetFragmentUsage() {
-                mFlags.add(Flag.DETECT_TARGET_FRAGMENT_USAGE);
-                return this;
+            fun detectTargetFragmentUsage(): Builder {
+                flags.add(Flag.DETECT_TARGET_FRAGMENT_USAGE)
+                return this
             }
 
             /**
-             * Detects cases where a #{@link Fragment} is added to a container other than a
-             * #{@link FragmentContainerView}.
+             * Detects cases where a [Fragment] is added to a container other than a
+             * [androidx.fragment.app.FragmentContainerView].
              */
-            @NonNull
             @SuppressLint("BuilderSetStyle")
-            public Builder detectWrongFragmentContainer() {
-                mFlags.add(Flag.DETECT_WRONG_FRAGMENT_CONTAINER);
-                return this;
+            fun detectWrongFragmentContainer(): Builder {
+                flags.add(Flag.DETECT_WRONG_FRAGMENT_CONTAINER)
+                return this
             }
 
             /**
-             * Allow the specified {@link Fragment} class to bypass penalties for the
-             * specified {@link Violation}, if detected.
+             * Allow the specified [Fragment] class to bypass penalties for the specified
+             * [Violation], if detected.
              *
-             * By default, all {@link Fragment} classes will incur penalties for any
-             * detected {@link Violation}.
+             * By default, all [Fragment] classes will incur penalties for any detected [Violation].
              */
-            @NonNull
             @SuppressLint("BuilderSetStyle")
-            public Builder allowViolation(
-                    @NonNull Class<? extends Fragment> fragmentClass,
-                    @NonNull Class<? extends Violation> violationClass) {
-                Set<Class<? extends Violation>> violationsToBypass =
-                        mAllowedViolations.get(fragmentClass);
+            fun allowViolation(
+                fragmentClass: Class<out Fragment>,
+                violationClass: Class<out Violation>
+            ): Builder {
+                var violationsToBypass = mAllowedViolations[fragmentClass]
                 if (violationsToBypass == null) {
-                    violationsToBypass = new HashSet<>();
+                    violationsToBypass = mutableSetOf()
                 }
-                violationsToBypass.add(violationClass);
-                mAllowedViolations.put(fragmentClass, violationsToBypass);
-                return this;
+                violationsToBypass.add(violationClass)
+                mAllowedViolations[fragmentClass] = violationsToBypass
+                return this
             }
 
             /**
              * Construct the Policy instance.
              *
-             * <p>Note: if no penalties are enabled before calling <code>build</code>, {@link
-             * #penaltyLog} is implicitly set.
+             * Note: if no penalties are enabled before calling `build`, [penaltyLog] is implicitly
+             * set.
              */
-            @NonNull
-            public Policy build() {
-                if (mListener == null && !mFlags.contains(Flag.PENALTY_DEATH)) {
-                    penaltyLog();
+            fun build(): Policy {
+                if (listener == null && !flags.contains(Flag.PENALTY_DEATH)) {
+                    penaltyLog()
                 }
-                return new Policy(mFlags, mListener, mAllowedViolations);
+                return Policy(flags, listener, mAllowedViolations)
             }
         }
-    }
 
-    /** Returns the current default policy. */
-     @NonNull
-    public static Policy getDefaultPolicy() {
-        return defaultPolicy;
-    }
+        internal companion object {
+            /** The default, lax policy which doesn't catch anything.  */
+            @JvmField
+            val LAX = Policy(emptySet(), null, emptyMap())
+        }
 
-    /**
-     * Sets the policy for what actions should be detected, as well as the penalty if such actions
-     * occur.
-     *
-     * @param policy the policy to put into place
-     */
-    public static void setDefaultPolicy(@NonNull Policy policy) {
-        defaultPolicy = policy;
-    }
-
-    private static Policy getNearestPolicy(@Nullable Fragment fragment) {
-        while (fragment != null) {
-            if (fragment.isAdded()) {
-                FragmentManager fragmentManager = fragment.getParentFragmentManager();
-                if (fragmentManager.getStrictModePolicy() != null) {
-                    return fragmentManager.getStrictModePolicy();
-                }
+        init {
+            this.listener = listener
+            val newAllowedViolationsMap:
+                MutableMap<Class<out Fragment>, Set<Class<out Violation>>> = mutableMapOf()
+            for ((key, value) in allowedViolations) {
+                newAllowedViolationsMap[key] = value
             }
-            fragment = fragment.getParentFragment();
-        }
-        return defaultPolicy;
-    }
-
-    /** @hide */
-    @RestrictTo(RestrictTo.Scope.LIBRARY)
-    public static void onFragmentReuse(@NonNull Fragment fragment, @NonNull String previousWho) {
-        Violation violation = new FragmentReuseViolation(fragment, previousWho);
-        logIfDebuggingEnabled(violation);
-
-        Policy policy = getNearestPolicy(fragment);
-        if (policy.mFlags.contains(Flag.DETECT_FRAGMENT_REUSE)
-                && shouldHandlePolicyViolation(
-                policy, fragment.getClass(), violation.getClass())) {
-            handlePolicyViolation(policy, violation);
-        }
-    }
-
-    /** @hide */
-    @RestrictTo(RestrictTo.Scope.LIBRARY)
-    public static void onFragmentTagUsage(
-            @NonNull Fragment fragment,
-            @Nullable ViewGroup container) {
-        Violation violation = new FragmentTagUsageViolation(fragment, container);
-        logIfDebuggingEnabled(violation);
-
-        Policy policy = getNearestPolicy(fragment);
-        if (policy.mFlags.contains(Flag.DETECT_FRAGMENT_TAG_USAGE)
-                && shouldHandlePolicyViolation(
-                policy, fragment.getClass(), violation.getClass())) {
-            handlePolicyViolation(policy, violation);
-        }
-    }
-
-    /** @hide */
-    @RestrictTo(RestrictTo.Scope.LIBRARY)
-    public static void onSetRetainInstanceUsage(@NonNull Fragment fragment) {
-        Violation violation = new SetRetainInstanceUsageViolation(fragment);
-        logIfDebuggingEnabled(violation);
-
-        Policy policy = getNearestPolicy(fragment);
-        if (policy.mFlags.contains(Flag.DETECT_RETAIN_INSTANCE_USAGE)
-                && shouldHandlePolicyViolation(
-                policy, fragment.getClass(), violation.getClass())) {
-            handlePolicyViolation(policy, violation);
-        }
-    }
-
-    /** @hide */
-    @RestrictTo(RestrictTo.Scope.LIBRARY)
-    public static void onGetRetainInstanceUsage(@NonNull Fragment fragment) {
-        Violation violation = new GetRetainInstanceUsageViolation(fragment);
-        logIfDebuggingEnabled(violation);
-
-        Policy policy = getNearestPolicy(fragment);
-        if (policy.mFlags.contains(Flag.DETECT_RETAIN_INSTANCE_USAGE)
-                && shouldHandlePolicyViolation(
-                policy, fragment.getClass(), violation.getClass())) {
-            handlePolicyViolation(policy, violation);
-        }
-    }
-
-    /** @hide */
-    @RestrictTo(RestrictTo.Scope.LIBRARY)
-    public static void onSetUserVisibleHint(@NonNull Fragment fragment, boolean isVisibleToUser) {
-        Violation violation = new SetUserVisibleHintViolation(fragment, isVisibleToUser);
-        logIfDebuggingEnabled(violation);
-
-        Policy policy = getNearestPolicy(fragment);
-        if (policy.mFlags.contains(Flag.DETECT_SET_USER_VISIBLE_HINT)
-                && shouldHandlePolicyViolation(
-                policy, fragment.getClass(), violation.getClass())) {
-            handlePolicyViolation(policy, violation);
-        }
-    }
-
-    /** @hide */
-    @RestrictTo(RestrictTo.Scope.LIBRARY)
-    public static void onSetTargetFragmentUsage(
-            @NonNull Fragment violatingFragment,
-            @NonNull Fragment targetFragment,
-            int requestCode) {
-        Violation violation = new SetTargetFragmentUsageViolation(
-                violatingFragment, targetFragment, requestCode);
-        logIfDebuggingEnabled(violation);
-
-        Policy policy = getNearestPolicy(violatingFragment);
-        if (policy.mFlags.contains(Flag.DETECT_TARGET_FRAGMENT_USAGE)
-                && shouldHandlePolicyViolation(
-                policy, violatingFragment.getClass(), violation.getClass())) {
-            handlePolicyViolation(policy, violation);
-        }
-    }
-
-    /** @hide */
-    @RestrictTo(RestrictTo.Scope.LIBRARY)
-    public static void onGetTargetFragmentUsage(@NonNull Fragment fragment) {
-        Violation violation = new GetTargetFragmentUsageViolation(fragment);
-        logIfDebuggingEnabled(violation);
-
-        Policy policy = getNearestPolicy(fragment);
-        if (policy.mFlags.contains(Flag.DETECT_TARGET_FRAGMENT_USAGE)
-                && shouldHandlePolicyViolation(
-                policy, fragment.getClass(), violation.getClass())) {
-            handlePolicyViolation(policy, violation);
-        }
-    }
-
-    /** @hide */
-    @RestrictTo(RestrictTo.Scope.LIBRARY)
-    public static void onGetTargetFragmentRequestCodeUsage(@NonNull Fragment fragment) {
-        Violation violation = new GetTargetFragmentRequestCodeUsageViolation(fragment);
-        logIfDebuggingEnabled(violation);
-
-        Policy policy = getNearestPolicy(fragment);
-        if (policy.mFlags.contains(Flag.DETECT_TARGET_FRAGMENT_USAGE)
-                && shouldHandlePolicyViolation(
-                policy, fragment.getClass(), violation.getClass())) {
-            handlePolicyViolation(policy, violation);
-        }
-    }
-
-    /** @hide */
-    @RestrictTo(RestrictTo.Scope.LIBRARY)
-    public static void onWrongFragmentContainer(
-            @NonNull Fragment fragment,
-            @NonNull ViewGroup container) {
-        Violation violation = new WrongFragmentContainerViolation(fragment, container);
-        logIfDebuggingEnabled(violation);
-
-        Policy policy = getNearestPolicy(fragment);
-        if (policy.mFlags.contains(Flag.DETECT_WRONG_FRAGMENT_CONTAINER)
-                && shouldHandlePolicyViolation(
-                policy, fragment.getClass(), violation.getClass())) {
-            handlePolicyViolation(policy, violation);
-        }
-    }
-
-    @VisibleForTesting
-    static void onPolicyViolation(@NonNull Violation violation) {
-        logIfDebuggingEnabled(violation);
-
-        Fragment fragment = violation.getFragment();
-        Policy policy = getNearestPolicy(fragment);
-        if (shouldHandlePolicyViolation(policy, fragment.getClass(), violation.getClass())) {
-            handlePolicyViolation(policy, violation);
-        }
-    }
-
-    private static void logIfDebuggingEnabled(@NonNull final Violation violation) {
-        if (FragmentManager.isLoggingEnabled(Log.DEBUG)) {
-            Log.d(FragmentManager.TAG,
-                    "StrictMode violation in " + violation.getFragment().getClass().getName(),
-                    violation);
-        }
-    }
-
-    private static boolean shouldHandlePolicyViolation(
-            @NonNull final Policy policy,
-            @NonNull Class<? extends Fragment> fragmentClass,
-            @NonNull Class<? extends Violation> violationClass) {
-        Set<Class<? extends Violation>> violationsToBypass =
-                policy.mAllowedViolations.get(fragmentClass);
-        if (violationsToBypass == null) {
-            return true;
-        }
-
-        if (violationClass.getSuperclass() != Violation.class) {
-            if (violationsToBypass.contains(violationClass.getSuperclass())) {
-                return false;
-            }
-        }
-        return !violationsToBypass.contains(violationClass);
-    }
-
-    private static void handlePolicyViolation(
-            @NonNull final Policy policy,
-            @NonNull final Violation violation
-    ) {
-        final Fragment fragment = violation.getFragment();
-        final String fragmentName = fragment.getClass().getName();
-
-        if (policy.mFlags.contains(Flag.PENALTY_LOG)) {
-            Log.d(TAG, "Policy violation in " + fragmentName, violation);
-        }
-
-        if (policy.mListener != null) {
-            runOnHostThread(fragment, new Runnable() {
-                @Override
-                public void run() {
-                    policy.mListener.onViolation(violation);
-                }
-            });
-        }
-
-        if (policy.mFlags.contains(Flag.PENALTY_DEATH)) {
-            runOnHostThread(fragment, new Runnable() {
-                @Override
-                public void run() {
-                    Log.e(TAG, "Policy violation with PENALTY_DEATH in " + fragmentName, violation);
-                    throw violation;
-                }
-            });
-        }
-    }
-
-    private static void runOnHostThread(@NonNull Fragment fragment, @NonNull Runnable runnable) {
-        if (fragment.isAdded()) {
-            Handler handler = fragment.getParentFragmentManager().getHost().getHandler();
-            if (handler.getLooper() == Looper.myLooper()) {
-                runnable.run(); // Already on correct thread -> run synchronously
-            } else {
-                handler.post(runnable); // Switch to correct thread
-            }
-        } else {
-            runnable.run(); // Fragment is not attached to any host -> run synchronously
+            mAllowedViolations = newAllowedViolationsMap
         }
     }
 }
diff --git a/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/FragmentTagUsageViolation.kt b/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/FragmentTagUsageViolation.kt
index c5d9b7c..cdb3dcd 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/FragmentTagUsageViolation.kt
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/FragmentTagUsageViolation.kt
@@ -13,39 +13,23 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package androidx.fragment.app.strictmode
 
-package androidx.fragment.app.strictmode;
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
 
-import android.view.ViewGroup;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.fragment.app.Fragment;
-
-/** See #{@link FragmentStrictMode.Policy.Builder#detectFragmentTagUsage()}. */
-public final class FragmentTagUsageViolation extends Violation {
-
-    @Nullable
-    private final ViewGroup mContainer;
-
-    FragmentTagUsageViolation(@NonNull Fragment fragment, @Nullable ViewGroup container) {
-        super(fragment);
-        this.mContainer = container;
-    }
-
+/**
+ * See [FragmentStrictMode.Policy.Builder.detectFragmentTagUsage].
+ */
+class FragmentTagUsageViolation internal constructor(
+    fragment: Fragment,
+    val parentContainer: ViewGroup?
+) : Violation(fragment) {
     /**
-     * Gets the parent container that the {@link Fragment} causing the Violation
+     * Gets the parent container that the [Fragment] causing the Violation
      * would have been added to.
      */
-    @Nullable
-    public ViewGroup getParentContainer() {
-        return mContainer;
-    }
-
-    @NonNull
-    @Override
-    public String getMessage() {
-        return "Attempting to use <fragment> tag to add fragment " + mFragment + " to container "
-                + mContainer;
-    }
+    override val message: String
+        get() = "Attempting to use <fragment> tag to add fragment $fragment to container " +
+            "$parentContainer"
 }
diff --git a/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/GetRetainInstanceUsageViolation.kt b/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/GetRetainInstanceUsageViolation.kt
index 96f00db..4c9b293 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/GetRetainInstanceUsageViolation.kt
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/GetRetainInstanceUsageViolation.kt
@@ -13,22 +13,15 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package androidx.fragment.app.strictmode
 
-package androidx.fragment.app.strictmode;
+import androidx.fragment.app.Fragment
 
-import androidx.annotation.NonNull;
-import androidx.fragment.app.Fragment;
-
-/** See #{@link FragmentStrictMode.Policy.Builder#detectRetainInstanceUsage()}. */
-public final class GetRetainInstanceUsageViolation extends RetainInstanceUsageViolation {
-
-    GetRetainInstanceUsageViolation(@NonNull Fragment fragment) {
-        super(fragment);
-    }
-
-    @NonNull
-    @Override
-    public String getMessage() {
-        return "Attempting to get retain instance for fragment " + mFragment;
-    }
+/**
+ * See #[FragmentStrictMode.Policy.Builder.detectRetainInstanceUsage].
+ */
+class GetRetainInstanceUsageViolation internal constructor(fragment: Fragment) :
+    RetainInstanceUsageViolation(fragment) {
+    override val message: String
+        get() = "Attempting to get retain instance for fragment $fragment"
 }
diff --git a/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/GetTargetFragmentRequestCodeUsageViolation.kt b/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/GetTargetFragmentRequestCodeUsageViolation.kt
index cfcb5ab..5595bd4 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/GetTargetFragmentRequestCodeUsageViolation.kt
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/GetTargetFragmentRequestCodeUsageViolation.kt
@@ -13,22 +13,15 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package androidx.fragment.app.strictmode
 
-package androidx.fragment.app.strictmode;
+import androidx.fragment.app.Fragment
 
-import androidx.annotation.NonNull;
-import androidx.fragment.app.Fragment;
-
-/** See #{@link FragmentStrictMode.Policy.Builder#detectTargetFragmentUsage()}. */
-public final class GetTargetFragmentRequestCodeUsageViolation extends TargetFragmentUsageViolation {
-
-    GetTargetFragmentRequestCodeUsageViolation(@NonNull Fragment fragment) {
-        super(fragment);
-    }
-
-    @NonNull
-    @Override
-    public String getMessage() {
-        return "Attempting to get target request code from fragment " + mFragment;
-    }
+/**
+ * See [FragmentStrictMode.Policy.Builder.detectTargetFragmentUsage].
+ */
+class GetTargetFragmentRequestCodeUsageViolation internal constructor(fragment: Fragment) :
+    TargetFragmentUsageViolation(fragment) {
+    override val message: String
+        get() = "Attempting to get target request code from fragment $fragment"
 }
diff --git a/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/GetTargetFragmentUsageViolation.kt b/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/GetTargetFragmentUsageViolation.kt
index db862c8..137ccdc 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/GetTargetFragmentUsageViolation.kt
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/GetTargetFragmentUsageViolation.kt
@@ -13,22 +13,15 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package androidx.fragment.app.strictmode
 
-package androidx.fragment.app.strictmode;
+import androidx.fragment.app.Fragment
 
-import androidx.annotation.NonNull;
-import androidx.fragment.app.Fragment;
-
-/** See #{@link FragmentStrictMode.Policy.Builder#detectTargetFragmentUsage()}. */
-public final class GetTargetFragmentUsageViolation extends TargetFragmentUsageViolation {
-
-    GetTargetFragmentUsageViolation(@NonNull Fragment fragment) {
-        super(fragment);
-    }
-
-    @NonNull
-    @Override
-    public String getMessage() {
-        return "Attempting to get target fragment from fragment " + mFragment;
-    }
+/**
+ * See [FragmentStrictMode.Policy.Builder.detectTargetFragmentUsage].
+ */
+class GetTargetFragmentUsageViolation internal constructor(fragment: Fragment) :
+    TargetFragmentUsageViolation(fragment) {
+    override val message: String
+        get() = "Attempting to get target fragment from fragment $fragment"
 }
diff --git a/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/RetainInstanceUsageViolation.kt b/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/RetainInstanceUsageViolation.kt
index f7ebdc2..714ed9f 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/RetainInstanceUsageViolation.kt
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/RetainInstanceUsageViolation.kt
@@ -13,16 +13,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package androidx.fragment.app.strictmode
 
-package androidx.fragment.app.strictmode;
+import androidx.fragment.app.Fragment
 
-import androidx.annotation.NonNull;
-import androidx.fragment.app.Fragment;
-
-/** See #{@link FragmentStrictMode.Policy.Builder#detectRetainInstanceUsage()}. */
-public abstract class RetainInstanceUsageViolation extends Violation {
-
-    RetainInstanceUsageViolation(@NonNull Fragment fragment) {
-        super(fragment);
-    }
-}
+/**
+ * See [FragmentStrictMode.Policy.Builder.detectRetainInstanceUsage].
+ */
+abstract class RetainInstanceUsageViolation internal constructor(fragment: Fragment) :
+    Violation(fragment)
diff --git a/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/SetRetainInstanceUsageViolation.kt b/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/SetRetainInstanceUsageViolation.kt
index c46cd61..0422f27 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/SetRetainInstanceUsageViolation.kt
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/SetRetainInstanceUsageViolation.kt
@@ -13,22 +13,15 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package androidx.fragment.app.strictmode
 
-package androidx.fragment.app.strictmode;
+import androidx.fragment.app.Fragment
 
-import androidx.annotation.NonNull;
-import androidx.fragment.app.Fragment;
-
-/** See #{@link FragmentStrictMode.Policy.Builder#detectRetainInstanceUsage()}. */
-public final class SetRetainInstanceUsageViolation extends RetainInstanceUsageViolation {
-
-    SetRetainInstanceUsageViolation(@NonNull Fragment fragment) {
-        super(fragment);
-    }
-
-    @NonNull
-    @Override
-    public String getMessage() {
-        return "Attempting to set retain instance for fragment " + mFragment;
-    }
+/**
+ * See [FragmentStrictMode.Policy.Builder.detectRetainInstanceUsage].
+ */
+class SetRetainInstanceUsageViolation internal constructor(fragment: Fragment) :
+    RetainInstanceUsageViolation(fragment) {
+    override val message: String
+        get() = "Attempting to set retain instance for fragment $fragment"
 }
diff --git a/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/SetTargetFragmentUsageViolation.kt b/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/SetTargetFragmentUsageViolation.kt
index 76962eda..7274f77 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/SetTargetFragmentUsageViolation.kt
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/SetTargetFragmentUsageViolation.kt
@@ -13,46 +13,25 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package androidx.fragment.app.strictmode
 
-package androidx.fragment.app.strictmode;
+import androidx.fragment.app.Fragment
 
-import androidx.annotation.NonNull;
-import androidx.fragment.app.Fragment;
-
-/** See #{@link FragmentStrictMode.Policy.Builder#detectTargetFragmentUsage()}. */
-public final class SetTargetFragmentUsageViolation extends TargetFragmentUsageViolation {
-
-    private final Fragment mTargetFragment;
-    private final int mRequestCode;
-
-    SetTargetFragmentUsageViolation(
-            @NonNull Fragment violatingFragment,
-            @NonNull Fragment targetFragment,
-            int requestCode) {
-        super(violatingFragment);
-        this.mTargetFragment = targetFragment;
-        this.mRequestCode = requestCode;
-    }
-
+/**
+ * See [FragmentStrictMode.Policy.Builder.detectTargetFragmentUsage].
+ */
+class SetTargetFragmentUsageViolation internal constructor(
+    violatingFragment: Fragment,
     /**
-     * Gets the target {@link Fragment} that was being set in the call causing the Violation.
+     * Gets the target [Fragment] that was being set in the call causing the Violation.
      */
-    @NonNull
-    public Fragment getTargetFragment() {
-        return mTargetFragment;
-    }
-
+    val targetFragment: Fragment,
     /**
      * Gets the request code that was passed in the call causing the Violation.
      */
-    public int getRequestCode() {
-        return mRequestCode;
-    }
-
-    @NonNull
-    @Override
-    public String getMessage() {
-        return "Attempting to set target fragment " + mTargetFragment + " with request code "
-                + mRequestCode + " for fragment " + mFragment;
-    }
+    val requestCode: Int
+) : TargetFragmentUsageViolation(violatingFragment) {
+    override val message: String
+        get() = "Attempting to set target fragment $targetFragment with request code " +
+            "$requestCode for fragment $fragment"
 }
diff --git a/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/SetUserVisibleHintViolation.kt b/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/SetUserVisibleHintViolation.kt
index dcf5bdc..490867b415 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/SetUserVisibleHintViolation.kt
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/SetUserVisibleHintViolation.kt
@@ -13,34 +13,21 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package androidx.fragment.app.strictmode
 
-package androidx.fragment.app.strictmode;
+import androidx.fragment.app.Fragment
 
-import androidx.annotation.NonNull;
-import androidx.fragment.app.Fragment;
-
-/** See #{@link FragmentStrictMode.Policy.Builder#detectSetUserVisibleHint()}. */
-public final class SetUserVisibleHintViolation extends Violation {
-
-    private final boolean mIsVisibleToUser;
-
-    SetUserVisibleHintViolation(@NonNull Fragment fragment, boolean isVisibleToUser) {
-        super(fragment);
-        this.mIsVisibleToUser = isVisibleToUser;
-    }
-
+/**
+ * See [FragmentStrictMode.Policy.Builder.detectSetUserVisibleHint].
+ */
+class SetUserVisibleHintViolation internal constructor(
+    fragment: Fragment,
+    val isVisibleToUser: Boolean
+) : Violation(fragment) {
     /**
-     * Indicates what the {@code isVisibleToUser} field for the {@link Fragment} causing the
+     * Indicates what the `isVisibleToUser` field for the [Fragment] causing the
      * Violation was being set to.
      */
-    public boolean isVisibleToUser() {
-        return mIsVisibleToUser;
-    }
-
-    @NonNull
-    @Override
-    public String getMessage() {
-        return "Attempting to set user visible hint to " + mIsVisibleToUser + " for fragment "
-                + mFragment;
-    }
+    override val message: String
+        get() = "Attempting to set user visible hint to $isVisibleToUser for fragment $fragment"
 }
diff --git a/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/TargetFragmentUsageViolation.kt b/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/TargetFragmentUsageViolation.kt
index b62c430..1c5614f 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/TargetFragmentUsageViolation.kt
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/TargetFragmentUsageViolation.kt
@@ -13,16 +13,12 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package androidx.fragment.app.strictmode
 
-package androidx.fragment.app.strictmode;
+import androidx.fragment.app.Fragment
 
-import androidx.annotation.NonNull;
-import androidx.fragment.app.Fragment;
-
-/** See #{@link FragmentStrictMode.Policy.Builder#detectTargetFragmentUsage()}. */
-public abstract class TargetFragmentUsageViolation extends Violation {
-
-    TargetFragmentUsageViolation(@NonNull Fragment fragment) {
-        super(fragment);
-    }
-}
+/**
+ * See [FragmentStrictMode.Policy.Builder.detectTargetFragmentUsage].
+ */
+abstract class TargetFragmentUsageViolation internal constructor(fragment: Fragment) :
+    Violation(fragment)
\ No newline at end of file
diff --git a/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/Violation.kt b/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/Violation.kt
index fae9784..9aed066 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/Violation.kt
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/Violation.kt
@@ -13,27 +13,15 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package androidx.fragment.app.strictmode
 
-package androidx.fragment.app.strictmode;
-
-import androidx.annotation.NonNull;
-import androidx.fragment.app.Fragment;
+import androidx.fragment.app.Fragment
 
 /** Root class for all FragmentStrictMode violations. */
 @SuppressWarnings("ExceptionName")
-public abstract class Violation extends RuntimeException {
-
-    final Fragment mFragment;
-
-    Violation(@NonNull Fragment fragment) {
-        mFragment = fragment;
-    }
-
+abstract class Violation internal constructor(
     /**
-     * Gets the {@link Fragment} causing the Violation.
+     * Gets the [Fragment] causing the Violation.
      */
-    @NonNull
-    public Fragment getFragment() {
-        return mFragment;
-    }
-}
+    val fragment: Fragment
+) : RuntimeException()
diff --git a/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/WrongFragmentContainerViolation.kt b/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/WrongFragmentContainerViolation.kt
index 61fb15d..2d5aafc 100644
--- a/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/WrongFragmentContainerViolation.kt
+++ b/fragment/fragment/src/main/java/androidx/fragment/app/strictmode/WrongFragmentContainerViolation.kt
@@ -13,37 +13,23 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+package androidx.fragment.app.strictmode
 
-package androidx.fragment.app.strictmode;
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
 
-import android.view.ViewGroup;
-
-import androidx.annotation.NonNull;
-import androidx.fragment.app.Fragment;
-
-/** See #{@link FragmentStrictMode.Policy.Builder#detectWrongFragmentContainer()}. */
-public final class WrongFragmentContainerViolation extends Violation {
-
-    private final ViewGroup mContainer;
-
-    WrongFragmentContainerViolation(@NonNull Fragment fragment, @NonNull ViewGroup container) {
-        super(fragment);
-        this.mContainer = container;
-    }
-
+/**
+ * See [FragmentStrictMode.Policy.Builder.detectWrongFragmentContainer].
+ */
+class WrongFragmentContainerViolation internal constructor(
+    fragment: Fragment,
+    val container: ViewGroup
+) : Violation(fragment) {
     /**
-     * Gets the container that the {@link Fragment} causing the Violation was
+     * Gets the container that the [Fragment] causing the Violation was
      * being added to.
      */
-    @NonNull
-    public ViewGroup getContainer() {
-        return mContainer;
-    }
-
-    @NonNull
-    @Override
-    public String getMessage() {
-        return "Attempting to add fragment " + mFragment + " to container " + mContainer
-                + " which is not a FragmentContainerView";
-    }
+    override val message: String
+        get() = "Attempting to add fragment $fragment to container $container which is not a " +
+            "FragmentContainerView"
 }