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

Commit 9d164dc5 authored by The Android Open Source Project's avatar The Android Open Source Project Committed by Android Git Automerger
Browse files

am f4dffd8a: merge from open-source master

Merge commit 'f4dffd8a' into kraken

* commit 'f4dffd8a':
  GpsLocationProvider: Store new Location before onGpsStatusChanged is sent
  Telephony: Add PUK MMI code support for CDMA RUIM phones
  Type Zero Sms should not be displayed/stored/notified.
parents 8a1c0934 f4dffd8a
Loading
Loading
Loading
Loading
+23 −23
Original line number Diff line number Diff line
@@ -950,29 +950,6 @@ public class GpsLocationProvider implements LocationProviderInterface {
        if (VERBOSE) Log.v(TAG, "reportLocation lat: " + latitude + " long: " + longitude +
                " timestamp: " + timestamp);

        mLastFixTime = System.currentTimeMillis();
        // report time to first fix
        if (mTTFF == 0 && (flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG) {
            mTTFF = (int)(mLastFixTime - mFixRequestTime);
            if (DEBUG) Log.d(TAG, "TTFF: " + mTTFF);

            // notify status listeners
            synchronized(mListeners) {
                int size = mListeners.size();
                for (int i = 0; i < size; i++) {
                    Listener listener = mListeners.get(i);
                    try {
                        listener.mListener.onFirstFix(mTTFF); 
                    } catch (RemoteException e) {
                        Log.w(TAG, "RemoteException in stopNavigating");
                        mListeners.remove(listener);
                        // adjust for size of list changing
                        size--;
                    }
                }
            }
        }

        synchronized (mLocation) {
            mLocationFlags = flags;
            if ((flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG) {
@@ -1008,6 +985,29 @@ public class GpsLocationProvider implements LocationProviderInterface {
            }
        }

        mLastFixTime = System.currentTimeMillis();
        // report time to first fix
        if (mTTFF == 0 && (flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG) {
            mTTFF = (int)(mLastFixTime - mFixRequestTime);
            if (DEBUG) Log.d(TAG, "TTFF: " + mTTFF);

            // notify status listeners
            synchronized(mListeners) {
                int size = mListeners.size();
                for (int i = 0; i < size; i++) {
                    Listener listener = mListeners.get(i);
                    try {
                        listener.mListener.onFirstFix(mTTFF); 
                    } catch (RemoteException e) {
                        Log.w(TAG, "RemoteException in stopNavigating");
                        mListeners.remove(listener);
                        // adjust for size of list changing
                        size--;
                    }
                }
            }
        }

        if (mStarted && mStatus != LocationProvider.AVAILABLE) {
            // we want to time out if we do not receive a fix
            // within the time out and we are requesting infrequent fixes
+42 −3
Original line number Diff line number Diff line
@@ -67,6 +67,7 @@ import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OP
import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_NUMERIC;
import static com.android.internal.telephony.TelephonyProperties.PROPERTY_ICC_OPERATOR_ISO_COUNTRY;

import java.util.ArrayList;
import java.util.List;


@@ -101,6 +102,7 @@ public class CDMAPhone extends PhoneBase {
    RuimFileHandler mRuimFileHandler;
    RuimRecords mRuimRecords;
    RuimCard mRuimCard;
    ArrayList <CdmaMmiCode> mPendingMmis = new ArrayList<CdmaMmiCode>();
    RuimPhoneBookInterfaceManager mRuimPhoneBookInterfaceManager;
    RuimSmsInterfaceManager mRuimSmsInterfaceManager;
    PhoneSubInfo mSubInfo;
@@ -219,6 +221,8 @@ public class CDMAPhone extends PhoneBase {
            mSST.unregisterForNetworkAttach(this); //EVENT_REGISTERED_TO_NETWORK
            mCM.unSetOnSuppServiceNotification(this);

            mPendingMmis.clear();

            //Force all referenced classes to unregister their former registered events
            mCT.dispose();
            mDataConnection.dispose();
@@ -355,8 +359,7 @@ public class CDMAPhone extends PhoneBase {

    public List<? extends MmiCode>
    getPendingMmiCodes() {
        Log.e(LOG_TAG, "method getPendingMmiCodes is NOT supported in CDMA!");
        return null;
        return mPendingMmis;
    }

    public void registerForSuppServiceNotification(
@@ -373,6 +376,15 @@ public class CDMAPhone extends PhoneBase {
        return false;
    }

    boolean isInCall() {
        CdmaCall.State foregroundCallState = getForegroundCall().getState();
        CdmaCall.State backgroundCallState = getBackgroundCall().getState();
        CdmaCall.State ringingCallState = getRingingCall().getState();

        return (foregroundCallState.isAlive() || backgroundCallState.isAlive() || ringingCallState
                .isAlive());
    }

    public void
    setNetworkSelectionModeAutomatic(Message response) {
        Log.e(LOG_TAG, "method setNetworkSelectionModeAutomatic is NOT supported in CDMA!");
@@ -472,7 +484,18 @@ public class CDMAPhone extends PhoneBase {
    }

    public boolean handlePinMmi(String dialString) {
        Log.e(LOG_TAG, "method handlePinMmi is NOT supported in CDMA!");
        CdmaMmiCode mmi = CdmaMmiCode.newFromDialString(dialString, this);

        if (mmi == null) {
            Log.e(LOG_TAG, "Mmi is NULL!");
            return false;
        } else if (mmi.isPukCommand()) {
            mPendingMmis.add(mmi);
            mMmiRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null));
            mmi.processCode();
            return true;
        }
        Log.e(LOG_TAG, "Unrecognized mmi!");
        return false;
    }

@@ -484,6 +507,22 @@ public class CDMAPhone extends PhoneBase {
                (mDataConnection.getDataOnRoamingEnabled() || !getServiceState().getRoaming());
    }

    /**
     * Removes the given MMI from the pending list and notifies registrants that
     * it is complete.
     *
     * @param mmi MMI that is done
     */
    void onMMIDone(CdmaMmiCode mmi) {
        /*
         * Only notify complete if it's on the pending list. Otherwise, it's
         * already been handled (eg, previously canceled).
         */
        if (mPendingMmis.remove(mmi)) {
            mMmiCompleteRegistrants.notifyRegistrants(new AsyncResult(null, mmi, null));
        }
    }

    public void setLine1Number(String alphaTag, String number, Message onComplete) {
        Log.e(LOG_TAG, "setLine1Number: not possible in CDMA");
    }
+296 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2006 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.cdma;

import android.content.Context;

import com.android.internal.telephony.CommandException;
import com.android.internal.telephony.MmiCode;

import android.os.AsyncResult;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

import java.util.regex.Pattern;
import java.util.regex.Matcher;

/**
 * This class can handle Puk code Mmi
 *
 * {@hide}
 *
 */
public final class CdmaMmiCode  extends Handler implements MmiCode {
    static final String LOG_TAG = "CDMA_MMI";

    // Constants

    // From TS 22.030 6.5.2
    static final String ACTION_REGISTER = "**";

    // Supp Service codes from TS 22.030 Annex B
    static final String SC_PUK          = "05";

    // Event Constant

    static final int EVENT_SET_COMPLETE = 1;

    // Instance Variables

    CDMAPhone phone;
    Context context;

    String action;              // ACTION_REGISTER
    String sc;                  // Service Code
    String sia, sib, sic;       // Service Info a,b,c
    String poundString;         // Entire MMI string up to and including #
    String dialingNumber;
    String pwd;                 // For password registration

    State state = State.PENDING;
    CharSequence message;

    // Class Variables

    static Pattern sPatternSuppService = Pattern.compile(
        "((\\*|#|\\*#|\\*\\*|##)(\\d{2,3})(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*)(\\*([^*#]*))?)?)?)?#)(.*)");
/*       1  2                    3          4  5       6   7         8    9     10  11             12

         1 = Full string up to and including #
         2 = action
         3 = service code
         5 = SIA
         7 = SIB
         9 = SIC
         10 = dialing number
*/

    static final int MATCH_GROUP_POUND_STRING = 1;
    static final int MATCH_GROUP_ACTION = 2;
    static final int MATCH_GROUP_SERVICE_CODE = 3;
    static final int MATCH_GROUP_SIA = 5;
    static final int MATCH_GROUP_SIB = 7;
    static final int MATCH_GROUP_SIC = 9;
    static final int MATCH_GROUP_PWD_CONFIRM = 11;
    static final int MATCH_GROUP_DIALING_NUMBER = 12;


    // Public Class methods

    /**
     * Check if provided string contains Mmi code in it and create corresponding
     * Mmi if it does
     */

    public static CdmaMmiCode
    newFromDialString(String dialString, CDMAPhone phone) {
        Matcher m;
        CdmaMmiCode ret = null;

        m = sPatternSuppService.matcher(dialString);

        // Is this formatted like a standard supplementary service code?
        if (m.matches()) {
            ret = new CdmaMmiCode(phone);
            ret.poundString = makeEmptyNull(m.group(MATCH_GROUP_POUND_STRING));
            ret.action = makeEmptyNull(m.group(MATCH_GROUP_ACTION));
            ret.sc = makeEmptyNull(m.group(MATCH_GROUP_SERVICE_CODE));
            ret.sia = makeEmptyNull(m.group(MATCH_GROUP_SIA));
            ret.sib = makeEmptyNull(m.group(MATCH_GROUP_SIB));
            ret.sic = makeEmptyNull(m.group(MATCH_GROUP_SIC));
            ret.pwd = makeEmptyNull(m.group(MATCH_GROUP_PWD_CONFIRM));
            ret.dialingNumber = makeEmptyNull(m.group(MATCH_GROUP_DIALING_NUMBER));

        }

        return ret;
    }

    // Private Class methods

    /** make empty strings be null.
     *  Regexp returns empty strings for empty groups
     */
    private static String
    makeEmptyNull (String s) {
        if (s != null && s.length() == 0) return null;

        return s;
    }

    // Constructor

    CdmaMmiCode (CDMAPhone phone) {
        super(phone.getHandler().getLooper());
        this.phone = phone;
        this.context = phone.getContext();
    }

    // MmiCode implementation

    public State
    getState() {
        return state;
    }

    public CharSequence
    getMessage() {
        return message;
    }

    // inherited javadoc suffices
    public void
    cancel() {
        // Complete or failed cannot be cancelled
        if (state == State.COMPLETE || state == State.FAILED) {
            return;
        }

        state = State.CANCELLED;
        phone.onMMIDone (this);
    }

    public boolean isCancelable() {
        return false;
    }

    // Instance Methods

    /**
     * @return true if the Service Code is PIN/PIN2/PUK/PUK2-related
     */
    boolean isPukCommand() {
        return sc != null && sc.equals(SC_PUK);
     }

    boolean isRegister() {
        return action != null && action.equals(ACTION_REGISTER);
    }

    public boolean isUssdRequest() {
        Log.w(LOG_TAG, "isUssdRequest is not implemented in CdmaMmiCode");
        return false;
    }

    /** Process a MMI PUK code */
    void
    processCode () {
        try {
            if (isPukCommand()) {
                // sia = old PUK
                // sib = new PIN
                // sic = new PIN
                String oldPinOrPuk = sia;
                String newPin = sib;
                int pinLen = newPin.length();
                if (isRegister()) {
                    if (!newPin.equals(sic)) {
                        // password mismatch; return error
                        handlePasswordError(com.android.internal.R.string.mismatchPin);
                    } else if (pinLen < 4 || pinLen > 8 ) {
                        // invalid length
                        handlePasswordError(com.android.internal.R.string.invalidPin);
                    } else {
                        phone.mCM.supplyIccPuk(oldPinOrPuk, newPin,
                                obtainMessage(EVENT_SET_COMPLETE, this));
                    }
                } else {
                    throw new RuntimeException ("Invalid or Unsupported MMI Code");
                }
            } else {
                throw new RuntimeException ("Invalid or Unsupported MMI Code");
            }
        } catch (RuntimeException exc) {
            state = State.FAILED;
            message = context.getText(com.android.internal.R.string.mmiError);
            phone.onMMIDone(this);
        }
    }

    private void handlePasswordError(int res) {
        state = State.FAILED;
        StringBuilder sb = new StringBuilder(getScString());
        sb.append("\n");
        sb.append(context.getText(res));
        message = sb;
        phone.onMMIDone(this);
    }

    public void
    handleMessage (Message msg) {
        AsyncResult ar;

        if (msg.what == EVENT_SET_COMPLETE) {
            ar = (AsyncResult) (msg.obj);
            onSetComplete(ar);
        } else {
            Log.e(LOG_TAG, "Unexpected reply");
        }
    }
    // Private instance methods

    private CharSequence getScString() {
        if (sc != null) {
            if (isPukCommand()) {
                return context.getText(com.android.internal.R.string.PinMmi);
            }
        }

        return "";
    }

    private void
    onSetComplete(AsyncResult ar){
        StringBuilder sb = new StringBuilder(getScString());
        sb.append("\n");

        if (ar.exception != null) {
            state = State.FAILED;
            if (ar.exception instanceof CommandException) {
                CommandException.Error err = ((CommandException)(ar.exception)).getCommandError();
                if (err == CommandException.Error.PASSWORD_INCORRECT) {
                    if (isPukCommand()) {
                        sb.append(context.getText(
                                com.android.internal.R.string.badPuk));
                    } else {
                        sb.append(context.getText(
                                com.android.internal.R.string.passwordIncorrect));
                    }
                } else {
                    sb.append(context.getText(
                            com.android.internal.R.string.mmiError));
                }
            } else {
                sb.append(context.getText(
                        com.android.internal.R.string.mmiError));
            }
        } else if (isRegister()) {
            state = State.COMPLETE;
            sb.append(context.getText(
                    com.android.internal.R.string.serviceRegistered));
        } else {
            state = State.FAILED;
            sb.append(context.getText(
                    com.android.internal.R.string.mmiError));
        }

        message = sb;
        phone.onMMIDone(this);
    }

}
+7 −0
Original line number Diff line number Diff line
@@ -94,6 +94,13 @@ final class GsmSMSDispatcher extends SMSDispatcher {
        SmsMessage sms = (SmsMessage) smsb;
        boolean handled = false;

        if (sms.isTypeZero()) {
            // As per 3GPP TS 23.040 9.2.3.9, Type Zero messages should not be
            // Displayed/Stored/Notified. They should only be acknowledged.
            Log.d(TAG, "Received short message type 0, Dont display or store it. Send Ack");
            return Intents.RESULT_SMS_HANDLED;
        }

        // Special case the message waiting indicator messages
        if (sms.isMWISetMessage()) {
            mGsmPhone.updateMessageWaitingIndicator(true);
+8 −0
Original line number Diff line number Diff line
@@ -110,6 +110,14 @@ public class SmsMessage extends SmsMessageBase{
        }
    }

    /**
     * 3GPP TS 23.040 9.2.3.9 specifies that Type Zero messages are indicated
     * by TP_PID field set to value 0x40
     */
    public boolean isTypeZero() {
        return (protocolIdentifier == 0x40);
    }

    /**
     * TS 27.005 3.4.1 lines[0] and lines[1] are the two lines read from the
     * +CMT unsolicited response (PDU mode, of course)