Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 10fa0163 authored by Sunny Goyal's avatar Sunny Goyal
Browse files

Fixing MainThreadInitializedObject

> Making SafeCloseable implementation mandatory, to prevent leaks during test and preview
> Removing getNoCreate method and defining executeIfCreated to avoid null pointer exceptions
> Fixing sandbox value leaking into main, by Checking sandbox against App context
> Converting sanbox to an interface instead a class

Bug: 335280439
Test: Presubmit
Flag: None
Change-Id: I951dcde871898e745ff6490a1c4f8fd1512888f5
parent 1f40fa0e
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import androidx.room.Room;
import com.android.internal.annotations.VisibleForTesting;
import com.android.launcher3.model.AppShareabilityDatabase.ShareabilityDao;
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.util.SafeCloseable;

import java.lang.annotation.Retention;
import java.util.ArrayList;
@@ -47,7 +48,7 @@ import java.util.function.Consumer;
 * Each app's status is retrieved from the Play Store's API. Statuses are cached in order
 * to limit extraneous calls to that API (which can be time-consuming).
 */
public class AppShareabilityManager {
public class AppShareabilityManager implements SafeCloseable {
    @Retention(SOURCE)
    @IntDef({
        ShareabilityStatus.UNKNOWN,
@@ -194,6 +195,11 @@ public class AppShareabilityManager {
        }
    }

    @Override
    public void close() {
        mDatabase.close();
    }

    /**
     * Provides a testable instance of this class
     * This instance allows database queries on the main thread
+6 −2
Original line number Diff line number Diff line
@@ -326,8 +326,12 @@ public class QuickstepModelDelegate extends ModelDelegate {
        super.destroy();
        mActive = false;
        StatsLogCompatManager.LOGS_CONSUMER.remove(mAppEventProducer);
        if (mIsPrimaryInstance) {
        if (mIsPrimaryInstance && mStatsManager != null) {
            try {
                mStatsManager.clearPullAtomCallback(SysUiStatsLog.LAUNCHER_LAYOUT_SNAPSHOT);
            } catch (RuntimeException e) {
                Log.e(TAG, "Failed to unregister snapshot logging callback with StatsManager", e);
            }
        }
        destroyPredictors();
    }
+32 −17
Original line number Diff line number Diff line
@@ -32,7 +32,6 @@ import android.net.Uri;
import android.os.Bundle;
import android.os.DeadObjectException;
import android.os.Handler;
import android.os.Looper;
import android.os.Process;
import android.os.UserHandle;
import android.text.TextUtils;
@@ -48,9 +47,10 @@ import com.android.launcher3.R;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.popup.RemoteActionShortcut;
import com.android.launcher3.popup.SystemShortcut;
import com.android.launcher3.util.BgObjectWithLooper;
import com.android.launcher3.util.Executors;
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.util.Preconditions;
import com.android.launcher3.util.SafeCloseable;
import com.android.launcher3.util.SimpleBroadcastReceiver;
import com.android.launcher3.views.ActivityContext;

@@ -61,7 +61,7 @@ import java.util.Map;
/**
 * Data model for digital wellbeing status of apps.
 */
public final class WellbeingModel extends BgObjectWithLooper {
public final class WellbeingModel implements SafeCloseable {
    private static final String TAG = "WellbeingModel";
    private static final int[] RETRY_TIMES_MS = {5000, 15000, 30000};
    private static final boolean DEBUG = false;
@@ -81,8 +81,12 @@ public final class WellbeingModel extends BgObjectWithLooper {
    private final Context mContext;
    private final String mWellbeingProviderPkg;

    private Handler mWorkerHandler;
    private ContentObserver mContentObserver;
    private final Handler mWorkerHandler;
    private final ContentObserver mContentObserver;
    private final SimpleBroadcastReceiver mWellbeingAppChangeReceiver =
            new SimpleBroadcastReceiver(t -> restartObserver());
    private final SimpleBroadcastReceiver mAppAddRemoveReceiver =
            new SimpleBroadcastReceiver(this::onAppPackageChanged);

    private final Object mModelLock = new Object();
    // Maps the action Id to the corresponding RemoteAction
@@ -94,16 +98,23 @@ public final class WellbeingModel extends BgObjectWithLooper {
    private WellbeingModel(final Context context) {
        mContext = context;
        mWellbeingProviderPkg = mContext.getString(R.string.wellbeing_provider_pkg);
        initializeInBackground("WellbeingHandler");
    }
        mWorkerHandler = new Handler(TextUtils.isEmpty(mWellbeingProviderPkg)
                ? Executors.UI_HELPER_EXECUTOR.getLooper()
                : Executors.getPackageExecutor(mWellbeingProviderPkg).getLooper());

        mContentObserver = new ContentObserver(mWorkerHandler) {
            @Override
    protected void onInitialized(Looper looper) {
        mWorkerHandler = new Handler(looper);
        mContentObserver = newContentObserver(mWorkerHandler, this::onWellbeingUriChanged);
            public void onChange(boolean selfChange, Uri uri) {
                updateAllPackages();
            }
        };
        mWorkerHandler.post(this::initializeInBackground);
    }

    private void initializeInBackground() {
        if (!TextUtils.isEmpty(mWellbeingProviderPkg)) {
            mContext.registerReceiver(
                    new SimpleBroadcastReceiver(t -> restartObserver()),
                    mWellbeingAppChangeReceiver,
                    getPackageFilter(mWellbeingProviderPkg,
                            Intent.ACTION_PACKAGE_ADDED, Intent.ACTION_PACKAGE_CHANGED,
                            Intent.ACTION_PACKAGE_REMOVED, Intent.ACTION_PACKAGE_DATA_CLEARED,
@@ -113,17 +124,21 @@ public final class WellbeingModel extends BgObjectWithLooper {
            IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
            filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
            filter.addDataScheme("package");
            mContext.registerReceiver(new SimpleBroadcastReceiver(this::onAppPackageChanged),
                    filter, null, mWorkerHandler);
            mContext.registerReceiver(mAppAddRemoveReceiver, filter, null, mWorkerHandler);

            restartObserver();
        }
    }

    @WorkerThread
    private void onWellbeingUriChanged(Uri uri) {
        Preconditions.assertNonUiThread();
        updateAllPackages();
    @Override
    public void close() {
        if (!TextUtils.isEmpty(mWellbeingProviderPkg)) {
            mWorkerHandler.post(() -> {
                mWellbeingAppChangeReceiver.unregisterReceiverSafely(mContext);
                mAppAddRemoveReceiver.unregisterReceiverSafely(mContext);
                mContext.getContentResolver().unregisterContentObserver(mContentObserver);
            });
        }
    }

    public void setInTest(boolean inTest) {
+7 −1
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import com.android.launcher3.util.DisplayController.DisplayInfoChangeListener;
import com.android.launcher3.util.DisplayController.Info;
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.util.NavigationMode;
import com.android.launcher3.util.SafeCloseable;
import com.android.quickstep.util.RecentsOrientedState;
import com.android.systemui.shared.system.QuickStepContract;
import com.android.systemui.shared.system.TaskStackChangeListener;
@@ -50,7 +51,7 @@ import java.util.ArrayList;
/**
 * Helper class for transforming touch events
 */
public class RotationTouchHelper implements DisplayInfoChangeListener {
public class RotationTouchHelper implements DisplayInfoChangeListener, SafeCloseable {

    public static final MainThreadInitializedObject<RotationTouchHelper> INSTANCE =
            new MainThreadInitializedObject<>(RotationTouchHelper::new);
@@ -197,6 +198,11 @@ public class RotationTouchHelper implements DisplayInfoChangeListener {
        mOnDestroyActions.add(action);
    }

    @Override
    public void close() {
        destroy();
    }

    /**
     * Cleans up all the registered listeners and receivers.
     */
+9 −1
Original line number Diff line number Diff line
@@ -24,21 +24,29 @@ import android.view.MotionEvent;

import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.MainThreadInitializedObject;
import com.android.launcher3.util.SafeCloseable;

public class SimpleOrientationTouchTransformer implements
        DisplayController.DisplayInfoChangeListener {
        DisplayController.DisplayInfoChangeListener, SafeCloseable {

    public static final MainThreadInitializedObject<SimpleOrientationTouchTransformer> INSTANCE =
            new MainThreadInitializedObject<>(SimpleOrientationTouchTransformer::new);

    private final Context mContext;
    private OrientationRectF mOrientationRectF;

    public SimpleOrientationTouchTransformer(Context context) {
        mContext = context;
        DisplayController.INSTANCE.get(context).addChangeListener(this);
        onDisplayInfoChanged(context, DisplayController.INSTANCE.get(context).getInfo(),
                CHANGE_ALL);
    }

    @Override
    public void close() {
        DisplayController.INSTANCE.get(mContext).removeChangeListener(this);
    }

    @Override
    public void onDisplayInfoChanged(Context context, DisplayController.Info info, int flags) {
        if ((flags & (CHANGE_ROTATION | CHANGE_ACTIVE_SCREEN)) == 0) {
Loading