Merge "Startup WAP PUSH service before handling SMS messages"
This commit is contained in:
@@ -27,7 +27,8 @@
|
|||||||
|
|
||||||
<original-package android:name="com.android.smspush" />
|
<original-package android:name="com.android.smspush" />
|
||||||
<application
|
<application
|
||||||
android:allowClearUserData="false">
|
android:allowClearUserData="false"
|
||||||
|
android:directBootAware="true">
|
||||||
<service android:name=".WapPushManager"
|
<service android:name=".WapPushManager"
|
||||||
android:permission="com.android.smspush.WAPPUSH_MANAGER_BIND"
|
android:permission="com.android.smspush.WAPPUSH_MANAGER_BIND"
|
||||||
android:exported="true">
|
android:exported="true">
|
||||||
|
|||||||
@@ -26,17 +26,21 @@ import android.content.pm.ApplicationInfo;
|
|||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.PackageManager.NameNotFoundException;
|
import android.content.pm.PackageManager.NameNotFoundException;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.database.sqlite.SQLiteOpenHelper;
|
|
||||||
import android.database.sqlite.SQLiteDatabase;
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
|
import android.database.sqlite.SQLiteOpenHelper;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
|
import android.os.UserManager;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.internal.telephony.IWapPushManager;
|
import com.android.internal.telephony.IWapPushManager;
|
||||||
import com.android.internal.telephony.WapPushManagerParams;
|
import com.android.internal.telephony.WapPushManagerParams;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The WapPushManager service is implemented to process incoming
|
* The WapPushManager service is implemented to process incoming
|
||||||
* WAP Push messages and to maintain the Receiver Application/Application
|
* WAP Push messages and to maintain the Receiver Application/Application
|
||||||
@@ -67,8 +71,13 @@ public class WapPushManager extends Service {
|
|||||||
/**
|
/**
|
||||||
* Inner class that deals with application ID table
|
* Inner class that deals with application ID table
|
||||||
*/
|
*/
|
||||||
private class WapPushManDBHelper extends SQLiteOpenHelper {
|
@VisibleForTesting
|
||||||
WapPushManDBHelper(Context context) {
|
public static class WapPushManDBHelper extends SQLiteOpenHelper {
|
||||||
|
/**
|
||||||
|
* Constructor
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
public WapPushManDBHelper(Context context) {
|
||||||
super(context, DATABASE_NAME, null, WAP_PUSH_MANAGER_VERSION);
|
super(context, DATABASE_NAME, null, WAP_PUSH_MANAGER_VERSION);
|
||||||
if (LOCAL_LOGV) Log.v(LOG_TAG, "helper instance created.");
|
if (LOCAL_LOGV) Log.v(LOG_TAG, "helper instance created.");
|
||||||
}
|
}
|
||||||
@@ -269,10 +278,6 @@ public class WapPushManager extends Service {
|
|||||||
int app_type, boolean need_signature, boolean further_processing) {
|
int app_type, boolean need_signature, boolean further_processing) {
|
||||||
WapPushManDBHelper dbh = getDatabase(mContext);
|
WapPushManDBHelper dbh = getDatabase(mContext);
|
||||||
SQLiteDatabase db = dbh.getWritableDatabase();
|
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)) {
|
if (!appTypeCheck(app_type)) {
|
||||||
Log.w(LOG_TAG, "invalid app_type " + app_type + ". app_type must be "
|
Log.w(LOG_TAG, "invalid app_type " + app_type + ". app_type must be "
|
||||||
@@ -280,34 +285,8 @@ public class WapPushManager extends Service {
|
|||||||
+ WapPushManagerParams.APP_TYPE_SERVICE);
|
+ WapPushManagerParams.APP_TYPE_SERVICE);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
boolean ret = insertPackage(dbh, db, x_app_id, content_type, package_name, class_name,
|
||||||
if (lastapp == null) {
|
app_type, need_signature, further_processing);
|
||||||
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();
|
db.close();
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@@ -404,11 +383,91 @@ public class WapPushManager extends Service {
|
|||||||
protected WapPushManDBHelper getDatabase(Context context) {
|
protected WapPushManDBHelper getDatabase(Context context) {
|
||||||
if (mDbHelper == null) {
|
if (mDbHelper == null) {
|
||||||
if (LOCAL_LOGV) Log.v(LOG_TAG, "create new db inst.");
|
if (LOCAL_LOGV) Log.v(LOG_TAG, "create new db inst.");
|
||||||
mDbHelper = new WapPushManDBHelper(context);
|
mDbHelper = new WapPushManDBHelper(context.createDeviceProtectedStorageContext());
|
||||||
}
|
}
|
||||||
|
// Migrate existing legacy database into the device encrypted storage.
|
||||||
|
migrateWapPushManDBIfNeeded(context);
|
||||||
return mDbHelper;
|
return mDbHelper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts a package information into a database
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
public boolean insertPackage(WapPushManDBHelper dbh, SQLiteDatabase db, String appId,
|
||||||
|
String contentType, String packageName, String className, int appType,
|
||||||
|
boolean needSignature, boolean furtherProcessing) {
|
||||||
|
|
||||||
|
WapPushManDBHelper.queryData lastapp = dbh.queryLastApp(db, appId, contentType);
|
||||||
|
boolean insert = false;
|
||||||
|
int sq = 0;
|
||||||
|
|
||||||
|
if (lastapp == null) {
|
||||||
|
insert = true;
|
||||||
|
sq = 0;
|
||||||
|
} else if (!lastapp.packageName.equals(packageName)
|
||||||
|
|| !lastapp.className.equals(className)) {
|
||||||
|
insert = true;
|
||||||
|
sq = lastapp.installOrder + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (insert) {
|
||||||
|
ContentValues values = new ContentValues();
|
||||||
|
|
||||||
|
values.put("x_wap_application", appId);
|
||||||
|
values.put("content_type", contentType);
|
||||||
|
values.put("package_name", packageName);
|
||||||
|
values.put("class_name", className);
|
||||||
|
values.put("app_type", appType);
|
||||||
|
values.put("need_signature", needSignature ? 1 : 0);
|
||||||
|
values.put("further_processing", furtherProcessing ? 1 : 0);
|
||||||
|
values.put("install_order", sq);
|
||||||
|
db.insert(APPID_TABLE_NAME, null, values);
|
||||||
|
if (LOCAL_LOGV) {
|
||||||
|
Log.v(LOG_TAG, "add:" + appId + ":" + contentType + " " + packageName
|
||||||
|
+ "." + className + ", newsq:" + sq);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Migrates a legacy database into the device encrypted storage
|
||||||
|
*/
|
||||||
|
private void migrateWapPushManDBIfNeeded(Context context) {
|
||||||
|
UserManager userManager = (UserManager) context.getSystemService(Context.USER_SERVICE);
|
||||||
|
File file = context.getDatabasePath(DATABASE_NAME);
|
||||||
|
if (!userManager.isUserUnlocked() || !file.exists()) {
|
||||||
|
// Check if the device is unlocked because a legacy database can't access during
|
||||||
|
// DirectBoot.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Migration steps below:
|
||||||
|
// 1. Merge the package info to legacy database if there is any package info which is
|
||||||
|
// registered during DirectBoot.
|
||||||
|
// 2. Move the data base to the device encryped storage.
|
||||||
|
WapPushManDBHelper legacyDbHelper = new WapPushManDBHelper(context);
|
||||||
|
SQLiteDatabase legacyDb = legacyDbHelper.getWritableDatabase();
|
||||||
|
SQLiteDatabase db = mDbHelper.getWritableDatabase();
|
||||||
|
Cursor cur = db.query(APPID_TABLE_NAME, null, null, null, null, null, null);
|
||||||
|
while (cur.moveToNext()) {
|
||||||
|
insertPackage(legacyDbHelper, legacyDb,
|
||||||
|
cur.getString(cur.getColumnIndex("x_wap_application")),
|
||||||
|
cur.getString(cur.getColumnIndex("content_type")),
|
||||||
|
cur.getString(cur.getColumnIndex("package_name")),
|
||||||
|
cur.getString(cur.getColumnIndex("class_name")),
|
||||||
|
cur.getInt(cur.getColumnIndex("app_type")),
|
||||||
|
cur.getInt(cur.getColumnIndex("need_signature")) == 1,
|
||||||
|
cur.getInt(cur.getColumnIndex("further_processing")) == 1);
|
||||||
|
}
|
||||||
|
cur.close();
|
||||||
|
legacyDb.close();
|
||||||
|
db.close();
|
||||||
|
context.createDeviceProtectedStorageContext().moveDatabaseFrom(context, DATABASE_NAME);
|
||||||
|
Log.i(LOG_TAG, "Migrated the legacy database.");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is used for testing
|
* This method is used for testing
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import android.content.ComponentName;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.ServiceConnection;
|
import android.content.ServiceConnection;
|
||||||
|
import android.database.sqlite.SQLiteDatabase;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.provider.Telephony.Sms.Intents;
|
import android.provider.Telephony.Sms.Intents;
|
||||||
@@ -33,7 +34,9 @@ import com.android.internal.telephony.WspTypeDecoder;
|
|||||||
import com.android.internal.telephony.uicc.IccUtils;
|
import com.android.internal.telephony.uicc.IccUtils;
|
||||||
import com.android.internal.util.HexDump;
|
import com.android.internal.util.HexDump;
|
||||||
import com.android.smspush.WapPushManager;
|
import com.android.smspush.WapPushManager;
|
||||||
|
import com.android.smspush.WapPushManager.WapPushManDBHelper;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -467,8 +470,9 @@ public class WapPushTest extends ServiceTestCase<WapPushManager> {
|
|||||||
try {
|
try {
|
||||||
super.setUp();
|
super.setUp();
|
||||||
// get verifier
|
// get verifier
|
||||||
getContext().bindService(new Intent(IDataVerify.class.getName()),
|
Intent intent = new Intent(IDataVerify.class.getName());
|
||||||
mConn, Context.BIND_AUTO_CREATE);
|
intent.setPackage("com.android.smspush.unitTests");
|
||||||
|
getContext().bindService(intent, mConn, Context.BIND_AUTO_CREATE);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.w(LOG_TAG, "super exception");
|
Log.w(LOG_TAG, "super exception");
|
||||||
}
|
}
|
||||||
@@ -552,15 +556,15 @@ public class WapPushTest extends ServiceTestCase<WapPushManager> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add sqlite injection test
|
* Sqlite injection test
|
||||||
*/
|
*/
|
||||||
public void testAddPackage0() {
|
public void testSqliteInjection() {
|
||||||
String inject = "' union select 0,'com.android.settings','com.android.settings.Settings',0,0,0--";
|
String inject = "' union select 0,'com.android.settings','com.android.settings.Settings',0,0,0--";
|
||||||
|
|
||||||
// insert new data
|
// update data
|
||||||
IWapPushManager iwapman = getInterface();
|
IWapPushManager iwapman = getInterface();
|
||||||
try {
|
try {
|
||||||
assertFalse(iwapman.addPackage(
|
assertFalse(iwapman.updatePackage(
|
||||||
inject,
|
inject,
|
||||||
Integer.toString(mContentTypeValue),
|
Integer.toString(mContentTypeValue),
|
||||||
mPackageName, mClassName,
|
mPackageName, mClassName,
|
||||||
@@ -2528,4 +2532,45 @@ public class WapPushTest extends ServiceTestCase<WapPushManager> {
|
|||||||
mMessageBody = originalMessageBody;
|
mMessageBody = originalMessageBody;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DataBase migration test.
|
||||||
|
*/
|
||||||
|
public void testDataBaseMigration() {
|
||||||
|
IWapPushManager iwapman = getInterface();
|
||||||
|
WapPushManager wpman = getService();
|
||||||
|
Context context = getContext();
|
||||||
|
|
||||||
|
addPackageToLegacyDB(mAppIdValue, mContentTypeValue, mPackageName, mClassName,
|
||||||
|
WapPushManagerParams.APP_TYPE_SERVICE, true, true);
|
||||||
|
addPackageToLegacyDB(mAppIdValue + 10, mContentTypeValue, mPackageName, mClassName,
|
||||||
|
WapPushManagerParams.APP_TYPE_SERVICE, true, true);
|
||||||
|
|
||||||
|
File oldDbFile = context.getDatabasePath("wappush.db");
|
||||||
|
assertTrue(oldDbFile.exists());
|
||||||
|
assertTrue(wpman.verifyData(Integer.toString(mAppIdValue),
|
||||||
|
Integer.toString(mContentTypeValue),
|
||||||
|
mPackageName, mClassName,
|
||||||
|
WapPushManagerParams.APP_TYPE_SERVICE, true, true));
|
||||||
|
assertFalse(oldDbFile.exists());
|
||||||
|
|
||||||
|
// Clean up DB
|
||||||
|
try {
|
||||||
|
iwapman.deletePackage(Integer.toString(mAppIdValue),
|
||||||
|
Integer.toString(mContentTypeValue), mPackageName, mClassName);
|
||||||
|
iwapman.deletePackage(Integer.toString(mAppIdValue + 10),
|
||||||
|
Integer.toString(mContentTypeValue), mPackageName, mClassName);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
assertTrue(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addPackageToLegacyDB(int appId, int contextType, String packagename,
|
||||||
|
String classnName, int appType, boolean signature, boolean furtherProcessing) {
|
||||||
|
WapPushManager wpman = getService();
|
||||||
|
WapPushManDBHelper dbh = new WapPushManDBHelper(getContext());
|
||||||
|
SQLiteDatabase db = dbh.getWritableDatabase();
|
||||||
|
|
||||||
|
wpman.insertPackage(dbh, db, Integer.toString(appId), Integer.toString(contextType),
|
||||||
|
packagename, classnName, appType, signature, furtherProcessing);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user