1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.location.listeners;
18 
19 import android.annotation.Nullable;
20 
21 import com.android.internal.listeners.ListenerExecutor;
22 
23 import java.util.Objects;
24 import java.util.concurrent.Executor;
25 
26 /**
27  * A listener registration object which holds data associated with the listener, such as an optional
28  * request, and an executor responsible for listener invocations.
29  *
30  * @param <TListener>          listener type
31  */
32 public class ListenerRegistration<TListener> implements ListenerExecutor {
33 
34     private final Executor mExecutor;
35 
36     private boolean mActive;
37 
38     @Nullable private volatile TListener mListener;
39 
ListenerRegistration(Executor executor, TListener listener)40     protected ListenerRegistration(Executor executor, TListener listener) {
41         mExecutor = Objects.requireNonNull(executor);
42         mActive = false;
43         mListener = Objects.requireNonNull(listener);
44     }
45 
46     /**
47      * Returns a tag to use for logging. Should be overridden by subclasses.
48      */
getTag()49     protected String getTag() {
50         return "ListenerRegistration";
51     }
52 
getExecutor()53     protected final Executor getExecutor() {
54         return mExecutor;
55     }
56 
57     /**
58      * May be overridden by subclasses. Invoked when registration occurs. Invoked while holding the
59      * owning multiplexer's internal lock.
60      *
61      * <p>If overridden you must ensure the superclass method is invoked (usually as the first thing
62      * in the overridden method).
63      */
onRegister(Object key)64     protected void onRegister(Object key) {}
65 
66     /**
67      * May be overridden by subclasses. Invoked when unregistration occurs. Invoked while holding
68      * the owning multiplexer's internal lock.
69      *
70      * <p>If overridden you must ensure the superclass method is invoked (usually as the last thing
71      * in the overridden method).
72      */
onUnregister()73     protected void onUnregister() {}
74 
75     /**
76      * May be overridden by subclasses. Invoked when this registration becomes active. Invoked while
77      * holding the owning multiplexer's internal lock.
78      *
79      * <p>If overridden you must ensure the superclass method is invoked (usually as the first thing
80      * in the overridden method).
81      */
onActive()82     protected void onActive() {}
83 
84     /**
85      * May be overridden by subclasses. Invoked when registration becomes inactive. Invoked while
86      * holding the owning multiplexer's internal lock.
87      *
88      * <p>If overridden you must ensure the superclass method is invoked (usually as the last thing
89      * in the overridden method).
90      */
onInactive()91     protected void onInactive() {}
92 
isActive()93     public final boolean isActive() {
94         return mActive;
95     }
96 
setActive(boolean active)97     final boolean setActive(boolean active) {
98         if (active != mActive) {
99             mActive = active;
100             return true;
101         }
102 
103         return false;
104     }
105 
isRegistered()106     public final boolean isRegistered() {
107         return mListener != null;
108     }
109 
unregisterInternal()110     final void unregisterInternal() {
111         mListener = null;
112         onListenerUnregister();
113     }
114 
115     /**
116      * May be overridden by subclasses, however should rarely be needed. Invoked when the listener
117      * associated with this registration is unregistered, which may occur before the registration
118      * itself is unregistered. This immediately prevents the listener from being further invoked
119      * until the registration itself can be finalized and unregistered completely.
120      */
onListenerUnregister()121     protected void onListenerUnregister() {}
122 
123     /**
124      * May be overridden by subclasses to handle listener operation failures. The default behavior
125      * is to further propagate any exceptions. Will always be invoked on the executor thread.
126      */
onOperationFailure(ListenerOperation<TListener> operation, Exception exception)127     protected void onOperationFailure(ListenerOperation<TListener> operation, Exception exception) {
128         throw new AssertionError(exception);
129     }
130 
131     /**
132      * Executes the given listener operation, invoking
133      * {@link #onOperationFailure(ListenerOperation, Exception)} in case the listener operation
134      * fails.
135      */
executeOperation(@ullable ListenerOperation<TListener> operation)136     protected final void executeOperation(@Nullable ListenerOperation<TListener> operation) {
137         executeSafely(mExecutor, () -> mListener, operation, this::onOperationFailure);
138     }
139 
140     @Override
toString()141     public String toString() {
142         return "[]";
143     }
144 
145     @Override
equals(Object obj)146     public final boolean equals(Object obj) {
147         // intentionally bound to reference equality so removal works as expected
148         return this == obj;
149     }
150 
151     @Override
hashCode()152     public final int hashCode() {
153         return super.hashCode();
154     }
155 }
156 
157