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:
Xavier Ducrohet
2011-02-28 09:16:38 -08:00
committed by Android Git Automerger
33 changed files with 4475 additions and 207 deletions

View File

@ -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 \

View File

@ -642,14 +642,18 @@ public class DateUtils
private static void initFormatStrings() {
synchronized (sLock) {
Resources r = Resources.getSystem();
Configuration cfg = r.getConfiguration();
if (sLastConfig == null || !sLastConfig.equals(cfg)) {
sLastConfig = cfg;
sStatusTimeFormat = java.text.DateFormat.getTimeInstance(java.text.DateFormat.SHORT);
sElapsedFormatMMSS = r.getString(com.android.internal.R.string.elapsed_time_short_format_mm_ss);
sElapsedFormatHMMSS = r.getString(com.android.internal.R.string.elapsed_time_short_format_h_mm_ss);
}
initFormatStringsLocked();
}
}
private static void initFormatStringsLocked() {
Resources r = Resources.getSystem();
Configuration cfg = r.getConfiguration();
if (sLastConfig == null || !sLastConfig.equals(cfg)) {
sLastConfig = cfg;
sStatusTimeFormat = java.text.DateFormat.getTimeInstance(java.text.DateFormat.SHORT);
sElapsedFormatMMSS = r.getString(com.android.internal.R.string.elapsed_time_short_format_mm_ss);
sElapsedFormatHMMSS = r.getString(com.android.internal.R.string.elapsed_time_short_format_h_mm_ss);
}
}
@ -659,8 +663,10 @@ public class DateUtils
* @hide
*/
public static final CharSequence timeString(long millis) {
initFormatStrings();
return sStatusTimeFormat.format(millis);
synchronized (sLock) {
initFormatStringsLocked();
return sStatusTimeFormat.format(millis);
}
}
/**

View File

@ -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;

View File

@ -317,6 +317,7 @@ public class EdgeGlow {
mEdgeScaleY = mEdgeScaleYStart +
(mEdgeScaleYFinish - mEdgeScaleYStart) *
interp * factor;
mState = STATE_RECEDE;
break;
case STATE_RECEDE:
mState = STATE_IDLE;

View File

@ -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.
*/
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;
/* Special case where the last 7 bits in the last byte could hold a valid
* 7-bit character or a padding character. Drop the last 7-bit character
* if it is a padding character.
*/
if (lengthBytes % 7 == 0) {
if (lengthBytes > 0) {
if ((input[lengthBytes - 1] >> 1) == PADDING_CHAR) {
lengthSeptets = lengthSeptets - 1;
}
nextChar = (byte) (cCurr >> 1);
stringBuf[nStridx++] = nextChar;
}
cPrev = cCurr;
}
try {
result = new String(stringBuf, 0, nStridx, "US-ASCII");
}
catch (UnsupportedEncodingException e)
{
Log.e(TAG, e.getMessage());
decoded = GsmAlphabet.gsm7BitPackedToString(input, 0, lengthSeptets);
// Return "" if decoding of GSM packed string fails
if (null == decoded) {
Log.e(TAG, "Decoding of GSM packed string failed");
decoded = "";
}
return result;
return decoded;
}
static String decodeUTF8String(byte[] input)

View 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))

View 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>

View 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
# ************************************************

View 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

View 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);
}

View File

@ -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;
}
}

View 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)

View 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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View 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>

View File

@ -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);
}
}

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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();
}

View File

@ -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();
}
}

View File

@ -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

View File

@ -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);
}
}
}

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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 {

View File

@ -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
*

View File

@ -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 */

View File

@ -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;

View File

@ -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;
}