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.PendingIntent;
20149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarimport android.app.Notification;
21149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarimport android.app.NotificationManager;
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;
32149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
337c29cabeb38ae8cb4f5764c2dc0a768de22d2f92fionaxuimport com.android.internal.telephony.util.NotificationChannelController;
3413ff522d752715d856bd4068d39a769cd0d54a24fionaxu
35149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar/**
36149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * This contains Carrier specific logic based on the states/events
37149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * managed in ServiceStateTracker.
38149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar * {@hide}
39149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar */
40149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwarpublic class CarrierServiceStateTracker extends Handler {
41149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    private static final String LOG_TAG = "CSST";
42149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    protected static final int CARRIER_EVENT_BASE = 100;
43149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    protected static final int CARRIER_EVENT_VOICE_REGISTRATION = CARRIER_EVENT_BASE + 1;
44149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    protected static final int CARRIER_EVENT_VOICE_DEREGISTRATION = CARRIER_EVENT_BASE + 2;
45149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    protected static final int CARRIER_EVENT_DATA_REGISTRATION = CARRIER_EVENT_BASE + 3;
46149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    protected static final int CARRIER_EVENT_DATA_DEREGISTRATION = CARRIER_EVENT_BASE + 4;
47149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    private static final int SHOW_NOTIFICATION = 200;
48149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    private static final int NOTIFICATION_ID = 1000;
49149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    private static final int UNINITIALIZED_DELAY_VALUE = -1;
50149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    private int mDelay = UNINITIALIZED_DELAY_VALUE;
51149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    private Phone mPhone;
52149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    private boolean mIsPhoneRegistered = false;
53149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    private ServiceStateTracker mSST;
54149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
55149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    public CarrierServiceStateTracker(Phone phone, ServiceStateTracker sst) {
56149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        this.mPhone = phone;
57149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        this.mSST = sst;
58149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        phone.getContext().registerReceiver(mBroadcastReceiver, new IntentFilter(
59149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED));
60149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    }
61149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
62149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    @Override
63149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    public void handleMessage(Message msg) {
64149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        switch (msg.what) {
65149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            case CARRIER_EVENT_VOICE_REGISTRATION:
66149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            case CARRIER_EVENT_DATA_REGISTRATION:
67149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                mIsPhoneRegistered = true;
68149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                handleConfigChanges();
69149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                break;
70149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            case CARRIER_EVENT_VOICE_DEREGISTRATION:
71149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            case CARRIER_EVENT_DATA_DEREGISTRATION:
72149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                if (isGlobalModeOrRadioOffOrAirplaneMode()) {
73149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                    break;
74149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                }
75149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                mIsPhoneRegistered = false;
76149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                handleConfigChanges();
77149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                break;
78149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            case SHOW_NOTIFICATION:
79149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                sendNotification();
80149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                break;
81149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        }
82149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    }
83149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
84149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    /**
85149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar     * Returns true if the preferred network is set to 'Global' or the radio is off or in
86149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar     * Airplane Mode else returns false.
87149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar     */
88149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    private boolean isGlobalModeOrRadioOffOrAirplaneMode() {
89149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        Context context = mPhone.getContext();
90149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        int preferredNetworkSetting = -1;
91149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        int airplaneMode = -1;
92149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        int subId = mPhone.getSubId();
93149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        try {
94149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            preferredNetworkSetting =
95149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                    android.provider.Settings.Global.getInt(context.getContentResolver(),
96149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                            android.provider.Settings.Global.PREFERRED_NETWORK_MODE + subId,
97149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                            Phone.PREFERRED_NT_MODE);
98149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            airplaneMode = Settings.Global.getInt(context.getContentResolver(),
99149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                    Settings.Global.AIRPLANE_MODE_ON, 0);
100149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        } catch (Exception e) {
101149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            Rlog.e(LOG_TAG, "Unable to get PREFERRED_NETWORK_MODE.");
102149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            return true;
103149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        }
104149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        return ((preferredNetworkSetting == RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA) ||
105149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                !mSST.isRadioOn() || (airplaneMode != 0));
106149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    }
107149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
108149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    /**
109149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar     * Contains logic to decide when to create/cancel notifications.
110149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar     */
111149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    private void handleConfigChanges() {
112149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
113149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        if (mDelay == UNINITIALIZED_DELAY_VALUE) {
114149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            cancelNotification();
115149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            return;
116149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        }
117149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        // send a notification if the device is registerd to a network.
118149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        if (mIsPhoneRegistered) {
119149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            cancelNotification();
120149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            Rlog.i(LOG_TAG, "canceling all notifications. ");
121149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        } else {
122149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            Message notificationMsg;
123149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            notificationMsg = obtainMessage(SHOW_NOTIFICATION, null);
124149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            Rlog.i(LOG_TAG, "starting timer for notifications. ");
125149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            sendMessageDelayed(notificationMsg, mDelay);
126149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        }
127149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    }
128149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
129149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
130149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        @Override
131149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        public void onReceive(Context context, Intent intent) {
132149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            CarrierConfigManager carrierConfigManager = (CarrierConfigManager)
133149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                    context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
134149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            PersistableBundle b = carrierConfigManager.getConfig();
135149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            mDelay = b.getInt(CarrierConfigManager.KEY_PREF_NETWORK_NOTIFICATION_DELAY_INT);
136149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            Rlog.i(LOG_TAG, "reading time to delay notification: " + mDelay);
137149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            handleConfigChanges();
138149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        }
139149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    };
140149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
141149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    /**
142149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar     * Post a notification to the NotificationManager for changing network type.
143149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar     */
144149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    private void sendNotification() {
145149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        Context context = mPhone.getContext();
146149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
147149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        Rlog.i(LOG_TAG, "w/values: " + "," + mIsPhoneRegistered + "," + mDelay
148149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                + "," + isGlobalModeOrRadioOffOrAirplaneMode() + "," + mSST.isRadioOn());
149149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
150149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        // exit if the network preference is set to Global or if the phone is registered.
151149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        if (isGlobalModeOrRadioOffOrAirplaneMode() || mIsPhoneRegistered) {
152149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar            return;
153149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        }
154149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
155149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        NotificationManager notificationManager = (NotificationManager)
156149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                context.getSystemService(Context.NOTIFICATION_SERVICE);
157149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
158149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
159149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        Intent notificationIntent = new Intent(Settings.ACTION_DATA_ROAMING_SETTINGS);
160149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        PendingIntent settingsIntent = PendingIntent.getActivity(context, 0, notificationIntent,
161149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                PendingIntent.FLAG_ONE_SHOT);
162149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
163149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        CharSequence title =
164149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                context.getText(com.android.internal.R.string.NetworkPreferenceSwitchTitle);
165149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        CharSequence details =
166149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                context.getText(com.android.internal.R.string.NetworkPreferenceSwitchSummary);
167149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
168149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
1697c29cabeb38ae8cb4f5764c2dc0a768de22d2f92fionaxu        Notification mNotification = new Notification.Builder(context)
170149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                .setWhen(System.currentTimeMillis())
171149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                .setAutoCancel(true)
172149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                .setSmallIcon(com.android.internal.R.drawable.stat_sys_warning)
173149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                .setContentTitle(title)
174149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                .setColor(context.getResources().getColor(
175149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                        com.android.internal.R.color.system_notification_accent_color))
176149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                .setStyle(new Notification.BigTextStyle().bigText(details))
177149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                .setContentText(details)
178149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                .setContentIntent(settingsIntent)
1797c29cabeb38ae8cb4f5764c2dc0a768de22d2f92fionaxu                .setChannel(NotificationChannelController.CHANNEL_ID_ALERT)
180149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                .build();
181149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
182149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        notificationManager.notify(NOTIFICATION_ID, mNotification);
183149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    }
184149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar
185149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    /**
186149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar     * Cancel notifications if a registration is pending or has been sent.
187149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar     */
188149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    private void cancelNotification() {
189149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        Context context = mPhone.getContext();
190149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        mIsPhoneRegistered = true;
191149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        NotificationManager notificationManager = (NotificationManager)
192149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar                context.getSystemService(Context.NOTIFICATION_SERVICE);
193149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar        notificationManager.cancel(NOTIFICATION_ID);
194149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar    }
195149f0d5d1ce3cebe17479d61454c33f700c3584bpkanwar}