diff --git a/src/com/android/launcher3/icons/LauncherIcons.java b/src/com/android/launcher3/icons/LauncherIcons.java
deleted file mode 100644
index 5c6debe..0000000
--- a/src/com/android/launcher3/icons/LauncherIcons.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3.icons;
-
-import static android.graphics.Color.BLACK;
-
-import static com.android.launcher3.graphics.ThemeManager.PREF_ICON_SHAPE;
-
-import android.content.Context;
-import android.graphics.Canvas;
-import android.graphics.Path;
-import android.graphics.Rect;
-import android.graphics.drawable.AdaptiveIconDrawable;
-import android.os.UserHandle;
-
-import androidx.annotation.NonNull;
-
-import com.android.launcher3.Flags;
-import com.android.launcher3.InvariantDeviceProfile;
-import com.android.launcher3.LauncherPrefs;
-import com.android.launcher3.graphics.IconShape;
-import com.android.launcher3.graphics.ThemeManager;
-import com.android.launcher3.pm.UserCache;
-import com.android.launcher3.util.MainThreadInitializedObject;
-import com.android.launcher3.util.SafeCloseable;
-import com.android.launcher3.util.UserIconInfo;
-
-import java.util.concurrent.ConcurrentLinkedQueue;
-
-/**
- * Wrapper class to provide access to {@link BaseIconFactory} and also to provide pool of this class
- * that are threadsafe.
- */
-public class LauncherIcons extends BaseIconFactory implements AutoCloseable {
-
-    private static final float SEVEN_SIDED_COOKIE_SCALE = 72f / 80f;
-    private static final float FOUR_SIDED_COOKIE_SCALE = 72f / 83.4f;
-    private static final float VERY_SUNNY_SCALE = 72f / 92f;
-    private static final float DEFAULT_ICON_SCALE = 1f;
-
-
-    private static final MainThreadInitializedObject<Pool> POOL =
-            new MainThreadInitializedObject<>(Pool::new);
-
-    /**
-     * Return a new Message instance from the global pool. Allows us to
-     * avoid allocating new objects in many cases.
-     */
-    public static LauncherIcons obtain(Context context) {
-        return POOL.get(context).obtain();
-    }
-
-    public static void clearPool(Context context) {
-        POOL.get(context).close();
-    }
-
-    private final ConcurrentLinkedQueue<LauncherIcons> mPool;
-
-    protected LauncherIcons(Context context, int fillResIconDpi, int iconBitmapSize,
-            ConcurrentLinkedQueue<LauncherIcons> pool) {
-        super(context, fillResIconDpi, iconBitmapSize);
-        mThemeController = ThemeManager.INSTANCE.get(context).getThemeController();
-        mPool = pool;
-    }
-
-    /**
-     * Recycles a LauncherIcons that may be in-use.
-     */
-    public void recycle() {
-        clear();
-        mPool.add(this);
-    }
-
-    @NonNull
-    @Override
-    protected UserIconInfo getUserInfo(@NonNull UserHandle user) {
-        return UserCache.INSTANCE.get(mContext).getUserInfo(user);
-    }
-
-    @NonNull
-    @Override
-    public Path getShapePath(AdaptiveIconDrawable drawable, Rect iconBounds) {
-        if (!Flags.enableLauncherIconShapes()) return drawable.getIconMask();
-        return IconShape.INSTANCE.get(mContext).getShape().getPath(iconBounds);
-    }
-
-    @Override
-    protected void drawAdaptiveIcon(
-            @NonNull Canvas canvas,
-            @NonNull AdaptiveIconDrawable drawable,
-            @NonNull Path overridePath
-    ) {
-        if (!Flags.enableLauncherIconShapes()) {
-            super.drawAdaptiveIcon(canvas, drawable, overridePath);
-            return;
-        }
-        String shapeKey = LauncherPrefs.get(mContext).get(PREF_ICON_SHAPE);
-        float iconScale = switch (shapeKey) {
-            case "seven_sided_cookie" -> SEVEN_SIDED_COOKIE_SCALE;
-            case "four_sided_cookie" -> FOUR_SIDED_COOKIE_SCALE;
-            case "sunny" -> VERY_SUNNY_SCALE;
-            default -> DEFAULT_ICON_SCALE;
-        };
-        canvas.clipPath(overridePath);
-        canvas.drawColor(BLACK);
-        canvas.save();
-        canvas.scale(iconScale, iconScale, canvas.getWidth() / 2f, canvas.getHeight() / 2f);
-        if (drawable.getBackground() != null) {
-            drawable.getBackground().draw(canvas);
-        }
-        if (drawable.getForeground() != null) {
-            drawable.getForeground().draw(canvas);
-        }
-        canvas.restore();
-    }
-
-    @Override
-    public void close() {
-        recycle();
-    }
-
-    private static class Pool implements SafeCloseable {
-
-        private final Context mContext;
-
-        @NonNull
-        private ConcurrentLinkedQueue<LauncherIcons> mPool = new ConcurrentLinkedQueue<>();
-
-        private Pool(Context context) {
-            mContext = context;
-        }
-
-        public LauncherIcons obtain() {
-            ConcurrentLinkedQueue<LauncherIcons> pool = mPool;
-            LauncherIcons m = pool.poll();
-
-            if (m == null) {
-                InvariantDeviceProfile idp = InvariantDeviceProfile.INSTANCE.get(mContext);
-                return new LauncherIcons(mContext, idp.fillResIconDpi, idp.iconBitmapSize, pool);
-            } else {
-                return m;
-            }
-        }
-
-        @Override
-        public void close() {
-            mPool = new ConcurrentLinkedQueue<>();
-        }
-    }
-}
diff --git a/src/com/android/launcher3/icons/LauncherIcons.kt b/src/com/android/launcher3/icons/LauncherIcons.kt
new file mode 100644
index 0000000..518f29d
--- /dev/null
+++ b/src/com/android/launcher3/icons/LauncherIcons.kt
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.launcher3.icons
+
+import android.content.Context
+import android.graphics.Canvas
+import android.graphics.Color
+import android.graphics.Path
+import android.graphics.Rect
+import android.graphics.drawable.AdaptiveIconDrawable
+import android.os.UserHandle
+import com.android.launcher3.Flags
+import com.android.launcher3.InvariantDeviceProfile
+import com.android.launcher3.LauncherPrefs
+import com.android.launcher3.graphics.IconShape
+import com.android.launcher3.graphics.ThemeManager
+import com.android.launcher3.pm.UserCache
+import com.android.launcher3.util.MainThreadInitializedObject
+import com.android.launcher3.util.SafeCloseable
+import com.android.launcher3.util.UserIconInfo
+import java.util.concurrent.ConcurrentLinkedQueue
+
+/**
+ * Wrapper class to provide access to [BaseIconFactory] and also to provide pool of this class that
+ * are threadsafe.
+ */
+class LauncherIcons
+protected constructor(
+    context: Context,
+    fillResIconDpi: Int,
+    iconBitmapSize: Int,
+    private val pool: ConcurrentLinkedQueue<LauncherIcons>,
+) : BaseIconFactory(context, fillResIconDpi, iconBitmapSize), AutoCloseable {
+
+    init {
+        mThemeController = ThemeManager.INSTANCE[context].themeController
+    }
+
+    /** Recycles a LauncherIcons that may be in-use. */
+    fun recycle() {
+        clear()
+        pool.add(this)
+    }
+
+    override fun getUserInfo(user: UserHandle): UserIconInfo {
+        return UserCache.INSTANCE[mContext].getUserInfo(user)
+    }
+
+    public override fun getShapePath(drawable: AdaptiveIconDrawable, iconBounds: Rect): Path {
+        if (!Flags.enableLauncherIconShapes()) return drawable.iconMask
+        return IconShape.INSTANCE[mContext].shape.getPath(iconBounds)
+    }
+
+    override fun drawAdaptiveIcon(
+        canvas: Canvas,
+        drawable: AdaptiveIconDrawable,
+        overridePath: Path,
+    ) {
+        if (!Flags.enableLauncherIconShapes()) {
+            super.drawAdaptiveIcon(canvas, drawable, overridePath)
+            return
+        }
+        val shapeKey = LauncherPrefs.get(mContext).get(ThemeManager.PREF_ICON_SHAPE)
+        val iconScale =
+            when (shapeKey) {
+                "seven_sided_cookie" -> SEVEN_SIDED_COOKIE_SCALE
+                "four_sided_cookie" -> FOUR_SIDED_COOKIE_SCALE
+                "sunny" -> VERY_SUNNY_SCALE
+                else -> DEFAULT_ICON_SCALE
+            }
+        canvas.clipPath(overridePath)
+        canvas.drawColor(Color.BLACK)
+        canvas.save()
+        canvas.scale(iconScale, iconScale, canvas.width / 2f, canvas.height / 2f)
+        if (drawable.background != null) {
+            drawable.background.draw(canvas)
+        }
+        if (drawable.foreground != null) {
+            drawable.foreground.draw(canvas)
+        }
+        canvas.restore()
+    }
+
+    override fun close() {
+        recycle()
+    }
+
+    private class Pool(private val context: Context) : SafeCloseable {
+        private var pool = ConcurrentLinkedQueue<LauncherIcons>()
+
+        fun obtain(): LauncherIcons {
+            val pool = pool
+            return pool.poll()
+                ?: InvariantDeviceProfile.INSTANCE[context].let {
+                    LauncherIcons(context, it.fillResIconDpi, it.iconBitmapSize, pool)
+                }
+        }
+
+        override fun close() {
+            pool = ConcurrentLinkedQueue()
+        }
+    }
+
+    companion object {
+        private const val SEVEN_SIDED_COOKIE_SCALE = 72f / 80f
+        private const val FOUR_SIDED_COOKIE_SCALE = 72f / 83.4f
+        private const val VERY_SUNNY_SCALE = 72f / 92f
+        private const val DEFAULT_ICON_SCALE = 1f
+
+        private val POOL = MainThreadInitializedObject { Pool(it) }
+
+        /**
+         * Return a new Message instance from the global pool. Allows us to avoid allocating new
+         * objects in many cases.
+         */
+        @JvmStatic
+        fun obtain(context: Context): LauncherIcons {
+            return POOL[context].obtain()
+        }
+
+        @JvmStatic
+        fun clearPool(context: Context) {
+            POOL[context].close()
+        }
+    }
+}
