GpsNetInitiatedHandlerpublic class GpsNetInitiatedHandler extends Object A GPS Network-initiated Handler class used by LocationManager.
{@hide} |
Fields Summary |
---|
private static final String | TAG | private static final boolean | DEBUG | private static final boolean | VERBOSE | public static final String | ACTION_NI_VERIFY | public static final String | NI_INTENT_KEY_NOTIF_ID | public static final String | NI_INTENT_KEY_TITLE | public static final String | NI_INTENT_KEY_MESSAGE | public static final String | NI_INTENT_KEY_TIMEOUT | public static final String | NI_INTENT_KEY_DEFAULT_RESPONSE | public static final String | NI_RESPONSE_EXTRA_CMD | public static final String | NI_EXTRA_CMD_NOTIF_ID | public static final String | NI_EXTRA_CMD_RESPONSE | public static final int | GPS_NI_TYPE_VOICE | public static final int | GPS_NI_TYPE_UMTS_SUPL | public static final int | GPS_NI_TYPE_UMTS_CTRL_PLANE | public static final int | GPS_NI_TYPE_EMERGENCY_SUPL | public static final int | GPS_NI_RESPONSE_ACCEPT | public static final int | GPS_NI_RESPONSE_DENY | public static final int | GPS_NI_RESPONSE_NORESP | public static final int | GPS_NI_RESPONSE_IGNORE | public static final int | GPS_NI_NEED_NOTIFY | public static final int | GPS_NI_NEED_VERIFY | public static final int | GPS_NI_PRIVACY_OVERRIDE | public static final int | GPS_ENC_NONE | public static final int | GPS_ENC_SUPL_GSM_DEFAULT | public static final int | GPS_ENC_SUPL_UTF8 | public static final int | GPS_ENC_SUPL_UCS2 | public static final int | GPS_ENC_UNKNOWN | private final android.content.Context | mContext | private final android.telephony.TelephonyManager | mTelephonyManager | private final android.telephony.PhoneStateListener | mPhoneStateListener | private final android.location.LocationManager | mLocationManager | private boolean | mPlaySounds | private boolean | mPopupImmediately | private volatile boolean | mIsSuplEsEnabled | private volatile boolean | mIsInEmergency | private volatile boolean | mIsLocationEnabled | private final android.location.INetInitiatedListener | mNetInitiatedListener | private static boolean | mIsHexInput | private final android.content.BroadcastReceiver | mBroadcastReciever | private android.app.Notification | mNiNotificationThe notification that is shown when a network-initiated notification
(and verification) event is received.
This is lazily created, so use {@link #setNINotification()}. |
Constructors Summary |
---|
public GpsNetInitiatedHandler(android.content.Context context, android.location.INetInitiatedListener netInitiatedListener, boolean isSuplEsEnabled)
mContext = context;
if (netInitiatedListener == null) {
throw new IllegalArgumentException("netInitiatedListener is null");
} else {
mNetInitiatedListener = netInitiatedListener;
}
setSuplEsEnabled(isSuplEsEnabled);
mLocationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
updateLocationMode();
mTelephonyManager =
(TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
mPhoneStateListener = new PhoneStateListener() {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
if (DEBUG) Log.d(TAG, "onCallStateChanged(): state is "+ state);
// listening for emergency call ends
if (state == TelephonyManager.CALL_STATE_IDLE) {
setInEmergency(false);
}
}
};
mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Intent.ACTION_NEW_OUTGOING_CALL);
intentFilter.addAction(LocationManager.MODE_CHANGED_ACTION);
mContext.registerReceiver(mBroadcastReciever, intentFilter);
|
Methods Summary |
---|
static java.lang.String | decodeGSMPackedString(byte[] input)Unpacks an byte array containing 7-bit packed characters into a String.
final char PADDING_CHAR = 0x00;
int lengthBytes = input.length;
int lengthSeptets = (lengthBytes * 8) / 7;
String decoded;
/* Special case where the last 7 bits in the last byte could hold a valid
* 7-bit character or a padding character. Drop the last 7-bit character
* if it is a padding character.
*/
if (lengthBytes % 7 == 0) {
if (lengthBytes > 0) {
if ((input[lengthBytes - 1] >> 1) == PADDING_CHAR) {
lengthSeptets = lengthSeptets - 1;
}
}
}
decoded = GsmAlphabet.gsm7BitPackedToString(input, 0, lengthSeptets);
// Return "" if decoding of GSM packed string fails
if (null == decoded) {
Log.e(TAG, "Decoding of GSM packed string failed");
decoded = "";
}
return decoded;
| private static java.lang.String | decodeString(java.lang.String original, boolean isHex, int coding)Decode NI string
String decoded = original;
byte[] input = stringToByteArray(original, isHex);
switch (coding) {
case GPS_ENC_NONE:
decoded = original;
break;
case GPS_ENC_SUPL_GSM_DEFAULT:
decoded = decodeGSMPackedString(input);
break;
case GPS_ENC_SUPL_UTF8:
decoded = decodeUTF8String(input);
break;
case GPS_ENC_SUPL_UCS2:
decoded = decodeUCS2String(input);
break;
case GPS_ENC_UNKNOWN:
decoded = original;
break;
default:
Log.e(TAG, "Unknown encoding " + coding + " for NI text " + original);
break;
}
return decoded;
| static java.lang.String | decodeUCS2String(byte[] input)
String decoded = "";
try {
decoded = new String(input, "UTF-16");
}
catch (UnsupportedEncodingException e)
{
throw new AssertionError();
}
return decoded;
| static java.lang.String | decodeUTF8String(byte[] input)
String decoded = "";
try {
decoded = new String(input, "UTF-8");
}
catch (UnsupportedEncodingException e)
{
throw new AssertionError();
}
return decoded;
| private static java.lang.String | getDialogMessage(com.android.internal.location.GpsNetInitiatedHandler$GpsNiNotification notif, android.content.Context context)
return getNotifMessage(notif, context);
| public static java.lang.String | getDialogTitle(com.android.internal.location.GpsNetInitiatedHandler$GpsNiNotification notif, android.content.Context context)
return getNotifTitle(notif, context);
| private android.content.Intent | getDlgIntent(com.android.internal.location.GpsNetInitiatedHandler$GpsNiNotification notif)
Intent intent = new Intent();
String title = getDialogTitle(notif, mContext);
String message = getDialogMessage(notif, mContext);
// directly bring up the NI activity
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.setClass(mContext, com.android.internal.app.NetInitiatedActivity.class);
// put data in the intent
intent.putExtra(NI_INTENT_KEY_NOTIF_ID, notif.notificationId);
intent.putExtra(NI_INTENT_KEY_TITLE, title);
intent.putExtra(NI_INTENT_KEY_MESSAGE, message);
intent.putExtra(NI_INTENT_KEY_TIMEOUT, notif.timeout);
intent.putExtra(NI_INTENT_KEY_DEFAULT_RESPONSE, notif.defaultResponse);
if (DEBUG) Log.d(TAG, "generateIntent, title: " + title + ", message: " + message +
", timeout: " + notif.timeout);
return intent;
| public boolean | getInEmergency()
boolean isInEmergencyCallback = Boolean.parseBoolean(
SystemProperties.get(TelephonyProperties.PROPERTY_INECM_MODE));
return mIsInEmergency || isInEmergencyCallback;
| public boolean | getLocationEnabled()Checks if user agreed to use location.
return mIsLocationEnabled;
| private static java.lang.String | getNotifMessage(com.android.internal.location.GpsNetInitiatedHandler$GpsNiNotification notif, android.content.Context context)
String message = String.format(context.getString(R.string.gpsNotifMessage),
decodeString(notif.requestorId, mIsHexInput, notif.requestorIdEncoding),
decodeString(notif.text, mIsHexInput, notif.textEncoding));
return message;
| private static java.lang.String | getNotifTicker(com.android.internal.location.GpsNetInitiatedHandler$GpsNiNotification notif, android.content.Context context)
String ticker = String.format(context.getString(R.string.gpsNotifTicker),
decodeString(notif.requestorId, mIsHexInput, notif.requestorIdEncoding),
decodeString(notif.text, mIsHexInput, notif.textEncoding));
return ticker;
| private static java.lang.String | getNotifTitle(com.android.internal.location.GpsNetInitiatedHandler$GpsNiNotification notif, android.content.Context context)
String title = String.format(context.getString(R.string.gpsNotifTitle));
return title;
| public boolean | getSuplEsEnabled()
return mIsSuplEsEnabled;
| private void | handleNi(com.android.internal.location.GpsNetInitiatedHandler$GpsNiNotification notif)
if (DEBUG) Log.d(TAG, "in handleNi () :"
+ " needNotify: " + notif.needNotify
+ " needVerify: " + notif.needVerify
+ " privacyOverride: " + notif.privacyOverride
+ " mPopupImmediately: " + mPopupImmediately
+ " mInEmergency: " + getInEmergency());
if (!getLocationEnabled() && !getInEmergency()) {
// Location is currently disabled, ignore all NI requests.
try {
mNetInitiatedListener.sendNiResponse(notif.notificationId,
GPS_NI_RESPONSE_IGNORE);
} catch (RemoteException e) {
Log.e(TAG, "RemoteException in sendNiResponse");
}
}
if (notif.needNotify) {
// If NI does not need verify or the dialog is not requested
// to pop up immediately, the dialog box will not pop up.
if (notif.needVerify && mPopupImmediately) {
// Popup the dialog box now
openNiDialog(notif);
} else {
// Show the notification
setNiNotification(notif);
}
}
// ACCEPT cases: 1. Notify, no verify; 2. no notify, no verify;
// 3. privacy override.
if (!notif.needVerify || notif.privacyOverride) {
try {
mNetInitiatedListener.sendNiResponse(notif.notificationId,
GPS_NI_RESPONSE_ACCEPT);
} catch (RemoteException e) {
Log.e(TAG, "RemoteException in sendNiResponse");
}
}
| private void | handleNiInEs(com.android.internal.location.GpsNetInitiatedHandler$GpsNiNotification notif)
if (DEBUG) Log.d(TAG, "in handleNiInEs () :"
+ " niType: " + notif.niType
+ " notificationId: " + notif.notificationId);
// UE is in emergency mode when in emergency call mode or in emergency call back mode
/*
1. When SUPL ES bit is off and UE is not in emergency mode:
Call handleNi() to do legacy behaviour.
2. When SUPL ES bit is on and UE is in emergency mode:
Call handleNi() to do acceptance behaviour.
3. When SUPL ES bit is off but UE is in emergency mode:
Ignore the emergency SUPL INIT.
4. When SUPL ES bit is on but UE is not in emergency mode:
Ignore the emergency SUPL INIT.
*/
boolean isNiTypeES = (notif.niType == GPS_NI_TYPE_EMERGENCY_SUPL);
if (isNiTypeES != getInEmergency()) {
try {
mNetInitiatedListener.sendNiResponse(notif.notificationId,
GPS_NI_RESPONSE_IGNORE);
} catch (RemoteException e) {
Log.e(TAG, "RemoteException in sendNiResponse");
}
} else {
handleNi(notif);
}
| public void | handleNiNotification(com.android.internal.location.GpsNetInitiatedHandler$GpsNiNotification notif)
if (DEBUG) Log.d(TAG, "in handleNiNotification () :"
+ " notificationId: " + notif.notificationId
+ " requestorId: " + notif.requestorId
+ " text: " + notif.text
+ " mIsSuplEsEnabled" + getSuplEsEnabled()
+ " mIsLocationEnabled" + getLocationEnabled());
if (getSuplEsEnabled()) {
handleNiInEs(notif);
} else {
handleNi(notif);
}
//////////////////////////////////////////////////////////////////////////
// A note about timeout
// According to the protocol, in the need_notify and need_verify case,
// a default response should be sent when time out.
//
// In some GPS hardware, the GPS driver (under HAL) can handle the timeout case
// and this class GpsNetInitiatedHandler does not need to do anything.
//
// However, the UI should at least close the dialog when timeout. Further,
// for more general handling, timeout response should be added to the Handler here.
//
| private void | openNiDialog(com.android.internal.location.GpsNetInitiatedHandler$GpsNiNotification notif)
Intent intent = getDlgIntent(notif);
if (DEBUG) Log.d(TAG, "openNiDialog, notifyId: " + notif.notificationId +
", requestorId: " + notif.requestorId +
", text: " + notif.text);
mContext.startActivity(intent);
| public void | setInEmergency(boolean isInEmergency)
mIsInEmergency = isInEmergency;
| private synchronized void | setNiNotification(com.android.internal.location.GpsNetInitiatedHandler$GpsNiNotification notif)
NotificationManager notificationManager = (NotificationManager) mContext
.getSystemService(Context.NOTIFICATION_SERVICE);
if (notificationManager == null) {
return;
}
String title = getNotifTitle(notif, mContext);
String message = getNotifMessage(notif, mContext);
if (DEBUG) Log.d(TAG, "setNiNotification, notifyId: " + notif.notificationId +
", title: " + title +
", message: " + message);
// Construct Notification
if (mNiNotification == null) {
mNiNotification = new Notification();
mNiNotification.icon = com.android.internal.R.drawable.stat_sys_gps_on; /* Change notification icon here */
mNiNotification.when = 0;
}
if (mPlaySounds) {
mNiNotification.defaults |= Notification.DEFAULT_SOUND;
} else {
mNiNotification.defaults &= ~Notification.DEFAULT_SOUND;
}
mNiNotification.flags = Notification.FLAG_ONGOING_EVENT | Notification.FLAG_AUTO_CANCEL;
mNiNotification.tickerText = getNotifTicker(notif, mContext);
// if not to popup dialog immediately, pending intent will open the dialog
Intent intent = !mPopupImmediately ? getDlgIntent(notif) : new Intent();
PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, intent, 0);
mNiNotification.color = mContext.getResources().getColor(
com.android.internal.R.color.system_notification_accent_color);
mNiNotification.setLatestEventInfo(mContext, title, message, pi);
notificationManager.notifyAsUser(null, notif.notificationId, mNiNotification,
UserHandle.ALL);
| public void | setSuplEsEnabled(boolean isEnabled)
mIsSuplEsEnabled = isEnabled;
| static byte[] | stringToByteArray(java.lang.String original, boolean isHex)
int length = isHex ? original.length() / 2 : original.length();
byte[] output = new byte[length];
int i;
if (isHex)
{
for (i = 0; i < length; i++)
{
output[i] = (byte) Integer.parseInt(original.substring(i*2, i*2+2), 16);
}
}
else {
for (i = 0; i < length; i++)
{
output[i] = (byte) original.charAt(i);
}
}
return output;
| public void | updateLocationMode()Updates Location enabler based on location setting.
mIsLocationEnabled = mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
|
|