• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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