package org.chromium.webengine;
import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.concurrent.futures.CallbackToFutureAdapter;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import org.chromium.base.Callback;
import org.chromium.webengine.interfaces.ITabCallback;
import org.chromium.webengine.interfaces.ITabManagerDelegate;
import org.chromium.webengine.interfaces.ITabParams;
import java.util.Set;
* Class for interaction with WebEngine Tabs.
* Calls into WebEngineDelegate which runs on the Binder thread, and requires
* finished initialization from onCreate on UIThread.
* Access only via ListenableFuture through WebEngine.
*/
public class TabManager {
@NonNull
private ITabManagerDelegate mDelegate;
@NonNull
private WebEngine mWebEngine;
@NonNull
private TabRegistry mTabRegistry;
@NonNull
private final TabListObserverDelegate mTabListObserverDelegate;
@NonNull
private Callback mInitializedTabsCallback;
private final class TabCallback extends ITabCallback.Stub {
private CallbackToFutureAdapter.Completer<Tab> mCompleter;
TabCallback(CallbackToFutureAdapter.Completer<Tab> completer) {
mCompleter = completer;
}
@Override
public void onResult(@Nullable ITabParams tabParams) {
if (tabParams != null) {
new Handler(Looper.getMainLooper()).post(() -> {
mCompleter.set(mTabRegistry.getOrCreateTab(tabParams));
});
return;
}
mCompleter.set(null);
}
};
TabManager(ITabManagerDelegate delegate, WebEngine webEngine) {
mDelegate = delegate;
mWebEngine = webEngine;
mTabRegistry = new TabRegistry(mWebEngine);
mTabListObserverDelegate = new TabListObserverDelegate(mWebEngine, mTabRegistry);
try {
mDelegate.setTabListObserverDelegate(mTabListObserverDelegate);
} catch (RemoteException e) {
}
}
void initialize(Callback<Void> initializedCallback) {
mTabListObserverDelegate.setInitializationFinishedCallback(initializedCallback);
try {
mDelegate.notifyInitialTabs();
} catch (RemoteException e) {
}
}
* Registers a tab observer and returns if successful.
*
* @param tabListObserver The TabListObserver.
*/
public boolean registerTabListObserver(@NonNull TabListObserver tabListObserver) {
ThreadCheck.ensureOnUiThread();
return mTabListObserverDelegate.registerObserver(tabListObserver);
}
* Unregisters a tab observer and returns if successful.
*
* @param tabListObserver The TabListObserver to remove.
*/
public boolean unregisterTabListObserver(@NonNull TabListObserver tabListObserver) {
ThreadCheck.ensureOnUiThread();
return mTabListObserverDelegate.unregisterObserver(tabListObserver);
}
* Returns the currently active Tab or null if no Tab is active.
*/
@Nullable
public Tab getActiveTab() {
return mTabRegistry.getActiveTab();
}
* Creates a new Tab and returns it in a ListenableFuture.
*/
@NonNull
public ListenableFuture<Tab> createTab() {
ThreadCheck.ensureOnUiThread();
if (mDelegate == null) {
return Futures.immediateFailedFuture(
new IllegalStateException("WebSandbox has been destroyed"));
}
return CallbackToFutureAdapter.getFuture(completer -> {
try {
mDelegate.createTab(new TabCallback(completer));
} catch (RemoteException e) {
completer.setException(e);
}
return "Create Tab Future";
});
}
* Returns a set of all the tabs.
*/
@NonNull
public Set<Tab> getAllTabs() {
return mTabRegistry.getTabs();
}
void invalidate() {
mDelegate = null;
mTabRegistry.invalidate();
}
}