1 /* 2 * Copyright (C) 2022 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 android.telephony.ims; 18 19 import android.annotation.CallbackExecutor; 20 import android.annotation.NonNull; 21 import android.annotation.SystemApi; 22 import android.os.Binder; 23 24 import com.android.internal.telephony.ISipDialogStateCallback; 25 26 import java.lang.ref.WeakReference; 27 import java.util.List; 28 import java.util.concurrent.Executor; 29 30 /** 31 * This callback is used to notify listeners of SIP Dialog state changes. 32 * @hide 33 */ 34 @SystemApi 35 public abstract class SipDialogStateCallback { 36 37 private CallbackBinder mCallback; 38 /** 39 * @hide 40 */ attachExecutor(@onNull @allbackExecutor Executor executor)41 public void attachExecutor(@NonNull @CallbackExecutor Executor executor) { 42 if (executor == null) { 43 throw new IllegalArgumentException("SipDialogStateCallback Executor must be non-null"); 44 } 45 mCallback = new CallbackBinder(this, executor); 46 } 47 48 private static class CallbackBinder extends ISipDialogStateCallback.Stub { 49 private WeakReference<SipDialogStateCallback> mSipDialogStateCallbackWeakRef; 50 private Executor mExecutor; 51 CallbackBinder(SipDialogStateCallback callback, Executor executor)52 private CallbackBinder(SipDialogStateCallback callback, Executor executor) { 53 mSipDialogStateCallbackWeakRef = new WeakReference<SipDialogStateCallback>(callback); 54 mExecutor = executor; 55 } 56 getExecutor()57 Executor getExecutor() { 58 return mExecutor; 59 } 60 61 @Override onActiveSipDialogsChanged(List<SipDialogState> dialogs)62 public void onActiveSipDialogsChanged(List<SipDialogState> dialogs) { 63 SipDialogStateCallback callback = mSipDialogStateCallbackWeakRef.get(); 64 if (callback == null || dialogs == null) return; 65 66 Binder.withCleanCallingIdentity( 67 () -> mExecutor.execute(() -> callback.onActiveSipDialogsChanged(dialogs))); 68 } 69 } 70 71 /** 72 * The state of one or more SIP dialogs has changed. 73 * 74 * @param dialogs A List of SipDialogState objects representing the state of the active 75 * SIP Dialogs. 76 */ onActiveSipDialogsChanged(@onNull List<SipDialogState> dialogs)77 public abstract void onActiveSipDialogsChanged(@NonNull List<SipDialogState> dialogs); 78 79 /** 80 * An unexpected error has occurred and the Telephony process has crashed. This 81 * has caused this callback to be deregistered. The callback must be re-registered 82 * in order to continue listening to the IMS service state. 83 */ onError()84 public abstract void onError(); 85 86 /** 87 * The callback to notify the death of telephony process 88 * @hide 89 */ binderDied()90 public final void binderDied() { 91 if (mCallback != null) { 92 mCallback.getExecutor().execute(() -> onError()); 93 } 94 } 95 96 /** 97 * Return the callback binder 98 * @hide 99 */ getCallbackBinder()100 public CallbackBinder getCallbackBinder() { 101 return mCallback; 102 } 103 } 104