1/* 2 * Copyright (C) 2006 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 17package com.android.internal.telephony.mocks; 18 19import android.net.LinkProperties; 20import android.net.NetworkCapabilities; 21import android.os.Bundle; 22import android.os.IBinder; 23import android.os.RemoteException; 24import android.os.UserHandle; 25import android.telephony.CellInfo; 26import android.telephony.ServiceState; 27import android.telephony.SignalStrength; 28import android.telephony.SubscriptionManager; 29import android.telephony.VoLteServiceState; 30import com.android.internal.telephony.IPhoneStateListener; 31import com.android.internal.telephony.IOnSubscriptionsChangedListener; 32import com.android.internal.telephony.ITelephonyRegistry; 33 34import java.util.ArrayList; 35import java.util.List; 36 37public class TelephonyRegistryMock extends ITelephonyRegistry.Stub { 38 39 private static class Record { 40 String callingPackage; 41 42 IBinder binder; 43 44 IPhoneStateListener callback; 45 IOnSubscriptionsChangedListener onSubscriptionsChangedListenerCallback; 46 47 int callerUserId; 48 49 int events; 50 51 int subId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; 52 53 int phoneId = SubscriptionManager.INVALID_PHONE_INDEX; 54 55 boolean canReadPhoneState; 56 57 boolean matchPhoneStateListenerEvent(int events) { 58 return (callback != null) && ((events & this.events) != 0); 59 } 60 61 boolean matchOnSubscriptionsChangedListener() { 62 return (onSubscriptionsChangedListenerCallback != null); 63 } 64 65 @Override 66 public String toString() { 67 return "{callingPackage=" + callingPackage + " binder=" + binder 68 + " callback=" + callback 69 + " onSubscriptionsChangedListenererCallback=" 70 + onSubscriptionsChangedListenerCallback 71 + " callerUserId=" + callerUserId + " subId=" + subId + " phoneId=" + phoneId 72 + " events=" + Integer.toHexString(events) 73 + " canReadPhoneState=" + canReadPhoneState + "}"; 74 } 75 } 76 77 private final ArrayList<IBinder> mRemoveList = new ArrayList<IBinder>(); 78 private final ArrayList<Record> mRecords = new ArrayList<Record>(); 79 private boolean hasNotifySubscriptionInfoChangedOccurred = false; 80 81 public TelephonyRegistryMock() { 82 } 83 84 private void remove(IBinder binder) { 85 synchronized (mRecords) { 86 final int recordCount = mRecords.size(); 87 for (int i = 0; i < recordCount; i++) { 88 if (mRecords.get(i).binder == binder) { 89 mRecords.remove(i); 90 return; 91 } 92 } 93 } 94 } 95 96 private void handleRemoveListLocked() { 97 int size = mRemoveList.size(); 98 if (size > 0) { 99 for (IBinder b: mRemoveList) { 100 remove(b); 101 } 102 mRemoveList.clear(); 103 } 104 } 105 106 107 @Override 108 public void addOnSubscriptionsChangedListener(String callingPackage, 109 IOnSubscriptionsChangedListener callback) { 110 Record r; 111 112 synchronized (mRecords) { 113 // register 114 find_and_add: { 115 IBinder b = callback.asBinder(); 116 final int N = mRecords.size(); 117 for (int i = 0; i < N; i++) { 118 r = mRecords.get(i); 119 if (b == r.binder) { 120 break find_and_add; 121 } 122 } 123 r = new Record(); 124 r.binder = b; 125 mRecords.add(r); 126 } 127 128 r.onSubscriptionsChangedListenerCallback = callback; 129 r.callingPackage = callingPackage; 130 r.callerUserId = UserHandle.getCallingUserId(); 131 r.events = 0; 132 r.canReadPhoneState = true; // permission has been enforced above 133 // Always notify when registration occurs if there has been a notification. 134 if (hasNotifySubscriptionInfoChangedOccurred) { 135 try { 136 r.onSubscriptionsChangedListenerCallback.onSubscriptionsChanged(); 137 } catch (RemoteException e) { 138 remove(r.binder); 139 } 140 } else { 141 //log("listen oscl: hasNotifySubscriptionInfoChangedOccurred==false no callback"); 142 } 143 } 144 145 } 146 147 @Override 148 public void removeOnSubscriptionsChangedListener(String pkgForDebug, 149 IOnSubscriptionsChangedListener callback) { 150 remove(callback.asBinder()); 151 } 152 153 @Override 154 public void notifySubscriptionInfoChanged() { 155 synchronized (mRecords) { 156 if (!hasNotifySubscriptionInfoChangedOccurred) { 157 //log("notifySubscriptionInfoChanged: first invocation mRecords.size=" 158 // + mRecords.size()); 159 } 160 hasNotifySubscriptionInfoChangedOccurred = true; 161 mRemoveList.clear(); 162 for (Record r : mRecords) { 163 if (r.matchOnSubscriptionsChangedListener()) { 164 try { 165 r.onSubscriptionsChangedListenerCallback.onSubscriptionsChanged(); 166 } catch (RemoteException ex) { 167 mRemoveList.add(r.binder); 168 } 169 } 170 } 171 handleRemoveListLocked(); 172 } 173 } 174 175 @Override 176 public void listen(String pkg, IPhoneStateListener callback, int events, boolean notifyNow) { 177 throw new RuntimeException("Not implemented"); 178 } 179 180 @Override 181 public void listenForSubscriber(int subId, String pkg, IPhoneStateListener callback, int events, 182 boolean notifyNow) { 183 throw new RuntimeException("Not implemented"); 184 } 185 186 @Override 187 public void notifyCallState(int state, String incomingNumber) { 188 throw new RuntimeException("Not implemented"); 189 } 190 191 @Override 192 public void notifyCallStateForPhoneId(int phoneId, int subId, int state, 193 String incomingNumber) { 194 throw new RuntimeException("Not implemented"); 195 } 196 197 @Override 198 public void notifyServiceStateForPhoneId(int phoneId, int subId, ServiceState state) { 199 throw new RuntimeException("Not implemented"); 200 } 201 202 @Override 203 public void notifySignalStrengthForPhoneId(int phoneId, int subId, 204 SignalStrength signalStrength) { 205 throw new RuntimeException("Not implemented"); 206 } 207 208 @Override 209 public void notifyMessageWaitingChangedForPhoneId(int phoneId, int subId, boolean mwi) { 210 throw new RuntimeException("Not implemented"); 211 } 212 213 @Override 214 public void notifyCallForwardingChanged(boolean cfi) { 215 throw new RuntimeException("Not implemented"); 216 } 217 218 @Override 219 public void notifyCallForwardingChangedForSubscriber(int subId, boolean cfi) { 220 throw new RuntimeException("Not implemented"); 221 } 222 223 @Override 224 public void notifyDataActivity(int state) { 225 throw new RuntimeException("Not implemented"); 226 } 227 228 @Override 229 public void notifyDataActivityForSubscriber(int subId, int state) { 230 throw new RuntimeException("Not implemented"); 231 } 232 233 @Override 234 public void notifyDataConnection(int state, boolean isDataConnectivityPossible, 235 String reason, String apn, String apnType, LinkProperties linkProperties, 236 NetworkCapabilities networkCapabilities, int networkType, boolean roaming) { 237 throw new RuntimeException("Not implemented"); 238 } 239 240 @Override 241 public void notifyDataConnectionForSubscriber(int subId, int state, 242 boolean isDataConnectivityPossible, String reason, String apn, String apnType, 243 LinkProperties linkProperties, NetworkCapabilities networkCapabilities, 244 int networkType, boolean roaming) { 245 throw new RuntimeException("Not implemented"); 246 } 247 248 @Override 249 public void notifyDataConnectionFailed(String reason, String apnType) { 250 throw new RuntimeException("Not implemented"); 251 } 252 253 @Override 254 public void notifyDataConnectionFailedForSubscriber(int subId, String reason, String apnType) { 255 throw new RuntimeException("Not implemented"); 256 } 257 258 @Override 259 public void notifyCellLocation(Bundle cellLocation) { 260 throw new RuntimeException("Not implemented"); 261 } 262 263 @Override 264 public void notifyCellLocationForSubscriber(int subId, Bundle cellLocation) { 265 throw new RuntimeException("Not implemented"); 266 } 267 268 @Override 269 public void notifyOtaspChanged(int otaspMode) { 270 throw new RuntimeException("Not implemented"); 271 } 272 273 @Override 274 public void notifyCellInfo(List<CellInfo> cellInfo) { 275 throw new RuntimeException("Not implemented"); 276 } 277 278 @Override 279 public void notifyPreciseCallState(int ringingCallState, int foregroundCallState, 280 int backgroundCallState) { 281 throw new RuntimeException("Not implemented"); 282 } 283 284 @Override 285 public void notifyDisconnectCause(int disconnectCause, int preciseDisconnectCause) { 286 throw new RuntimeException("Not implemented"); 287 } 288 289 @Override 290 public void notifyPreciseDataConnectionFailed(String reason, String apnType, String apn, 291 String failCause) { 292 throw new RuntimeException("Not implemented"); 293 } 294 295 @Override 296 public void notifyCellInfoForSubscriber(int subId, List<CellInfo> cellInfo) { 297 throw new RuntimeException("Not implemented"); 298 } 299 300 @Override 301 public void notifyVoLteServiceStateChanged(VoLteServiceState lteState) { 302 throw new RuntimeException("Not implemented"); 303 } 304 305 @Override 306 public void notifyOemHookRawEventForSubscriber(int subId, byte[] rawData) { 307 throw new RuntimeException("Not implemented"); 308 } 309 310 @Override 311 public void notifyCarrierNetworkChange(boolean active) { 312 throw new RuntimeException("Not implemented"); 313 } 314 315 @Override 316 public void notifySimActivationStateChangedForPhoneId(int phoneId, int subId, 317 int activationType, int state) { 318 throw new RuntimeException("Not implemented"); 319 } 320} 321