1 // Copyright 2020 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 package org.chromium.base.supplier; 6 7 import androidx.annotation.CallSuper; 8 import androidx.annotation.NonNull; 9 10 import org.chromium.base.UnownedUserData; 11 import org.chromium.base.UnownedUserDataHost; 12 import org.chromium.base.UnownedUserDataKey; 13 import org.chromium.base.lifetime.DestroyChecker; 14 import org.chromium.base.lifetime.Destroyable; 15 16 /** 17 * UnownedUserDataSupplier handles the combined lifecycle management for {@link UnownedUserData} and 18 * {@link DestroyableObservableSupplier}. It can be constructed anywhere but needs to be attached 19 * before it's accessible via {@link UnownedUserDataHost}. When destroyed, UnownedUserDataSupplier 20 * is detached from all hosts. 21 * 22 * <p>A functional implementation with best practices is defined in {@link 23 * UnownedUserDataSupplierTest}. 24 * 25 * <p>Classes that hold a reference to to the concrete implementation of this class are also in 26 * charge of its lifecycle. {@link #destroy} should be called when the application is shutting down. 27 * This will detach the {@link UnownedUserDataSupplier}, but it won't destroy the supplied object. 28 * 29 * <p>In practice, UnownedUserDataSupplier owners should declare and assign the supplier inline. 30 * This allows interop between other supplier implementations as well as use in activity 31 * constructors before {@link WindowAndroid} is created. See the example below: 32 * 33 * <pre>{@code 34 * UnownedUserDataSupplier<Foo> mFooSupplier = new FooSupplier(); 35 * ... 36 * // Sometime after WindowAndroid has been created. 37 * mFooSupplier.attach(mWindowAndroid.getUnownedUserDataHost()); 38 * }</pre> 39 * 40 * @param <E> The type of the data to be Supplied and stored in UnownedUserData. 41 * @see UnownedUserDataHost for more details on ownership and typical usage. 42 * @see UnownedUserDataKey for information about the type of key that is required. 43 * @see UnownedUserData for the marker interface used for this type of data. 44 */ 45 public abstract class UnownedUserDataSupplier<E> extends ObservableSupplierImpl<E> 46 implements Destroyable, UnownedUserData { 47 private final UnownedUserDataKey<UnownedUserDataSupplier<E>> mUudKey; 48 private final DestroyChecker mDestroyChecker = new DestroyChecker(); 49 50 /** 51 * Constructs an UnownedUserDataSupplier. 52 * @param uudKey The {@link UnownedUserDataKey}, which is defined in subclasses. 53 */ UnownedUserDataSupplier( @onNull UnownedUserDataKey<? extends UnownedUserDataSupplier<E>> uudKey)54 protected UnownedUserDataSupplier( 55 @NonNull UnownedUserDataKey<? extends UnownedUserDataSupplier<E>> uudKey) { 56 mUudKey = (UnownedUserDataKey<UnownedUserDataSupplier<E>>) uudKey; 57 } 58 59 /** 60 * Attach to the specified host. 61 * @param host The host to attach the supplier to. 62 */ attach(@onNull UnownedUserDataHost host)63 public void attach(@NonNull UnownedUserDataHost host) { 64 mDestroyChecker.checkNotDestroyed(); 65 mUudKey.attachToHost(host, this); 66 } 67 68 @Override 69 @CallSuper destroy()70 public void destroy() { 71 mDestroyChecker.destroy(); 72 mUudKey.detachFromAllHosts(this); 73 } 74 } 75