17640caaf912a7eefacc3e2108c5afd70f7b072a4noda/*
27640caaf912a7eefacc3e2108c5afd70f7b072a4noda * Copyright (C) 2010 The Android Open Source Project
37640caaf912a7eefacc3e2108c5afd70f7b072a4noda *
47640caaf912a7eefacc3e2108c5afd70f7b072a4noda * Licensed under the Apache License, Version 2.0 (the "License");
57640caaf912a7eefacc3e2108c5afd70f7b072a4noda * you may not use this file except in compliance with the License.
67640caaf912a7eefacc3e2108c5afd70f7b072a4noda * You may obtain a copy of the License at
77640caaf912a7eefacc3e2108c5afd70f7b072a4noda *
87640caaf912a7eefacc3e2108c5afd70f7b072a4noda *      http://www.apache.org/licenses/LICENSE-2.0
97640caaf912a7eefacc3e2108c5afd70f7b072a4noda *
107640caaf912a7eefacc3e2108c5afd70f7b072a4noda * Unless required by applicable law or agreed to in writing, software
117640caaf912a7eefacc3e2108c5afd70f7b072a4noda * distributed under the License is distributed on an "AS IS" BASIS,
127640caaf912a7eefacc3e2108c5afd70f7b072a4noda * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137640caaf912a7eefacc3e2108c5afd70f7b072a4noda * See the License for the specific language governing permissions and
147640caaf912a7eefacc3e2108c5afd70f7b072a4noda * limitations under the License.
157640caaf912a7eefacc3e2108c5afd70f7b072a4noda */
167640caaf912a7eefacc3e2108c5afd70f7b072a4noda
177640caaf912a7eefacc3e2108c5afd70f7b072a4nodapackage com.android.smspush;
187640caaf912a7eefacc3e2108c5afd70f7b072a4noda
197640caaf912a7eefacc3e2108c5afd70f7b072a4nodaimport android.app.Service;
207640caaf912a7eefacc3e2108c5afd70f7b072a4nodaimport android.content.ActivityNotFoundException;
217640caaf912a7eefacc3e2108c5afd70f7b072a4nodaimport android.content.ComponentName;
227640caaf912a7eefacc3e2108c5afd70f7b072a4nodaimport android.content.ContentValues;
237640caaf912a7eefacc3e2108c5afd70f7b072a4nodaimport android.content.Context;
247640caaf912a7eefacc3e2108c5afd70f7b072a4nodaimport android.content.Intent;
257640caaf912a7eefacc3e2108c5afd70f7b072a4nodaimport android.content.pm.PackageManager;
267640caaf912a7eefacc3e2108c5afd70f7b072a4nodaimport android.database.Cursor;
277640caaf912a7eefacc3e2108c5afd70f7b072a4nodaimport android.database.sqlite.SQLiteOpenHelper;
287640caaf912a7eefacc3e2108c5afd70f7b072a4nodaimport android.database.sqlite.SQLiteDatabase;
297640caaf912a7eefacc3e2108c5afd70f7b072a4nodaimport android.os.IBinder;
307640caaf912a7eefacc3e2108c5afd70f7b072a4nodaimport android.os.RemoteException;
317640caaf912a7eefacc3e2108c5afd70f7b072a4nodaimport android.util.Log;
327640caaf912a7eefacc3e2108c5afd70f7b072a4noda
337640caaf912a7eefacc3e2108c5afd70f7b072a4nodaimport com.android.internal.telephony.IWapPushManager;
347640caaf912a7eefacc3e2108c5afd70f7b072a4nodaimport com.android.internal.telephony.WapPushManagerParams;
357640caaf912a7eefacc3e2108c5afd70f7b072a4noda
367640caaf912a7eefacc3e2108c5afd70f7b072a4noda/**
377640caaf912a7eefacc3e2108c5afd70f7b072a4noda * The WapPushManager service is implemented to process incoming
387640caaf912a7eefacc3e2108c5afd70f7b072a4noda * WAP Push messages and to maintain the Receiver Application/Application
397640caaf912a7eefacc3e2108c5afd70f7b072a4noda * ID mapping. The WapPushManager runs as a system service, and only the
407640caaf912a7eefacc3e2108c5afd70f7b072a4noda * WapPushManager can update the WAP Push message and Receiver Application
417640caaf912a7eefacc3e2108c5afd70f7b072a4noda * mapping (Application ID Table). When the device receives an SMS WAP Push
427640caaf912a7eefacc3e2108c5afd70f7b072a4noda * message, the WapPushManager looks up the Receiver Application name in
437640caaf912a7eefacc3e2108c5afd70f7b072a4noda * Application ID Table. If an application is found, the application is
447640caaf912a7eefacc3e2108c5afd70f7b072a4noda * launched using its full component name instead of broadcasting an implicit
457640caaf912a7eefacc3e2108c5afd70f7b072a4noda * Intent. If a Receiver Application is not found in the Application ID
467640caaf912a7eefacc3e2108c5afd70f7b072a4noda * Table or the WapPushManager returns a process-further value, the
477640caaf912a7eefacc3e2108c5afd70f7b072a4noda * telephony stack will process the message using existing message processing
487640caaf912a7eefacc3e2108c5afd70f7b072a4noda * flow, and broadcast an implicit Intent.
497640caaf912a7eefacc3e2108c5afd70f7b072a4noda */
507640caaf912a7eefacc3e2108c5afd70f7b072a4nodapublic class WapPushManager extends Service {
517640caaf912a7eefacc3e2108c5afd70f7b072a4noda
527640caaf912a7eefacc3e2108c5afd70f7b072a4noda    private static final String LOG_TAG = "WAP PUSH";
537640caaf912a7eefacc3e2108c5afd70f7b072a4noda    private static final String DATABASE_NAME = "wappush.db";
547640caaf912a7eefacc3e2108c5afd70f7b072a4noda    private static final String APPID_TABLE_NAME = "appid_tbl";
557640caaf912a7eefacc3e2108c5afd70f7b072a4noda
567640caaf912a7eefacc3e2108c5afd70f7b072a4noda    /**
577640caaf912a7eefacc3e2108c5afd70f7b072a4noda     * Version number must be incremented when table structure is changed.
587640caaf912a7eefacc3e2108c5afd70f7b072a4noda     */
597640caaf912a7eefacc3e2108c5afd70f7b072a4noda    private static final int WAP_PUSH_MANAGER_VERSION = 1;
607640caaf912a7eefacc3e2108c5afd70f7b072a4noda    private static final boolean DEBUG_SQL = false;
617640caaf912a7eefacc3e2108c5afd70f7b072a4noda    private static final boolean LOCAL_LOGV = false;
627640caaf912a7eefacc3e2108c5afd70f7b072a4noda
637640caaf912a7eefacc3e2108c5afd70f7b072a4noda    /**
647640caaf912a7eefacc3e2108c5afd70f7b072a4noda     * Inner class that deals with application ID table
657640caaf912a7eefacc3e2108c5afd70f7b072a4noda     */
667640caaf912a7eefacc3e2108c5afd70f7b072a4noda    private class WapPushManDBHelper extends SQLiteOpenHelper {
677640caaf912a7eefacc3e2108c5afd70f7b072a4noda        WapPushManDBHelper(Context context) {
687640caaf912a7eefacc3e2108c5afd70f7b072a4noda            super(context, DATABASE_NAME, null, WAP_PUSH_MANAGER_VERSION);
697640caaf912a7eefacc3e2108c5afd70f7b072a4noda            if (LOCAL_LOGV) Log.v(LOG_TAG, "helper instance created.");
707640caaf912a7eefacc3e2108c5afd70f7b072a4noda        }
717640caaf912a7eefacc3e2108c5afd70f7b072a4noda
727640caaf912a7eefacc3e2108c5afd70f7b072a4noda        @Override
737640caaf912a7eefacc3e2108c5afd70f7b072a4noda        public void onCreate(SQLiteDatabase db) {
747640caaf912a7eefacc3e2108c5afd70f7b072a4noda            if (LOCAL_LOGV) Log.v(LOG_TAG, "db onCreate.");
757640caaf912a7eefacc3e2108c5afd70f7b072a4noda            String sql = "CREATE TABLE " + APPID_TABLE_NAME + " ("
767640caaf912a7eefacc3e2108c5afd70f7b072a4noda                    + "id INTEGER PRIMARY KEY, "
777640caaf912a7eefacc3e2108c5afd70f7b072a4noda                    + "x_wap_application TEXT, "
787640caaf912a7eefacc3e2108c5afd70f7b072a4noda                    + "content_type TEXT, "
797640caaf912a7eefacc3e2108c5afd70f7b072a4noda                    + "package_name TEXT, "
807640caaf912a7eefacc3e2108c5afd70f7b072a4noda                    + "class_name TEXT, "
817640caaf912a7eefacc3e2108c5afd70f7b072a4noda                    + "app_type INTEGER, "
827640caaf912a7eefacc3e2108c5afd70f7b072a4noda                    + "need_signature INTEGER, "
837640caaf912a7eefacc3e2108c5afd70f7b072a4noda                    + "further_processing INTEGER, "
847640caaf912a7eefacc3e2108c5afd70f7b072a4noda                    + "install_order INTEGER "
857640caaf912a7eefacc3e2108c5afd70f7b072a4noda                    + ")";
867640caaf912a7eefacc3e2108c5afd70f7b072a4noda
877640caaf912a7eefacc3e2108c5afd70f7b072a4noda            if (DEBUG_SQL) Log.v(LOG_TAG, "sql: " + sql);
887640caaf912a7eefacc3e2108c5afd70f7b072a4noda            db.execSQL(sql);
897640caaf912a7eefacc3e2108c5afd70f7b072a4noda        }
907640caaf912a7eefacc3e2108c5afd70f7b072a4noda
917640caaf912a7eefacc3e2108c5afd70f7b072a4noda        @Override
927640caaf912a7eefacc3e2108c5afd70f7b072a4noda        public void onUpgrade(SQLiteDatabase db,
937640caaf912a7eefacc3e2108c5afd70f7b072a4noda                    int oldVersion, int newVersion) {
947640caaf912a7eefacc3e2108c5afd70f7b072a4noda            // TODO: when table structure is changed, need to dump and restore data.
957640caaf912a7eefacc3e2108c5afd70f7b072a4noda            /*
967640caaf912a7eefacc3e2108c5afd70f7b072a4noda              db.execSQL(
977640caaf912a7eefacc3e2108c5afd70f7b072a4noda              "drop table if exists "+APPID_TABLE_NAME);
987640caaf912a7eefacc3e2108c5afd70f7b072a4noda              onCreate(db);
997640caaf912a7eefacc3e2108c5afd70f7b072a4noda            */
1007640caaf912a7eefacc3e2108c5afd70f7b072a4noda            Log.w(LOG_TAG, "onUpgrade is not implemented yet. do nothing.");
1017640caaf912a7eefacc3e2108c5afd70f7b072a4noda        }
1027640caaf912a7eefacc3e2108c5afd70f7b072a4noda
1037640caaf912a7eefacc3e2108c5afd70f7b072a4noda        protected class queryData {
1047640caaf912a7eefacc3e2108c5afd70f7b072a4noda            public String packageName;
1057640caaf912a7eefacc3e2108c5afd70f7b072a4noda            public String className;
1067640caaf912a7eefacc3e2108c5afd70f7b072a4noda            int appType;
1077640caaf912a7eefacc3e2108c5afd70f7b072a4noda            int needSignature;
1087640caaf912a7eefacc3e2108c5afd70f7b072a4noda            int furtherProcessing;
1097640caaf912a7eefacc3e2108c5afd70f7b072a4noda            int installOrder;
1107640caaf912a7eefacc3e2108c5afd70f7b072a4noda        }
1117640caaf912a7eefacc3e2108c5afd70f7b072a4noda
1127640caaf912a7eefacc3e2108c5afd70f7b072a4noda        /**
1137640caaf912a7eefacc3e2108c5afd70f7b072a4noda         * Query the latest receiver application info with supplied application ID and
1147640caaf912a7eefacc3e2108c5afd70f7b072a4noda         * content type.
1157640caaf912a7eefacc3e2108c5afd70f7b072a4noda         * @param app_id    application ID to look up
1167640caaf912a7eefacc3e2108c5afd70f7b072a4noda         * @param content_type    content type to look up
1177640caaf912a7eefacc3e2108c5afd70f7b072a4noda         */
1187640caaf912a7eefacc3e2108c5afd70f7b072a4noda        protected queryData queryLastApp(SQLiteDatabase db,
1197640caaf912a7eefacc3e2108c5afd70f7b072a4noda                String app_id, String content_type) {
1207640caaf912a7eefacc3e2108c5afd70f7b072a4noda            String sql = "select install_order, package_name, class_name, "
1217640caaf912a7eefacc3e2108c5afd70f7b072a4noda                    + " app_type, need_signature, further_processing"
1227640caaf912a7eefacc3e2108c5afd70f7b072a4noda                    + " from " + APPID_TABLE_NAME
1237640caaf912a7eefacc3e2108c5afd70f7b072a4noda                    + " where x_wap_application=\'" + app_id + "\'"
1247640caaf912a7eefacc3e2108c5afd70f7b072a4noda                    + " and content_type=\'" + content_type + "\'"
1257640caaf912a7eefacc3e2108c5afd70f7b072a4noda                    + " order by install_order desc";
1267640caaf912a7eefacc3e2108c5afd70f7b072a4noda            if (DEBUG_SQL) Log.v(LOG_TAG, "sql: " + sql);
1277640caaf912a7eefacc3e2108c5afd70f7b072a4noda            Cursor cur = db.rawQuery(sql, null);
1287640caaf912a7eefacc3e2108c5afd70f7b072a4noda            queryData ret = null;
1297640caaf912a7eefacc3e2108c5afd70f7b072a4noda
1307640caaf912a7eefacc3e2108c5afd70f7b072a4noda            if (cur.moveToNext()) {
1317640caaf912a7eefacc3e2108c5afd70f7b072a4noda                ret = new queryData();
1327640caaf912a7eefacc3e2108c5afd70f7b072a4noda                ret.installOrder = cur.getInt(cur.getColumnIndex("install_order"));
1337640caaf912a7eefacc3e2108c5afd70f7b072a4noda                ret.packageName = cur.getString(cur.getColumnIndex("package_name"));
1347640caaf912a7eefacc3e2108c5afd70f7b072a4noda                ret.className = cur.getString(cur.getColumnIndex("class_name"));
1357640caaf912a7eefacc3e2108c5afd70f7b072a4noda                ret.appType = cur.getInt(cur.getColumnIndex("app_type"));
1367640caaf912a7eefacc3e2108c5afd70f7b072a4noda                ret.needSignature = cur.getInt(cur.getColumnIndex("need_signature"));
1377640caaf912a7eefacc3e2108c5afd70f7b072a4noda                ret.furtherProcessing = cur.getInt(cur.getColumnIndex("further_processing"));
1387640caaf912a7eefacc3e2108c5afd70f7b072a4noda            }
1397640caaf912a7eefacc3e2108c5afd70f7b072a4noda            cur.close();
1407640caaf912a7eefacc3e2108c5afd70f7b072a4noda            return ret;
1417640caaf912a7eefacc3e2108c5afd70f7b072a4noda        }
1427640caaf912a7eefacc3e2108c5afd70f7b072a4noda
1437640caaf912a7eefacc3e2108c5afd70f7b072a4noda    }
1447640caaf912a7eefacc3e2108c5afd70f7b072a4noda
1457640caaf912a7eefacc3e2108c5afd70f7b072a4noda    /**
1467640caaf912a7eefacc3e2108c5afd70f7b072a4noda     * The exported API implementations class
1477640caaf912a7eefacc3e2108c5afd70f7b072a4noda     */
1487640caaf912a7eefacc3e2108c5afd70f7b072a4noda    private class IWapPushManagerStub extends IWapPushManager.Stub {
1497640caaf912a7eefacc3e2108c5afd70f7b072a4noda        public Context mContext;
1507640caaf912a7eefacc3e2108c5afd70f7b072a4noda
1517640caaf912a7eefacc3e2108c5afd70f7b072a4noda        public IWapPushManagerStub() {
1527640caaf912a7eefacc3e2108c5afd70f7b072a4noda
1537640caaf912a7eefacc3e2108c5afd70f7b072a4noda        }
1547640caaf912a7eefacc3e2108c5afd70f7b072a4noda
1557640caaf912a7eefacc3e2108c5afd70f7b072a4noda        /**
1567640caaf912a7eefacc3e2108c5afd70f7b072a4noda         * Compare the package signature with WapPushManager package
1577640caaf912a7eefacc3e2108c5afd70f7b072a4noda         */
1587640caaf912a7eefacc3e2108c5afd70f7b072a4noda        protected boolean signatureCheck(String package_name) {
1597640caaf912a7eefacc3e2108c5afd70f7b072a4noda            PackageManager pm = mContext.getPackageManager();
1607640caaf912a7eefacc3e2108c5afd70f7b072a4noda            int match = pm.checkSignatures(mContext.getPackageName(), package_name);
1617640caaf912a7eefacc3e2108c5afd70f7b072a4noda
1627640caaf912a7eefacc3e2108c5afd70f7b072a4noda            if (LOCAL_LOGV) Log.v(LOG_TAG, "compare signature " + mContext.getPackageName()
1637640caaf912a7eefacc3e2108c5afd70f7b072a4noda                    + " and " +  package_name + ", match=" + match);
1647640caaf912a7eefacc3e2108c5afd70f7b072a4noda
1657640caaf912a7eefacc3e2108c5afd70f7b072a4noda            return match == PackageManager.SIGNATURE_MATCH;
1667640caaf912a7eefacc3e2108c5afd70f7b072a4noda        }
1677640caaf912a7eefacc3e2108c5afd70f7b072a4noda
1687640caaf912a7eefacc3e2108c5afd70f7b072a4noda        /**
1697640caaf912a7eefacc3e2108c5afd70f7b072a4noda         * Returns the status value of the message processing.
1707640caaf912a7eefacc3e2108c5afd70f7b072a4noda         * The message will be processed as follows:
1717640caaf912a7eefacc3e2108c5afd70f7b072a4noda         * 1.Look up Application ID Table with x-wap-application-id + content type
1727640caaf912a7eefacc3e2108c5afd70f7b072a4noda         * 2.Check the signature of package name that is found in the
1737640caaf912a7eefacc3e2108c5afd70f7b072a4noda         *   Application ID Table by using PackageManager.checkSignature
1747640caaf912a7eefacc3e2108c5afd70f7b072a4noda         * 3.Trigger the Application
1757640caaf912a7eefacc3e2108c5afd70f7b072a4noda         * 4.Returns the process status value.
1767640caaf912a7eefacc3e2108c5afd70f7b072a4noda         */
1777640caaf912a7eefacc3e2108c5afd70f7b072a4noda        public int processMessage(String app_id, String content_type, Intent intent)
1787640caaf912a7eefacc3e2108c5afd70f7b072a4noda            throws RemoteException {
1797640caaf912a7eefacc3e2108c5afd70f7b072a4noda            Log.d(LOG_TAG, "wpman processMsg " + app_id + ":" + content_type);
1807640caaf912a7eefacc3e2108c5afd70f7b072a4noda
1817640caaf912a7eefacc3e2108c5afd70f7b072a4noda            WapPushManDBHelper dbh = getDatabase(mContext);
1827640caaf912a7eefacc3e2108c5afd70f7b072a4noda            SQLiteDatabase db = dbh.getReadableDatabase();
1837640caaf912a7eefacc3e2108c5afd70f7b072a4noda            WapPushManDBHelper.queryData lastapp = dbh.queryLastApp(db, app_id, content_type);
1847640caaf912a7eefacc3e2108c5afd70f7b072a4noda            db.close();
1857640caaf912a7eefacc3e2108c5afd70f7b072a4noda
1867640caaf912a7eefacc3e2108c5afd70f7b072a4noda            if (lastapp == null) {
1877640caaf912a7eefacc3e2108c5afd70f7b072a4noda                Log.w(LOG_TAG, "no receiver app found for " + app_id + ":" + content_type);
1887640caaf912a7eefacc3e2108c5afd70f7b072a4noda                return WapPushManagerParams.APP_QUERY_FAILED;
1897640caaf912a7eefacc3e2108c5afd70f7b072a4noda            }
1907640caaf912a7eefacc3e2108c5afd70f7b072a4noda            if (LOCAL_LOGV) Log.v(LOG_TAG, "starting " + lastapp.packageName
1917640caaf912a7eefacc3e2108c5afd70f7b072a4noda                    + "/" + lastapp.className);
1927640caaf912a7eefacc3e2108c5afd70f7b072a4noda
1937640caaf912a7eefacc3e2108c5afd70f7b072a4noda            if (lastapp.needSignature != 0) {
1947640caaf912a7eefacc3e2108c5afd70f7b072a4noda                if (!signatureCheck(lastapp.packageName)) {
1957640caaf912a7eefacc3e2108c5afd70f7b072a4noda                    return WapPushManagerParams.SIGNATURE_NO_MATCH;
1967640caaf912a7eefacc3e2108c5afd70f7b072a4noda                }
1977640caaf912a7eefacc3e2108c5afd70f7b072a4noda            }
1987640caaf912a7eefacc3e2108c5afd70f7b072a4noda
1997640caaf912a7eefacc3e2108c5afd70f7b072a4noda            if (lastapp.appType == WapPushManagerParams.APP_TYPE_ACTIVITY) {
2007640caaf912a7eefacc3e2108c5afd70f7b072a4noda                //Intent intent = new Intent(Intent.ACTION_MAIN);
2017640caaf912a7eefacc3e2108c5afd70f7b072a4noda                intent.setClassName(lastapp.packageName, lastapp.className);
2027640caaf912a7eefacc3e2108c5afd70f7b072a4noda                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2037640caaf912a7eefacc3e2108c5afd70f7b072a4noda
2047640caaf912a7eefacc3e2108c5afd70f7b072a4noda                try {
2057640caaf912a7eefacc3e2108c5afd70f7b072a4noda                    mContext.startActivity(intent);
2067640caaf912a7eefacc3e2108c5afd70f7b072a4noda                } catch (ActivityNotFoundException e) {
2077640caaf912a7eefacc3e2108c5afd70f7b072a4noda                    Log.w(LOG_TAG, "invalid name " +
2087640caaf912a7eefacc3e2108c5afd70f7b072a4noda                            lastapp.packageName + "/" + lastapp.className);
2097640caaf912a7eefacc3e2108c5afd70f7b072a4noda                    return WapPushManagerParams.INVALID_RECEIVER_NAME;
2107640caaf912a7eefacc3e2108c5afd70f7b072a4noda                }
2117640caaf912a7eefacc3e2108c5afd70f7b072a4noda            } else {
2127640caaf912a7eefacc3e2108c5afd70f7b072a4noda                intent.setClassName(mContext, lastapp.className);
2137640caaf912a7eefacc3e2108c5afd70f7b072a4noda                intent.setComponent(new ComponentName(lastapp.packageName,
2147640caaf912a7eefacc3e2108c5afd70f7b072a4noda                        lastapp.className));
2157640caaf912a7eefacc3e2108c5afd70f7b072a4noda                if (mContext.startService(intent) == null) {
2167640caaf912a7eefacc3e2108c5afd70f7b072a4noda                    Log.w(LOG_TAG, "invalid name " +
2177640caaf912a7eefacc3e2108c5afd70f7b072a4noda                            lastapp.packageName + "/" + lastapp.className);
2187640caaf912a7eefacc3e2108c5afd70f7b072a4noda                    return WapPushManagerParams.INVALID_RECEIVER_NAME;
2197640caaf912a7eefacc3e2108c5afd70f7b072a4noda                }
2207640caaf912a7eefacc3e2108c5afd70f7b072a4noda            }
2217640caaf912a7eefacc3e2108c5afd70f7b072a4noda
2227640caaf912a7eefacc3e2108c5afd70f7b072a4noda            return WapPushManagerParams.MESSAGE_HANDLED
2237640caaf912a7eefacc3e2108c5afd70f7b072a4noda                    | (lastapp.furtherProcessing == 1 ?
2247640caaf912a7eefacc3e2108c5afd70f7b072a4noda                            WapPushManagerParams.FURTHER_PROCESSING : 0);
2257640caaf912a7eefacc3e2108c5afd70f7b072a4noda        }
2267640caaf912a7eefacc3e2108c5afd70f7b072a4noda
2277640caaf912a7eefacc3e2108c5afd70f7b072a4noda        protected boolean appTypeCheck(int app_type) {
2287640caaf912a7eefacc3e2108c5afd70f7b072a4noda            if (app_type == WapPushManagerParams.APP_TYPE_ACTIVITY ||
2297640caaf912a7eefacc3e2108c5afd70f7b072a4noda                    app_type == WapPushManagerParams.APP_TYPE_SERVICE) {
2307640caaf912a7eefacc3e2108c5afd70f7b072a4noda                return true;
2317640caaf912a7eefacc3e2108c5afd70f7b072a4noda            } else {
2327640caaf912a7eefacc3e2108c5afd70f7b072a4noda                return false;
2337640caaf912a7eefacc3e2108c5afd70f7b072a4noda            }
2347640caaf912a7eefacc3e2108c5afd70f7b072a4noda        }
2357640caaf912a7eefacc3e2108c5afd70f7b072a4noda
2367640caaf912a7eefacc3e2108c5afd70f7b072a4noda        /**
2377640caaf912a7eefacc3e2108c5afd70f7b072a4noda         * Returns true if adding the package succeeded.
2387640caaf912a7eefacc3e2108c5afd70f7b072a4noda         */
2397640caaf912a7eefacc3e2108c5afd70f7b072a4noda        public boolean addPackage(String x_app_id, String content_type,
2407640caaf912a7eefacc3e2108c5afd70f7b072a4noda                String package_name, String class_name,
2417640caaf912a7eefacc3e2108c5afd70f7b072a4noda                int app_type, boolean need_signature, boolean further_processing) {
2427640caaf912a7eefacc3e2108c5afd70f7b072a4noda            WapPushManDBHelper dbh = getDatabase(mContext);
2437640caaf912a7eefacc3e2108c5afd70f7b072a4noda            SQLiteDatabase db = dbh.getWritableDatabase();
2447640caaf912a7eefacc3e2108c5afd70f7b072a4noda            WapPushManDBHelper.queryData lastapp = dbh.queryLastApp(db, x_app_id, content_type);
2457640caaf912a7eefacc3e2108c5afd70f7b072a4noda            boolean ret = false;
2467640caaf912a7eefacc3e2108c5afd70f7b072a4noda            boolean insert = false;
2477640caaf912a7eefacc3e2108c5afd70f7b072a4noda            int sq = 0;
2487640caaf912a7eefacc3e2108c5afd70f7b072a4noda
2497640caaf912a7eefacc3e2108c5afd70f7b072a4noda            if (!appTypeCheck(app_type)) {
2507640caaf912a7eefacc3e2108c5afd70f7b072a4noda                Log.w(LOG_TAG, "invalid app_type " + app_type + ". app_type must be "
2517640caaf912a7eefacc3e2108c5afd70f7b072a4noda                        + WapPushManagerParams.APP_TYPE_ACTIVITY + " or "
2527640caaf912a7eefacc3e2108c5afd70f7b072a4noda                        + WapPushManagerParams.APP_TYPE_SERVICE);
2537640caaf912a7eefacc3e2108c5afd70f7b072a4noda                return false;
2547640caaf912a7eefacc3e2108c5afd70f7b072a4noda            }
2557640caaf912a7eefacc3e2108c5afd70f7b072a4noda
2567640caaf912a7eefacc3e2108c5afd70f7b072a4noda            if (lastapp == null) {
2577640caaf912a7eefacc3e2108c5afd70f7b072a4noda                insert = true;
2587640caaf912a7eefacc3e2108c5afd70f7b072a4noda                sq = 0;
2597640caaf912a7eefacc3e2108c5afd70f7b072a4noda            } else if (!lastapp.packageName.equals(package_name) ||
2607640caaf912a7eefacc3e2108c5afd70f7b072a4noda                    !lastapp.className.equals(class_name)) {
2617640caaf912a7eefacc3e2108c5afd70f7b072a4noda                insert = true;
2627640caaf912a7eefacc3e2108c5afd70f7b072a4noda                sq = lastapp.installOrder + 1;
2637640caaf912a7eefacc3e2108c5afd70f7b072a4noda            }
2647640caaf912a7eefacc3e2108c5afd70f7b072a4noda
2657640caaf912a7eefacc3e2108c5afd70f7b072a4noda            if (insert) {
2667640caaf912a7eefacc3e2108c5afd70f7b072a4noda                ContentValues values = new ContentValues();
2677640caaf912a7eefacc3e2108c5afd70f7b072a4noda
2687640caaf912a7eefacc3e2108c5afd70f7b072a4noda                values.put("x_wap_application", x_app_id);
2697640caaf912a7eefacc3e2108c5afd70f7b072a4noda                values.put("content_type", content_type);
2707640caaf912a7eefacc3e2108c5afd70f7b072a4noda                values.put("package_name", package_name);
2717640caaf912a7eefacc3e2108c5afd70f7b072a4noda                values.put("class_name", class_name);
2727640caaf912a7eefacc3e2108c5afd70f7b072a4noda                values.put("app_type", app_type);
2737640caaf912a7eefacc3e2108c5afd70f7b072a4noda                values.put("need_signature", need_signature ? 1 : 0);
2747640caaf912a7eefacc3e2108c5afd70f7b072a4noda                values.put("further_processing", further_processing ? 1 : 0);
2757640caaf912a7eefacc3e2108c5afd70f7b072a4noda                values.put("install_order", sq);
2767640caaf912a7eefacc3e2108c5afd70f7b072a4noda                db.insert(APPID_TABLE_NAME, null, values);
2777640caaf912a7eefacc3e2108c5afd70f7b072a4noda                if (LOCAL_LOGV) Log.v(LOG_TAG, "add:" + x_app_id + ":" + content_type
2787640caaf912a7eefacc3e2108c5afd70f7b072a4noda                        + " " + package_name + "." + class_name
2797640caaf912a7eefacc3e2108c5afd70f7b072a4noda                        + ", newsq:" + sq);
2807640caaf912a7eefacc3e2108c5afd70f7b072a4noda                ret = true;
2817640caaf912a7eefacc3e2108c5afd70f7b072a4noda            }
2827640caaf912a7eefacc3e2108c5afd70f7b072a4noda
2837640caaf912a7eefacc3e2108c5afd70f7b072a4noda            db.close();
2847640caaf912a7eefacc3e2108c5afd70f7b072a4noda
2857640caaf912a7eefacc3e2108c5afd70f7b072a4noda            return ret;
2867640caaf912a7eefacc3e2108c5afd70f7b072a4noda        }
2877640caaf912a7eefacc3e2108c5afd70f7b072a4noda
2887640caaf912a7eefacc3e2108c5afd70f7b072a4noda        /**
2897640caaf912a7eefacc3e2108c5afd70f7b072a4noda         * Returns true if updating the package succeeded.
2907640caaf912a7eefacc3e2108c5afd70f7b072a4noda         */
2917640caaf912a7eefacc3e2108c5afd70f7b072a4noda        public boolean updatePackage(String x_app_id, String content_type,
2927640caaf912a7eefacc3e2108c5afd70f7b072a4noda                String package_name, String class_name,
2937640caaf912a7eefacc3e2108c5afd70f7b072a4noda                int app_type, boolean need_signature, boolean further_processing) {
2947640caaf912a7eefacc3e2108c5afd70f7b072a4noda
2957640caaf912a7eefacc3e2108c5afd70f7b072a4noda            if (!appTypeCheck(app_type)) {
2967640caaf912a7eefacc3e2108c5afd70f7b072a4noda                Log.w(LOG_TAG, "invalid app_type " + app_type + ". app_type must be "
2977640caaf912a7eefacc3e2108c5afd70f7b072a4noda                        + WapPushManagerParams.APP_TYPE_ACTIVITY + " or "
2987640caaf912a7eefacc3e2108c5afd70f7b072a4noda                        + WapPushManagerParams.APP_TYPE_SERVICE);
2997640caaf912a7eefacc3e2108c5afd70f7b072a4noda                return false;
3007640caaf912a7eefacc3e2108c5afd70f7b072a4noda            }
3017640caaf912a7eefacc3e2108c5afd70f7b072a4noda
3027640caaf912a7eefacc3e2108c5afd70f7b072a4noda            WapPushManDBHelper dbh = getDatabase(mContext);
3037640caaf912a7eefacc3e2108c5afd70f7b072a4noda            SQLiteDatabase db = dbh.getWritableDatabase();
3047640caaf912a7eefacc3e2108c5afd70f7b072a4noda            WapPushManDBHelper.queryData lastapp = dbh.queryLastApp(db, x_app_id, content_type);
3057640caaf912a7eefacc3e2108c5afd70f7b072a4noda
3067640caaf912a7eefacc3e2108c5afd70f7b072a4noda            if (lastapp == null) {
3077640caaf912a7eefacc3e2108c5afd70f7b072a4noda                db.close();
3087640caaf912a7eefacc3e2108c5afd70f7b072a4noda                return false;
3097640caaf912a7eefacc3e2108c5afd70f7b072a4noda            }
3107640caaf912a7eefacc3e2108c5afd70f7b072a4noda
3117640caaf912a7eefacc3e2108c5afd70f7b072a4noda            ContentValues values = new ContentValues();
3127640caaf912a7eefacc3e2108c5afd70f7b072a4noda            String where = "x_wap_application=\'" + x_app_id + "\'"
3137640caaf912a7eefacc3e2108c5afd70f7b072a4noda                    + " and content_type=\'" + content_type + "\'"
3147640caaf912a7eefacc3e2108c5afd70f7b072a4noda                    + " and install_order=" + lastapp.installOrder;
3157640caaf912a7eefacc3e2108c5afd70f7b072a4noda
3167640caaf912a7eefacc3e2108c5afd70f7b072a4noda            values.put("package_name", package_name);
3177640caaf912a7eefacc3e2108c5afd70f7b072a4noda            values.put("class_name", class_name);
3187640caaf912a7eefacc3e2108c5afd70f7b072a4noda            values.put("app_type", app_type);
3197640caaf912a7eefacc3e2108c5afd70f7b072a4noda            values.put("need_signature", need_signature ? 1 : 0);
3207640caaf912a7eefacc3e2108c5afd70f7b072a4noda            values.put("further_processing", further_processing ? 1 : 0);
3217640caaf912a7eefacc3e2108c5afd70f7b072a4noda
3227640caaf912a7eefacc3e2108c5afd70f7b072a4noda            int num = db.update(APPID_TABLE_NAME, values, where, null);
3237640caaf912a7eefacc3e2108c5afd70f7b072a4noda            if (LOCAL_LOGV) Log.v(LOG_TAG, "update:" + x_app_id + ":" + content_type + " "
3247640caaf912a7eefacc3e2108c5afd70f7b072a4noda                    + package_name + "." + class_name
3257640caaf912a7eefacc3e2108c5afd70f7b072a4noda                    + ", sq:" + lastapp.installOrder);
3267640caaf912a7eefacc3e2108c5afd70f7b072a4noda
3277640caaf912a7eefacc3e2108c5afd70f7b072a4noda            db.close();
3287640caaf912a7eefacc3e2108c5afd70f7b072a4noda
3297640caaf912a7eefacc3e2108c5afd70f7b072a4noda            return num > 0;
3307640caaf912a7eefacc3e2108c5afd70f7b072a4noda        }
3317640caaf912a7eefacc3e2108c5afd70f7b072a4noda
3327640caaf912a7eefacc3e2108c5afd70f7b072a4noda        /**
3337640caaf912a7eefacc3e2108c5afd70f7b072a4noda         * Returns true if deleting the package succeeded.
3347640caaf912a7eefacc3e2108c5afd70f7b072a4noda         */
3357640caaf912a7eefacc3e2108c5afd70f7b072a4noda        public boolean deletePackage(String x_app_id, String content_type,
3367640caaf912a7eefacc3e2108c5afd70f7b072a4noda                String package_name, String class_name) {
3377640caaf912a7eefacc3e2108c5afd70f7b072a4noda            WapPushManDBHelper dbh = getDatabase(mContext);
3387640caaf912a7eefacc3e2108c5afd70f7b072a4noda            SQLiteDatabase db = dbh.getWritableDatabase();
3397640caaf912a7eefacc3e2108c5afd70f7b072a4noda            String where = "x_wap_application=\'" + x_app_id + "\'"
3407640caaf912a7eefacc3e2108c5afd70f7b072a4noda                    + " and content_type=\'" + content_type + "\'"
3417640caaf912a7eefacc3e2108c5afd70f7b072a4noda                    + " and package_name=\'" + package_name + "\'"
3427640caaf912a7eefacc3e2108c5afd70f7b072a4noda                    + " and class_name=\'" + class_name + "\'";
3437640caaf912a7eefacc3e2108c5afd70f7b072a4noda            int num_removed = db.delete(APPID_TABLE_NAME, where, null);
3447640caaf912a7eefacc3e2108c5afd70f7b072a4noda
3457640caaf912a7eefacc3e2108c5afd70f7b072a4noda            db.close();
3467640caaf912a7eefacc3e2108c5afd70f7b072a4noda            if (LOCAL_LOGV) Log.v(LOG_TAG, "deleted " + num_removed + " rows:"
3477640caaf912a7eefacc3e2108c5afd70f7b072a4noda                    + x_app_id + ":" + content_type + " "
3487640caaf912a7eefacc3e2108c5afd70f7b072a4noda                    + package_name + "." + class_name);
3497640caaf912a7eefacc3e2108c5afd70f7b072a4noda            return num_removed > 0;
3507640caaf912a7eefacc3e2108c5afd70f7b072a4noda        }
3517640caaf912a7eefacc3e2108c5afd70f7b072a4noda    };
3527640caaf912a7eefacc3e2108c5afd70f7b072a4noda
3537640caaf912a7eefacc3e2108c5afd70f7b072a4noda
3547640caaf912a7eefacc3e2108c5afd70f7b072a4noda    /**
3557640caaf912a7eefacc3e2108c5afd70f7b072a4noda     * Linux IPC Binder
3567640caaf912a7eefacc3e2108c5afd70f7b072a4noda     */
3577640caaf912a7eefacc3e2108c5afd70f7b072a4noda    private final IWapPushManagerStub mBinder = new IWapPushManagerStub();
3587640caaf912a7eefacc3e2108c5afd70f7b072a4noda
3597640caaf912a7eefacc3e2108c5afd70f7b072a4noda    /**
3607640caaf912a7eefacc3e2108c5afd70f7b072a4noda     * Default constructor
3617640caaf912a7eefacc3e2108c5afd70f7b072a4noda     */
3627640caaf912a7eefacc3e2108c5afd70f7b072a4noda    public WapPushManager() {
3637640caaf912a7eefacc3e2108c5afd70f7b072a4noda        super();
3647640caaf912a7eefacc3e2108c5afd70f7b072a4noda        mBinder.mContext = this;
3657640caaf912a7eefacc3e2108c5afd70f7b072a4noda    }
3667640caaf912a7eefacc3e2108c5afd70f7b072a4noda
3677640caaf912a7eefacc3e2108c5afd70f7b072a4noda    @Override
3687640caaf912a7eefacc3e2108c5afd70f7b072a4noda    public IBinder onBind(Intent arg0) {
3697640caaf912a7eefacc3e2108c5afd70f7b072a4noda        return mBinder;
3707640caaf912a7eefacc3e2108c5afd70f7b072a4noda    }
3717640caaf912a7eefacc3e2108c5afd70f7b072a4noda
3727640caaf912a7eefacc3e2108c5afd70f7b072a4noda    /**
3737640caaf912a7eefacc3e2108c5afd70f7b072a4noda     * Application ID database instance
3747640caaf912a7eefacc3e2108c5afd70f7b072a4noda     */
3757640caaf912a7eefacc3e2108c5afd70f7b072a4noda    private WapPushManDBHelper mDbHelper = null;
3767640caaf912a7eefacc3e2108c5afd70f7b072a4noda    protected WapPushManDBHelper getDatabase(Context context) {
3777640caaf912a7eefacc3e2108c5afd70f7b072a4noda        if (mDbHelper == null) {
3787640caaf912a7eefacc3e2108c5afd70f7b072a4noda            if (LOCAL_LOGV) Log.v(LOG_TAG, "create new db inst.");
3797640caaf912a7eefacc3e2108c5afd70f7b072a4noda            mDbHelper = new WapPushManDBHelper(context);
3807640caaf912a7eefacc3e2108c5afd70f7b072a4noda        }
3817640caaf912a7eefacc3e2108c5afd70f7b072a4noda        return mDbHelper;
3827640caaf912a7eefacc3e2108c5afd70f7b072a4noda    }
3837640caaf912a7eefacc3e2108c5afd70f7b072a4noda
3847640caaf912a7eefacc3e2108c5afd70f7b072a4noda
3857640caaf912a7eefacc3e2108c5afd70f7b072a4noda    /**
3867640caaf912a7eefacc3e2108c5afd70f7b072a4noda     * This method is used for testing
3877640caaf912a7eefacc3e2108c5afd70f7b072a4noda     */
3887640caaf912a7eefacc3e2108c5afd70f7b072a4noda    public boolean verifyData(String x_app_id, String content_type,
3897640caaf912a7eefacc3e2108c5afd70f7b072a4noda            String package_name, String class_name,
3907640caaf912a7eefacc3e2108c5afd70f7b072a4noda            int app_type, boolean need_signature, boolean further_processing) {
3917640caaf912a7eefacc3e2108c5afd70f7b072a4noda        WapPushManDBHelper dbh = getDatabase(this);
3927640caaf912a7eefacc3e2108c5afd70f7b072a4noda        SQLiteDatabase db = dbh.getReadableDatabase();
3937640caaf912a7eefacc3e2108c5afd70f7b072a4noda        WapPushManDBHelper.queryData lastapp = dbh.queryLastApp(db, x_app_id, content_type);
3947640caaf912a7eefacc3e2108c5afd70f7b072a4noda
3957640caaf912a7eefacc3e2108c5afd70f7b072a4noda        db.close();
3967640caaf912a7eefacc3e2108c5afd70f7b072a4noda
3977640caaf912a7eefacc3e2108c5afd70f7b072a4noda        if (lastapp == null) return false;
3987640caaf912a7eefacc3e2108c5afd70f7b072a4noda
3997640caaf912a7eefacc3e2108c5afd70f7b072a4noda        if (lastapp.packageName.equals(package_name)
4007640caaf912a7eefacc3e2108c5afd70f7b072a4noda                && lastapp.className.equals(class_name)
4017640caaf912a7eefacc3e2108c5afd70f7b072a4noda                && lastapp.appType == app_type
4027640caaf912a7eefacc3e2108c5afd70f7b072a4noda                &&  lastapp.needSignature == (need_signature ? 1 : 0)
4037640caaf912a7eefacc3e2108c5afd70f7b072a4noda                &&  lastapp.furtherProcessing == (further_processing ? 1 : 0)) {
4047640caaf912a7eefacc3e2108c5afd70f7b072a4noda            return true;
4057640caaf912a7eefacc3e2108c5afd70f7b072a4noda        } else {
4067640caaf912a7eefacc3e2108c5afd70f7b072a4noda            return false;
4077640caaf912a7eefacc3e2108c5afd70f7b072a4noda        }
4087640caaf912a7eefacc3e2108c5afd70f7b072a4noda    }
4097640caaf912a7eefacc3e2108c5afd70f7b072a4noda
4107640caaf912a7eefacc3e2108c5afd70f7b072a4noda    /**
4117640caaf912a7eefacc3e2108c5afd70f7b072a4noda     * This method is used for testing
4127640caaf912a7eefacc3e2108c5afd70f7b072a4noda     */
4137640caaf912a7eefacc3e2108c5afd70f7b072a4noda    public boolean isDataExist(String x_app_id, String content_type,
4147640caaf912a7eefacc3e2108c5afd70f7b072a4noda            String package_name, String class_name) {
4157640caaf912a7eefacc3e2108c5afd70f7b072a4noda        WapPushManDBHelper dbh = getDatabase(this);
4167640caaf912a7eefacc3e2108c5afd70f7b072a4noda        SQLiteDatabase db = dbh.getReadableDatabase();
4177640caaf912a7eefacc3e2108c5afd70f7b072a4noda        boolean ret = dbh.queryLastApp(db, x_app_id, content_type) != null;
4187640caaf912a7eefacc3e2108c5afd70f7b072a4noda
4197640caaf912a7eefacc3e2108c5afd70f7b072a4noda        db.close();
4207640caaf912a7eefacc3e2108c5afd70f7b072a4noda        return ret;
4217640caaf912a7eefacc3e2108c5afd70f7b072a4noda    }
4227640caaf912a7eefacc3e2108c5afd70f7b072a4noda
4237640caaf912a7eefacc3e2108c5afd70f7b072a4noda}
4247640caaf912a7eefacc3e2108c5afd70f7b072a4noda
425