• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.internal.telephony;
18 
19 import android.annotation.NonNull;
20 import android.os.Handler;
21 import android.os.Registrant;
22 import android.os.RegistrantList;
23 import android.telephony.AccessNetworkConstants;
24 import android.telephony.AnomalyReporter;
25 import android.telephony.NetworkRegistrationInfo;
26 import android.telephony.TelephonyDisplayInfo;
27 import android.telephony.TelephonyManager;
28 import android.util.IndentingPrintWriter;
29 import android.util.LocalLog;
30 import android.util.Pair;
31 
32 import com.android.telephony.Rlog;
33 
34 import java.io.FileDescriptor;
35 import java.io.PrintWriter;
36 import java.util.Set;
37 import java.util.UUID;
38 
39 import javax.sip.InvalidArgumentException;
40 
41 /**
42  * The DisplayInfoController updates and broadcasts all changes to {@link TelephonyDisplayInfo}.
43  * It manages all the information necessary for display purposes. Clients can register for display
44  * info changes via {@link #registerForTelephonyDisplayInfoChanged} and obtain the current
45  * TelephonyDisplayInfo via {@link #getTelephonyDisplayInfo}.
46  */
47 public class DisplayInfoController extends Handler {
48     private static final String TAG = "DisplayInfoController";
49 
50     private final String mLogTag;
51     private final LocalLog mLocalLog = new LocalLog(128);
52 
53     private static final Set<Pair<Integer, Integer>> VALID_DISPLAY_INFO_SET = Set.of(
54             // LTE
55             Pair.create(TelephonyManager.NETWORK_TYPE_LTE,
56                     TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_CA),
57             Pair.create(TelephonyManager.NETWORK_TYPE_LTE,
58                     TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_ADVANCED_PRO),
59             Pair.create(TelephonyManager.NETWORK_TYPE_LTE,
60                     TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_NSA),
61             Pair.create(TelephonyManager.NETWORK_TYPE_LTE,
62                     TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED),
63 
64             // NR
65             Pair.create(TelephonyManager.NETWORK_TYPE_NR,
66                     TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NR_ADVANCED)
67             );
68 
69     private final Phone mPhone;
70     private final NetworkTypeController mNetworkTypeController;
71     private final RegistrantList mTelephonyDisplayInfoChangedRegistrants = new RegistrantList();
72     private TelephonyDisplayInfo mTelephonyDisplayInfo;
73 
DisplayInfoController(Phone phone)74     public DisplayInfoController(Phone phone) {
75         mPhone = phone;
76         mLogTag = "DIC-" + mPhone.getPhoneId();
77         mNetworkTypeController = new NetworkTypeController(phone, this);
78         mNetworkTypeController.sendMessage(NetworkTypeController.EVENT_UPDATE);
79     }
80 
81     /**
82      * @return the current TelephonyDisplayInfo
83      */
getTelephonyDisplayInfo()84     public TelephonyDisplayInfo getTelephonyDisplayInfo() {
85         return mTelephonyDisplayInfo;
86     }
87 
88     /**
89      * Update TelephonyDisplayInfo based on network type and override network type, received from
90      * NetworkTypeController.
91      */
updateTelephonyDisplayInfo()92     public void updateTelephonyDisplayInfo() {
93         NetworkRegistrationInfo nri =  mPhone.getServiceState().getNetworkRegistrationInfo(
94                 NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
95         int dataNetworkType = nri == null ? TelephonyManager.NETWORK_TYPE_UNKNOWN
96                 : nri.getAccessNetworkTechnology();
97         TelephonyDisplayInfo newDisplayInfo = new TelephonyDisplayInfo(dataNetworkType,
98                 mNetworkTypeController.getOverrideNetworkType());
99         if (!newDisplayInfo.equals(mTelephonyDisplayInfo)) {
100             logl("TelephonyDisplayInfo changed from " + mTelephonyDisplayInfo + " to "
101                     + newDisplayInfo);
102             validateDisplayInfo(newDisplayInfo);
103             mTelephonyDisplayInfo = newDisplayInfo;
104             mTelephonyDisplayInfoChangedRegistrants.notifyRegistrants();
105             mPhone.notifyDisplayInfoChanged(mTelephonyDisplayInfo);
106         }
107     }
108 
109     /**
110      * Validate the display info and trigger anomaly report if needed.
111      *
112      * @param displayInfo The display info to validate.
113      */
validateDisplayInfo(@onNull TelephonyDisplayInfo displayInfo)114     private void validateDisplayInfo(@NonNull TelephonyDisplayInfo displayInfo) {
115         try {
116             if (displayInfo.getNetworkType() == TelephonyManager.NETWORK_TYPE_LTE_CA) {
117                 throw new InvalidArgumentException("LTE_CA is not a valid network type.");
118             }
119             if (displayInfo.getNetworkType() < TelephonyManager.NETWORK_TYPE_UNKNOWN
120                     && displayInfo.getNetworkType() > TelephonyManager.NETWORK_TYPE_NR) {
121                 throw new InvalidArgumentException("Invalid network type "
122                         + displayInfo.getNetworkType());
123             }
124             if (displayInfo.getOverrideNetworkType()
125                     != TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE
126                     && !VALID_DISPLAY_INFO_SET.contains(Pair.create(displayInfo.getNetworkType(),
127                     displayInfo.getOverrideNetworkType()))) {
128                 throw new InvalidArgumentException("Invalid network type override "
129                         + TelephonyDisplayInfo.overrideNetworkTypeToString(
130                                 displayInfo.getOverrideNetworkType())
131                         + " for " + TelephonyManager.getNetworkTypeName(
132                                 displayInfo.getNetworkType()));
133             }
134         } catch (InvalidArgumentException e) {
135             logel(e.getMessage());
136             AnomalyReporter.reportAnomaly(UUID.fromString("3aa92a2c-94ed-46a0-a744-d6b1dfec2a55"),
137                     e.getMessage(), mPhone.getCarrierId());
138         }
139     }
140 
141     /**
142      * Register for TelephonyDisplayInfo changed.
143      * @param h Handler to notify
144      * @param what msg.what when the message is delivered
145      * @param obj msg.obj when the message is delivered
146      */
registerForTelephonyDisplayInfoChanged(Handler h, int what, Object obj)147     public void registerForTelephonyDisplayInfoChanged(Handler h, int what, Object obj) {
148         Registrant r = new Registrant(h, what, obj);
149         mTelephonyDisplayInfoChangedRegistrants.add(r);
150     }
151 
152     /**
153      * Unregister for TelephonyDisplayInfo changed.
154      * @param h Handler to notify
155      */
unregisterForTelephonyDisplayInfoChanged(Handler h)156     public void unregisterForTelephonyDisplayInfoChanged(Handler h) {
157         mTelephonyDisplayInfoChangedRegistrants.remove(h);
158     }
159 
160     /**
161      * Log debug messages.
162      * @param s debug messages
163      */
log(@onNull String s)164     private void log(@NonNull String s) {
165         Rlog.d(mLogTag, s);
166     }
167 
168     /**
169      * Log error messages.
170      * @param s error messages
171      */
loge(@onNull String s)172     private void loge(@NonNull String s) {
173         Rlog.e(mLogTag, s);
174     }
175 
176     /**
177      * Log debug messages and also log into the local log.
178      * @param s debug messages
179      */
logl(@onNull String s)180     private void logl(@NonNull String s) {
181         log(s);
182         mLocalLog.log(s);
183     }
184 
185     /**
186      * Log error messages and also log into the local log.
187      * @param s debug messages
188      */
logel(@onNull String s)189     private void logel(@NonNull String s) {
190         loge(s);
191         mLocalLog.log(s);
192     }
193 
194     /**
195      * Dump the current state.
196      */
dump(FileDescriptor fd, PrintWriter printWriter, String[] args)197     public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) {
198         IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, "  ");
199         pw.println("DisplayInfoController:");
200         pw.println(" mPhone=" + mPhone.getPhoneName());
201         pw.println(" mTelephonyDisplayInfo=" + mTelephonyDisplayInfo.toString());
202         pw.flush();
203         pw.println("Local logs:");
204         pw.increaseIndent();
205         mLocalLog.dump(fd, pw, args);
206         pw.decreaseIndent();
207         pw.println(" ***************************************");
208         mNetworkTypeController.dump(fd, pw, args);
209         pw.flush();
210     }
211 }
212