am dff6b8e7
: Merge "Add --non-constant-id to aapt."
* commit 'dff6b8e71dda9f5d841fa26408714aec2aef1505': GpsLocationProvider: Clean up HAL initialization/cleanup sequence Fixed GSM encoded network initiated position request Ensuring thread-safe usage of DateFormat. Fixing infinite loop for zero duration. Fix for an infinite loop while scrolling lists. WAPPushManager, WAP Push over SMS message handler Add --non-constant-id to aapt.
This commit is contained in:
@ -184,6 +184,7 @@ LOCAL_SRC_FILES += \
|
||||
telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl \
|
||||
telephony/java/com/android/internal/telephony/IIccPhoneBook.aidl \
|
||||
telephony/java/com/android/internal/telephony/ISms.aidl \
|
||||
telephony/java/com/android/internal/telephony/IWapPushManager.aidl \
|
||||
wifi/java/android/net/wifi/IWifiManager.aidl \
|
||||
telephony/java/com/android/internal/telephony/IExtendedNetworkService.aidl \
|
||||
vpn/java/android/net/vpn/IVpnService.aidl \
|
||||
|
@ -642,6 +642,11 @@ public class DateUtils
|
||||
|
||||
private static void initFormatStrings() {
|
||||
synchronized (sLock) {
|
||||
initFormatStringsLocked();
|
||||
}
|
||||
}
|
||||
|
||||
private static void initFormatStringsLocked() {
|
||||
Resources r = Resources.getSystem();
|
||||
Configuration cfg = r.getConfiguration();
|
||||
if (sLastConfig == null || !sLastConfig.equals(cfg)) {
|
||||
@ -651,7 +656,6 @@ public class DateUtils
|
||||
sElapsedFormatHMMSS = r.getString(com.android.internal.R.string.elapsed_time_short_format_h_mm_ss);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Format a time so it appears like it would in the status bar clock.
|
||||
@ -659,9 +663,11 @@ public class DateUtils
|
||||
* @hide
|
||||
*/
|
||||
public static final CharSequence timeString(long millis) {
|
||||
initFormatStrings();
|
||||
synchronized (sLock) {
|
||||
initFormatStringsLocked();
|
||||
return sStatusTimeFormat.format(millis);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats an elapsed time in the form "MM:SS" or "H:MM:SS"
|
||||
|
@ -190,7 +190,7 @@ public class TimeUtils {
|
||||
int pos = 0;
|
||||
fieldLen -= 1;
|
||||
while (pos < fieldLen) {
|
||||
formatStr[pos] = ' ';
|
||||
formatStr[pos++] = ' ';
|
||||
}
|
||||
formatStr[pos] = '0';
|
||||
return pos+1;
|
||||
|
@ -317,6 +317,7 @@ public class EdgeGlow {
|
||||
mEdgeScaleY = mEdgeScaleYStart +
|
||||
(mEdgeScaleYFinish - mEdgeScaleYStart) *
|
||||
interp * factor;
|
||||
mState = STATE_RECEDE;
|
||||
break;
|
||||
case STATE_RECEDE:
|
||||
mState = STATE_IDLE;
|
||||
|
@ -29,6 +29,7 @@ import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.R;
|
||||
import com.android.internal.telephony.GsmAlphabet;
|
||||
|
||||
/**
|
||||
* A GPS Network-initiated Handler class used by LocationManager.
|
||||
@ -288,58 +289,32 @@ public class GpsNetInitiatedHandler {
|
||||
*/
|
||||
static String decodeGSMPackedString(byte[] input)
|
||||
{
|
||||
final char CHAR_CR = 0x0D;
|
||||
int nStridx = 0;
|
||||
int nPckidx = 0;
|
||||
int num_bytes = input.length;
|
||||
int cPrev = 0;
|
||||
int cCurr = 0;
|
||||
byte nShift;
|
||||
byte nextChar;
|
||||
byte[] stringBuf = new byte[input.length * 2];
|
||||
String result = "";
|
||||
final char PADDING_CHAR = 0x00;
|
||||
int lengthBytes = input.length;
|
||||
int lengthSeptets = (lengthBytes * 8) / 7;
|
||||
String decoded;
|
||||
|
||||
while(nPckidx < num_bytes)
|
||||
{
|
||||
nShift = (byte) (nStridx & 0x07);
|
||||
cCurr = input[nPckidx++];
|
||||
if (cCurr < 0) cCurr += 256;
|
||||
|
||||
/* A 7-bit character can be split at the most between two bytes of packed
|
||||
** data.
|
||||
/* 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.
|
||||
*/
|
||||
nextChar = (byte) (( (cCurr << nShift) | (cPrev >> (8-nShift)) ) & 0x7F);
|
||||
stringBuf[nStridx++] = nextChar;
|
||||
|
||||
/* Special case where the whole of the next 7-bit character fits inside
|
||||
** the current byte of packed data.
|
||||
*/
|
||||
if(nShift == 6)
|
||||
{
|
||||
/* If the next 7-bit character is a CR (0x0D) and it is the last
|
||||
** character, then it indicates a padding character. Drop it.
|
||||
*/
|
||||
if (nPckidx == num_bytes || (cCurr >> 1) == CHAR_CR)
|
||||
{
|
||||
break;
|
||||
if (lengthBytes % 7 == 0) {
|
||||
if (lengthBytes > 0) {
|
||||
if ((input[lengthBytes - 1] >> 1) == PADDING_CHAR) {
|
||||
lengthSeptets = lengthSeptets - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nextChar = (byte) (cCurr >> 1);
|
||||
stringBuf[nStridx++] = nextChar;
|
||||
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 = "";
|
||||
}
|
||||
|
||||
cPrev = cCurr;
|
||||
}
|
||||
|
||||
try {
|
||||
result = new String(stringBuf, 0, nStridx, "US-ASCII");
|
||||
}
|
||||
catch (UnsupportedEncodingException e)
|
||||
{
|
||||
Log.e(TAG, e.getMessage());
|
||||
}
|
||||
|
||||
return result;
|
||||
return decoded;
|
||||
}
|
||||
|
||||
static String decodeUTF8String(byte[] input)
|
||||
|
20
packages/WAPPushManager/Android.mk
Normal file
20
packages/WAPPushManager/Android.mk
Normal file
@ -0,0 +1,20 @@
|
||||
# Copyright 2007-2008 The Android Open Source Project
|
||||
|
||||
|
||||
LOCAL_PATH:= $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
|
||||
LOCAL_SRC_FILES := $(call all-java-files-under, src)
|
||||
|
||||
LOCAL_PACKAGE_NAME := WAPPushManager
|
||||
|
||||
LOCAL_STATIC_JAVA_LIBRARIES += android-common
|
||||
|
||||
LOCAL_PROGUARD_FLAGS := -include $(LOCAL_PATH)/proguard.flags
|
||||
|
||||
include $(BUILD_PACKAGE)
|
||||
|
||||
# This finds and builds the test apk as well, so a single make does both.
|
||||
include $(call all-makefiles-under,$(LOCAL_PATH))
|
38
packages/WAPPushManager/AndroidManifest.xml
Normal file
38
packages/WAPPushManager/AndroidManifest.xml
Normal file
@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
/*
|
||||
* Copyright (C) 2007-2008 The Android Open Source Project
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
-->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.android.smspush">
|
||||
|
||||
<permission android:name="com.android.smspush.WAPPUSH_MANAGER_BIND"
|
||||
android:protectionLevel="signatureOrSystem" />
|
||||
|
||||
<original-package android:name="com.android.smspush" />
|
||||
<application>
|
||||
<service android:name=".WapPushManager"
|
||||
android:permission="com.android.smspush.WAPPUSH_MANAGER_BIND"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="com.android.internal.telephony.IWapPushManager"></action>
|
||||
</intent-filter>
|
||||
</service>
|
||||
</application>
|
||||
|
||||
|
||||
</manifest>
|
49
packages/WAPPushManager/CleanSpec.mk
Normal file
49
packages/WAPPushManager/CleanSpec.mk
Normal file
@ -0,0 +1,49 @@
|
||||
# Copyright (C) 2007 The Android Open Source Project
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
# If you don't need to do a full clean build but would like to touch
|
||||
# a file or delete some intermediate files, add a clean step to the end
|
||||
# of the list. These steps will only be run once, if they haven't been
|
||||
# run before.
|
||||
#
|
||||
# E.g.:
|
||||
# $(call add-clean-step, touch -c external/sqlite/sqlite3.h)
|
||||
# $(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libz_intermediates)
|
||||
#
|
||||
# Always use "touch -c" and "rm -f" or "rm -rf" to gracefully deal with
|
||||
# files that are missing or have been moved.
|
||||
#
|
||||
# Use $(PRODUCT_OUT) to get to the "out/target/product/blah/" directory.
|
||||
# Use $(OUT_DIR) to refer to the "out" directory.
|
||||
#
|
||||
# If you need to re-do something that's already mentioned, just copy
|
||||
# the command and add it to the bottom of the list. E.g., if a change
|
||||
# that you made last week required touching a file and a change you
|
||||
# made today requires touching the same file, just copy the old
|
||||
# touch step and add it to the end of the list.
|
||||
#
|
||||
# ************************************************
|
||||
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
|
||||
# ************************************************
|
||||
|
||||
# For example:
|
||||
#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/APPS/AndroidTests_intermediates)
|
||||
#$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/core_intermediates)
|
||||
#$(call add-clean-step, find $(OUT_DIR) -type f -name "IGTalkSession*" -print0 | xargs -0 rm -f)
|
||||
#$(call add-clean-step, rm -rf $(PRODUCT_OUT)/data/*)
|
||||
|
||||
# ************************************************
|
||||
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
|
||||
# ************************************************
|
0
packages/WAPPushManager/MODULE_LICENSE_APACHE2
Normal file
0
packages/WAPPushManager/MODULE_LICENSE_APACHE2
Normal file
190
packages/WAPPushManager/NOTICE
Normal file
190
packages/WAPPushManager/NOTICE
Normal file
@ -0,0 +1,190 @@
|
||||
|
||||
Copyright (c) 2005-2008, The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
18
packages/WAPPushManager/proguard.flags
Normal file
18
packages/WAPPushManager/proguard.flags
Normal file
@ -0,0 +1,18 @@
|
||||
|
||||
#apply method is dynamically referenced by the reflection class.
|
||||
-keep class android.app.ContextImpl$SharedPreferencesImpl$EditorImpl {
|
||||
void apply();
|
||||
}
|
||||
-keep class android.content.SharedPreferences$Editor {
|
||||
void apply();
|
||||
}
|
||||
|
||||
#WapPushManager is referenced only by AndroidManifest.xml
|
||||
-keep class com.android.smspush.WapPushManager {
|
||||
#CTS module method
|
||||
public boolean isDataExist(java.lang.String, java.lang.String,
|
||||
java.lang.String, java.lang.String);
|
||||
public boolean verifyData(java.lang.String, java.lang.String,
|
||||
java.lang.String, java.lang.String, int, boolean, boolean);
|
||||
}
|
||||
|
@ -0,0 +1,424 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.smspush;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.ComponentName;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.database.Cursor;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.telephony.IWapPushManager;
|
||||
import com.android.internal.telephony.WapPushManagerParams;
|
||||
|
||||
/**
|
||||
* The WapPushManager service is implemented to process incoming
|
||||
* WAP Push messages and to maintain the Receiver Application/Application
|
||||
* ID mapping. The WapPushManager runs as a system service, and only the
|
||||
* WapPushManager can update the WAP Push message and Receiver Application
|
||||
* mapping (Application ID Table). When the device receives an SMS WAP Push
|
||||
* message, the WapPushManager looks up the Receiver Application name in
|
||||
* Application ID Table. If an application is found, the application is
|
||||
* launched using its full component name instead of broadcasting an implicit
|
||||
* Intent. If a Receiver Application is not found in the Application ID
|
||||
* Table or the WapPushManager returns a process-further value, the
|
||||
* telephony stack will process the message using existing message processing
|
||||
* flow, and broadcast an implicit Intent.
|
||||
*/
|
||||
public class WapPushManager extends Service {
|
||||
|
||||
private static final String LOG_TAG = "WAP PUSH";
|
||||
private static final String DATABASE_NAME = "wappush.db";
|
||||
private static final String APPID_TABLE_NAME = "appid_tbl";
|
||||
|
||||
/**
|
||||
* Version number must be incremented when table structure is changed.
|
||||
*/
|
||||
private static final int WAP_PUSH_MANAGER_VERSION = 1;
|
||||
private static final boolean DEBUG_SQL = false;
|
||||
private static final boolean LOCAL_LOGV = false;
|
||||
|
||||
/**
|
||||
* Inner class that deals with application ID table
|
||||
*/
|
||||
private class WapPushManDBHelper extends SQLiteOpenHelper {
|
||||
WapPushManDBHelper(Context context) {
|
||||
super(context, DATABASE_NAME, null, WAP_PUSH_MANAGER_VERSION);
|
||||
if (LOCAL_LOGV) Log.v(LOG_TAG, "helper instance created.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(SQLiteDatabase db) {
|
||||
if (LOCAL_LOGV) Log.v(LOG_TAG, "db onCreate.");
|
||||
String sql = "CREATE TABLE " + APPID_TABLE_NAME + " ("
|
||||
+ "id INTEGER PRIMARY KEY, "
|
||||
+ "x_wap_application TEXT, "
|
||||
+ "content_type TEXT, "
|
||||
+ "package_name TEXT, "
|
||||
+ "class_name TEXT, "
|
||||
+ "app_type INTEGER, "
|
||||
+ "need_signature INTEGER, "
|
||||
+ "further_processing INTEGER, "
|
||||
+ "install_order INTEGER "
|
||||
+ ")";
|
||||
|
||||
if (DEBUG_SQL) Log.v(LOG_TAG, "sql: " + sql);
|
||||
db.execSQL(sql);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpgrade(SQLiteDatabase db,
|
||||
int oldVersion, int newVersion) {
|
||||
// TODO: when table structure is changed, need to dump and restore data.
|
||||
/*
|
||||
db.execSQL(
|
||||
"drop table if exists "+APPID_TABLE_NAME);
|
||||
onCreate(db);
|
||||
*/
|
||||
Log.w(LOG_TAG, "onUpgrade is not implemented yet. do nothing.");
|
||||
}
|
||||
|
||||
protected class queryData {
|
||||
public String packageName;
|
||||
public String className;
|
||||
int appType;
|
||||
int needSignature;
|
||||
int furtherProcessing;
|
||||
int installOrder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Query the latest receiver application info with supplied application ID and
|
||||
* content type.
|
||||
* @param app_id application ID to look up
|
||||
* @param content_type content type to look up
|
||||
*/
|
||||
protected queryData queryLastApp(SQLiteDatabase db,
|
||||
String app_id, String content_type) {
|
||||
String sql = "select install_order, package_name, class_name, "
|
||||
+ " app_type, need_signature, further_processing"
|
||||
+ " from " + APPID_TABLE_NAME
|
||||
+ " where x_wap_application=\'" + app_id + "\'"
|
||||
+ " and content_type=\'" + content_type + "\'"
|
||||
+ " order by install_order desc";
|
||||
if (DEBUG_SQL) Log.v(LOG_TAG, "sql: " + sql);
|
||||
Cursor cur = db.rawQuery(sql, null);
|
||||
queryData ret = null;
|
||||
|
||||
if (cur.moveToNext()) {
|
||||
ret = new queryData();
|
||||
ret.installOrder = cur.getInt(cur.getColumnIndex("install_order"));
|
||||
ret.packageName = cur.getString(cur.getColumnIndex("package_name"));
|
||||
ret.className = cur.getString(cur.getColumnIndex("class_name"));
|
||||
ret.appType = cur.getInt(cur.getColumnIndex("app_type"));
|
||||
ret.needSignature = cur.getInt(cur.getColumnIndex("need_signature"));
|
||||
ret.furtherProcessing = cur.getInt(cur.getColumnIndex("further_processing"));
|
||||
}
|
||||
cur.close();
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The exported API implementations class
|
||||
*/
|
||||
private class IWapPushManagerStub extends IWapPushManager.Stub {
|
||||
public Context mContext;
|
||||
|
||||
public IWapPushManagerStub() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare the package signature with WapPushManager package
|
||||
*/
|
||||
protected boolean signatureCheck(String package_name) {
|
||||
PackageManager pm = mContext.getPackageManager();
|
||||
int match = pm.checkSignatures(mContext.getPackageName(), package_name);
|
||||
|
||||
if (LOCAL_LOGV) Log.v(LOG_TAG, "compare signature " + mContext.getPackageName()
|
||||
+ " and " + package_name + ", match=" + match);
|
||||
|
||||
return match == PackageManager.SIGNATURE_MATCH;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the status value of the message processing.
|
||||
* The message will be processed as follows:
|
||||
* 1.Look up Application ID Table with x-wap-application-id + content type
|
||||
* 2.Check the signature of package name that is found in the
|
||||
* Application ID Table by using PackageManager.checkSignature
|
||||
* 3.Trigger the Application
|
||||
* 4.Returns the process status value.
|
||||
*/
|
||||
public int processMessage(String app_id, String content_type, Intent intent)
|
||||
throws RemoteException {
|
||||
Log.d(LOG_TAG, "wpman processMsg " + app_id + ":" + content_type);
|
||||
|
||||
WapPushManDBHelper dbh = getDatabase(mContext);
|
||||
SQLiteDatabase db = dbh.getReadableDatabase();
|
||||
WapPushManDBHelper.queryData lastapp = dbh.queryLastApp(db, app_id, content_type);
|
||||
db.close();
|
||||
|
||||
if (lastapp == null) {
|
||||
Log.w(LOG_TAG, "no receiver app found for " + app_id + ":" + content_type);
|
||||
return WapPushManagerParams.APP_QUERY_FAILED;
|
||||
}
|
||||
if (LOCAL_LOGV) Log.v(LOG_TAG, "starting " + lastapp.packageName
|
||||
+ "/" + lastapp.className);
|
||||
|
||||
if (lastapp.needSignature != 0) {
|
||||
if (!signatureCheck(lastapp.packageName)) {
|
||||
return WapPushManagerParams.SIGNATURE_NO_MATCH;
|
||||
}
|
||||
}
|
||||
|
||||
if (lastapp.appType == WapPushManagerParams.APP_TYPE_ACTIVITY) {
|
||||
//Intent intent = new Intent(Intent.ACTION_MAIN);
|
||||
intent.setClassName(lastapp.packageName, lastapp.className);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
|
||||
try {
|
||||
mContext.startActivity(intent);
|
||||
} catch (ActivityNotFoundException e) {
|
||||
Log.w(LOG_TAG, "invalid name " +
|
||||
lastapp.packageName + "/" + lastapp.className);
|
||||
return WapPushManagerParams.INVALID_RECEIVER_NAME;
|
||||
}
|
||||
} else {
|
||||
intent.setClassName(mContext, lastapp.className);
|
||||
intent.setComponent(new ComponentName(lastapp.packageName,
|
||||
lastapp.className));
|
||||
if (mContext.startService(intent) == null) {
|
||||
Log.w(LOG_TAG, "invalid name " +
|
||||
lastapp.packageName + "/" + lastapp.className);
|
||||
return WapPushManagerParams.INVALID_RECEIVER_NAME;
|
||||
}
|
||||
}
|
||||
|
||||
return WapPushManagerParams.MESSAGE_HANDLED
|
||||
| (lastapp.furtherProcessing == 1 ?
|
||||
WapPushManagerParams.FURTHER_PROCESSING : 0);
|
||||
}
|
||||
|
||||
protected boolean appTypeCheck(int app_type) {
|
||||
if (app_type == WapPushManagerParams.APP_TYPE_ACTIVITY ||
|
||||
app_type == WapPushManagerParams.APP_TYPE_SERVICE) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if adding the package succeeded.
|
||||
*/
|
||||
public boolean addPackage(String x_app_id, String content_type,
|
||||
String package_name, String class_name,
|
||||
int app_type, boolean need_signature, boolean further_processing) {
|
||||
WapPushManDBHelper dbh = getDatabase(mContext);
|
||||
SQLiteDatabase db = dbh.getWritableDatabase();
|
||||
WapPushManDBHelper.queryData lastapp = dbh.queryLastApp(db, x_app_id, content_type);
|
||||
boolean ret = false;
|
||||
boolean insert = false;
|
||||
int sq = 0;
|
||||
|
||||
if (!appTypeCheck(app_type)) {
|
||||
Log.w(LOG_TAG, "invalid app_type " + app_type + ". app_type must be "
|
||||
+ WapPushManagerParams.APP_TYPE_ACTIVITY + " or "
|
||||
+ WapPushManagerParams.APP_TYPE_SERVICE);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (lastapp == null) {
|
||||
insert = true;
|
||||
sq = 0;
|
||||
} else if (!lastapp.packageName.equals(package_name) ||
|
||||
!lastapp.className.equals(class_name)) {
|
||||
insert = true;
|
||||
sq = lastapp.installOrder + 1;
|
||||
}
|
||||
|
||||
if (insert) {
|
||||
ContentValues values = new ContentValues();
|
||||
|
||||
values.put("x_wap_application", x_app_id);
|
||||
values.put("content_type", content_type);
|
||||
values.put("package_name", package_name);
|
||||
values.put("class_name", class_name);
|
||||
values.put("app_type", app_type);
|
||||
values.put("need_signature", need_signature ? 1 : 0);
|
||||
values.put("further_processing", further_processing ? 1 : 0);
|
||||
values.put("install_order", sq);
|
||||
db.insert(APPID_TABLE_NAME, null, values);
|
||||
if (LOCAL_LOGV) Log.v(LOG_TAG, "add:" + x_app_id + ":" + content_type
|
||||
+ " " + package_name + "." + class_name
|
||||
+ ", newsq:" + sq);
|
||||
ret = true;
|
||||
}
|
||||
|
||||
db.close();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if updating the package succeeded.
|
||||
*/
|
||||
public boolean updatePackage(String x_app_id, String content_type,
|
||||
String package_name, String class_name,
|
||||
int app_type, boolean need_signature, boolean further_processing) {
|
||||
|
||||
if (!appTypeCheck(app_type)) {
|
||||
Log.w(LOG_TAG, "invalid app_type " + app_type + ". app_type must be "
|
||||
+ WapPushManagerParams.APP_TYPE_ACTIVITY + " or "
|
||||
+ WapPushManagerParams.APP_TYPE_SERVICE);
|
||||
return false;
|
||||
}
|
||||
|
||||
WapPushManDBHelper dbh = getDatabase(mContext);
|
||||
SQLiteDatabase db = dbh.getWritableDatabase();
|
||||
WapPushManDBHelper.queryData lastapp = dbh.queryLastApp(db, x_app_id, content_type);
|
||||
|
||||
if (lastapp == null) {
|
||||
db.close();
|
||||
return false;
|
||||
}
|
||||
|
||||
ContentValues values = new ContentValues();
|
||||
String where = "x_wap_application=\'" + x_app_id + "\'"
|
||||
+ " and content_type=\'" + content_type + "\'"
|
||||
+ " and install_order=" + lastapp.installOrder;
|
||||
|
||||
values.put("package_name", package_name);
|
||||
values.put("class_name", class_name);
|
||||
values.put("app_type", app_type);
|
||||
values.put("need_signature", need_signature ? 1 : 0);
|
||||
values.put("further_processing", further_processing ? 1 : 0);
|
||||
|
||||
int num = db.update(APPID_TABLE_NAME, values, where, null);
|
||||
if (LOCAL_LOGV) Log.v(LOG_TAG, "update:" + x_app_id + ":" + content_type + " "
|
||||
+ package_name + "." + class_name
|
||||
+ ", sq:" + lastapp.installOrder);
|
||||
|
||||
db.close();
|
||||
|
||||
return num > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if deleting the package succeeded.
|
||||
*/
|
||||
public boolean deletePackage(String x_app_id, String content_type,
|
||||
String package_name, String class_name) {
|
||||
WapPushManDBHelper dbh = getDatabase(mContext);
|
||||
SQLiteDatabase db = dbh.getWritableDatabase();
|
||||
String where = "x_wap_application=\'" + x_app_id + "\'"
|
||||
+ " and content_type=\'" + content_type + "\'"
|
||||
+ " and package_name=\'" + package_name + "\'"
|
||||
+ " and class_name=\'" + class_name + "\'";
|
||||
int num_removed = db.delete(APPID_TABLE_NAME, where, null);
|
||||
|
||||
db.close();
|
||||
if (LOCAL_LOGV) Log.v(LOG_TAG, "deleted " + num_removed + " rows:"
|
||||
+ x_app_id + ":" + content_type + " "
|
||||
+ package_name + "." + class_name);
|
||||
return num_removed > 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Linux IPC Binder
|
||||
*/
|
||||
private final IWapPushManagerStub mBinder = new IWapPushManagerStub();
|
||||
|
||||
/**
|
||||
* Default constructor
|
||||
*/
|
||||
public WapPushManager() {
|
||||
super();
|
||||
mBinder.mContext = this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent arg0) {
|
||||
return mBinder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Application ID database instance
|
||||
*/
|
||||
private WapPushManDBHelper mDbHelper = null;
|
||||
protected WapPushManDBHelper getDatabase(Context context) {
|
||||
if (mDbHelper == null) {
|
||||
if (LOCAL_LOGV) Log.v(LOG_TAG, "create new db inst.");
|
||||
mDbHelper = new WapPushManDBHelper(context);
|
||||
}
|
||||
return mDbHelper;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method is used for testing
|
||||
*/
|
||||
public boolean verifyData(String x_app_id, String content_type,
|
||||
String package_name, String class_name,
|
||||
int app_type, boolean need_signature, boolean further_processing) {
|
||||
WapPushManDBHelper dbh = getDatabase(this);
|
||||
SQLiteDatabase db = dbh.getReadableDatabase();
|
||||
WapPushManDBHelper.queryData lastapp = dbh.queryLastApp(db, x_app_id, content_type);
|
||||
|
||||
db.close();
|
||||
|
||||
if (lastapp == null) return false;
|
||||
|
||||
if (lastapp.packageName.equals(package_name)
|
||||
&& lastapp.className.equals(class_name)
|
||||
&& lastapp.appType == app_type
|
||||
&& lastapp.needSignature == (need_signature ? 1 : 0)
|
||||
&& lastapp.furtherProcessing == (further_processing ? 1 : 0)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is used for testing
|
||||
*/
|
||||
public boolean isDataExist(String x_app_id, String content_type,
|
||||
String package_name, String class_name) {
|
||||
WapPushManDBHelper dbh = getDatabase(this);
|
||||
SQLiteDatabase db = dbh.getReadableDatabase();
|
||||
boolean ret = dbh.queryLastApp(db, x_app_id, content_type) != null;
|
||||
|
||||
db.close();
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
38
packages/WAPPushManager/tests/Android.mk
Normal file
38
packages/WAPPushManager/tests/Android.mk
Normal file
@ -0,0 +1,38 @@
|
||||
# Copyright 2008, The Android Open Source Project
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
LOCAL_PATH:= $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
# We only want this apk build for tests.
|
||||
LOCAL_MODULE_TAGS := tests
|
||||
|
||||
LOCAL_JAVA_LIBRARIES := android.test.runner
|
||||
|
||||
# Include all test java files.
|
||||
LOCAL_SRC_FILES := $(call all-java-files-under, src)
|
||||
LOCAL_SRC_FILES += \
|
||||
src/com/android/smspush/unitTests/IDataVerify.aidl
|
||||
|
||||
|
||||
# Notice that we don't have to include the src files of Email because, by
|
||||
# running the tests using an instrumentation targeting Eamil, we
|
||||
# automatically get all of its classes loaded into our environment.
|
||||
|
||||
LOCAL_PACKAGE_NAME := WAPPushManagerTests
|
||||
|
||||
LOCAL_INSTRUMENTATION_FOR := WAPPushManager
|
||||
|
||||
include $(BUILD_PACKAGE)
|
||||
|
71
packages/WAPPushManager/tests/AndroidManifest.xml
Normal file
71
packages/WAPPushManager/tests/AndroidManifest.xml
Normal file
@ -0,0 +1,71 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2008 The Android Open Source Project
|
||||
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
-->
|
||||
|
||||
<!-- package name must be unique so suffix with "tests" so package loader doesn't ignore us -->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.android.smspush.unitTests">
|
||||
|
||||
|
||||
<uses-permission android:name="com.android.smspush.WAPPUSH_MANAGER_BIND" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_WAP_PUSH" />
|
||||
<!--testing.../-->
|
||||
<application android:icon="@drawable/icon" android:label="wappush test">
|
||||
<uses-library android:name="android.test.runner" />
|
||||
<activity android:name=".ClientTest"
|
||||
android:label="wappush test">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<receiver android:name=".DrmReceiver" android:enabled="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.provider.Telephony.WAP_PUSH_RECEIVED" />
|
||||
<data android:mimeType="application/vnd.oma.drm.rights+xml" />
|
||||
<data android:value="application/vnd.oma.drm.rights+wbxml" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<service android:enabled="true" android:name=".ReceiverService"
|
||||
android:exported="true"/>
|
||||
|
||||
<activity android:name=".ReceiverActivity"
|
||||
android:exported="true" android:label="test receiver" />
|
||||
|
||||
<service android:name=".DataVerify"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="com.android.smspush.unitTests.IDataVerify" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
|
||||
</application>
|
||||
|
||||
<!--
|
||||
This declares that this application uses the instrumentation test runner targeting
|
||||
the package of com.android.smspush. To run the tests use the command:
|
||||
"adb shell am instrument -w
|
||||
com.android.smspush.unitTests/android.test.InstrumentationTestRunner"
|
||||
-->
|
||||
<instrumentation android:name="android.test.InstrumentationTestRunner"
|
||||
android:targetPackage="com.android.smspush"
|
||||
android:label="Tests for WAPPushManager"/>
|
||||
|
||||
</manifest>
|
||||
|
BIN
packages/WAPPushManager/tests/res/drawable-hdpi/icon.png
Normal file
BIN
packages/WAPPushManager/tests/res/drawable-hdpi/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.0 KiB |
BIN
packages/WAPPushManager/tests/res/drawable-ldpi/icon.png
Normal file
BIN
packages/WAPPushManager/tests/res/drawable-ldpi/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
BIN
packages/WAPPushManager/tests/res/drawable-mdpi/icon.png
Normal file
BIN
packages/WAPPushManager/tests/res/drawable-mdpi/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.5 KiB |
152
packages/WAPPushManager/tests/res/layout/main.xml
Normal file
152
packages/WAPPushManager/tests/res/layout/main.xml
Normal file
@ -0,0 +1,152 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Copyright (C) 2010 The Android Open Source Project
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<AbsoluteLayout
|
||||
android:id="@+id/widget133"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
>
|
||||
<EditText
|
||||
android:id="@+id/app_id"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="10"
|
||||
android:textSize="18sp"
|
||||
android:layout_x="0px"
|
||||
android:layout_y="26px"
|
||||
>
|
||||
</EditText>
|
||||
<EditText
|
||||
android:id="@+id/cont"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="20"
|
||||
android:textSize="18sp"
|
||||
android:layout_x="47px"
|
||||
android:layout_y="26px"
|
||||
>
|
||||
</EditText>
|
||||
<EditText
|
||||
android:id="@+id/pkg"
|
||||
android:layout_width="125px"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="pkg"
|
||||
android:textSize="18sp"
|
||||
android:layout_x="0px"
|
||||
android:layout_y="81px"
|
||||
>
|
||||
</EditText>
|
||||
<EditText
|
||||
android:id="@+id/cls"
|
||||
android:layout_width="173px"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="cls"
|
||||
android:textSize="18sp"
|
||||
android:layout_x="147px"
|
||||
android:layout_y="81px"
|
||||
>
|
||||
</EditText>
|
||||
<Button
|
||||
android:id="@+id/addpkg"
|
||||
android:layout_width="182px"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="add/update package"
|
||||
android:layout_x="15px"
|
||||
android:layout_y="225px"
|
||||
>
|
||||
</Button>
|
||||
<TextView
|
||||
android:id="@+id/widget52"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="input app_id, cont_type, pkg, cls"
|
||||
android:textSize="18sp"
|
||||
android:layout_x="0px"
|
||||
android:layout_y="0px"
|
||||
>
|
||||
</TextView>
|
||||
<Button
|
||||
android:id="@+id/procmsg"
|
||||
android:layout_width="109px"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="process msg"
|
||||
android:layout_x="197px"
|
||||
android:layout_y="361px"
|
||||
>
|
||||
</Button>
|
||||
<RadioGroup
|
||||
android:id="@+id/widget137"
|
||||
android:layout_width="83px"
|
||||
android:layout_height="80px"
|
||||
android:orientation="vertical"
|
||||
android:layout_x="19px"
|
||||
android:layout_y="137px"
|
||||
>
|
||||
<RadioButton
|
||||
android:id="@+id/act"
|
||||
android:layout_width="182px"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="act"
|
||||
android:checked="true"
|
||||
>
|
||||
</RadioButton>
|
||||
<RadioButton
|
||||
android:id="@+id/svc"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="svc"
|
||||
>
|
||||
</RadioButton>
|
||||
</RadioGroup>
|
||||
<Button
|
||||
android:id="@+id/delpkg"
|
||||
android:layout_width="174px"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="delete pkg"
|
||||
android:layout_x="14px"
|
||||
android:layout_y="283px"
|
||||
>
|
||||
</Button>
|
||||
<EditText
|
||||
android:id="@+id/pdu"
|
||||
android:layout_width="186px"
|
||||
android:layout_height="83px"
|
||||
android:text="0006080302030aaf02905c030d6a0085070373616d706c6540646f636f6d6f2e6e652e6a700005c3072009102012345601"
|
||||
android:textSize="18sp"
|
||||
android:layout_x="10px"
|
||||
android:layout_y="341px"
|
||||
>
|
||||
</EditText>
|
||||
<CheckBox
|
||||
android:id="@+id/ftr"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="ftr_proc"
|
||||
android:layout_x="143px"
|
||||
android:layout_y="181px"
|
||||
>
|
||||
</CheckBox>
|
||||
<CheckBox
|
||||
android:id="@+id/sig"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="nd_sig"
|
||||
android:checked="true"
|
||||
android:layout_x="142px"
|
||||
android:layout_y="140px"
|
||||
>
|
||||
</CheckBox>
|
||||
</AbsoluteLayout>
|
@ -0,0 +1,174 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.smspush.unitTests;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.EditText;
|
||||
import android.widget.RadioButton;
|
||||
|
||||
import com.android.internal.telephony.IWapPushManager;
|
||||
import com.android.internal.telephony.WapPushManagerParams;
|
||||
import com.android.internal.telephony.WapPushOverSms;
|
||||
import com.android.internal.util.HexDump;
|
||||
import com.android.smspush.WapPushManager;
|
||||
|
||||
/**
|
||||
* WapPushManager test application
|
||||
*/
|
||||
public class ClientTest extends Activity {
|
||||
private static final String LOG_TAG = "WAP PUSH";
|
||||
|
||||
/** Called when the activity is first created. */
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.main);
|
||||
|
||||
Button addpbtn = (Button) findViewById(R.id.addpkg);
|
||||
Button procbtn = (Button) findViewById(R.id.procmsg);
|
||||
Button delbtn = (Button) findViewById(R.id.delpkg);
|
||||
|
||||
Log.v(LOG_TAG, "activity created!!");
|
||||
|
||||
addpbtn.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
EditText app_id = (EditText) findViewById(R.id.app_id);
|
||||
EditText cont = (EditText) findViewById(R.id.cont);
|
||||
EditText pkg = (EditText) findViewById(R.id.pkg);
|
||||
EditText cls = (EditText) findViewById(R.id.cls);
|
||||
RadioButton act = (RadioButton) findViewById(R.id.act);
|
||||
CheckBox sig = (CheckBox) findViewById(R.id.sig);
|
||||
CheckBox ftr = (CheckBox) findViewById(R.id.ftr);
|
||||
|
||||
try {
|
||||
if (!mWapPushMan.addPackage(
|
||||
app_id.getText().toString(),
|
||||
cont.getText().toString(),
|
||||
pkg.getText().toString(),
|
||||
cls.getText().toString(),
|
||||
act.isChecked() ? WapPushManagerParams.APP_TYPE_ACTIVITY :
|
||||
WapPushManagerParams.APP_TYPE_SERVICE,
|
||||
sig.isChecked(), ftr.isChecked())) {
|
||||
|
||||
Log.w(LOG_TAG, "remote add pkg failed...");
|
||||
mWapPushMan.updatePackage(
|
||||
app_id.getText().toString(),
|
||||
cont.getText().toString(),
|
||||
pkg.getText().toString(),
|
||||
cls.getText().toString(),
|
||||
act.isChecked() ? WapPushManagerParams.APP_TYPE_ACTIVITY :
|
||||
WapPushManagerParams.APP_TYPE_SERVICE,
|
||||
sig.isChecked(), ftr.isChecked());
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
Log.w(LOG_TAG, "remote func failed...");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
delbtn.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
EditText app_id = (EditText) findViewById(R.id.app_id);
|
||||
EditText cont = (EditText) findViewById(R.id.cont);
|
||||
EditText pkg = (EditText) findViewById(R.id.pkg);
|
||||
EditText cls = (EditText) findViewById(R.id.cls);
|
||||
// CheckBox delall = (CheckBox) findViewById(R.id.delall);
|
||||
// Log.d(LOG_TAG, "button clicked");
|
||||
|
||||
try {
|
||||
mWapPushMan.deletePackage(
|
||||
app_id.getText().toString(),
|
||||
cont.getText().toString(),
|
||||
pkg.getText().toString(),
|
||||
cls.getText().toString());
|
||||
// delall.isChecked());
|
||||
} catch (RemoteException e) {
|
||||
Log.w(LOG_TAG, "remote func failed...");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
procbtn.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
EditText pdu = (EditText) findViewById(R.id.pdu);
|
||||
EditText app_id = (EditText) findViewById(R.id.app_id);
|
||||
EditText cont = (EditText) findViewById(R.id.cont);
|
||||
|
||||
// WapPushOverSms wap = new WapPushOverSms();
|
||||
// wap.dispatchWapPdu(strToHex(pdu.getText().toString()));
|
||||
try {
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra("transactionId", 0);
|
||||
intent.putExtra("pduType", 6);
|
||||
intent.putExtra("header",
|
||||
HexDump.hexStringToByteArray(pdu.getText().toString()));
|
||||
intent.putExtra("data",
|
||||
HexDump.hexStringToByteArray(pdu.getText().toString()));
|
||||
|
||||
mWapPushMan.processMessage(
|
||||
app_id.getText().toString(),
|
||||
cont.getText().toString(),
|
||||
intent);
|
||||
//HexDump.hexStringToByteArray(pdu.getText().toString()), 0, 6, 5, 5);
|
||||
} catch (RemoteException e) {
|
||||
Log.w(LOG_TAG, "remote func failed...");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private IWapPushManager mWapPushMan;
|
||||
private ServiceConnection conn = new ServiceConnection() {
|
||||
public void onServiceDisconnected(ComponentName name) {
|
||||
mWapPushMan = null;
|
||||
Log.v(LOG_TAG, "service disconnected.");
|
||||
}
|
||||
|
||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||
mWapPushMan = IWapPushManager.Stub.asInterface(service);
|
||||
Log.v(LOG_TAG, "service connected.");
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public void onStart() {
|
||||
super.onStart();
|
||||
Log.v(LOG_TAG, "onStart bind WAPPushManager service "
|
||||
+ IWapPushManager.class.getName());
|
||||
this.bindService(new Intent(IWapPushManager.class.getName()), conn,
|
||||
Context.BIND_AUTO_CREATE);
|
||||
Log.v(LOG_TAG, "bind service done.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
this.unbindService(conn);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.smspush.unitTests;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.IBinder;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.util.HexDump;
|
||||
|
||||
/**
|
||||
* To verify that receiver application receives correct body data.
|
||||
*/
|
||||
public class DataVerify extends Service {
|
||||
private static final String LOG_TAG = "WAP PUSH";
|
||||
private static final int TIME_WAIT = 100;
|
||||
private static final int WAIT_COUNT = 100;
|
||||
private static byte[] mLastReceivedPdu = null;
|
||||
private static boolean sDataSet = false;
|
||||
|
||||
private class IDataVerifyStub extends IDataVerify.Stub {
|
||||
public Context mContext;
|
||||
|
||||
public IDataVerifyStub() {
|
||||
}
|
||||
|
||||
boolean arrayCompare(byte[] arr1, byte[] arr2) {
|
||||
int i;
|
||||
|
||||
if (arr1 == null || arr2 == null) {
|
||||
if (arr1 == null) {
|
||||
Log.w(LOG_TAG, "arr1 is null");
|
||||
} else {
|
||||
Log.w(LOG_TAG, "arr2 is null");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (arr1.length != arr2.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; i < arr1.length; i++) {
|
||||
if (arr1[i] != arr2[i]) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare pdu and received pdu
|
||||
*/
|
||||
public synchronized boolean verifyData(byte[] pdu) {
|
||||
int cnt = 0;
|
||||
|
||||
while (!sDataSet) {
|
||||
// wait for the activity receive data.
|
||||
try {
|
||||
Thread.sleep(TIME_WAIT);
|
||||
if (cnt++ > WAIT_COUNT) {
|
||||
// don't wait more than 10 sec.
|
||||
return false;
|
||||
}
|
||||
} catch (InterruptedException e) {}
|
||||
}
|
||||
|
||||
Log.v(LOG_TAG, "verify pdu");
|
||||
boolean ret = arrayCompare(pdu, mLastReceivedPdu);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the old data. This method must be called before starting the test
|
||||
*/
|
||||
public void resetData() {
|
||||
mLastReceivedPdu = null;
|
||||
sDataSet = false;
|
||||
}
|
||||
}
|
||||
|
||||
private final IDataVerifyStub binder = new IDataVerifyStub();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public DataVerify() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Receiver application must call this method when it receives the wap push message
|
||||
*/
|
||||
public static void SetLastReceivedPdu(byte[] pdu) {
|
||||
mLastReceivedPdu = pdu;
|
||||
sDataSet = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent arg0) {
|
||||
return binder;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.smspush.unitTests;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.util.HexDump;
|
||||
|
||||
/**
|
||||
* A sample wap push receiver application for existing framework
|
||||
* This class is listening for "application/vnd.oma.drm.rights+xml" message
|
||||
*/
|
||||
public class DrmReceiver extends BroadcastReceiver {
|
||||
private static final String LOG_TAG = "WAP PUSH";
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
Log.d(LOG_TAG, "DrmReceiver received.");
|
||||
|
||||
byte[] body;
|
||||
byte[] header;
|
||||
|
||||
body = intent.getByteArrayExtra("data");
|
||||
header = intent.getByteArrayExtra("header");
|
||||
|
||||
Log.d(LOG_TAG, "header:");
|
||||
Log.d(LOG_TAG, HexDump.dumpHexString(header));
|
||||
Log.d(LOG_TAG, "body:");
|
||||
Log.d(LOG_TAG, HexDump.dumpHexString(body));
|
||||
|
||||
DataVerify.SetLastReceivedPdu(body);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.smspush.unitTests;
|
||||
|
||||
/**
|
||||
* Interface to receiver application data verifyer class
|
||||
*/
|
||||
interface IDataVerify {
|
||||
/**
|
||||
* Verify data
|
||||
*/
|
||||
boolean verifyData(in byte[] pdu);
|
||||
|
||||
/**
|
||||
* Initialize data
|
||||
*/
|
||||
void resetData();
|
||||
}
|
||||
|
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.smspush.unitTests;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.util.HexDump;
|
||||
|
||||
/**
|
||||
* Activity type receiver application
|
||||
*/
|
||||
public class ReceiverActivity extends Activity {
|
||||
private static final String LOG_TAG = "WAP PUSH";
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
Log.d(LOG_TAG, "activity created!!");
|
||||
|
||||
Intent in = getIntent();
|
||||
byte[] body;
|
||||
byte[] header;
|
||||
|
||||
body = in.getByteArrayExtra("data");
|
||||
header = in.getByteArrayExtra("header");
|
||||
|
||||
Log.d(LOG_TAG, "header:");
|
||||
Log.d(LOG_TAG, HexDump.dumpHexString(header));
|
||||
Log.d(LOG_TAG, "body:");
|
||||
Log.d(LOG_TAG, HexDump.dumpHexString(body));
|
||||
|
||||
DataVerify.SetLastReceivedPdu(body);
|
||||
|
||||
finish();
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.smspush.unitTests;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.IBinder;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.util.HexDump;
|
||||
|
||||
/**
|
||||
* Service type receiver application
|
||||
*/
|
||||
public class ReceiverService extends Service {
|
||||
private static final String LOG_TAG = "WAP PUSH";
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
Log.d(LOG_TAG, "Receiver service created");
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
Log.d(LOG_TAG, "Receiver service started");
|
||||
|
||||
byte[] body;
|
||||
byte[] header;
|
||||
body = intent.getByteArrayExtra("data");
|
||||
header = intent.getByteArrayExtra("header");
|
||||
|
||||
Log.d(LOG_TAG, "header:");
|
||||
Log.d(LOG_TAG, HexDump.dumpHexString(header));
|
||||
Log.d(LOG_TAG, "body:");
|
||||
Log.d(LOG_TAG, HexDump.dumpHexString(body));
|
||||
|
||||
DataVerify.SetLastReceivedPdu(body);
|
||||
return START_STICKY;
|
||||
}
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -217,82 +217,10 @@ AGpsRilCallbacks sAGpsRilCallbacks = {
|
||||
create_thread_callback,
|
||||
};
|
||||
|
||||
static const GpsInterface* get_gps_interface() {
|
||||
static void android_location_GpsLocationProvider_class_init_native(JNIEnv* env, jclass clazz) {
|
||||
int err;
|
||||
hw_module_t* module;
|
||||
const GpsInterface* interface = NULL;
|
||||
|
||||
err = hw_get_module(GPS_HARDWARE_MODULE_ID, (hw_module_t const**)&module);
|
||||
if (err == 0) {
|
||||
hw_device_t* device;
|
||||
err = module->methods->open(module, GPS_HARDWARE_MODULE_ID, &device);
|
||||
if (err == 0) {
|
||||
gps_device_t* gps_device = (gps_device_t *)device;
|
||||
interface = gps_device->get_gps_interface(gps_device);
|
||||
}
|
||||
}
|
||||
|
||||
return interface;
|
||||
}
|
||||
|
||||
static const GpsInterface* GetGpsInterface(JNIEnv* env, jobject obj) {
|
||||
// this must be set before calling into the HAL library
|
||||
if (!mCallbacksObj)
|
||||
mCallbacksObj = env->NewGlobalRef(obj);
|
||||
|
||||
if (!sGpsInterface) {
|
||||
sGpsInterface = get_gps_interface();
|
||||
if (!sGpsInterface || sGpsInterface->init(&sGpsCallbacks) != 0) {
|
||||
sGpsInterface = NULL;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return sGpsInterface;
|
||||
}
|
||||
|
||||
static const AGpsInterface* GetAGpsInterface(JNIEnv* env, jobject obj)
|
||||
{
|
||||
const GpsInterface* interface = GetGpsInterface(env, obj);
|
||||
if (!interface)
|
||||
return NULL;
|
||||
|
||||
if (!sAGpsInterface) {
|
||||
sAGpsInterface = (const AGpsInterface*)interface->get_extension(AGPS_INTERFACE);
|
||||
if (sAGpsInterface)
|
||||
sAGpsInterface->init(&sAGpsCallbacks);
|
||||
}
|
||||
return sAGpsInterface;
|
||||
}
|
||||
|
||||
static const GpsNiInterface* GetNiInterface(JNIEnv* env, jobject obj)
|
||||
{
|
||||
const GpsInterface* interface = GetGpsInterface(env, obj);
|
||||
if (!interface)
|
||||
return NULL;
|
||||
|
||||
if (!sGpsNiInterface) {
|
||||
sGpsNiInterface = (const GpsNiInterface*)interface->get_extension(GPS_NI_INTERFACE);
|
||||
if (sGpsNiInterface)
|
||||
sGpsNiInterface->init(&sGpsNiCallbacks);
|
||||
}
|
||||
return sGpsNiInterface;
|
||||
}
|
||||
|
||||
static const AGpsRilInterface* GetAGpsRilInterface(JNIEnv* env, jobject obj)
|
||||
{
|
||||
const GpsInterface* interface = GetGpsInterface(env, obj);
|
||||
if (!interface)
|
||||
return NULL;
|
||||
|
||||
if (!sAGpsRilInterface) {
|
||||
sAGpsRilInterface = (const AGpsRilInterface*)interface->get_extension(AGPS_RIL_INTERFACE);
|
||||
if (sAGpsRilInterface)
|
||||
sAGpsRilInterface->init(&sAGpsRilCallbacks);
|
||||
}
|
||||
return sAGpsRilInterface;
|
||||
}
|
||||
|
||||
static void android_location_GpsLocationProvider_class_init_native(JNIEnv* env, jclass clazz) {
|
||||
method_reportLocation = env->GetMethodID(clazz, "reportLocation", "(IDDDFFFJ)V");
|
||||
method_reportStatus = env->GetMethodID(clazz, "reportStatus", "(I)V");
|
||||
method_reportSvStatus = env->GetMethodID(clazz, "reportSvStatus", "()V");
|
||||
@ -300,40 +228,73 @@ static void android_location_GpsLocationProvider_class_init_native(JNIEnv* env,
|
||||
method_reportNmea = env->GetMethodID(clazz, "reportNmea", "(J)V");
|
||||
method_setEngineCapabilities = env->GetMethodID(clazz, "setEngineCapabilities", "(I)V");
|
||||
method_xtraDownloadRequest = env->GetMethodID(clazz, "xtraDownloadRequest", "()V");
|
||||
method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification", "(IIIIILjava/lang/String;Ljava/lang/String;IILjava/lang/String;)V");
|
||||
method_reportNiNotification = env->GetMethodID(clazz, "reportNiNotification",
|
||||
"(IIIIILjava/lang/String;Ljava/lang/String;IILjava/lang/String;)V");
|
||||
method_requestRefLocation = env->GetMethodID(clazz,"requestRefLocation","(I)V");
|
||||
method_requestSetID = env->GetMethodID(clazz,"requestSetID","(I)V");
|
||||
|
||||
err = hw_get_module(GPS_HARDWARE_MODULE_ID, (hw_module_t const**)&module);
|
||||
if (err == 0) {
|
||||
hw_device_t* device;
|
||||
err = module->methods->open(module, GPS_HARDWARE_MODULE_ID, &device);
|
||||
if (err == 0) {
|
||||
gps_device_t* gps_device = (gps_device_t *)device;
|
||||
sGpsInterface = gps_device->get_gps_interface(gps_device);
|
||||
}
|
||||
}
|
||||
if (sGpsInterface) {
|
||||
sGpsXtraInterface =
|
||||
(const GpsXtraInterface*)sGpsInterface->get_extension(GPS_XTRA_INTERFACE);
|
||||
sAGpsInterface =
|
||||
(const AGpsInterface*)sGpsInterface->get_extension(AGPS_INTERFACE);
|
||||
sGpsNiInterface =
|
||||
(const GpsNiInterface*)sGpsInterface->get_extension(GPS_NI_INTERFACE);
|
||||
sGpsDebugInterface =
|
||||
(const GpsDebugInterface*)sGpsInterface->get_extension(GPS_DEBUG_INTERFACE);
|
||||
sAGpsRilInterface =
|
||||
(const AGpsRilInterface*)sGpsInterface->get_extension(AGPS_RIL_INTERFACE);
|
||||
}
|
||||
}
|
||||
|
||||
static jboolean android_location_GpsLocationProvider_is_supported(JNIEnv* env, jclass clazz) {
|
||||
return (sGpsInterface != NULL || get_gps_interface() != NULL);
|
||||
return (sGpsInterface != NULL);
|
||||
}
|
||||
|
||||
static jboolean android_location_GpsLocationProvider_init(JNIEnv* env, jobject obj)
|
||||
{
|
||||
const GpsInterface* interface = GetGpsInterface(env, obj);
|
||||
if (!interface)
|
||||
// this must be set before calling into the HAL library
|
||||
if (!mCallbacksObj)
|
||||
mCallbacksObj = env->NewGlobalRef(obj);
|
||||
|
||||
// fail if the main interface fails to initialize
|
||||
if (!sGpsInterface || sGpsInterface->init(&sGpsCallbacks) != 0)
|
||||
return false;
|
||||
|
||||
if (!sGpsDebugInterface)
|
||||
sGpsDebugInterface = (const GpsDebugInterface*)interface->get_extension(GPS_DEBUG_INTERFACE);
|
||||
// if XTRA initialization fails we will disable it by sGpsXtraInterface to null,
|
||||
// but continue to allow the rest of the GPS interface to work.
|
||||
if (sGpsXtraInterface && sGpsXtraInterface->init(&sGpsXtraCallbacks) != 0)
|
||||
sGpsXtraInterface = NULL;
|
||||
if (sAGpsInterface)
|
||||
sAGpsInterface->init(&sAGpsCallbacks);
|
||||
if (sGpsNiInterface)
|
||||
sGpsNiInterface->init(&sGpsNiCallbacks);
|
||||
if (sAGpsRilInterface)
|
||||
sAGpsRilInterface->init(&sAGpsRilCallbacks);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void android_location_GpsLocationProvider_cleanup(JNIEnv* env, jobject obj)
|
||||
{
|
||||
const GpsInterface* interface = GetGpsInterface(env, obj);
|
||||
if (interface)
|
||||
interface->cleanup();
|
||||
if (sGpsInterface)
|
||||
sGpsInterface->cleanup();
|
||||
}
|
||||
|
||||
static jboolean android_location_GpsLocationProvider_set_position_mode(JNIEnv* env, jobject obj,
|
||||
jint mode, jint recurrence, jint min_interval, jint preferred_accuracy, jint preferred_time)
|
||||
{
|
||||
const GpsInterface* interface = GetGpsInterface(env, obj);
|
||||
if (interface)
|
||||
return (interface->set_position_mode(mode, recurrence, min_interval, preferred_accuracy,
|
||||
if (sGpsInterface)
|
||||
return (sGpsInterface->set_position_mode(mode, recurrence, min_interval, preferred_accuracy,
|
||||
preferred_time) == 0);
|
||||
else
|
||||
return false;
|
||||
@ -341,27 +302,24 @@ static jboolean android_location_GpsLocationProvider_set_position_mode(JNIEnv* e
|
||||
|
||||
static jboolean android_location_GpsLocationProvider_start(JNIEnv* env, jobject obj)
|
||||
{
|
||||
const GpsInterface* interface = GetGpsInterface(env, obj);
|
||||
if (interface)
|
||||
return (interface->start() == 0);
|
||||
if (sGpsInterface)
|
||||
return (sGpsInterface->start() == 0);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
static jboolean android_location_GpsLocationProvider_stop(JNIEnv* env, jobject obj)
|
||||
{
|
||||
const GpsInterface* interface = GetGpsInterface(env, obj);
|
||||
if (interface)
|
||||
return (interface->stop() == 0);
|
||||
if (sGpsInterface)
|
||||
return (sGpsInterface->stop() == 0);
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
static void android_location_GpsLocationProvider_delete_aiding_data(JNIEnv* env, jobject obj, jint flags)
|
||||
{
|
||||
const GpsInterface* interface = GetGpsInterface(env, obj);
|
||||
if (interface)
|
||||
interface->delete_aiding_data(flags);
|
||||
if (sGpsInterface)
|
||||
sGpsInterface->delete_aiding_data(flags);
|
||||
}
|
||||
|
||||
static jint android_location_GpsLocationProvider_read_sv_status(JNIEnv* env, jobject obj,
|
||||
@ -399,8 +357,8 @@ static void android_location_GpsLocationProvider_agps_set_reference_location_cel
|
||||
jobject obj, jint type, jint mcc, jint mnc, jint lac, jint cid)
|
||||
{
|
||||
AGpsRefLocation location;
|
||||
const AGpsRilInterface* interface = GetAGpsRilInterface(env, obj);
|
||||
if (!interface) {
|
||||
|
||||
if (!sAGpsRilInterface) {
|
||||
LOGE("no AGPS RIL interface in agps_set_reference_location_cellid");
|
||||
return;
|
||||
}
|
||||
@ -419,15 +377,15 @@ static void android_location_GpsLocationProvider_agps_set_reference_location_cel
|
||||
return;
|
||||
break;
|
||||
}
|
||||
interface->set_ref_location(&location, sizeof(location));
|
||||
sAGpsRilInterface->set_ref_location(&location, sizeof(location));
|
||||
}
|
||||
|
||||
static void android_location_GpsLocationProvider_agps_send_ni_message(JNIEnv* env,
|
||||
jobject obj, jbyteArray ni_msg, jint size)
|
||||
{
|
||||
size_t sz;
|
||||
const AGpsRilInterface* interface = GetAGpsRilInterface(env, obj);
|
||||
if (!interface) {
|
||||
|
||||
if (!sAGpsRilInterface) {
|
||||
LOGE("no AGPS RIL interface in send_ni_message");
|
||||
return;
|
||||
}
|
||||
@ -435,21 +393,20 @@ static void android_location_GpsLocationProvider_agps_send_ni_message(JNIEnv* en
|
||||
return;
|
||||
sz = (size_t)size;
|
||||
jbyte* b = env->GetByteArrayElements(ni_msg, 0);
|
||||
interface->ni_message((uint8_t *)b,sz);
|
||||
sAGpsRilInterface->ni_message((uint8_t *)b,sz);
|
||||
env->ReleaseByteArrayElements(ni_msg,b,0);
|
||||
}
|
||||
|
||||
static void android_location_GpsLocationProvider_agps_set_id(JNIEnv *env,
|
||||
jobject obj, jint type, jstring setid_string)
|
||||
{
|
||||
const AGpsRilInterface* interface = GetAGpsRilInterface(env, obj);
|
||||
if (!interface) {
|
||||
if (!sAGpsRilInterface) {
|
||||
LOGE("no AGPS RIL interface in agps_set_id");
|
||||
return;
|
||||
}
|
||||
|
||||
const char *setid = env->GetStringUTFChars(setid_string, NULL);
|
||||
interface->set_set_id(type, setid);
|
||||
sAGpsRilInterface->set_set_id(type, setid);
|
||||
env->ReleaseStringUTFChars(setid_string, setid);
|
||||
}
|
||||
|
||||
@ -469,40 +426,30 @@ static jint android_location_GpsLocationProvider_read_nmea(JNIEnv* env, jobject
|
||||
static void android_location_GpsLocationProvider_inject_time(JNIEnv* env, jobject obj,
|
||||
jlong time, jlong timeReference, jint uncertainty)
|
||||
{
|
||||
const GpsInterface* interface = GetGpsInterface(env, obj);
|
||||
if (interface)
|
||||
interface->inject_time(time, timeReference, uncertainty);
|
||||
if (sGpsInterface)
|
||||
sGpsInterface->inject_time(time, timeReference, uncertainty);
|
||||
}
|
||||
|
||||
static void android_location_GpsLocationProvider_inject_location(JNIEnv* env, jobject obj,
|
||||
jdouble latitude, jdouble longitude, jfloat accuracy)
|
||||
{
|
||||
const GpsInterface* interface = GetGpsInterface(env, obj);
|
||||
if (interface)
|
||||
interface->inject_location(latitude, longitude, accuracy);
|
||||
if (sGpsInterface)
|
||||
sGpsInterface->inject_location(latitude, longitude, accuracy);
|
||||
}
|
||||
|
||||
static jboolean android_location_GpsLocationProvider_supports_xtra(JNIEnv* env, jobject obj)
|
||||
{
|
||||
if (!sGpsXtraInterface) {
|
||||
const GpsInterface* interface = GetGpsInterface(env, obj);
|
||||
if (!interface)
|
||||
return false;
|
||||
sGpsXtraInterface = (const GpsXtraInterface*)interface->get_extension(GPS_XTRA_INTERFACE);
|
||||
if (sGpsXtraInterface) {
|
||||
int result = sGpsXtraInterface->init(&sGpsXtraCallbacks);
|
||||
if (result) {
|
||||
sGpsXtraInterface = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (sGpsXtraInterface != NULL);
|
||||
}
|
||||
|
||||
static void android_location_GpsLocationProvider_inject_xtra_data(JNIEnv* env, jobject obj,
|
||||
jbyteArray data, jint length)
|
||||
{
|
||||
if (!sGpsXtraInterface) {
|
||||
LOGE("no XTRA interface in inject_xtra_data");
|
||||
return;
|
||||
}
|
||||
|
||||
jbyte* bytes = (jbyte *)env->GetPrimitiveArrayCritical(data, 0);
|
||||
sGpsXtraInterface->inject_xtra_data((char *)bytes, length);
|
||||
env->ReleasePrimitiveArrayCritical(data, bytes, JNI_ABORT);
|
||||
@ -510,8 +457,7 @@ static void android_location_GpsLocationProvider_inject_xtra_data(JNIEnv* env, j
|
||||
|
||||
static void android_location_GpsLocationProvider_agps_data_conn_open(JNIEnv* env, jobject obj, jstring apn)
|
||||
{
|
||||
const AGpsInterface* interface = GetAGpsInterface(env, obj);
|
||||
if (!interface) {
|
||||
if (!sAGpsInterface) {
|
||||
LOGE("no AGPS interface in agps_data_conn_open");
|
||||
return;
|
||||
}
|
||||
@ -520,53 +466,49 @@ static void android_location_GpsLocationProvider_agps_data_conn_open(JNIEnv* env
|
||||
return;
|
||||
}
|
||||
const char *apnStr = env->GetStringUTFChars(apn, NULL);
|
||||
interface->data_conn_open(apnStr);
|
||||
sAGpsInterface->data_conn_open(apnStr);
|
||||
env->ReleaseStringUTFChars(apn, apnStr);
|
||||
}
|
||||
|
||||
static void android_location_GpsLocationProvider_agps_data_conn_closed(JNIEnv* env, jobject obj)
|
||||
{
|
||||
const AGpsInterface* interface = GetAGpsInterface(env, obj);
|
||||
if (!interface) {
|
||||
if (!sAGpsInterface) {
|
||||
LOGE("no AGPS interface in agps_data_conn_open");
|
||||
return;
|
||||
}
|
||||
interface->data_conn_closed();
|
||||
sAGpsInterface->data_conn_closed();
|
||||
}
|
||||
|
||||
static void android_location_GpsLocationProvider_agps_data_conn_failed(JNIEnv* env, jobject obj)
|
||||
{
|
||||
const AGpsInterface* interface = GetAGpsInterface(env, obj);
|
||||
if (!interface) {
|
||||
if (!sAGpsInterface) {
|
||||
LOGE("no AGPS interface in agps_data_conn_open");
|
||||
return;
|
||||
}
|
||||
interface->data_conn_failed();
|
||||
sAGpsInterface->data_conn_failed();
|
||||
}
|
||||
|
||||
static void android_location_GpsLocationProvider_set_agps_server(JNIEnv* env, jobject obj,
|
||||
jint type, jstring hostname, jint port)
|
||||
{
|
||||
const AGpsInterface* interface = GetAGpsInterface(env, obj);
|
||||
if (!interface) {
|
||||
if (!sAGpsInterface) {
|
||||
LOGE("no AGPS interface in agps_data_conn_open");
|
||||
return;
|
||||
}
|
||||
const char *c_hostname = env->GetStringUTFChars(hostname, NULL);
|
||||
interface->set_server(type, c_hostname, port);
|
||||
sAGpsInterface->set_server(type, c_hostname, port);
|
||||
env->ReleaseStringUTFChars(hostname, c_hostname);
|
||||
}
|
||||
|
||||
static void android_location_GpsLocationProvider_send_ni_response(JNIEnv* env, jobject obj,
|
||||
jint notifId, jint response)
|
||||
{
|
||||
const GpsNiInterface* interface = GetNiInterface(env, obj);
|
||||
if (!interface) {
|
||||
if (!sGpsNiInterface) {
|
||||
LOGE("no NI interface in send_ni_response");
|
||||
return;
|
||||
}
|
||||
|
||||
interface->respond(notifId, response);
|
||||
sGpsNiInterface->respond(notifId, response);
|
||||
}
|
||||
|
||||
static jstring android_location_GpsLocationProvider_get_internal_state(JNIEnv* env, jobject obj)
|
||||
@ -586,14 +528,14 @@ static jstring android_location_GpsLocationProvider_get_internal_state(JNIEnv* e
|
||||
static void android_location_GpsLocationProvider_update_network_state(JNIEnv* env, jobject obj,
|
||||
jboolean connected, int type, jboolean roaming, jstring extraInfo)
|
||||
{
|
||||
const AGpsRilInterface* interface = GetAGpsRilInterface(env, obj);
|
||||
if (interface && interface->update_network_state) {
|
||||
|
||||
if (sAGpsRilInterface && sAGpsRilInterface->update_network_state) {
|
||||
if (extraInfo) {
|
||||
const char *extraInfoStr = env->GetStringUTFChars(extraInfo, NULL);
|
||||
interface->update_network_state(connected, type, roaming, extraInfoStr);
|
||||
sAGpsRilInterface->update_network_state(connected, type, roaming, extraInfoStr);
|
||||
env->ReleaseStringUTFChars(extraInfo, extraInfoStr);
|
||||
} else {
|
||||
interface->update_network_state(connected, type, roaming, NULL);
|
||||
sAGpsRilInterface->update_network_state(connected, type, roaming, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.internal.telephony;
|
||||
|
||||
import android.content.Intent;
|
||||
|
||||
interface IWapPushManager {
|
||||
/**
|
||||
* Processes WAP push message and triggers the receiver application registered
|
||||
* in the application ID table.
|
||||
*/
|
||||
int processMessage(String app_id, String content_type, in Intent intent);
|
||||
|
||||
/**
|
||||
* Add receiver application into the application ID table.
|
||||
* Returns true if inserting the information is successfull. Inserting the duplicated
|
||||
* record in the application ID table is not allowed. Use update/delete method.
|
||||
*/
|
||||
boolean addPackage(String x_app_id, String content_type,
|
||||
String package_name, String class_name,
|
||||
int app_type, boolean need_signature, boolean further_processing);
|
||||
|
||||
/**
|
||||
* Updates receiver application that is last added.
|
||||
* Returns true if updating the information is successfull.
|
||||
*/
|
||||
boolean updatePackage(String x_app_id, String content_type,
|
||||
String package_name, String class_name,
|
||||
int app_type, boolean need_signature, boolean further_processing);
|
||||
|
||||
/**
|
||||
* Delites receiver application information.
|
||||
* Returns true if deleting is successfull.
|
||||
*/
|
||||
boolean deletePackage(String x_app_id, String content_type,
|
||||
String package_name, String class_name);
|
||||
}
|
||||
|
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (C) 2010 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.internal.telephony;
|
||||
|
||||
/**
|
||||
* WapPushManager constant value definitions
|
||||
*/
|
||||
public class WapPushManagerParams {
|
||||
/**
|
||||
* Application type activity
|
||||
*/
|
||||
public static final int APP_TYPE_ACTIVITY = 0;
|
||||
|
||||
/**
|
||||
* Application type service
|
||||
*/
|
||||
public static final int APP_TYPE_SERVICE = 1;
|
||||
|
||||
/**
|
||||
* Process Message return value
|
||||
* Message is handled
|
||||
*/
|
||||
public static final int MESSAGE_HANDLED = 0x1;
|
||||
|
||||
/**
|
||||
* Process Message return value
|
||||
* Application ID or content type was not found in the application ID table
|
||||
*/
|
||||
public static final int APP_QUERY_FAILED = 0x2;
|
||||
|
||||
/**
|
||||
* Process Message return value
|
||||
* Receiver application signature check failed
|
||||
*/
|
||||
public static final int SIGNATURE_NO_MATCH = 0x4;
|
||||
|
||||
/**
|
||||
* Process Message return value
|
||||
* Receiver application was not found
|
||||
*/
|
||||
public static final int INVALID_RECEIVER_NAME = 0x8;
|
||||
|
||||
/**
|
||||
* Process Message return value
|
||||
* Unknown exception
|
||||
*/
|
||||
public static final int EXCEPTION_CAUGHT = 0x10;
|
||||
|
||||
/**
|
||||
* Process Message return value
|
||||
* Need further processing after WapPushManager message processing
|
||||
*/
|
||||
public static final int FURTHER_PROCESSING = 0x8000;
|
||||
|
||||
}
|
||||
|
@ -14,15 +14,20 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
|
||||
package com.android.internal.telephony;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.provider.Telephony;
|
||||
import android.provider.Telephony.Sms.Intents;
|
||||
import android.util.Config;
|
||||
import android.util.Log;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
|
||||
/**
|
||||
* WAP push handler class.
|
||||
@ -42,11 +47,83 @@ public class WapPushOverSms {
|
||||
*/
|
||||
private final int WAKE_LOCK_TIMEOUT = 5000;
|
||||
|
||||
private final int BIND_RETRY_INTERVAL = 1000;
|
||||
/**
|
||||
* A handle to WapPushManager interface
|
||||
*/
|
||||
private WapPushConnection mWapConn = null;
|
||||
private class WapPushConnection implements ServiceConnection {
|
||||
private IWapPushManager mWapPushMan;
|
||||
private Context mOwner;
|
||||
|
||||
public WapPushConnection(Context ownerContext) {
|
||||
mOwner = ownerContext;
|
||||
}
|
||||
|
||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||
mWapPushMan = IWapPushManager.Stub.asInterface(service);
|
||||
if (Config.DEBUG) Log.v(LOG_TAG, "wappush manager connected to " +
|
||||
mOwner.hashCode());
|
||||
}
|
||||
|
||||
public void onServiceDisconnected(ComponentName name) {
|
||||
mWapPushMan = null;
|
||||
if (Config.DEBUG) Log.v(LOG_TAG, "wappush manager disconnected.");
|
||||
// WapPushManager must be always attached.
|
||||
rebindWapPushManager();
|
||||
}
|
||||
|
||||
/**
|
||||
* bind WapPushManager
|
||||
*/
|
||||
public void bindWapPushManager() {
|
||||
if (mWapPushMan != null) return;
|
||||
|
||||
final ServiceConnection wapPushConnection = this;
|
||||
|
||||
mOwner.bindService(new Intent(IWapPushManager.class.getName()),
|
||||
wapPushConnection, Context.BIND_AUTO_CREATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* rebind WapPushManager
|
||||
* This method is called when WapPushManager is disconnected unexpectedly.
|
||||
*/
|
||||
private void rebindWapPushManager() {
|
||||
if (mWapPushMan != null) return;
|
||||
|
||||
final ServiceConnection wapPushConnection = this;
|
||||
new Thread() {
|
||||
public void run() {
|
||||
while (mWapPushMan == null) {
|
||||
mOwner.bindService(new Intent(IWapPushManager.class.getName()),
|
||||
wapPushConnection, Context.BIND_AUTO_CREATE);
|
||||
try {
|
||||
Thread.sleep(BIND_RETRY_INTERVAL);
|
||||
} catch (InterruptedException e) {
|
||||
if (Config.DEBUG) Log.v(LOG_TAG, "sleep interrupted.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns interface to WapPushManager
|
||||
*/
|
||||
public IWapPushManager getWapPushManager() {
|
||||
return mWapPushMan;
|
||||
}
|
||||
}
|
||||
|
||||
public WapPushOverSms(Phone phone, SMSDispatcher smsDispatcher) {
|
||||
mSmsDispatcher = smsDispatcher;
|
||||
mContext = phone.getContext();
|
||||
mWapConn = new WapPushConnection(mContext);
|
||||
mWapConn.bindWapPushManager();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Dispatches inbound messages that are in the WAP PDU format. See
|
||||
* wap-230-wsp-20010705-a section 8 for details on the WAP PDU format.
|
||||
@ -106,16 +183,15 @@ public class WapPushOverSms {
|
||||
}
|
||||
|
||||
String mimeType = pduDecoder.getValueString();
|
||||
|
||||
long binaryContentType = pduDecoder.getValue32();
|
||||
index += pduDecoder.getDecodedDataLength();
|
||||
|
||||
byte[] header = new byte[headerLength];
|
||||
System.arraycopy(pdu, headerStartIndex, header, 0, header.length);
|
||||
|
||||
byte[] intentData;
|
||||
String permission;
|
||||
|
||||
if (mimeType.equals(WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO)) {
|
||||
if (mimeType != null && mimeType.equals(WspTypeDecoder.CONTENT_TYPE_B_PUSH_CO)) {
|
||||
intentData = pdu;
|
||||
} else {
|
||||
int dataIndex = headerStartIndex + headerLength;
|
||||
@ -123,6 +199,62 @@ public class WapPushOverSms {
|
||||
System.arraycopy(pdu, dataIndex, intentData, 0, intentData.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Seek for application ID field in WSP header.
|
||||
* If application ID is found, WapPushManager substitute the message
|
||||
* processing. Since WapPushManager is optional module, if WapPushManager
|
||||
* is not found, legacy message processing will be continued.
|
||||
*/
|
||||
if (pduDecoder.seekXWapApplicationId(index, index + headerLength - 1)) {
|
||||
index = (int) pduDecoder.getValue32();
|
||||
pduDecoder.decodeXWapApplicationId(index);
|
||||
String wapAppId = pduDecoder.getValueString();
|
||||
if (wapAppId == null) {
|
||||
wapAppId = Integer.toString((int) pduDecoder.getValue32());
|
||||
}
|
||||
|
||||
String contentType = ((mimeType == null) ?
|
||||
Long.toString(binaryContentType) : mimeType);
|
||||
if (Config.DEBUG) Log.v(LOG_TAG, "appid found: " + wapAppId + ":" + contentType);
|
||||
|
||||
try {
|
||||
boolean processFurther = true;
|
||||
IWapPushManager wapPushMan = mWapConn.getWapPushManager();
|
||||
|
||||
if (wapPushMan == null) {
|
||||
if (Config.DEBUG) Log.w(LOG_TAG, "wap push manager not found!");
|
||||
} else {
|
||||
Intent intent = new Intent();
|
||||
intent.putExtra("transactionId", transactionId);
|
||||
intent.putExtra("pduType", pduType);
|
||||
intent.putExtra("header", header);
|
||||
intent.putExtra("data", intentData);
|
||||
intent.putExtra("contentTypeParameters",
|
||||
pduDecoder.getContentParameters());
|
||||
|
||||
int procRet = wapPushMan.processMessage(wapAppId, contentType, intent);
|
||||
if (Config.DEBUG) Log.v(LOG_TAG, "procRet:" + procRet);
|
||||
if ((procRet & WapPushManagerParams.MESSAGE_HANDLED) > 0
|
||||
&& (procRet & WapPushManagerParams.FURTHER_PROCESSING) == 0) {
|
||||
processFurther = false;
|
||||
}
|
||||
}
|
||||
if (!processFurther) {
|
||||
return Intents.RESULT_SMS_HANDLED;
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
if (Config.DEBUG) Log.w(LOG_TAG, "remote func failed...");
|
||||
}
|
||||
}
|
||||
if (Config.DEBUG) Log.v(LOG_TAG, "fall back to existing handler");
|
||||
|
||||
if (mimeType == null) {
|
||||
if (Config.DEBUG) Log.w(LOG_TAG, "Header Content-Type error.");
|
||||
return Intents.RESULT_SMS_GENERIC_ERROR;
|
||||
}
|
||||
|
||||
String permission;
|
||||
|
||||
if (mimeType.equals(WspTypeDecoder.CONTENT_TYPE_B_MMS)) {
|
||||
permission = "android.permission.RECEIVE_MMS";
|
||||
} else {
|
||||
|
@ -37,6 +37,7 @@ public class WspTypeDecoder {
|
||||
private final static HashMap<Integer, String> WELL_KNOWN_PARAMETERS =
|
||||
new HashMap<Integer, String>();
|
||||
|
||||
public static final int PARAMETER_ID_X_WAP_APPLICATION_ID = 0x2f;
|
||||
private static final int Q_VALUE = 0x00;
|
||||
|
||||
static {
|
||||
@ -602,6 +603,70 @@ public class WspTypeDecoder {
|
||||
return decodeTextString(startIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Seek for the "X-Wap-Application-Id" field for WSP pdu
|
||||
*
|
||||
* @param startIndex The starting position of seek pointer
|
||||
* @param endIndex Valid seek area end point
|
||||
*
|
||||
* @return false when error(not a X-Wap-Application-Id) occur
|
||||
* return value can be retrieved by getValue32()
|
||||
*/
|
||||
public boolean seekXWapApplicationId(int startIndex, int endIndex) {
|
||||
int index = startIndex;
|
||||
|
||||
try {
|
||||
for (index = startIndex; index <= endIndex; ) {
|
||||
/**
|
||||
* 8.4.1.1 Field name
|
||||
* Field name is integer or text.
|
||||
*/
|
||||
if (decodeIntegerValue(index)) {
|
||||
int fieldValue = (int) getValue32();
|
||||
|
||||
if (fieldValue == PARAMETER_ID_X_WAP_APPLICATION_ID) {
|
||||
unsigned32bit = index + 1;
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (!decodeTextString(index)) return false;
|
||||
}
|
||||
index += getDecodedDataLength();
|
||||
if (index > endIndex) return false;
|
||||
|
||||
/**
|
||||
* 8.4.1.2 Field values
|
||||
* Value Interpretation of First Octet
|
||||
* 0 - 30 This octet is followed by the indicated number (0 - 30)
|
||||
of data octets
|
||||
* 31 This octet is followed by a uintvar, which indicates the number
|
||||
* of data octets after it
|
||||
* 32 - 127 The value is a text string, terminated by a zero octet
|
||||
(NUL character)
|
||||
* 128 - 255 It is an encoded 7-bit value; this header has no more data
|
||||
*/
|
||||
byte val = wspData[index];
|
||||
if (0 <= val && val <= WAP_PDU_SHORT_LENGTH_MAX) {
|
||||
index += wspData[index] + 1;
|
||||
} else if (val == WAP_PDU_LENGTH_QUOTE) {
|
||||
if (index + 1 >= endIndex) return false;
|
||||
index++;
|
||||
if (!decodeUintvarInteger(index)) return false;
|
||||
index += getDecodedDataLength();
|
||||
} else if (WAP_PDU_LENGTH_QUOTE < val && val <= 127) {
|
||||
if (!decodeTextString(index)) return false;
|
||||
index += getDecodedDataLength();
|
||||
} else {
|
||||
index++;
|
||||
}
|
||||
}
|
||||
} catch (ArrayIndexOutOfBoundsException e) {
|
||||
//seek application ID failed. WSP header might be corrupted
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode the "X-Wap-Content-URI" type for WSP pdu
|
||||
*
|
||||
|
@ -45,7 +45,7 @@ public:
|
||||
mRClassDir(NULL), mResourceIntermediatesDir(NULL), mManifestMinSdkVersion(NULL),
|
||||
mMinSdkVersion(NULL), mTargetSdkVersion(NULL), mMaxSdkVersion(NULL),
|
||||
mVersionCode(NULL), mVersionName(NULL), mCustomPackage(NULL),
|
||||
mMaxResVersion(NULL), mDebugMode(false), mProduct(NULL),
|
||||
mMaxResVersion(NULL), mDebugMode(false), mNonConstantId(false), mProduct(NULL),
|
||||
mArgc(0), mArgv(NULL)
|
||||
{}
|
||||
~Bundle(void) {}
|
||||
@ -139,6 +139,8 @@ public:
|
||||
void setMaxResVersion(const char * val) { mMaxResVersion = val; }
|
||||
bool getDebugMode() { return mDebugMode; }
|
||||
void setDebugMode(bool val) { mDebugMode = val; }
|
||||
bool getNonConstantId() { return mNonConstantId; }
|
||||
void setNonConstantId(bool val) { mNonConstantId = val; }
|
||||
const char* getProduct() const { return mProduct; }
|
||||
void setProduct(const char * val) { mProduct = val; }
|
||||
|
||||
@ -239,6 +241,7 @@ private:
|
||||
const char* mCustomPackage;
|
||||
const char* mMaxResVersion;
|
||||
bool mDebugMode;
|
||||
bool mNonConstantId;
|
||||
const char* mProduct;
|
||||
|
||||
/* file specification */
|
||||
|
@ -160,7 +160,11 @@ void usage(void)
|
||||
" product variants\n"
|
||||
" --utf16\n"
|
||||
" changes default encoding for resources to UTF-16. Only useful when API\n"
|
||||
" level is set to 7 or higher where the default encoding is UTF-8.\n");
|
||||
" level is set to 7 or higher where the default encoding is UTF-8.\n"
|
||||
" --non-constant-id\n"
|
||||
" Make the resources ID non constant. This is required to make an R java class\n"
|
||||
" that does not contain the final value but is used to make reusable compiled\n"
|
||||
" libraries that need to access resources.\n");
|
||||
}
|
||||
|
||||
/*
|
||||
@ -497,6 +501,8 @@ int main(int argc, char* const argv[])
|
||||
goto bail;
|
||||
}
|
||||
bundle.setProduct(argv[0]);
|
||||
} else if (strcmp(cp, "-non-constant-id") == 0) {
|
||||
bundle.setNonConstantId(true);
|
||||
} else {
|
||||
fprintf(stderr, "ERROR: Unknown option '-%s'\n", cp);
|
||||
wantUsage = true;
|
||||
|
@ -1655,7 +1655,8 @@ static status_t writeLayoutClasses(
|
||||
|
||||
static status_t writeSymbolClass(
|
||||
FILE* fp, const sp<AaptAssets>& assets, bool includePrivate,
|
||||
const sp<AaptSymbols>& symbols, const String8& className, int indent)
|
||||
const sp<AaptSymbols>& symbols, const String8& className, int indent,
|
||||
bool nonConstantId)
|
||||
{
|
||||
fprintf(fp, "%spublic %sfinal class %s {\n",
|
||||
getIndentSpace(indent),
|
||||
@ -1665,6 +1666,10 @@ static status_t writeSymbolClass(
|
||||
size_t i;
|
||||
status_t err = NO_ERROR;
|
||||
|
||||
const char * id_format = nonConstantId ?
|
||||
"%spublic static int %s=0x%08x;\n" :
|
||||
"%spublic static final int %s=0x%08x;\n";
|
||||
|
||||
size_t N = symbols->getSymbols().size();
|
||||
for (i=0; i<N; i++) {
|
||||
const AaptSymbolEntry& sym = symbols->getSymbols().valueAt(i);
|
||||
@ -1717,7 +1722,7 @@ static status_t writeSymbolClass(
|
||||
if (deprecated) {
|
||||
fprintf(fp, "%s@Deprecated\n", getIndentSpace(indent));
|
||||
}
|
||||
fprintf(fp, "%spublic static final int %s=0x%08x;\n",
|
||||
fprintf(fp, id_format,
|
||||
getIndentSpace(indent),
|
||||
String8(name).string(), (int)sym.int32Val);
|
||||
}
|
||||
@ -1768,7 +1773,7 @@ static status_t writeSymbolClass(
|
||||
if (nclassName == "styleable") {
|
||||
styleableSymbols = nsymbols;
|
||||
} else {
|
||||
err = writeSymbolClass(fp, assets, includePrivate, nsymbols, nclassName, indent);
|
||||
err = writeSymbolClass(fp, assets, includePrivate, nsymbols, nclassName, indent, nonConstantId);
|
||||
}
|
||||
if (err != NO_ERROR) {
|
||||
return err;
|
||||
@ -1839,7 +1844,7 @@ status_t writeResourceSymbols(Bundle* bundle, const sp<AaptAssets>& assets,
|
||||
"\n"
|
||||
"package %s;\n\n", package.string());
|
||||
|
||||
status_t err = writeSymbolClass(fp, assets, includePrivate, symbols, className, 0);
|
||||
status_t err = writeSymbolClass(fp, assets, includePrivate, symbols, className, 0, bundle->getNonConstantId());
|
||||
if (err != NO_ERROR) {
|
||||
return err;
|
||||
}
|
||||
|
Reference in New Issue
Block a user