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 com.android.services.telephony.domainselection;
18 
19 import android.annotation.NonNull;
20 import android.content.Context;
21 import android.os.Handler;
22 import android.os.Looper;
23 import android.telephony.DomainSelectionService.SelectionAttributes;
24 import android.telephony.DomainSelector;
25 import android.telephony.TransportSelectorCallback;
26 import android.telephony.WwanSelectorCallback;
27 import android.util.IndentingPrintWriter;
28 import android.util.LocalLog;
29 import android.util.Log;
30 
31 import com.android.internal.annotations.Keep;
32 
33 import java.io.PrintWriter;
34 
35 /**
36  * An abstract base class to implement domain selector for a specific use case.
37  */
38 @Keep
39 public abstract class DomainSelectorBase extends Handler implements DomainSelector {
40     /**
41      * A listener used to inform the DomainSelectorService that this DomainSelector has been
42      * destroyed.
43      */
44     public interface DestroyListener {
45         /**
46          * Called when the specified domain selector is being destroyed.
47          * This MUST be called when this domain selector is no longer available after
48          * {@link DomainSelector#finishSelection} called.
49          */
onDomainSelectorDestroyed(DomainSelectorBase selector)50         void onDomainSelectorDestroyed(DomainSelectorBase selector);
51     }
52 
53     // Persistent Logging
54     protected final LocalLog mEventLog = new LocalLog(30);
55     protected final Context mContext;
56     protected final ImsStateTracker mImsStateTracker;
57     protected SelectionAttributes mSelectionAttributes;
58     protected TransportSelectorCallback mTransportSelectorCallback;
59     protected WwanSelectorCallback mWwanSelectorCallback;
60     private final int mSlotId;
61     private final int mSubId;
62     private final DestroyListener mDestroyListener;
63     private final String mLogTag;
64 
DomainSelectorBase(Context context, int slotId, int subId, @NonNull Looper looper, @NonNull ImsStateTracker imsStateTracker, @NonNull DestroyListener destroyListener, String logTag)65     public DomainSelectorBase(Context context, int slotId, int subId, @NonNull Looper looper,
66             @NonNull ImsStateTracker imsStateTracker, @NonNull DestroyListener destroyListener,
67             String logTag) {
68         super(looper);
69         mContext = context;
70         mImsStateTracker = imsStateTracker;
71         mSlotId = slotId;
72         mSubId = subId;
73         mDestroyListener = destroyListener;
74         mLogTag = logTag;
75     }
76 
77     /**
78      * Selects a domain for the specified attributes and callback.
79      *
80      * @param attr The attributes required to determine the domain.
81      * @param callback The callback called when the transport selection is completed.
82      */
selectDomain(SelectionAttributes attr, TransportSelectorCallback callback)83     public abstract void selectDomain(SelectionAttributes attr, TransportSelectorCallback callback);
84 
85     /**
86      * Destroys this domain selector.
87      */
destroy()88     protected void destroy() {
89         removeCallbacksAndMessages(null);
90         notifyDomainSelectorDestroyed();
91     }
92 
93     /**
94      * Notifies the application that this domain selector is being destroyed.
95      */
notifyDomainSelectorDestroyed()96     protected void notifyDomainSelectorDestroyed() {
97         if (mDestroyListener != null) {
98             mDestroyListener.onDomainSelectorDestroyed(this);
99         }
100     }
101 
102     /**
103      * Returns the slot index for this domain selector.
104      */
getSlotId()105     protected int getSlotId() {
106         return mSlotId;
107     }
108 
109     /**
110      * Returns the subscription index for this domain selector.
111      */
getSubId()112     protected int getSubId() {
113         return mSubId;
114     }
115 
116     /**
117      * Dumps this instance into a readable format for dumpsys usage.
118      */
dump(@onNull PrintWriter pw)119     protected void dump(@NonNull PrintWriter pw) {
120         IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "  ");
121         ipw.println(mLogTag + ":");
122         ipw.increaseIndent();
123         ipw.println("SlotId: " + getSlotId());
124         ipw.println("SubId: " + getSubId());
125         mEventLog.dump(ipw);
126         ipw.decreaseIndent();
127     }
128 
logd(String s)129     protected void logd(String s) {
130         Log.d(mLogTag, "[" + getSlotId() + "|" + getSubId() + "] " + s);
131     }
132 
logi(String s)133     protected void logi(String s) {
134         Log.i(mLogTag, "[" + getSlotId() + "|" + getSubId() + "] " + s);
135         mEventLog.log("[" + getSlotId() + "|" + getSubId() + "] " + s);
136     }
137 
loge(String s)138     protected void loge(String s) {
139         Log.e(mLogTag, "[" + getSlotId() + "|" + getSubId() + "] " + s);
140         mEventLog.log("[" + getSlotId() + "|" + getSubId() + "] " + s);
141     }
142 }
143