1149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar/*
2149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * Copyright (C) 2016 The Android Open Source Project
3149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar *
4149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * Licensed under the Apache License, Version 2.0 (the "License");
5149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * you may not use this file except in compliance with the License.
6149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * You may obtain a copy of the License at
7149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar *
8149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar *      http://www.apache.org/licenses/LICENSE-2.0
9149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar *
10149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * Unless required by applicable law or agreed to in writing, software
11149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * distributed under the License is distributed on an "AS IS" BASIS,
12149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * See the License for the specific language governing permissions and
14149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * limitations under the License.
15149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar */
16149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
17149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarpackage com.android.internal.telephony;
18149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
19149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarimport android.app.Notification;
20149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarimport android.app.NotificationManager;
21a092e4830ed77a5f158de5673944c395b475192fpkanwarimport android.app.PendingIntent;
22149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarimport android.content.BroadcastReceiver;
23149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarimport android.content.Context;
24149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarimport android.content.Intent;
25149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarimport android.content.IntentFilter;
26149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarimport android.os.Handler;
27149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarimport android.os.Message;
28149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarimport android.os.PersistableBundle;
29149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarimport android.provider.Settings;
30149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarimport android.telephony.CarrierConfigManager;
31149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarimport android.telephony.Rlog;
322cab3ec97219a25aa7dabfd48a98cddba79ceebapkanwarimport android.telephony.ServiceState;
33149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
34a092e4830ed77a5f158de5673944c395b475192fpkanwarimport com.android.internal.annotations.VisibleForTesting;
357c29cabeb38ae8cb4f5764c2dc0a768de22d2f92fionaxuimport com.android.internal.telephony.util.NotificationChannelController;
3613ff522d752715d856bd4068d39a769cd0d54a24fionaxu
37a092e4830ed77a5f158de5673944c395b475192fpkanwarimport java.util.HashMap;
38a092e4830ed77a5f158de5673944c395b475192fpkanwarimport java.util.Map;
39a092e4830ed77a5f158de5673944c395b475192fpkanwar
40a092e4830ed77a5f158de5673944c395b475192fpkanwar
41149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar/**
42149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * This contains Carrier specific logic based on the states/events
43149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * managed in ServiceStateTracker.
44149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * {@hide}
45149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar */
46149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarpublic class CarrierServiceStateTracker extends Handler {
47149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    private static final String LOG_TAG = "CSST";
48149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    protected static final int CARRIER_EVENT_BASE = 100;
49149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    protected static final int CARRIER_EVENT_VOICE_REGISTRATION = CARRIER_EVENT_BASE + 1;
50149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    protected static final int CARRIER_EVENT_VOICE_DEREGISTRATION = CARRIER_EVENT_BASE + 2;
51149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    protected static final int CARRIER_EVENT_DATA_REGISTRATION = CARRIER_EVENT_BASE + 3;
52149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    protected static final int CARRIER_EVENT_DATA_DEREGISTRATION = CARRIER_EVENT_BASE + 4;
53149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    private static final int UNINITIALIZED_DELAY_VALUE = -1;
54149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    private Phone mPhone;
55149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    private ServiceStateTracker mSST;
56149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
57a092e4830ed77a5f158de5673944c395b475192fpkanwar    public static final int NOTIFICATION_PREF_NETWORK = 1000;
58a092e4830ed77a5f158de5673944c395b475192fpkanwar    public static final int NOTIFICATION_EMERGENCY_NETWORK = 1001;
59a092e4830ed77a5f158de5673944c395b475192fpkanwar
60a092e4830ed77a5f158de5673944c395b475192fpkanwar    private final Map<Integer, NotificationType> mNotificationTypeMap = new HashMap<>();
61a092e4830ed77a5f158de5673944c395b475192fpkanwar
62149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    public CarrierServiceStateTracker(Phone phone, ServiceStateTracker sst) {
63149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        this.mPhone = phone;
64149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        this.mSST = sst;
65149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        phone.getContext().registerReceiver(mBroadcastReceiver, new IntentFilter(
66149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED));
67a092e4830ed77a5f158de5673944c395b475192fpkanwar        registerNotificationTypes();
68a092e4830ed77a5f158de5673944c395b475192fpkanwar    }
69a092e4830ed77a5f158de5673944c395b475192fpkanwar
70a092e4830ed77a5f158de5673944c395b475192fpkanwar    private void registerNotificationTypes() {
71a092e4830ed77a5f158de5673944c395b475192fpkanwar        mNotificationTypeMap.put(NOTIFICATION_PREF_NETWORK,
72a092e4830ed77a5f158de5673944c395b475192fpkanwar                new PrefNetworkNotification(NOTIFICATION_PREF_NETWORK));
73a092e4830ed77a5f158de5673944c395b475192fpkanwar        mNotificationTypeMap.put(NOTIFICATION_EMERGENCY_NETWORK,
74a092e4830ed77a5f158de5673944c395b475192fpkanwar                new EmergencyNetworkNotification(NOTIFICATION_EMERGENCY_NETWORK));
75149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    }
76149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
77149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    @Override
78149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    public void handleMessage(Message msg) {
79149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        switch (msg.what) {
80149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            case CARRIER_EVENT_VOICE_REGISTRATION:
81149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            case CARRIER_EVENT_DATA_REGISTRATION:
82149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            case CARRIER_EVENT_VOICE_DEREGISTRATION:
83149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            case CARRIER_EVENT_DATA_DEREGISTRATION:
84149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                handleConfigChanges();
85149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                break;
86a092e4830ed77a5f158de5673944c395b475192fpkanwar            case NOTIFICATION_EMERGENCY_NETWORK:
87a092e4830ed77a5f158de5673944c395b475192fpkanwar            case NOTIFICATION_PREF_NETWORK:
88a092e4830ed77a5f158de5673944c395b475192fpkanwar                Rlog.d(LOG_TAG, "sending notification after delay: " + msg.what);
89a092e4830ed77a5f158de5673944c395b475192fpkanwar                NotificationType notificationType = mNotificationTypeMap.get(msg.what);
90a092e4830ed77a5f158de5673944c395b475192fpkanwar                if (notificationType != null) {
91a092e4830ed77a5f158de5673944c395b475192fpkanwar                    sendNotification(notificationType);
92a092e4830ed77a5f158de5673944c395b475192fpkanwar                }
93149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                break;
94149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        }
95149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    }
96149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
972cab3ec97219a25aa7dabfd48a98cddba79ceebapkanwar    private boolean isPhoneStillRegistered() {
982cab3ec97219a25aa7dabfd48a98cddba79ceebapkanwar        if (mSST.mSS == null) {
992cab3ec97219a25aa7dabfd48a98cddba79ceebapkanwar            return true; //something has gone wrong, return true and not show the notification.
1002cab3ec97219a25aa7dabfd48a98cddba79ceebapkanwar        }
1012cab3ec97219a25aa7dabfd48a98cddba79ceebapkanwar        return (mSST.mSS.getVoiceRegState() == ServiceState.STATE_IN_SERVICE
1022cab3ec97219a25aa7dabfd48a98cddba79ceebapkanwar                || mSST.mSS.getDataRegState() == ServiceState.STATE_IN_SERVICE);
1032cab3ec97219a25aa7dabfd48a98cddba79ceebapkanwar    }
1042cab3ec97219a25aa7dabfd48a98cddba79ceebapkanwar
105a092e4830ed77a5f158de5673944c395b475192fpkanwar    private boolean isPhoneVoiceRegistered() {
106a092e4830ed77a5f158de5673944c395b475192fpkanwar        if (mSST.mSS == null) {
107a092e4830ed77a5f158de5673944c395b475192fpkanwar            return true; //something has gone wrong, return true and not show the notification.
108a092e4830ed77a5f158de5673944c395b475192fpkanwar        }
109a092e4830ed77a5f158de5673944c395b475192fpkanwar        return (mSST.mSS.getVoiceRegState() == ServiceState.STATE_IN_SERVICE);
110a092e4830ed77a5f158de5673944c395b475192fpkanwar    }
111a092e4830ed77a5f158de5673944c395b475192fpkanwar
112a092e4830ed77a5f158de5673944c395b475192fpkanwar    private boolean isPhoneRegisteredForWifiCalling() {
113a092e4830ed77a5f158de5673944c395b475192fpkanwar        Rlog.d(LOG_TAG, "isPhoneRegisteredForWifiCalling: " + mPhone.isWifiCallingEnabled());
114a092e4830ed77a5f158de5673944c395b475192fpkanwar        return mPhone.isWifiCallingEnabled();
115a092e4830ed77a5f158de5673944c395b475192fpkanwar    }
116a092e4830ed77a5f158de5673944c395b475192fpkanwar
117149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    /**
118a092e4830ed77a5f158de5673944c395b475192fpkanwar     * Returns true if the radio is off or in Airplane Mode else returns false.
119149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar     */
120a092e4830ed77a5f158de5673944c395b475192fpkanwar    @VisibleForTesting
121a092e4830ed77a5f158de5673944c395b475192fpkanwar    public boolean isRadioOffOrAirplaneMode() {
122149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        Context context = mPhone.getContext();
123149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        int airplaneMode = -1;
124149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        try {
125149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            airplaneMode = Settings.Global.getInt(context.getContentResolver(),
126149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                    Settings.Global.AIRPLANE_MODE_ON, 0);
127149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        } catch (Exception e) {
128a092e4830ed77a5f158de5673944c395b475192fpkanwar            Rlog.e(LOG_TAG, "Unable to get AIRPLACE_MODE_ON.");
129149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            return true;
130149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        }
131a092e4830ed77a5f158de5673944c395b475192fpkanwar        return (!mSST.isRadioOn() || (airplaneMode != 0));
132149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    }
133149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
134149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    /**
135a092e4830ed77a5f158de5673944c395b475192fpkanwar     * Returns true if the preferred network is set to 'Global'.
136149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar     */
137a092e4830ed77a5f158de5673944c395b475192fpkanwar    private boolean isGlobalMode() {
138a092e4830ed77a5f158de5673944c395b475192fpkanwar        Context context = mPhone.getContext();
139a092e4830ed77a5f158de5673944c395b475192fpkanwar        int preferredNetworkSetting = -1;
140a092e4830ed77a5f158de5673944c395b475192fpkanwar        try {
141a092e4830ed77a5f158de5673944c395b475192fpkanwar            preferredNetworkSetting =
142a092e4830ed77a5f158de5673944c395b475192fpkanwar                    android.provider.Settings.Global.getInt(context.getContentResolver(),
143a092e4830ed77a5f158de5673944c395b475192fpkanwar                            android.provider.Settings.Global.PREFERRED_NETWORK_MODE
144a092e4830ed77a5f158de5673944c395b475192fpkanwar                                    + mPhone.getSubId(), Phone.PREFERRED_NT_MODE);
145a092e4830ed77a5f158de5673944c395b475192fpkanwar        } catch (Exception e) {
146a092e4830ed77a5f158de5673944c395b475192fpkanwar            Rlog.e(LOG_TAG, "Unable to get PREFERRED_NETWORK_MODE.");
147a092e4830ed77a5f158de5673944c395b475192fpkanwar            return true;
148149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        }
149a092e4830ed77a5f158de5673944c395b475192fpkanwar        return (preferredNetworkSetting == RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA);
150a092e4830ed77a5f158de5673944c395b475192fpkanwar    }
151a092e4830ed77a5f158de5673944c395b475192fpkanwar
152a092e4830ed77a5f158de5673944c395b475192fpkanwar    private void handleConfigChanges() {
153a092e4830ed77a5f158de5673944c395b475192fpkanwar        for (Map.Entry<Integer, NotificationType> entry : mNotificationTypeMap.entrySet()) {
154a092e4830ed77a5f158de5673944c395b475192fpkanwar            NotificationType notificationType = entry.getValue();
155a092e4830ed77a5f158de5673944c395b475192fpkanwar            if (evaluateSendingMessage(notificationType)) {
156a092e4830ed77a5f158de5673944c395b475192fpkanwar                Message notificationMsg = obtainMessage(notificationType.getTypeId(), null);
157a092e4830ed77a5f158de5673944c395b475192fpkanwar                Rlog.i(LOG_TAG, "starting timer for notifications." + notificationType.getTypeId());
158a092e4830ed77a5f158de5673944c395b475192fpkanwar                sendMessageDelayed(notificationMsg, getDelay(notificationType));
159a092e4830ed77a5f158de5673944c395b475192fpkanwar            } else {
160a092e4830ed77a5f158de5673944c395b475192fpkanwar                cancelNotification(notificationType.getTypeId());
161a092e4830ed77a5f158de5673944c395b475192fpkanwar                Rlog.i(LOG_TAG, "canceling notifications: " + notificationType.getTypeId());
162a092e4830ed77a5f158de5673944c395b475192fpkanwar            }
163149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        }
164149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    }
165149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
166a092e4830ed77a5f158de5673944c395b475192fpkanwar    /**
167a092e4830ed77a5f158de5673944c395b475192fpkanwar     * This method adds a level of indirection, and was created so we can unit the class.
168a092e4830ed77a5f158de5673944c395b475192fpkanwar     **/
169a092e4830ed77a5f158de5673944c395b475192fpkanwar    @VisibleForTesting
170a092e4830ed77a5f158de5673944c395b475192fpkanwar    public boolean evaluateSendingMessage(NotificationType notificationType) {
171a092e4830ed77a5f158de5673944c395b475192fpkanwar        return notificationType.sendMessage();
172a092e4830ed77a5f158de5673944c395b475192fpkanwar    }
173a092e4830ed77a5f158de5673944c395b475192fpkanwar
174a092e4830ed77a5f158de5673944c395b475192fpkanwar    /**
175a092e4830ed77a5f158de5673944c395b475192fpkanwar     * This method adds a level of indirection, and was created so we can unit the class.
176a092e4830ed77a5f158de5673944c395b475192fpkanwar     **/
177a092e4830ed77a5f158de5673944c395b475192fpkanwar    @VisibleForTesting
178a092e4830ed77a5f158de5673944c395b475192fpkanwar    public int getDelay(NotificationType notificationType) {
179a092e4830ed77a5f158de5673944c395b475192fpkanwar        return notificationType.getDelay();
180a092e4830ed77a5f158de5673944c395b475192fpkanwar    }
181a092e4830ed77a5f158de5673944c395b475192fpkanwar
182a092e4830ed77a5f158de5673944c395b475192fpkanwar    /**
183a092e4830ed77a5f158de5673944c395b475192fpkanwar     * This method adds a level of indirection, and was created so we can unit the class.
184a092e4830ed77a5f158de5673944c395b475192fpkanwar     **/
185a092e4830ed77a5f158de5673944c395b475192fpkanwar    @VisibleForTesting
186a092e4830ed77a5f158de5673944c395b475192fpkanwar    public Notification.Builder getNotificationBuilder(NotificationType notificationType) {
187a092e4830ed77a5f158de5673944c395b475192fpkanwar        return notificationType.getNotificationBuilder();
188a092e4830ed77a5f158de5673944c395b475192fpkanwar    }
189a092e4830ed77a5f158de5673944c395b475192fpkanwar
190a092e4830ed77a5f158de5673944c395b475192fpkanwar    /**
191a092e4830ed77a5f158de5673944c395b475192fpkanwar     * This method adds a level of indirection, and was created so we can unit the class.
192a092e4830ed77a5f158de5673944c395b475192fpkanwar     **/
193a092e4830ed77a5f158de5673944c395b475192fpkanwar    @VisibleForTesting
194a092e4830ed77a5f158de5673944c395b475192fpkanwar    public NotificationManager getNotificationManager(Context context) {
195a092e4830ed77a5f158de5673944c395b475192fpkanwar        return (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
196a092e4830ed77a5f158de5673944c395b475192fpkanwar    }
197a092e4830ed77a5f158de5673944c395b475192fpkanwar
198149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
199149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        @Override
200149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        public void onReceive(Context context, Intent intent) {
201149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            CarrierConfigManager carrierConfigManager = (CarrierConfigManager)
202149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                    context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
203a092e4830ed77a5f158de5673944c395b475192fpkanwar            PersistableBundle b = carrierConfigManager.getConfigForSubId(mPhone.getSubId());
204a092e4830ed77a5f158de5673944c395b475192fpkanwar
205a092e4830ed77a5f158de5673944c395b475192fpkanwar            for (Map.Entry<Integer, NotificationType> entry : mNotificationTypeMap.entrySet()) {
206a092e4830ed77a5f158de5673944c395b475192fpkanwar                NotificationType notificationType = entry.getValue();
207a092e4830ed77a5f158de5673944c395b475192fpkanwar                notificationType.setDelay(b);
208a092e4830ed77a5f158de5673944c395b475192fpkanwar            }
209149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            handleConfigChanges();
210149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        }
211149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    };
212149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
213149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    /**
214149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar     * Post a notification to the NotificationManager for changing network type.
215149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar     */
216a092e4830ed77a5f158de5673944c395b475192fpkanwar    @VisibleForTesting
217a092e4830ed77a5f158de5673944c395b475192fpkanwar    public void sendNotification(NotificationType notificationType) {
218a092e4830ed77a5f158de5673944c395b475192fpkanwar        if (!evaluateSendingMessage(notificationType)) {
219a092e4830ed77a5f158de5673944c395b475192fpkanwar            return;
220a092e4830ed77a5f158de5673944c395b475192fpkanwar        }
221a092e4830ed77a5f158de5673944c395b475192fpkanwar
222149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        Context context = mPhone.getContext();
223a092e4830ed77a5f158de5673944c395b475192fpkanwar        Notification.Builder builder = getNotificationBuilder(notificationType);
224a092e4830ed77a5f158de5673944c395b475192fpkanwar        // set some common attributes
225a092e4830ed77a5f158de5673944c395b475192fpkanwar        builder.setWhen(System.currentTimeMillis())
226a092e4830ed77a5f158de5673944c395b475192fpkanwar                .setAutoCancel(true)
227a092e4830ed77a5f158de5673944c395b475192fpkanwar                .setSmallIcon(com.android.internal.R.drawable.stat_sys_warning)
228a092e4830ed77a5f158de5673944c395b475192fpkanwar                .setColor(context.getResources().getColor(
229a092e4830ed77a5f158de5673944c395b475192fpkanwar                       com.android.internal.R.color.system_notification_accent_color));
230149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
231a092e4830ed77a5f158de5673944c395b475192fpkanwar        getNotificationManager(context).notify(notificationType.getTypeId(), builder.build());
232a092e4830ed77a5f158de5673944c395b475192fpkanwar    }
233149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
234a092e4830ed77a5f158de5673944c395b475192fpkanwar    /**
235a092e4830ed77a5f158de5673944c395b475192fpkanwar     * Cancel notifications if a registration is pending or has been sent.
236a092e4830ed77a5f158de5673944c395b475192fpkanwar     **/
237a092e4830ed77a5f158de5673944c395b475192fpkanwar    public void cancelNotification(int notificationId) {
238a092e4830ed77a5f158de5673944c395b475192fpkanwar        Context context = mPhone.getContext();
239a092e4830ed77a5f158de5673944c395b475192fpkanwar        removeMessages(notificationId);
240a092e4830ed77a5f158de5673944c395b475192fpkanwar        getNotificationManager(context).cancel(notificationId);
241a092e4830ed77a5f158de5673944c395b475192fpkanwar    }
242a092e4830ed77a5f158de5673944c395b475192fpkanwar
243a092e4830ed77a5f158de5673944c395b475192fpkanwar    /**
244a092e4830ed77a5f158de5673944c395b475192fpkanwar     * Class that defines the different types of notifications.
245a092e4830ed77a5f158de5673944c395b475192fpkanwar     */
246a092e4830ed77a5f158de5673944c395b475192fpkanwar    public interface NotificationType {
247149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
248a092e4830ed77a5f158de5673944c395b475192fpkanwar        /**
249a092e4830ed77a5f158de5673944c395b475192fpkanwar         * decides if the message should be sent, Returns boolean
250a092e4830ed77a5f158de5673944c395b475192fpkanwar         **/
251a092e4830ed77a5f158de5673944c395b475192fpkanwar        boolean sendMessage();
252149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
253a092e4830ed77a5f158de5673944c395b475192fpkanwar        /**
254a092e4830ed77a5f158de5673944c395b475192fpkanwar         * returns the interval by which the message is delayed.
255a092e4830ed77a5f158de5673944c395b475192fpkanwar         **/
256a092e4830ed77a5f158de5673944c395b475192fpkanwar        int getDelay();
257149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
258a092e4830ed77a5f158de5673944c395b475192fpkanwar        /** sets the interval by which the message is delayed.
259a092e4830ed77a5f158de5673944c395b475192fpkanwar         * @param bundle PersistableBundle
260a092e4830ed77a5f158de5673944c395b475192fpkanwar        **/
261a092e4830ed77a5f158de5673944c395b475192fpkanwar        void setDelay(PersistableBundle bundle);
262149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
263a092e4830ed77a5f158de5673944c395b475192fpkanwar        /**
264a092e4830ed77a5f158de5673944c395b475192fpkanwar         * returns notification type id.
265a092e4830ed77a5f158de5673944c395b475192fpkanwar         **/
266a092e4830ed77a5f158de5673944c395b475192fpkanwar        int getTypeId();
267149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
268a092e4830ed77a5f158de5673944c395b475192fpkanwar        /**
269a092e4830ed77a5f158de5673944c395b475192fpkanwar         * returns the notification builder, for the notification to be displayed.
270a092e4830ed77a5f158de5673944c395b475192fpkanwar         **/
271a092e4830ed77a5f158de5673944c395b475192fpkanwar        Notification.Builder getNotificationBuilder();
272a092e4830ed77a5f158de5673944c395b475192fpkanwar    }
273149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
274a092e4830ed77a5f158de5673944c395b475192fpkanwar    /**
275a092e4830ed77a5f158de5673944c395b475192fpkanwar     * Class that defines the network notification, which is shown when the phone cannot camp on
276a092e4830ed77a5f158de5673944c395b475192fpkanwar     * a network, and has 'preferred mode' set to global.
277a092e4830ed77a5f158de5673944c395b475192fpkanwar     */
278a092e4830ed77a5f158de5673944c395b475192fpkanwar    public class PrefNetworkNotification implements NotificationType {
279a092e4830ed77a5f158de5673944c395b475192fpkanwar
280a092e4830ed77a5f158de5673944c395b475192fpkanwar        private final int mTypeId;
281a092e4830ed77a5f158de5673944c395b475192fpkanwar        private int mDelay = UNINITIALIZED_DELAY_VALUE;
282a092e4830ed77a5f158de5673944c395b475192fpkanwar
283a092e4830ed77a5f158de5673944c395b475192fpkanwar        PrefNetworkNotification(int typeId) {
284a092e4830ed77a5f158de5673944c395b475192fpkanwar            this.mTypeId = typeId;
285a092e4830ed77a5f158de5673944c395b475192fpkanwar        }
286a092e4830ed77a5f158de5673944c395b475192fpkanwar
287a092e4830ed77a5f158de5673944c395b475192fpkanwar        /** sets the interval by which the message is delayed.
288a092e4830ed77a5f158de5673944c395b475192fpkanwar         * @param bundle PersistableBundle
289a092e4830ed77a5f158de5673944c395b475192fpkanwar         **/
290a092e4830ed77a5f158de5673944c395b475192fpkanwar        public void setDelay(PersistableBundle bundle) {
291a092e4830ed77a5f158de5673944c395b475192fpkanwar            if (bundle == null) {
292a092e4830ed77a5f158de5673944c395b475192fpkanwar                Rlog.e(LOG_TAG, "bundle is null");
293a092e4830ed77a5f158de5673944c395b475192fpkanwar                return;
294a092e4830ed77a5f158de5673944c395b475192fpkanwar            }
295a092e4830ed77a5f158de5673944c395b475192fpkanwar            this.mDelay = bundle.getInt(
296a092e4830ed77a5f158de5673944c395b475192fpkanwar                    CarrierConfigManager.KEY_PREF_NETWORK_NOTIFICATION_DELAY_INT);
297a092e4830ed77a5f158de5673944c395b475192fpkanwar            Rlog.i(LOG_TAG, "reading time to delay notification emergency: " + mDelay);
298a092e4830ed77a5f158de5673944c395b475192fpkanwar        }
299149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
300a092e4830ed77a5f158de5673944c395b475192fpkanwar        public int getDelay() {
301a092e4830ed77a5f158de5673944c395b475192fpkanwar            return mDelay;
302a092e4830ed77a5f158de5673944c395b475192fpkanwar        }
303a092e4830ed77a5f158de5673944c395b475192fpkanwar
304a092e4830ed77a5f158de5673944c395b475192fpkanwar        public int getTypeId() {
305a092e4830ed77a5f158de5673944c395b475192fpkanwar            return mTypeId;
306a092e4830ed77a5f158de5673944c395b475192fpkanwar        }
307a092e4830ed77a5f158de5673944c395b475192fpkanwar
308a092e4830ed77a5f158de5673944c395b475192fpkanwar        /**
309a092e4830ed77a5f158de5673944c395b475192fpkanwar         * Contains logic on sending notifications.
310a092e4830ed77a5f158de5673944c395b475192fpkanwar         */
311a092e4830ed77a5f158de5673944c395b475192fpkanwar        public boolean sendMessage() {
312a092e4830ed77a5f158de5673944c395b475192fpkanwar            Rlog.i(LOG_TAG, "PrefNetworkNotification: sendMessage() w/values: "
313a092e4830ed77a5f158de5673944c395b475192fpkanwar                    + "," + isPhoneStillRegistered() + "," + mDelay + "," + isGlobalMode()
314a092e4830ed77a5f158de5673944c395b475192fpkanwar                    + "," + mSST.isRadioOn());
315ebb5717eed7380442f7c32a377aeae597d1f2a90pkanwar            if (mDelay == UNINITIALIZED_DELAY_VALUE ||  isPhoneStillRegistered() || isGlobalMode()
316ebb5717eed7380442f7c32a377aeae597d1f2a90pkanwar                    || isRadioOffOrAirplaneMode()) {
317a092e4830ed77a5f158de5673944c395b475192fpkanwar                return false;
318a092e4830ed77a5f158de5673944c395b475192fpkanwar            }
319a092e4830ed77a5f158de5673944c395b475192fpkanwar            return true;
320a092e4830ed77a5f158de5673944c395b475192fpkanwar        }
321a092e4830ed77a5f158de5673944c395b475192fpkanwar
322a092e4830ed77a5f158de5673944c395b475192fpkanwar        /**
323a092e4830ed77a5f158de5673944c395b475192fpkanwar         * Builds a partial notificaiton builder, and returns it.
324a092e4830ed77a5f158de5673944c395b475192fpkanwar         */
325a092e4830ed77a5f158de5673944c395b475192fpkanwar        public Notification.Builder getNotificationBuilder() {
326a092e4830ed77a5f158de5673944c395b475192fpkanwar            Context context = mPhone.getContext();
327a092e4830ed77a5f158de5673944c395b475192fpkanwar            Intent notificationIntent = new Intent(Settings.ACTION_DATA_ROAMING_SETTINGS);
328a092e4830ed77a5f158de5673944c395b475192fpkanwar            PendingIntent settingsIntent = PendingIntent.getActivity(context, 0, notificationIntent,
329a092e4830ed77a5f158de5673944c395b475192fpkanwar                    PendingIntent.FLAG_ONE_SHOT);
330a092e4830ed77a5f158de5673944c395b475192fpkanwar            CharSequence title = context.getText(
331a092e4830ed77a5f158de5673944c395b475192fpkanwar                    com.android.internal.R.string.NetworkPreferenceSwitchTitle);
332a092e4830ed77a5f158de5673944c395b475192fpkanwar            CharSequence details = context.getText(
333a092e4830ed77a5f158de5673944c395b475192fpkanwar                    com.android.internal.R.string.NetworkPreferenceSwitchSummary);
334a092e4830ed77a5f158de5673944c395b475192fpkanwar            return new Notification.Builder(context)
335a092e4830ed77a5f158de5673944c395b475192fpkanwar                    .setContentTitle(title)
336a092e4830ed77a5f158de5673944c395b475192fpkanwar                    .setStyle(new Notification.BigTextStyle().bigText(details))
337a092e4830ed77a5f158de5673944c395b475192fpkanwar                    .setContentText(details)
338a092e4830ed77a5f158de5673944c395b475192fpkanwar                    .setChannel(NotificationChannelController.CHANNEL_ID_ALERT)
339a092e4830ed77a5f158de5673944c395b475192fpkanwar                    .setContentIntent(settingsIntent);
340a092e4830ed77a5f158de5673944c395b475192fpkanwar        }
341149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    }
342149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
343149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    /**
344a092e4830ed77a5f158de5673944c395b475192fpkanwar     * Class that defines the emergency notification, which is shown when the user is out of cell
345a092e4830ed77a5f158de5673944c395b475192fpkanwar     * connectivity, but has wifi enabled.
346149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar     */
347a092e4830ed77a5f158de5673944c395b475192fpkanwar    public class EmergencyNetworkNotification implements NotificationType {
348a092e4830ed77a5f158de5673944c395b475192fpkanwar
349a092e4830ed77a5f158de5673944c395b475192fpkanwar        private final int mTypeId;
350a092e4830ed77a5f158de5673944c395b475192fpkanwar        private int mDelay = UNINITIALIZED_DELAY_VALUE;
351a092e4830ed77a5f158de5673944c395b475192fpkanwar
352a092e4830ed77a5f158de5673944c395b475192fpkanwar        EmergencyNetworkNotification(int typeId) {
353a092e4830ed77a5f158de5673944c395b475192fpkanwar            this.mTypeId = typeId;
354a092e4830ed77a5f158de5673944c395b475192fpkanwar        }
355a092e4830ed77a5f158de5673944c395b475192fpkanwar
356a092e4830ed77a5f158de5673944c395b475192fpkanwar        /** sets the interval by which the message is delayed.
357a092e4830ed77a5f158de5673944c395b475192fpkanwar         * @param bundle PersistableBundle
358a092e4830ed77a5f158de5673944c395b475192fpkanwar         **/
359a092e4830ed77a5f158de5673944c395b475192fpkanwar        public void setDelay(PersistableBundle bundle) {
360a092e4830ed77a5f158de5673944c395b475192fpkanwar            if (bundle == null) {
361a092e4830ed77a5f158de5673944c395b475192fpkanwar                Rlog.e(LOG_TAG, "bundle is null");
362a092e4830ed77a5f158de5673944c395b475192fpkanwar                return;
363a092e4830ed77a5f158de5673944c395b475192fpkanwar            }
364a092e4830ed77a5f158de5673944c395b475192fpkanwar            this.mDelay = bundle.getInt(
365a092e4830ed77a5f158de5673944c395b475192fpkanwar                    CarrierConfigManager.KEY_EMERGENCY_NOTIFICATION_DELAY_INT);
366a092e4830ed77a5f158de5673944c395b475192fpkanwar            Rlog.i(LOG_TAG, "reading time to delay notification emergency: " + mDelay);
367a092e4830ed77a5f158de5673944c395b475192fpkanwar        }
368a092e4830ed77a5f158de5673944c395b475192fpkanwar
369a092e4830ed77a5f158de5673944c395b475192fpkanwar        public int getDelay() {
370a092e4830ed77a5f158de5673944c395b475192fpkanwar            return mDelay;
371a092e4830ed77a5f158de5673944c395b475192fpkanwar        }
372a092e4830ed77a5f158de5673944c395b475192fpkanwar
373a092e4830ed77a5f158de5673944c395b475192fpkanwar        public int getTypeId() {
374a092e4830ed77a5f158de5673944c395b475192fpkanwar            return mTypeId;
375a092e4830ed77a5f158de5673944c395b475192fpkanwar        }
376a092e4830ed77a5f158de5673944c395b475192fpkanwar
377a092e4830ed77a5f158de5673944c395b475192fpkanwar        /**
378a092e4830ed77a5f158de5673944c395b475192fpkanwar         * Contains logic on sending notifications,
379a092e4830ed77a5f158de5673944c395b475192fpkanwar         */
380a092e4830ed77a5f158de5673944c395b475192fpkanwar        public boolean sendMessage() {
381a092e4830ed77a5f158de5673944c395b475192fpkanwar            Rlog.i(LOG_TAG, "EmergencyNetworkNotification: sendMessage() w/values: "
382a092e4830ed77a5f158de5673944c395b475192fpkanwar                    + "," + isPhoneVoiceRegistered() + "," + mDelay + ","
383a092e4830ed77a5f158de5673944c395b475192fpkanwar                    + isPhoneRegisteredForWifiCalling() + "," + mSST.isRadioOn());
384a092e4830ed77a5f158de5673944c395b475192fpkanwar            if (mDelay == UNINITIALIZED_DELAY_VALUE || isPhoneVoiceRegistered()
385a092e4830ed77a5f158de5673944c395b475192fpkanwar                    || !isPhoneRegisteredForWifiCalling()) {
386a092e4830ed77a5f158de5673944c395b475192fpkanwar                return false;
387a092e4830ed77a5f158de5673944c395b475192fpkanwar            }
388a092e4830ed77a5f158de5673944c395b475192fpkanwar            return true;
389a092e4830ed77a5f158de5673944c395b475192fpkanwar        }
390a092e4830ed77a5f158de5673944c395b475192fpkanwar
391a092e4830ed77a5f158de5673944c395b475192fpkanwar        /**
392a092e4830ed77a5f158de5673944c395b475192fpkanwar         * Builds a partial notificaiton builder, and returns it.
393a092e4830ed77a5f158de5673944c395b475192fpkanwar         */
394a092e4830ed77a5f158de5673944c395b475192fpkanwar        public Notification.Builder getNotificationBuilder() {
395a092e4830ed77a5f158de5673944c395b475192fpkanwar            Context context = mPhone.getContext();
396a092e4830ed77a5f158de5673944c395b475192fpkanwar            CharSequence title = context.getText(
397a092e4830ed77a5f158de5673944c395b475192fpkanwar                    com.android.internal.R.string.EmergencyCallWarningTitle);
398a092e4830ed77a5f158de5673944c395b475192fpkanwar            CharSequence details = context.getText(
399a092e4830ed77a5f158de5673944c395b475192fpkanwar                    com.android.internal.R.string.EmergencyCallWarningSummary);
400a092e4830ed77a5f158de5673944c395b475192fpkanwar            return new Notification.Builder(context)
401a092e4830ed77a5f158de5673944c395b475192fpkanwar                    .setContentTitle(title)
402a092e4830ed77a5f158de5673944c395b475192fpkanwar                    .setStyle(new Notification.BigTextStyle().bigText(details))
403a092e4830ed77a5f158de5673944c395b475192fpkanwar                    .setContentText(details)
404a092e4830ed77a5f158de5673944c395b475192fpkanwar                    .setChannel(NotificationChannelController.CHANNEL_ID_WFC);
405a092e4830ed77a5f158de5673944c395b475192fpkanwar        }
406149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    }
4072cab3ec97219a25aa7dabfd48a98cddba79ceebapkanwar}
408