• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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.thread;
18 
19 import static android.net.thread.ThreadNetworkException.ERROR_INTERNAL_ERROR;
20 import static android.net.thread.ThreadNetworkException.ERROR_UNAVAILABLE;
21 
22 import android.net.thread.ActiveOperationalDataset;
23 import android.net.thread.IActiveOperationalDatasetReceiver;
24 import android.net.thread.ThreadNetworkException;
25 import android.os.RemoteException;
26 
27 import com.android.internal.annotations.GuardedBy;
28 
29 import java.util.HashSet;
30 import java.util.Set;
31 
32 /**
33  * A {@link IActiveOperationalDatasetReceiver} wrapper which makes it easier to invoke the
34  * callbacks.
35  */
36 final class ActiveOperationalDatasetReceiverWrapper {
37     private final IActiveOperationalDatasetReceiver mReceiver;
38 
39     private static final Object sPendingReceiversLock = new Object();
40 
41     @GuardedBy("sPendingReceiversLock")
42     private static final Set<ActiveOperationalDatasetReceiverWrapper> sPendingReceivers =
43             new HashSet<>();
44 
ActiveOperationalDatasetReceiverWrapper(IActiveOperationalDatasetReceiver receiver)45     public ActiveOperationalDatasetReceiverWrapper(IActiveOperationalDatasetReceiver receiver) {
46         this.mReceiver = receiver;
47 
48         synchronized (sPendingReceiversLock) {
49             sPendingReceivers.add(this);
50         }
51     }
52 
onOtDaemonDied()53     public static void onOtDaemonDied() {
54         synchronized (sPendingReceiversLock) {
55             for (ActiveOperationalDatasetReceiverWrapper receiver : sPendingReceivers) {
56                 try {
57                     receiver.mReceiver.onError(ERROR_UNAVAILABLE, "Thread daemon died");
58                 } catch (RemoteException e) {
59                     // The client is dead, do nothing
60                 }
61             }
62             sPendingReceivers.clear();
63         }
64     }
65 
onSuccess(ActiveOperationalDataset dataset)66     public void onSuccess(ActiveOperationalDataset dataset) {
67         synchronized (sPendingReceiversLock) {
68             sPendingReceivers.remove(this);
69         }
70 
71         try {
72             mReceiver.onSuccess(dataset);
73         } catch (RemoteException e) {
74             // The client is dead, do nothing
75         }
76     }
77 
onError(Throwable e)78     public void onError(Throwable e) {
79         if (e instanceof ThreadNetworkException) {
80             ThreadNetworkException threadException = (ThreadNetworkException) e;
81             onError(threadException.getErrorCode(), threadException.getMessage());
82         } else if (e instanceof RemoteException) {
83             onError(ERROR_INTERNAL_ERROR, "Thread stack error");
84         } else {
85             throw new AssertionError(e);
86         }
87     }
88 
onError(int errorCode, String errorMessage)89     public void onError(int errorCode, String errorMessage) {
90         synchronized (sPendingReceiversLock) {
91             sPendingReceivers.remove(this);
92         }
93 
94         try {
95             mReceiver.onError(errorCode, errorMessage);
96         } catch (RemoteException e) {
97             // The client is dead, do nothing
98         }
99     }
100 }
101