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;
2622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport android.os.Bundle;
2722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport android.os.RemoteException;
2822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport android.util.Log;
2922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
3022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie/**
3122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie * A GPS Network-initiated Handler class used by LocationManager.
3222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie *
3322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie * {@hide}
3422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie */
3522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xiepublic class GpsNetInitiatedHandler {
3622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
3722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    private static final String TAG = "GpsNetInitiatedHandler";
3822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
3922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    private static final boolean DEBUG = true;
4022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    private static final boolean VERBOSE = false;
4122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
4222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    // NI verify activity for bringing up UI (not used yet)
4322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final String ACTION_NI_VERIFY = "android.intent.action.NETWORK_INITIATED_VERIFY";
4422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
4522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    // string constants for defining data fields in NI Intent
4622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final String NI_INTENT_KEY_NOTIF_ID = "notif_id";
4722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final String NI_INTENT_KEY_TITLE = "title";
4822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final String NI_INTENT_KEY_MESSAGE = "message";
4922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final String NI_INTENT_KEY_TIMEOUT = "timeout";
5022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final String NI_INTENT_KEY_DEFAULT_RESPONSE = "default_resp";
5122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
5222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    // the extra command to send NI response to GpsLocationProvider
5322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final String NI_RESPONSE_EXTRA_CMD = "send_ni_response";
5422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
5522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    // the extra command parameter names in the Bundle
5622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final String NI_EXTRA_CMD_NOTIF_ID = "notif_id";
5722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final String NI_EXTRA_CMD_RESPONSE = "response";
5822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
5922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    // these need to match GpsNiType constants in gps_ni.h
6022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final int GPS_NI_TYPE_VOICE = 1;
6122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final int GPS_NI_TYPE_UMTS_SUPL = 2;
6222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final int GPS_NI_TYPE_UMTS_CTRL_PLANE = 3;
6322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
6422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    // these need to match GpsUserResponseType constants in gps_ni.h
6522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final int GPS_NI_RESPONSE_ACCEPT = 1;
6622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final int GPS_NI_RESPONSE_DENY = 2;
6722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final int GPS_NI_RESPONSE_NORESP = 3;
6822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
6922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    // these need to match GpsNiNotifyFlags constants in gps_ni.h
7022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final int GPS_NI_NEED_NOTIFY = 0x0001;
7122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final int GPS_NI_NEED_VERIFY = 0x0002;
7222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final int GPS_NI_PRIVACY_OVERRIDE = 0x0004;
7322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
7422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    // these need to match GpsNiEncodingType in gps_ni.h
7522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final int GPS_ENC_NONE = 0;
7622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final int GPS_ENC_SUPL_GSM_DEFAULT = 1;
7722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final int GPS_ENC_SUPL_UTF8 = 2;
7822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final int GPS_ENC_SUPL_UCS2 = 3;
7922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static final int GPS_ENC_UNKNOWN = -1;
8022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
8122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    private final Context mContext;
8222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
8322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    // parent gps location provider
8422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    private final GpsLocationProvider mGpsLocationProvider;
8522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
8622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    // configuration of notificaiton behavior
8722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    private boolean mPlaySounds = false;
8822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    private boolean visible = true;
8922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    private boolean mPopupImmediately = true;
9022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
9122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    // Set to true if string from HAL is encoded as Hex, e.g., "3F0039"
9222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    static private boolean mIsHexInput = true;
9322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
9422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static class GpsNiNotification
9522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    {
9622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	int notificationId;
9722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	int niType;
9822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	boolean needNotify;
9922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	boolean needVerify;
10022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	boolean privacyOverride;
10122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	int timeout;
10222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	int defaultResponse;
10322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	String requestorId;
10422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	String text;
10522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	int requestorIdEncoding;
10622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	int textEncoding;
10722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	Bundle extras;
10822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    };
10922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
11022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public static class GpsNiResponse {
11122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	/* User reponse, one of the values in GpsUserResponseType */
11222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	int userResponse;
11322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	/* Optional extra data to pass with the user response */
11422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	Bundle extras;
11522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    };
11622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
11722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    /**
11822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie     * The notification that is shown when a network-initiated notification
11922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie     * (and verification) event is received.
12022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie     * <p>
12122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie     * This is lazily created, so use {@link #setNINotification()}.
12222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie     */
12322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    private Notification mNiNotification;
12422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
12522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public GpsNetInitiatedHandler(Context context, GpsLocationProvider gpsLocationProvider) {
12622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	mContext = context;
12722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	mGpsLocationProvider = gpsLocationProvider;
12822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    }
12922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
13022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    // Handles NI events from HAL
13122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    public void handleNiNotification(GpsNiNotification notif)
13222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    {
13322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	if (DEBUG) Log.d(TAG, "handleNiNotification" + " notificationId: " + notif.notificationId
13422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    			+ " requestorId: " + notif.requestorId + " text: " + notif.text);
13522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
13622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	// Notify and verify with immediate pop-up
13722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	if (notif.needNotify && notif.needVerify && mPopupImmediately)
13822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	{
13922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		// Popup the dialog box now
14022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		openNiDialog(notif);
14122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	}
14222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
14322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	// Notify only, or delayed pop-up (change mPopupImmediately to FALSE)
14422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	if (notif.needNotify && !notif.needVerify ||
14522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		notif.needNotify && notif.needVerify && !mPopupImmediately)
14622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	{
14722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		// Show the notification
14822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
14922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		// if mPopupImmediately == FALSE and needVerify == TRUE, a dialog will be opened
15022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		// when the user opens the notification message
15122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
15222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		setNiNotification(notif);
15322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	}
15422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
15522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	// ACCEPT cases: 1. Notify, no verify; 2. no notify, no verify; 3. privacy override.
15622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	if ( notif.needNotify && !notif.needVerify ||
15722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		!notif.needNotify && !notif.needVerify ||
15822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		 notif.privacyOverride)
15922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	{
16022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		try {
16122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    			mGpsLocationProvider.getNetInitiatedListener().sendNiResponse(notif.notificationId, GPS_NI_RESPONSE_ACCEPT);
16222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		}
16322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		catch (RemoteException e)
16422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		{
16522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    			Log.e(TAG, e.getMessage());
16622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		}
16722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	}
16822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
16922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	//////////////////////////////////////////////////////////////////////////
17022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	//   A note about timeout
17122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	//   According to the protocol, in the need_notify and need_verify case,
17222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	//   a default response should be sent when time out.
17322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	//
17422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	//   In some GPS hardware, the GPS driver (under HAL) can handle the timeout case
17522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	//   and this class GpsNetInitiatedHandler does not need to do anything.
17622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	//
17722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	//   However, the UI should at least close the dialog when timeout. Further,
17822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	//   for more general handling, timeout response should be added to the Handler here.
17922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	//
18022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    }
18122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
18222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    // Sets the NI notification.
18322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    private synchronized void setNiNotification(GpsNiNotification notif) {
18422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie        NotificationManager notificationManager = (NotificationManager) mContext
18522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie                .getSystemService(Context.NOTIFICATION_SERVICE);
18622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie        if (notificationManager == null) {
18722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie            return;
18822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie        }
18922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
19022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	String title = getNotifTitle(notif);
19122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	String message = getNotifMessage(notif);
19222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
19322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie        if (DEBUG) Log.d(TAG, "setNiNotification, notifyId: " + notif.notificationId +
19422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie        		", title: " + title +
19522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie        		", message: " + message);
19622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
19722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	// Construct Notification
19822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	if (mNiNotification == null) {
19922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie        	mNiNotification = new Notification();
20022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie        	mNiNotification.icon = com.android.internal.R.drawable.stat_sys_gps_on; /* Change notification icon here */
20122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie        	mNiNotification.when = 0;
20222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie        }
20322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
20422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie        if (mPlaySounds) {
20522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie        	mNiNotification.defaults |= Notification.DEFAULT_SOUND;
20622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie        } else {
20722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie        	mNiNotification.defaults &= ~Notification.DEFAULT_SOUND;
20822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie        }
20922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
21022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie        mNiNotification.flags = Notification.FLAG_ONGOING_EVENT;
21122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie        mNiNotification.tickerText = getNotifTicker(notif);
21222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
21322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie        // if not to popup dialog immediately, pending intent will open the dialog
21422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie        Intent intent = !mPopupImmediately ? getDlgIntent(notif) : new Intent();
21522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie        PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, intent, 0);
21622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie        mNiNotification.setLatestEventInfo(mContext, title, message, pi);
21722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
21822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie        if (visible) {
21922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie            notificationManager.notify(notif.notificationId, mNiNotification);
22022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie        } else {
22122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie            notificationManager.cancel(notif.notificationId);
22222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie        }
22322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    }
22422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
22522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    // Opens the notification dialog and waits for user input
22622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    private void openNiDialog(GpsNiNotification notif)
22722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    {
22822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	Intent intent = getDlgIntent(notif);
22922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
23022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	if (DEBUG) Log.d(TAG, "openNiDialog, notifyId: " + notif.notificationId +
23122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    			", requestorId: " + notif.requestorId +
23222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    			", text: " + notif.text);
23322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
23422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	mContext.startActivity(intent);
23522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    }
23622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
23722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    // Construct the intent for bringing up the dialog activity, which shows the
23822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    // notification and takes user input
23922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    private Intent getDlgIntent(GpsNiNotification notif)
24022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    {
24122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	Intent intent = new Intent();
24222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	String title = getDialogTitle(notif);
24322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	String message = getDialogMessage(notif);
24422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
24522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	// directly bring up the NI activity
24622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
24722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	intent.setClass(mContext, com.android.internal.app.NetInitiatedActivity.class);
24822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
24922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	// put data in the intent
25022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	intent.putExtra(NI_INTENT_KEY_NOTIF_ID, notif.notificationId);
25122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	intent.putExtra(NI_INTENT_KEY_TITLE, title);
25222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	intent.putExtra(NI_INTENT_KEY_MESSAGE, message);
25322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	intent.putExtra(NI_INTENT_KEY_TIMEOUT, notif.timeout);
25422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	intent.putExtra(NI_INTENT_KEY_DEFAULT_RESPONSE, notif.defaultResponse);
25522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
25622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	if (DEBUG) Log.d(TAG, "generateIntent, title: " + title + ", message: " + message +
25722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    			", timeout: " + notif.timeout);
25822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
25922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	return intent;
26022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    }
26122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
26222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    // Converts a string (or Hex string) to a char array
26322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    static byte[] stringToByteArray(String original, boolean isHex)
26422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    {
26522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	int length = isHex ? original.length() / 2 : original.length();
26622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	byte[] output = new byte[length];
26722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	int i;
26822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
26922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	if (isHex)
27022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	{
27122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		for (i = 0; i < length; i++)
27222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		{
27322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    			output[i] = (byte) Integer.parseInt(original.substring(i*2, i*2+2), 16);
27422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		}
27522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	}
27622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	else {
27722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		for (i = 0; i < length; i++)
27822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		{
27922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    			output[i] = (byte) original.charAt(i);
28022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		}
28122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	}
28222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
28322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	return output;
28422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    }
28522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
28622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    /**
28722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie     * Unpacks an byte array containing 7-bit packed characters into a String.
28822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie     *
28922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie     * @param input a 7-bit packed char array
29022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie     * @return the unpacked String
29122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie     */
29222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    static String decodeGSMPackedString(byte[] input)
29322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    {
29422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	final char CHAR_CR = 0x0D;
29522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	int nStridx = 0;
29622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	int nPckidx = 0;
29722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	int num_bytes = input.length;
29822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	int cPrev = 0;
29922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	int cCurr = 0;
30022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	byte nShift;
30122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	byte nextChar;
30222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	byte[] stringBuf = new byte[input.length * 2];
30322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	String result = "";
30422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
30522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	while(nPckidx < num_bytes)
30622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	{
30722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		nShift = (byte) (nStridx & 0x07);
30822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		cCurr = input[nPckidx++];
30922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		if (cCurr < 0) cCurr += 256;
31022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
31122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		/* A 7-bit character can be split at the most between two bytes of packed
31222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		 ** data.
31322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		 */
31422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		nextChar = (byte) (( (cCurr << nShift) | (cPrev >> (8-nShift)) ) & 0x7F);
31522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		stringBuf[nStridx++] = nextChar;
31622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
31722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		/* Special case where the whole of the next 7-bit character fits inside
31822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		 ** the current byte of packed data.
31922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		 */
32022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		if(nShift == 6)
32122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		{
32222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    			/* If the next 7-bit character is a CR (0x0D) and it is the last
32322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    			 ** character, then it indicates a padding character. Drop it.
32422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    			 */
32522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    			if (nPckidx == num_bytes || (cCurr >> 1) == CHAR_CR)
32622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    			{
32722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    				break;
32822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    			}
32922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
33022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    			nextChar = (byte) (cCurr >> 1);
33122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    			stringBuf[nStridx++] = nextChar;
33222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		}
33322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
33422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		cPrev = cCurr;
33522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	}
33622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
33722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	try{
33822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		result = new String(stringBuf, 0, nStridx, "US-ASCII");
33922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	}
34022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	catch (UnsupportedEncodingException e)
34122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	{
34222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		Log.e(TAG, e.getMessage());
34322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	}
34422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
34522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	return result;
34622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    }
34722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
34822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    static String decodeUTF8String(byte[] input)
34922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    {
35022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	String decoded = "";
35122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	try {
35222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		decoded = new String(input, "UTF-8");
35322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	}
35422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	catch (UnsupportedEncodingException e)
35522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	{
35622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		Log.e(TAG, e.getMessage());
35722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	}
35822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie		return decoded;
35922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    }
36022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
36122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    static String decodeUCS2String(byte[] input)
36222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    {
36322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	String decoded = "";
36422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	try {
36522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		decoded = new String(input, "UTF-16");
36622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	}
36722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	catch (UnsupportedEncodingException e)
36822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	{
36922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		Log.e(TAG, e.getMessage());
37022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	}
37122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie		return decoded;
37222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    }
37322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
37422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    /** Decode NI string
37522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie     *
37622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie     * @param original   The text string to be decoded
37722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie     * @param isHex      Specifies whether the content of the string has been encoded as a Hex string. Encoding
37822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie     *                   a string as Hex can allow zeros inside the coded text.
37922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie     * @param coding     Specifies the coding scheme of the string, such as GSM, UTF8, UCS2, etc. This coding scheme
38022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie     * 					 needs to match those used passed to HAL from the native GPS driver. Decoding is done according
38122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie     *                   to the <code> coding </code>, after a Hex string is decoded. Generally, if the
38222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie     *                   notification strings don't need further decoding, <code> coding </code> encoding can be
38322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie     *                   set to -1, and <code> isHex </code> can be false.
38422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie     * @return the decoded string
38522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie     */
38622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    static private String decodeString(String original, boolean isHex, int coding)
38722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    {
38822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	String decoded = original;
38922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	byte[] input = stringToByteArray(original, isHex);
39022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
39122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	switch (coding) {
39222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	case GPS_ENC_NONE:
39322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		decoded = original;
39422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		break;
39522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
39622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	case GPS_ENC_SUPL_GSM_DEFAULT:
39722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		decoded = decodeGSMPackedString(input);
39822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		break;
39922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
40022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	case GPS_ENC_SUPL_UTF8:
40122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		decoded = decodeUTF8String(input);
40222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		break;
40322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
40422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	case GPS_ENC_SUPL_UCS2:
40522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		decoded = decodeUCS2String(input);
40622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		break;
40722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
40822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	case GPS_ENC_UNKNOWN:
40922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		decoded = original;
41022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		break;
41122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
41222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	default:
41322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		Log.e(TAG, "Unknown encoding " + coding + " for NI text " + original);
41422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    		break;
41522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	}
41622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	return decoded;
41722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    }
41822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
41922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    // change this to configure notification display
42022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    static private String getNotifTicker(GpsNiNotification notif)
42122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    {
42222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	String ticker = String.format("Position request! ReqId: [%s] ClientName: [%s]",
42322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    			decodeString(notif.requestorId, mIsHexInput, notif.requestorIdEncoding),
42422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    			decodeString(notif.text, mIsHexInput, notif.textEncoding));
42522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	return ticker;
42622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    }
42722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
42822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    // change this to configure notification display
42922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    static private String getNotifTitle(GpsNiNotification notif)
43022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    {
43122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	String title = String.format("Position Request");
43222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	return title;
43322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    }
43422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
43522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    // change this to configure notification display
43622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    static private String getNotifMessage(GpsNiNotification notif)
43722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    {
43822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	String message = String.format(
43922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    			"NI Request received from [%s] for client [%s]!",
44022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    			decodeString(notif.requestorId, mIsHexInput, notif.requestorIdEncoding),
44122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    			decodeString(notif.text, mIsHexInput, notif.textEncoding));
44222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	return message;
44322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    }
44422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
44522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    // change this to configure dialog display (for verification)
44622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    static public String getDialogTitle(GpsNiNotification notif)
44722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    {
44822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	return getNotifTitle(notif);
44922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    }
45022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
45122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    // change this to configure dialog display (for verification)
45222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    static private String getDialogMessage(GpsNiNotification notif)
45322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    {
45422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    	return getNotifMessage(notif);
45522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie    }
45622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie
45722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie}
458