122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie/*
222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie * Copyright (C) 2008 The Android Open Source Project
322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie *
422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie * Licensed under the Apache License, Version 2.0 (the "License");
522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie * you may not use this file except in compliance with the License.
622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie * You may obtain a copy of the License at
722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie *
822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie *      http://www.apache.org/licenses/LICENSE-2.0
922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie *
1022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie * Unless required by applicable law or agreed to in writing, software
1122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie * distributed under the License is distributed on an "AS IS" BASIS,
1222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie * See the License for the specific language governing permissions and
1422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie * limitations under the License.
1522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie */
1622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
1722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xiepackage com.android.internal.location;
1822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
1922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport java.io.UnsupportedEncodingException;
2022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
2122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport android.app.Notification;
2222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport android.app.NotificationManager;
2322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport android.app.PendingIntent;
2422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport android.content.Context;
2522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport android.content.Intent;
2679e642e8ed75033eacc461633a8f4cd5157d25dfMike Lockwoodimport android.location.LocationManager;
2722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport android.os.Bundle;
2822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport android.os.RemoteException;
2922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport android.util.Log;
3022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
3122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie/**
3222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie * A GPS Network-initiated Handler class used by LocationManager.
3322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie *
3422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie * {@hide}
3522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie */
3622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xiepublic class GpsNetInitiatedHandler {
3722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
3822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    private static final String TAG = "GpsNetInitiatedHandler";
3922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
4022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    private static final boolean DEBUG = true;
4122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    private static final boolean VERBOSE = false;
4222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
4322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    // NI verify activity for bringing up UI (not used yet)
4422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final String ACTION_NI_VERIFY = "android.intent.action.NETWORK_INITIATED_VERIFY";
4522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
4622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    // string constants for defining data fields in NI Intent
4722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final String NI_INTENT_KEY_NOTIF_ID = "notif_id";
4822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final String NI_INTENT_KEY_TITLE = "title";
4922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final String NI_INTENT_KEY_MESSAGE = "message";
5022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final String NI_INTENT_KEY_TIMEOUT = "timeout";
5122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final String NI_INTENT_KEY_DEFAULT_RESPONSE = "default_resp";
5222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
5322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    // the extra command to send NI response to GpsLocationProvider
5422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final String NI_RESPONSE_EXTRA_CMD = "send_ni_response";
5522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
5622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    // the extra command parameter names in the Bundle
5722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final String NI_EXTRA_CMD_NOTIF_ID = "notif_id";
5822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final String NI_EXTRA_CMD_RESPONSE = "response";
5922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
6022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    // these need to match GpsNiType constants in gps_ni.h
6122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final int GPS_NI_TYPE_VOICE = 1;
6222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final int GPS_NI_TYPE_UMTS_SUPL = 2;
6322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final int GPS_NI_TYPE_UMTS_CTRL_PLANE = 3;
6422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
6522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    // these need to match GpsUserResponseType constants in gps_ni.h
6622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final int GPS_NI_RESPONSE_ACCEPT = 1;
6722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final int GPS_NI_RESPONSE_DENY = 2;
6822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final int GPS_NI_RESPONSE_NORESP = 3;
6922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
7022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    // these need to match GpsNiNotifyFlags constants in gps_ni.h
7122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final int GPS_NI_NEED_NOTIFY = 0x0001;
7222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final int GPS_NI_NEED_VERIFY = 0x0002;
7322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final int GPS_NI_PRIVACY_OVERRIDE = 0x0004;
7422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
7522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    // these need to match GpsNiEncodingType in gps_ni.h
7622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final int GPS_ENC_NONE = 0;
7722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final int GPS_ENC_SUPL_GSM_DEFAULT = 1;
7822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final int GPS_ENC_SUPL_UTF8 = 2;
7922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final int GPS_ENC_SUPL_UCS2 = 3;
8022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final int GPS_ENC_UNKNOWN = -1;
8122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
8222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    private final Context mContext;
8322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
8422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    // parent gps location provider
8579e642e8ed75033eacc461633a8f4cd5157d25dfMike Lockwood    private final LocationManager mLocationManager;
8622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
8722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    // configuration of notificaiton behavior
8822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    private boolean mPlaySounds = false;
8922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    private boolean visible = true;
9022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    private boolean mPopupImmediately = true;
9122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
9222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    // Set to true if string from HAL is encoded as Hex, e.g., "3F0039"
9322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    static private boolean mIsHexInput = true;
9422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
9522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static class GpsNiNotification
9622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    {
9700b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwood        public int notificationId;
9800b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwood        public int niType;
9900b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwood        public boolean needNotify;
10000b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwood        public boolean needVerify;
10100b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwood        public boolean privacyOverride;
10200b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwood        public int timeout;
10300b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwood        public int defaultResponse;
10400b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwood        public String requestorId;
10500b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwood        public String text;
10600b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwood        public int requestorIdEncoding;
10700b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwood        public int textEncoding;
10800b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwood        public Bundle extras;
10922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    };
11022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
11122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static class GpsNiResponse {
1125b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        /* User reponse, one of the values in GpsUserResponseType */
1135b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        int userResponse;
1145b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        /* Optional extra data to pass with the user response */
1155b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        Bundle extras;
11622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    };
11722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
11822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    /**
11922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie     * The notification that is shown when a network-initiated notification
12022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie     * (and verification) event is received.
12122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie     * <p>
12222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie     * This is lazily created, so use {@link #setNINotification()}.
12322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie     */
12422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    private Notification mNiNotification;
12522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
12679e642e8ed75033eacc461633a8f4cd5157d25dfMike Lockwood    public GpsNetInitiatedHandler(Context context) {
1275b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        mContext = context;
1285b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        mLocationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
12922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    }
13022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
13122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    // Handles NI events from HAL
13222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public void handleNiNotification(GpsNiNotification notif)
13322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    {
1345b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        if (DEBUG) Log.d(TAG, "handleNiNotification" + " notificationId: " + notif.notificationId
1355b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood                + " requestorId: " + notif.requestorId + " text: " + notif.text);
1365b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
1375b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        // Notify and verify with immediate pop-up
1385b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        if (notif.needNotify && notif.needVerify && mPopupImmediately)
1395b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        {
1405b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            // Popup the dialog box now
1415b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            openNiDialog(notif);
1425b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        }
1435b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
1445b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        // Notify only, or delayed pop-up (change mPopupImmediately to FALSE)
1455b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        if (notif.needNotify && !notif.needVerify ||
1465b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            notif.needNotify && notif.needVerify && !mPopupImmediately)
1475b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        {
1485b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            // Show the notification
1495b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
1505b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            // if mPopupImmediately == FALSE and needVerify == TRUE, a dialog will be opened
1515b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            // when the user opens the notification message
1525b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
1535b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            setNiNotification(notif);
1545b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        }
1555b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
1565b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        // ACCEPT cases: 1. Notify, no verify; 2. no notify, no verify; 3. privacy override.
1575b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        if ( notif.needNotify && !notif.needVerify ||
1585b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            !notif.needNotify && !notif.needVerify ||
1595b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood             notif.privacyOverride)
1605b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        {
1615b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            mLocationManager.sendNiResponse(notif.notificationId, GPS_NI_RESPONSE_ACCEPT);
1625b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        }
1635b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
1645b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        //////////////////////////////////////////////////////////////////////////
1655b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        //   A note about timeout
1665b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        //   According to the protocol, in the need_notify and need_verify case,
1675b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        //   a default response should be sent when time out.
1685b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        //
1695b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        //   In some GPS hardware, the GPS driver (under HAL) can handle the timeout case
1705b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        //   and this class GpsNetInitiatedHandler does not need to do anything.
1715b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        //
1725b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        //   However, the UI should at least close the dialog when timeout. Further,
1735b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        //   for more general handling, timeout response should be added to the Handler here.
1745b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        //
17522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    }
1765b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
17722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    // Sets the NI notification.
17822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    private synchronized void setNiNotification(GpsNiNotification notif) {
17922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie        NotificationManager notificationManager = (NotificationManager) mContext
18022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie                .getSystemService(Context.NOTIFICATION_SERVICE);
18122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie        if (notificationManager == null) {
18222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie            return;
18322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie        }
1845b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
1855b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        String title = getNotifTitle(notif);
1865b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        String message = getNotifMessage(notif);
1875b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
18822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie        if (DEBUG) Log.d(TAG, "setNiNotification, notifyId: " + notif.notificationId +
1895b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood                ", title: " + title +
1905b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood                ", message: " + message);
1915b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
1925b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        // Construct Notification
1935b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        if (mNiNotification == null) {
1945b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            mNiNotification = new Notification();
1955b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            mNiNotification.icon = com.android.internal.R.drawable.stat_sys_gps_on; /* Change notification icon here */
1965b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            mNiNotification.when = 0;
19722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie        }
1985b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
19922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie        if (mPlaySounds) {
2005b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            mNiNotification.defaults |= Notification.DEFAULT_SOUND;
20122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie        } else {
2025b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            mNiNotification.defaults &= ~Notification.DEFAULT_SOUND;
20322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie        }
2045b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
20522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie        mNiNotification.flags = Notification.FLAG_ONGOING_EVENT;
20622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie        mNiNotification.tickerText = getNotifTicker(notif);
2075b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
20822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie        // if not to popup dialog immediately, pending intent will open the dialog
2095b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        Intent intent = !mPopupImmediately ? getDlgIntent(notif) : new Intent();
21022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie        PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, intent, 0);
21122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie        mNiNotification.setLatestEventInfo(mContext, title, message, pi);
2125b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
21322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie        if (visible) {
21422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie            notificationManager.notify(notif.notificationId, mNiNotification);
21522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie        } else {
21622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie            notificationManager.cancel(notif.notificationId);
21722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie        }
21822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    }
2195b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
22022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    // Opens the notification dialog and waits for user input
2215b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood    private void openNiDialog(GpsNiNotification notif)
22222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    {
2235b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        Intent intent = getDlgIntent(notif);
22422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
2255b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        if (DEBUG) Log.d(TAG, "openNiDialog, notifyId: " + notif.notificationId +
2265b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood                ", requestorId: " + notif.requestorId +
2275b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood                ", text: " + notif.text);
2285b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
2295b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        mContext.startActivity(intent);
23022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    }
2315b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
23222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    // Construct the intent for bringing up the dialog activity, which shows the
23322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    // notification and takes user input
23422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    private Intent getDlgIntent(GpsNiNotification notif)
23522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    {
2365b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        Intent intent = new Intent();
2375b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        String title = getDialogTitle(notif);
2385b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        String message = getDialogMessage(notif);
2395b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
2405b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        // directly bring up the NI activity
2415b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2425b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        intent.setClass(mContext, com.android.internal.app.NetInitiatedActivity.class);
2435b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
2445b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        // put data in the intent
2455b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        intent.putExtra(NI_INTENT_KEY_NOTIF_ID, notif.notificationId);
2465b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        intent.putExtra(NI_INTENT_KEY_TITLE, title);
2475b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        intent.putExtra(NI_INTENT_KEY_MESSAGE, message);
2485b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        intent.putExtra(NI_INTENT_KEY_TIMEOUT, notif.timeout);
2495b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        intent.putExtra(NI_INTENT_KEY_DEFAULT_RESPONSE, notif.defaultResponse);
2505b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
2515b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        if (DEBUG) Log.d(TAG, "generateIntent, title: " + title + ", message: " + message +
2525b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood                ", timeout: " + notif.timeout);
2535b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
2545b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        return intent;
25522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    }
2565b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
25722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    // Converts a string (or Hex string) to a char array
25822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    static byte[] stringToByteArray(String original, boolean isHex)
25922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    {
2605b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        int length = isHex ? original.length() / 2 : original.length();
2615b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        byte[] output = new byte[length];
2625b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        int i;
2635b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
2645b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        if (isHex)
2655b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        {
2665b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            for (i = 0; i < length; i++)
2675b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            {
2685b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood                output[i] = (byte) Integer.parseInt(original.substring(i*2, i*2+2), 16);
2695b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            }
2705b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        }
2715b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        else {
2725b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            for (i = 0; i < length; i++)
2735b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            {
2745b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood                output[i] = (byte) original.charAt(i);
2755b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            }
2765b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        }
2775b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
2785b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        return output;
27922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    }
2805b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
28122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    /**
28222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie     * Unpacks an byte array containing 7-bit packed characters into a String.
2835b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood     *
28422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie     * @param input a 7-bit packed char array
28522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie     * @return the unpacked String
28622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie     */
28722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    static String decodeGSMPackedString(byte[] input)
28822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    {
2895b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        final char CHAR_CR = 0x0D;
2905b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        int nStridx = 0;
2915b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        int nPckidx = 0;
2925b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        int num_bytes = input.length;
2935b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        int cPrev = 0;
2945b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        int cCurr = 0;
2955b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        byte nShift;
2965b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        byte nextChar;
2975b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        byte[] stringBuf = new byte[input.length * 2];
2985b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        String result = "";
2995b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
3005b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        while(nPckidx < num_bytes)
3015b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        {
3025b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            nShift = (byte) (nStridx & 0x07);
3035b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            cCurr = input[nPckidx++];
3045b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            if (cCurr < 0) cCurr += 256;
3055b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
3065b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            /* A 7-bit character can be split at the most between two bytes of packed
3075b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood             ** data.
3085b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood             */
3095b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            nextChar = (byte) (( (cCurr << nShift) | (cPrev >> (8-nShift)) ) & 0x7F);
3105b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            stringBuf[nStridx++] = nextChar;
3115b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
3125b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            /* Special case where the whole of the next 7-bit character fits inside
3135b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood             ** the current byte of packed data.
3145b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood             */
3155b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            if(nShift == 6)
3165b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            {
3175b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood                /* If the next 7-bit character is a CR (0x0D) and it is the last
3185b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood                 ** character, then it indicates a padding character. Drop it.
3195b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood                 */
3205b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood                if (nPckidx == num_bytes || (cCurr >> 1) == CHAR_CR)
3215b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood                {
3225b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood                    break;
3235b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood                }
3245b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
3255b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood                nextChar = (byte) (cCurr >> 1);
3265b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood                stringBuf[nStridx++] = nextChar;
3275b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            }
3285b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
3295b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            cPrev = cCurr;
3305b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        }
3315b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
3325b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        try {
3335b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            result = new String(stringBuf, 0, nStridx, "US-ASCII");
3345b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        }
3355b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        catch (UnsupportedEncodingException e)
3365b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        {
3375b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            Log.e(TAG, e.getMessage());
3385b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        }
3395b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
3405b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        return result;
34122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    }
3425b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
34322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    static String decodeUTF8String(byte[] input)
34422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    {
3455b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        String decoded = "";
3465b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        try {
3475b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            decoded = new String(input, "UTF-8");
3485b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        }
3495b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        catch (UnsupportedEncodingException e)
3505b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        {
3515b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            Log.e(TAG, e.getMessage());
3525b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        }
3535b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        return decoded;
35422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    }
3555b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
35622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    static String decodeUCS2String(byte[] input)
35722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    {
3585b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        String decoded = "";
3595b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        try {
3605b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            decoded = new String(input, "UTF-16");
3615b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        }
3625b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        catch (UnsupportedEncodingException e)
3635b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        {
3645b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            Log.e(TAG, e.getMessage());
3655b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        }
3665b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        return decoded;
36722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    }
3685b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
36922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    /** Decode NI string
3705b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood     *
37122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie     * @param original   The text string to be decoded
37222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie     * @param isHex      Specifies whether the content of the string has been encoded as a Hex string. Encoding
3735b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood     *                   a string as Hex can allow zeros inside the coded text.
37422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie     * @param coding     Specifies the coding scheme of the string, such as GSM, UTF8, UCS2, etc. This coding scheme
3755b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood     *                      needs to match those used passed to HAL from the native GPS driver. Decoding is done according
37622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie     *                   to the <code> coding </code>, after a Hex string is decoded. Generally, if the
3775b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood     *                   notification strings don't need further decoding, <code> coding </code> encoding can be
37822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie     *                   set to -1, and <code> isHex </code> can be false.
37922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie     * @return the decoded string
38022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie     */
38122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    static private String decodeString(String original, boolean isHex, int coding)
38222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    {
3835b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        String decoded = original;
3845b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        byte[] input = stringToByteArray(original, isHex);
3855b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
3865b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        switch (coding) {
3875b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        case GPS_ENC_NONE:
3885b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            decoded = original;
3895b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            break;
3905b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
3915b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        case GPS_ENC_SUPL_GSM_DEFAULT:
3925b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            decoded = decodeGSMPackedString(input);
3935b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            break;
3945b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
3955b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        case GPS_ENC_SUPL_UTF8:
3965b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            decoded = decodeUTF8String(input);
3975b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            break;
3985b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
3995b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        case GPS_ENC_SUPL_UCS2:
4005b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            decoded = decodeUCS2String(input);
4015b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            break;
4025b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
4035b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        case GPS_ENC_UNKNOWN:
4045b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            decoded = original;
4055b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            break;
4065b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
4075b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        default:
4085b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            Log.e(TAG, "Unknown encoding " + coding + " for NI text " + original);
4095b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood            break;
4105b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        }
4115b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        return decoded;
41222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    }
4135b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
41422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    // change this to configure notification display
41522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    static private String getNotifTicker(GpsNiNotification notif)
41622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    {
4175b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        String ticker = String.format("Position request! ReqId: [%s] ClientName: [%s]",
4185b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood                decodeString(notif.requestorId, mIsHexInput, notif.requestorIdEncoding),
4195b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood                decodeString(notif.text, mIsHexInput, notif.textEncoding));
4205b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        return ticker;
42122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    }
4225b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
42322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    // change this to configure notification display
42422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    static private String getNotifTitle(GpsNiNotification notif)
42522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    {
4265b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        String title = String.format("Position Request");
4275b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        return title;
42822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    }
4295b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
43022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    // change this to configure notification display
43122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    static private String getNotifMessage(GpsNiNotification notif)
43222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    {
4335b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        String message = String.format(
4345b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood                "NI Request received from [%s] for client [%s]!",
4355b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood                decodeString(notif.requestorId, mIsHexInput, notif.requestorIdEncoding),
4365b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood                decodeString(notif.text, mIsHexInput, notif.textEncoding));
4375b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        return message;
43822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    }
4395b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
44022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    // change this to configure dialog display (for verification)
44122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    static public String getDialogTitle(GpsNiNotification notif)
44222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    {
4435b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        return getNotifTitle(notif);
44422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    }
4455b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
44622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    // change this to configure dialog display (for verification)
44722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    static private String getDialogMessage(GpsNiNotification notif)
44822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    {
4495b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood        return getNotifMessage(notif);
45022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    }
4515b53244a4e6c81b5346cde22fabbbefe5b472cf7Mike Lockwood
45222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie}
453