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 package android.net.wifi;
17 
18 import android.net.wifi.twt.TwtSession;
19 import android.os.Binder;
20 import android.os.Bundle;
21 import android.util.CloseGuard;
22 import android.util.Log;
23 
24 import java.lang.ref.Reference;
25 import java.lang.ref.WeakReference;
26 import java.util.concurrent.Executor;
27 import java.util.function.Consumer;
28 
29 /**
30  * Implementation of the interface {@link TwtSession}
31  *
32  * @hide
33  */
34 public class WifiTwtSession implements TwtSession {
35     private static final String TAG = "WifiTwtSession";
36     public static final int MAX_TWT_SESSIONS = 8;
37     private final int mWakeDurationMicros;
38     private final long mWakeIntervalMicros;
39     private final int mMloLinkId;
40     private final int mOwner;
41     private final int mSessionId;
42     private final WeakReference<WifiManager> mMgr;
43     private final CloseGuard mCloseGuard = new CloseGuard();
44 
45     @Override
getWakeDurationMicros()46     public int getWakeDurationMicros() {
47         return mWakeDurationMicros;
48     }
49 
50     @Override
getWakeIntervalMicros()51     public long getWakeIntervalMicros() {
52         return mWakeIntervalMicros;
53     }
54 
55     @Override
getMloLinkId()56     public int getMloLinkId() {
57         return mMloLinkId;
58     }
59 
getOwner()60     public int getOwner() {
61         return mOwner;
62     }
63 
getSessionId()64     public int getSessionId() {
65         return mSessionId;
66     }
67 
68     @Override
getStats(Executor executor, Consumer<Bundle> resultCallback)69     public void getStats(Executor executor, Consumer<Bundle> resultCallback) {
70         WifiManager mgr = mMgr.get();
71         if (mgr == null) {
72             Log.e(TAG, "getStats: called post garbage collection");
73             return;
74         }
75         if (Binder.getCallingUid() != mOwner) {
76             throw new SecurityException("TWT session is not owned by the caller");
77         }
78         mgr.getStatsTwtSession(mSessionId, executor, resultCallback);
79     }
80 
WifiTwtSession(WifiManager wifiManager, int wakeDurationMicros, long wakeIntervalMicros, int mloLinkId, int owner, int sessionId)81     public WifiTwtSession(WifiManager wifiManager, int wakeDurationMicros, long wakeIntervalMicros,
82             int mloLinkId, int owner, int sessionId) {
83         mMgr = new WeakReference<>(wifiManager);
84         mWakeDurationMicros = wakeDurationMicros;
85         mWakeIntervalMicros = wakeIntervalMicros;
86         mMloLinkId = mloLinkId;
87         mOwner = owner;
88         mSessionId = sessionId;
89         mCloseGuard.open("teardown");
90     }
91 
92     @Override
teardown()93     public void teardown() {
94         try {
95             WifiManager mgr = mMgr.get();
96             if (mgr == null) {
97                 Log.w(TAG, "close: called post garbage collection");
98                 return;
99             }
100             mgr.teardownTwtSession(mSessionId);
101             mMgr.clear();
102             mCloseGuard.close();
103         } finally {
104             Reference.reachabilityFence(this);
105         }
106     }
107 }
108