Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c0cb41db authored by Pankaj Kanwar's avatar Pankaj Kanwar Committed by Android (Google) Code Review
Browse files

Merge "Notify user when user fails to connect to the network." into nyc-mr2-dev

parents d92c67aa 149f0d5d
Loading
Loading
Loading
Loading
+192 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.internal.telephony;

import android.app.PendingIntent;
import android.app.Notification;
import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;
import android.os.Message;
import android.os.PersistableBundle;
import android.provider.Settings;
import android.telephony.CarrierConfigManager;
import android.telephony.Rlog;

/**
 * This contains Carrier specific logic based on the states/events
 * managed in ServiceStateTracker.
 * {@hide}
 */
public class CarrierServiceStateTracker extends Handler {
    private static final String LOG_TAG = "CSST";
    protected static final int CARRIER_EVENT_BASE = 100;
    protected static final int CARRIER_EVENT_VOICE_REGISTRATION = CARRIER_EVENT_BASE + 1;
    protected static final int CARRIER_EVENT_VOICE_DEREGISTRATION = CARRIER_EVENT_BASE + 2;
    protected static final int CARRIER_EVENT_DATA_REGISTRATION = CARRIER_EVENT_BASE + 3;
    protected static final int CARRIER_EVENT_DATA_DEREGISTRATION = CARRIER_EVENT_BASE + 4;
    private static final int SHOW_NOTIFICATION = 200;
    private static final int NOTIFICATION_ID = 1000;
    private static final int UNINITIALIZED_DELAY_VALUE = -1;
    private int mDelay = UNINITIALIZED_DELAY_VALUE;
    private Phone mPhone;
    private boolean mIsPhoneRegistered = false;
    private ServiceStateTracker mSST;

    public CarrierServiceStateTracker(Phone phone, ServiceStateTracker sst) {
        this.mPhone = phone;
        this.mSST = sst;
        phone.getContext().registerReceiver(mBroadcastReceiver, new IntentFilter(
                CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED));
    }

    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case CARRIER_EVENT_VOICE_REGISTRATION:
            case CARRIER_EVENT_DATA_REGISTRATION:
                mIsPhoneRegistered = true;
                handleConfigChanges();
                break;
            case CARRIER_EVENT_VOICE_DEREGISTRATION:
            case CARRIER_EVENT_DATA_DEREGISTRATION:
                if (isGlobalModeOrRadioOffOrAirplaneMode()) {
                    break;
                }
                mIsPhoneRegistered = false;
                handleConfigChanges();
                break;
            case SHOW_NOTIFICATION:
                sendNotification();
                break;
        }
    }

    /**
     * Returns true if the preferred network is set to 'Global' or the radio is off or in
     * Airplane Mode else returns false.
     */
    private boolean isGlobalModeOrRadioOffOrAirplaneMode() {
        Context context = mPhone.getContext();
        int preferredNetworkSetting = -1;
        int airplaneMode = -1;
        int subId = mPhone.getSubId();
        try {
            preferredNetworkSetting =
                    android.provider.Settings.Global.getInt(context.getContentResolver(),
                            android.provider.Settings.Global.PREFERRED_NETWORK_MODE + subId,
                            Phone.PREFERRED_NT_MODE);
            airplaneMode = Settings.Global.getInt(context.getContentResolver(),
                    Settings.Global.AIRPLANE_MODE_ON, 0);
        } catch (Exception e) {
            Rlog.e(LOG_TAG, "Unable to get PREFERRED_NETWORK_MODE.");
            return true;
        }
        return ((preferredNetworkSetting == RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA) ||
                !mSST.isRadioOn() || (airplaneMode != 0));
    }

    /**
     * Contains logic to decide when to create/cancel notifications.
     */
    private void handleConfigChanges() {

        if (mDelay == UNINITIALIZED_DELAY_VALUE) {
            cancelNotification();
            return;
        }
        // send a notification if the device is registerd to a network.
        if (mIsPhoneRegistered) {
            cancelNotification();
            Rlog.i(LOG_TAG, "canceling all notifications. ");
        } else {
            Message notificationMsg;
            notificationMsg = obtainMessage(SHOW_NOTIFICATION, null);
            Rlog.i(LOG_TAG, "starting timer for notifications. ");
            sendMessageDelayed(notificationMsg, mDelay);
        }
    }

    private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            CarrierConfigManager carrierConfigManager = (CarrierConfigManager)
                    context.getSystemService(Context.CARRIER_CONFIG_SERVICE);
            PersistableBundle b = carrierConfigManager.getConfig();
            mDelay = b.getInt(CarrierConfigManager.KEY_PREF_NETWORK_NOTIFICATION_DELAY_INT);
            Rlog.i(LOG_TAG, "reading time to delay notification: " + mDelay);
            handleConfigChanges();
        }
    };

    /**
     * Post a notification to the NotificationManager for changing network type.
     */
    private void sendNotification() {
        Context context = mPhone.getContext();

        Rlog.i(LOG_TAG, "w/values: " + "," + mIsPhoneRegistered + "," + mDelay
                + "," + isGlobalModeOrRadioOffOrAirplaneMode() + "," + mSST.isRadioOn());

        // exit if the network preference is set to Global or if the phone is registered.
        if (isGlobalModeOrRadioOffOrAirplaneMode() || mIsPhoneRegistered) {
            return;
        }

        NotificationManager notificationManager = (NotificationManager)
                context.getSystemService(Context.NOTIFICATION_SERVICE);


        Intent notificationIntent = new Intent(Settings.ACTION_DATA_ROAMING_SETTINGS);
        PendingIntent settingsIntent = PendingIntent.getActivity(context, 0, notificationIntent,
                PendingIntent.FLAG_ONE_SHOT);

        CharSequence title =
                context.getText(com.android.internal.R.string.NetworkPreferenceSwitchTitle);
        CharSequence details =
                context.getText(com.android.internal.R.string.NetworkPreferenceSwitchSummary);


        Notification mNotification = new Notification.Builder(context)
                .setWhen(System.currentTimeMillis())
                .setAutoCancel(true)
                .setSmallIcon(com.android.internal.R.drawable.stat_sys_warning)
                .setContentTitle(title)
                .setColor(context.getResources().getColor(
                        com.android.internal.R.color.system_notification_accent_color))
                .setStyle(new Notification.BigTextStyle().bigText(details))
                .setContentText(details)
                .setContentIntent(settingsIntent)
                .build();

        notificationManager.notify(NOTIFICATION_ID, mNotification);
    }

    /**
     * Cancel notifications if a registration is pending or has been sent.
     */
    private void cancelNotification() {
        Context context = mPhone.getContext();
        mIsPhoneRegistered = true;
        NotificationManager notificationManager = (NotificationManager)
                context.getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.cancel(NOTIFICATION_ID);
    }
}
 No newline at end of file
+50 −0
Original line number Diff line number Diff line
@@ -155,6 +155,7 @@ public class ServiceStateTracker extends Handler {
    protected RegistrantList mDetachedRegistrants = new RegistrantList();
    private RegistrantList mDataRegStateOrRatChangedRegistrants = new RegistrantList();
    private RegistrantList mNetworkAttachedRegistrants = new RegistrantList();
    private RegistrantList mNetworkDetachedRegistrants = new RegistrantList();
    private RegistrantList mPsRestrictEnabledRegistrants = new RegistrantList();
    private RegistrantList mPsRestrictDisabledRegistrants = new RegistrantList();

@@ -423,6 +424,8 @@ public class ServiceStateTracker extends Handler {
    private boolean mStartedGprsRegCheck;
    /** Already sent the event-log for no gprs register. */
    private boolean mReportedGprsNoReg;

    private CarrierServiceStateTracker mCSST;
    /**
     * The Notification object given to the NotificationManager.
     */
@@ -552,6 +555,17 @@ public class ServiceStateTracker extends Handler {
        mPhone.notifyOtaspChanged(OTASP_UNINITIALIZED);

        updatePhoneType();

        mCSST = new CarrierServiceStateTracker(phone, this);

        registerForNetworkAttached(mCSST,
                CarrierServiceStateTracker.CARRIER_EVENT_VOICE_REGISTRATION, null);
        registerForNetworkDetached(mCSST,
                CarrierServiceStateTracker.CARRIER_EVENT_VOICE_DEREGISTRATION, null);
        registerForDataConnectionAttached(mCSST,
                CarrierServiceStateTracker.CARRIER_EVENT_DATA_REGISTRATION, null);
        registerForDataConnectionDetached(mCSST,
                CarrierServiceStateTracker.CARRIER_EVENT_DATA_DEREGISTRATION, null);
    }

    @VisibleForTesting
@@ -2694,6 +2708,10 @@ public class ServiceStateTracker extends Handler {
            mNitzUpdatedTime = false;
        }

        if (hasDeregistered) {
            mNetworkDetachedRegistrants.notifyRegistrants();
        }

        if (hasChanged) {
            String operatorNumeric;

@@ -2848,6 +2866,10 @@ public class ServiceStateTracker extends Handler {
                mSS.getVoiceRegState() != ServiceState.STATE_IN_SERVICE
                        && mNewSS.getVoiceRegState() == ServiceState.STATE_IN_SERVICE;

        boolean hasDeregistered =
                mSS.getVoiceRegState() == ServiceState.STATE_IN_SERVICE
                        && mNewSS.getVoiceRegState() != ServiceState.STATE_IN_SERVICE;

        boolean hasCdmaDataConnectionAttached =
                mSS.getDataRegState() != ServiceState.STATE_IN_SERVICE
                        && mNewSS.getDataRegState() == ServiceState.STATE_IN_SERVICE;
@@ -2922,6 +2944,10 @@ public class ServiceStateTracker extends Handler {
            mNetworkAttachedRegistrants.notifyRegistrants();
        }

        if (hasDeregistered) {
            mNetworkDetachedRegistrants.notifyRegistrants();
        }

        if (hasChanged) {
            updateSpnDisplay();

@@ -3161,6 +3187,10 @@ public class ServiceStateTracker extends Handler {
            mNetworkAttachedRegistrants.notifyRegistrants();
        }

        if (hasDeregistered) {
            mNetworkDetachedRegistrants.notifyRegistrants();
        }

        if (hasChanged) {
            updateSpnDisplay();

@@ -4274,10 +4304,30 @@ public class ServiceStateTracker extends Handler {
            r.notifyRegistrant();
        }
    }

    public void unregisterForNetworkAttached(Handler h) {
        mNetworkAttachedRegistrants.remove(h);
    }

    /**
     * Registration point for transition into network detached.
     * @param h handler to notify
     * @param what what code of message when delivered
     * @param obj in Message.obj
     */
    public void registerForNetworkDetached(Handler h, int what, Object obj) {
        Registrant r = new Registrant(h, what, obj);

        mNetworkDetachedRegistrants.add(r);
        if (mSS.getVoiceRegState() != ServiceState.STATE_IN_SERVICE) {
            r.notifyRegistrant();
        }
    }

    public void unregisterForNetworkDetached(Handler h) {
        mNetworkDetachedRegistrants.remove(h);
    }

    /**
     * Registration point for transition into packet service restricted zone.
     * @param h handler to notify