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

Commit a17ff1d7 authored by Simon Shields's avatar Simon Shields Committed by Dan Pasanen
Browse files

Merge tag 'android-7.1.2_r2' into cm-14.1

Android 7.1.2 Release 2 (N2G47E)

Change-Id: Ic4e01f328b050179df40b25940ea48d8f63c1b03
parents c31cf848 37392ec0
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -1018,6 +1018,13 @@ message TelephonyCallSession {
      optional CallState state = 2;

      optional Type type = 3;

      // For possible values for a call end reason check
      // frameworks/base/telephony/java/android/telephony/DisconnectCause.java
      optional int32 call_end_reason = 4;

      // This field is true for Conference Calls
      optional bool is_multiparty = 5;
    }

    // Single Radio Voice Call Continuity(SRVCC) progress state
+1 −1
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ public interface CallFailCause {
    // Unassigned/Unobtainable number
    int UNOBTAINABLE_NUMBER = 1;

    int OPERATOR_DETERMINED_BARRING = 8;
    int NORMAL_CLEARING     = 16;
    // Busy Tone
    int USER_BUSY           = 17;
@@ -61,7 +62,6 @@ public interface CallFailCause {
    // Supplementary
    int NO_ROUTE_TO_DESTINAON = 3;
    int CHANNEL_UNACCEPTABLE = 6;
    int OPERATOR_DETERMINED_BARRING = 8;
    int CALL_FAIL_NO_USER_RESPONDING = 18;
    int CALL_FAIL_NO_ANSWER_FROM_USER = 19;
    int CALL_REJECTED = 21;
+1 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ public class CallStateException extends Exception
    public static final int ERROR_INVALID = -1;

    public static final int ERROR_DISCONNECTED = 1;
    public static final int ERROR_POWER_OFF = 2;

    public
    CallStateException()
+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
+46 −9
Original line number Diff line number Diff line
@@ -88,6 +88,8 @@ public class GsmCdmaCallTracker extends CallTracker {

    public PhoneConstants.State mState = PhoneConstants.State.IDLE;

    private TelephonyMetrics mMetrics = TelephonyMetrics.getInstance();

    // Following member variables are for CDMA only
    private RegistrantList mCallWaitingRegistrants = new RegistrantList();
    private boolean mPendingCallInEcm;
@@ -303,6 +305,8 @@ public class GsmCdmaCallTracker extends CallTracker {
        mPendingMO = new GsmCdmaConnection(mPhone, checkForTestEmergencyNumber(dialString),
                this, mForegroundCall, isEmergencyCall);
        mHangupPendingMO = false;
        mMetrics.writeRilDial(mPhone.getPhoneId(), mPendingMO, clirMode, uusInfo);


        if ( mPendingMO.getAddress() == null || mPendingMO.getAddress().length() == 0
                || mPendingMO.getAddress().indexOf(PhoneNumberUtils.WILD) >= 0) {
@@ -715,7 +719,7 @@ public class GsmCdmaCallTracker extends CallTracker {
        }
        if (mState != oldState) {
            mPhone.notifyPhoneStateChanged();
            TelephonyMetrics.getInstance().writePhoneState(mPhone.getPhoneId(), mState);
            mMetrics.writePhoneState(mPhone.getPhoneId(), mState);
        }
    }

@@ -863,9 +867,6 @@ public class GsmCdmaCallTracker extends CallTracker {
                    // Connection missing in CLCC response that we were
                    // tracking.
                    mDroppedDuringPoll.add(conn);
                    // Dropped connections are removed from the CallTracker
                    // list but kept in the GsmCdmaCall list
                    mConnections[i] = null;
                } else {
                    // This case means the RIL has no more active call anymore and
                    // we need to clean up the foregroundCall and ringingCall.
@@ -892,12 +893,10 @@ public class GsmCdmaCallTracker extends CallTracker {
                    }
                    // If emergency call is not going through while dialing
                    checkAndEnableDataCallAfterEmergencyCallDropped();

                }
                // Dropped connections are removed from the CallTracker
                // list but kept in the Call list
                mConnections[i] = null;

                }
            } else if (conn != null && dc != null && !conn.compareTo(dc) && isPhoneTypeGsm()) {
                // Connection in CLCC response does not match what
                // we were tracking. Assume dropped call and new call
@@ -987,6 +986,7 @@ public class GsmCdmaCallTracker extends CallTracker {
        // clear the "local hangup" and "missed/rejected call"
        // cases from the "dropped during poll" list
        // These cases need no "last call fail" reason
        ArrayList<GsmCdmaConnection> locallyDisconnectedConnections = new ArrayList<>();
        for (int i = mDroppedDuringPoll.size() - 1; i >= 0 ; i--) {
            GsmCdmaConnection conn = mDroppedDuringPoll.get(i);
            //CDMA
@@ -1008,11 +1008,13 @@ public class GsmCdmaCallTracker extends CallTracker {
                mDroppedDuringPoll.remove(i);
                hasAnyCallDisconnected |= conn.onDisconnect(cause);
                wasDisconnected = true;
                locallyDisconnectedConnections.add(conn);
            } else if (conn.mCause == DisconnectCause.LOCAL
                    || conn.mCause == DisconnectCause.INVALID_NUMBER) {
                mDroppedDuringPoll.remove(i);
                hasAnyCallDisconnected |= conn.onDisconnect(conn.mCause);
                wasDisconnected = true;
                locallyDisconnectedConnections.add(conn);
            }

            if (!isPhoneTypeGsm() && wasDisconnected && unknownConnectionAppeared
@@ -1021,6 +1023,9 @@ public class GsmCdmaCallTracker extends CallTracker {
                newUnknownConnectionCdma = null;
            }
        }
        if (locallyDisconnectedConnections.size() > 0) {
            mMetrics.writeRilCallList(mPhone.getPhoneId(), locallyDisconnectedConnections);
        }

        /* Disconnect any pending Handover connections */
        for (Iterator<Connection> it = mHandoverConnections.iterator();
@@ -1033,6 +1038,7 @@ public class GsmCdmaCallTracker extends CallTracker {
            } else {
                hoConnection.onDisconnect(DisconnectCause.NOT_VALID);
            }
            // TODO: Do we need to update these hoConnections in Metrics ?
            it.remove();
        }

@@ -1071,6 +1077,7 @@ public class GsmCdmaCallTracker extends CallTracker {

        if (hasNonHangupStateChanged || newRinging != null || hasAnyCallDisconnected) {
            mPhone.notifyPreciseCallStateChanged();
            updateMetrics(mConnections);
        }

        // If all handover connections are mapped during this poll process clean it up
@@ -1083,6 +1090,14 @@ public class GsmCdmaCallTracker extends CallTracker {
        //dumpState();
    }

    private void updateMetrics(GsmCdmaConnection []connections) {
        ArrayList<GsmCdmaConnection> activeConnections = new ArrayList<>();
        for(GsmCdmaConnection conn : connections) {
            if(conn != null) activeConnections.add(conn);
        }
        mMetrics.writeRilCallList(mPhone.getPhoneId(), activeConnections);
    }

    private void handleRadioNotAvailable() {
        // handlePollCalls will clear out its
        // call list when it gets the CommandException
@@ -1156,6 +1171,7 @@ public class GsmCdmaCallTracker extends CallTracker {
            return;
        } else {
            try {
                mMetrics.writeRilHangup(mPhone.getPhoneId(), conn, conn.getGsmCdmaIndex());
                mCi.hangupConnection (conn.getGsmCdmaIndex(), obtainCompleteMessage());
            } catch (CallStateException ex) {
                // Ignore "connection not found"
@@ -1204,6 +1220,7 @@ public class GsmCdmaCallTracker extends CallTracker {

        if (call == mRingingCall) {
            if (Phone.DEBUG_PHONE) log("(ringing) hangup waiting or background");
            logHangupEvent(call);
            mCi.hangupWaitingOrBackground(obtainCompleteMessage());
        } else if (call == mForegroundCall) {
            if (call.isDialingOrAlerting()) {
@@ -1217,6 +1234,7 @@ public class GsmCdmaCallTracker extends CallTracker {
                log("hangup all conns in active/background call, without affecting ringing call");
                hangupAllConnections(call);
            } else {
                logHangupEvent(call);
                hangupForegroundResumeBackground();
            }
        } else if (call == mBackgroundCall) {
@@ -1237,8 +1255,24 @@ public class GsmCdmaCallTracker extends CallTracker {
        mPhone.notifyPreciseCallStateChanged();
    }

    private void logHangupEvent(GsmCdmaCall call) {
        int count = call.mConnections.size();
        for (int i = 0; i < count; i++) {
            GsmCdmaConnection cn = (GsmCdmaConnection) call.mConnections.get(i);
            int call_index;
            try {
                call_index = cn.getGsmCdmaIndex();
            } catch (CallStateException ex) {
                call_index = -1;
            }
            mMetrics.writeRilHangup(mPhone.getPhoneId(), cn, call_index);
        }
        if (VDBG) Rlog.v(LOG_TAG, "logHangupEvent logged " + count + " Connections ");
    }

    public void hangupWaitingOrBackground() {
        if (Phone.DEBUG_PHONE) log("hangupWaitingOrBackground");
        logHangupEvent(mBackgroundCall);
        mCi.hangupWaitingOrBackground(obtainCompleteMessage());
    }

@@ -1253,6 +1287,7 @@ public class GsmCdmaCallTracker extends CallTracker {
        for (int i = 0; i < count; i++) {
            GsmCdmaConnection cn = (GsmCdmaConnection)call.mConnections.get(i);
            if (cn.getGsmCdmaIndex() == index) {
                mMetrics.writeRilHangup(mPhone.getPhoneId(), cn, cn.getGsmCdmaIndex());
                mCi.hangupConnection(index, obtainCompleteMessage());
                return;
            }
@@ -1266,6 +1301,7 @@ public class GsmCdmaCallTracker extends CallTracker {
            int count = call.mConnections.size();
            for (int i = 0; i < count; i++) {
                GsmCdmaConnection cn = (GsmCdmaConnection)call.mConnections.get(i);
                mMetrics.writeRilHangup(mPhone.getPhoneId(), cn, cn.getGsmCdmaIndex());
                mCi.hangupConnection(cn.getGsmCdmaIndex(), obtainCompleteMessage());
            }
        } catch (CallStateException ex) {
@@ -1422,6 +1458,7 @@ public class GsmCdmaCallTracker extends CallTracker {
                updatePhoneState();

                mPhone.notifyPreciseCallStateChanged();
                mMetrics.writeRilCallList(mPhone.getPhoneId(), mDroppedDuringPoll);
                mDroppedDuringPoll.clear();
            break;

Loading