/* * Copyright (C) 2017 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.documentsui; import static com.android.documentsui.base.SharedMinimal.DEBUG; import android.util.Log; import androidx.annotation.GuardedBy; import androidx.annotation.Nullable; import androidx.recyclerview.selection.OperationMonitor; /** * ContentLock provides a mechanism to block content from reloading while selection * activities like gesture and band selection are active. Clients using live data * (data loaded, for example by a {@link Loader}), should route calls to load * content through this lock using {@link ContentLock#runWhenUnlocked(Runnable)}. */ public final class ContentLock { private static final String TAG = "ContentLock"; private final OperationMonitor mMonitor = new OperationMonitor(); @GuardedBy("this") private @Nullable Runnable mCallback; public ContentLock() { mMonitor.addListener(() -> { if (DEBUG) { Log.d(TAG, "monitor listener, is locked : " + isLocked()); } if (!isLocked()) { synchronized (this) { final Runnable callback = mCallback; if (callback != null) { callback.run(); mCallback = null; } } } }); } public OperationMonitor getMonitor() { return mMonitor; } /** * Returns true if locked. */ private boolean isLocked() { return mMonitor.isStarted(); } /** * Attempts to run the given Runnable if not-locked, or else the Runnable is set to be ran next * (replacing any previous set Runnables). */ public synchronized void runWhenUnlocked(Runnable runnable) { if (DEBUG) { Log.d(TAG, "run when unlock, is locked : " + isLocked()); } if (!isLocked()) { runnable.run(); } else { mCallback = runnable; } } }