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.connectivity; 18 19 import static android.net.QosCallbackException.EX_TYPE_FILTER_NONE; 20 21 import android.annotation.NonNull; 22 import android.net.IQosCallback; 23 import android.net.Network; 24 import android.net.QosCallbackException; 25 import android.net.QosFilter; 26 import android.net.QosSession; 27 import android.os.IBinder; 28 import android.os.RemoteException; 29 import android.telephony.data.EpsBearerQosSessionAttributes; 30 import android.telephony.data.NrQosSessionAttributes; 31 import android.util.Log; 32 33 import java.util.Objects; 34 35 /** 36 * Wraps callback related information and sends messages between network agent and the application. 37 * <p/> 38 * This is a satellite class of {@link com.android.server.ConnectivityService} and not meant 39 * to be used in other contexts. 40 * 41 * @hide 42 */ 43 class QosCallbackAgentConnection implements IBinder.DeathRecipient { 44 private static final String TAG = QosCallbackAgentConnection.class.getSimpleName(); 45 private static final boolean DBG = false; 46 47 private final int mAgentCallbackId; 48 @NonNull private final QosCallbackTracker mQosCallbackTracker; 49 @NonNull private final IQosCallback mCallback; 50 @NonNull private final IBinder mBinder; 51 @NonNull private final QosFilter mFilter; 52 @NonNull private final NetworkAgentInfo mNetworkAgentInfo; 53 54 private final int mUid; 55 56 /** 57 * Gets the uid 58 * @return uid 59 */ 60 int getUid() { 61 return mUid; 62 } 63 64 /** 65 * Gets the binder 66 * @return binder 67 */ 68 @NonNull 69 IBinder getBinder() { 70 return mBinder; 71 } 72 73 /** 74 * Gets the callback id 75 * 76 * @return callback id 77 */ 78 int getAgentCallbackId() { 79 return mAgentCallbackId; 80 } 81 82 /** 83 * Gets the network tied to the callback of this connection 84 * 85 * @return network 86 */ 87 @NonNull 88 Network getNetwork() { 89 return mFilter.getNetwork(); 90 } 91 92 QosCallbackAgentConnection(@NonNull final QosCallbackTracker qosCallbackTracker, 93 final int agentCallbackId, 94 @NonNull final IQosCallback callback, 95 @NonNull final QosFilter filter, 96 final int uid, 97 @NonNull final NetworkAgentInfo networkAgentInfo) { 98 Objects.requireNonNull(qosCallbackTracker, "qosCallbackTracker must be non-null"); 99 Objects.requireNonNull(callback, "callback must be non-null"); 100 Objects.requireNonNull(filter, "filter must be non-null"); 101 Objects.requireNonNull(networkAgentInfo, "networkAgentInfo must be non-null"); 102 103 mQosCallbackTracker = qosCallbackTracker; 104 mAgentCallbackId = agentCallbackId; 105 mCallback = callback; 106 mFilter = filter; 107 mUid = uid; 108 mBinder = mCallback.asBinder(); 109 mNetworkAgentInfo = networkAgentInfo; 110 } 111 112 @Override 113 public void binderDied() { 114 logw("binderDied: binder died with callback id: " + mAgentCallbackId); 115 mQosCallbackTracker.unregisterCallback(mCallback); 116 } 117 118 void unlinkToDeathRecipient() { 119 mBinder.unlinkToDeath(this, 0); 120 } 121 122 // Returns false if the NetworkAgent was never notified. 123 boolean sendCmdRegisterCallback() { 124 final int exceptionType = mFilter.validate(); 125 if (exceptionType != EX_TYPE_FILTER_NONE) { 126 try { 127 if (DBG) log("sendCmdRegisterCallback: filter validation failed"); 128 mCallback.onError(exceptionType); 129 } catch (final RemoteException e) { 130 loge("sendCmdRegisterCallback:", e); 131 } 132 return false; 133 } 134 135 try { 136 mBinder.linkToDeath(this, 0); 137 } catch (final RemoteException e) { 138 loge("failed linking to death recipient", e); 139 return false; 140 } 141 mNetworkAgentInfo.onQosFilterCallbackRegistered(mAgentCallbackId, mFilter); 142 return true; 143 } 144 145 void sendCmdUnregisterCallback() { 146 if (DBG) log("sendCmdUnregisterCallback: unregistering"); 147 mNetworkAgentInfo.onQosCallbackUnregistered(mAgentCallbackId); 148 } 149 150 void sendEventEpsQosSessionAvailable(final QosSession session, 151 final EpsBearerQosSessionAttributes attributes) { 152 try { 153 if (DBG) log("sendEventEpsQosSessionAvailable: sending..."); 154 mCallback.onQosEpsBearerSessionAvailable(session, attributes); 155 } catch (final RemoteException e) { 156 loge("sendEventEpsQosSessionAvailable: remote exception", e); 157 } 158 } 159 160 void sendEventNrQosSessionAvailable(final QosSession session, 161 final NrQosSessionAttributes attributes) { 162 try { 163 if (DBG) log("sendEventNrQosSessionAvailable: sending..."); 164 mCallback.onNrQosSessionAvailable(session, attributes); 165 } catch (final RemoteException e) { 166 loge("sendEventNrQosSessionAvailable: remote exception", e); 167 } 168 } 169 170 void sendEventQosSessionLost(@NonNull final QosSession session) { 171 try { 172 if (DBG) log("sendEventQosSessionLost: sending..."); 173 mCallback.onQosSessionLost(session); 174 } catch (final RemoteException e) { 175 loge("sendEventQosSessionLost: remote exception", e); 176 } 177 } 178 179 void sendEventQosCallbackError(@QosCallbackException.ExceptionType final int exceptionType) { 180 try { 181 if (DBG) log("sendEventQosCallbackError: sending..."); 182 mCallback.onError(exceptionType); 183 } catch (final RemoteException e) { 184 loge("sendEventQosCallbackError: remote exception", e); 185 } 186 } 187 188 private static void log(@NonNull final String msg) { 189 Log.d(TAG, msg); 190 } 191 192 private static void logw(@NonNull final String msg) { 193 Log.w(TAG, msg); 194 } 195 196 private static void loge(@NonNull final String msg, final Throwable t) { 197 Log.e(TAG, msg, t); 198 } 199 } 200