Migrate to gradle, appcompat as external dependency.
[mobilnebezpieczenstwo.git] / src / com / samsung / srpol / loader / AppListLoader.java
diff --git a/src/com/samsung/srpol/loader/AppListLoader.java b/src/com/samsung/srpol/loader/AppListLoader.java
deleted file mode 100644 (file)
index 3dfdb0f..0000000
+++ /dev/null
@@ -1,627 +0,0 @@
-/*
-   Copyright (C) 2014  Samsung Electronics Polska Sp. z o.o.
-
-    This program is free software: you can redistribute it and/or modify
-    it under the terms of the GNU AFFERO General Public License as published by
-    the Free Software Foundation, either version 3 of the License, or
-    (at your option) any later version.
-    You may obtain a copy of the License at
-
-                http://www.gnu.org/licenses/agpl-3.0.txt
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-package com.samsung.srpol.loader;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-
-import org.xmlpull.v1.XmlPullParserException;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.Signature;
-import android.content.res.XmlResourceParser;
-import android.support.v4.content.AsyncTaskLoader;
-
-import com.samsung.srpol.R;
-import com.samsung.srpol.data.Category;
-import com.samsung.srpol.data.Subcategory;
-
-/**
- * A custom Loader that loads all of the installed applications.
- */
-public class AppListLoader extends AsyncTaskLoader<List<AppDetails>> {
-    private static final String SYSTEM_UI = "com.android.systemui";
-    private static final String PHONE = "com.android.phone";
-
-    public static final String PREF_INCLUDE_SYSTEM_APPS = "include_system_apps";
-
-    private final PackageManager mPm;
-
-    private static List<AppDetails> mAppDetailsList = null;
-    private static List<Category> mCategories;
-    private static ArrayList<Subcategory> mSubcategories;
-    private static HashMap<String, Integer> mAllPermissionsHash;
-
-    private PackageIntentReceiver mPackageObserver;
-    private boolean mWasDataReloaded = true;
-    private static OnAppRemoveListener mChangeListener = null;
-
-    public AppListLoader(Context context) {
-        super(context);
-
-        if (mCategories == null || mSubcategories == null
-                || mAllPermissionsHash == null)
-            initCategories(context);
-
-        mPm = getContext().getPackageManager();
-    }
-
-    private void initCategories(Context context) {
-        mCategories = new ArrayList<Category>();
-        mSubcategories = new ArrayList<Subcategory>();
-        Subcategory.resetGenerator();
-
-        // Reading "data send" subcategory as it is common
-        try {
-            XmlResourceParser parser = context.getResources().getXml(
-                    R.xml.data_send_subcategory);
-            int eventType = 0;
-            while (eventType != XmlResourceParser.END_DOCUMENT
-                    && eventType != XmlResourceParser.START_TAG)
-                eventType = parser.next();
-            if (eventType != XmlResourceParser.END_DOCUMENT) {
-                Subcategory subcategory = readSubCategory(parser);
-                mSubcategories.add(subcategory);
-            }
-        } catch (XmlPullParserException ex) {
-            ex.printStackTrace();
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-
-        // Reading all categories and subcategories from xml
-        try {
-            XmlResourceParser parser = context.getResources().getXml(
-                    R.xml.categories);
-            int eventType = 0;
-            while (eventType != XmlResourceParser.END_DOCUMENT
-                    && eventType != XmlResourceParser.START_TAG)
-                eventType = parser.next();
-            if (eventType != XmlResourceParser.END_DOCUMENT) {
-                parser.require(XmlResourceParser.START_TAG, null, "container");
-                while (parser.next() != XmlResourceParser.END_TAG) {
-                    if (parser.getEventType() != XmlResourceParser.START_TAG)
-                        continue;
-                    if (!parser.getName().equals("category"))
-                        continue;
-                    Category cat = readCategory(parser);
-                    mCategories.add(cat);
-                    mSubcategories.addAll(cat.getSubCategories());
-                }
-            }
-        } catch (XmlPullParserException ex) {
-            ex.printStackTrace();
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-
-        mAllPermissionsHash = new HashMap<String, Integer>();
-        for (Subcategory subcat : mSubcategories) {
-            for (String perm : subcat.getPermissions()) {
-                Integer value = mAllPermissionsHash.get(perm);
-                if (value == null) {
-                    mAllPermissionsHash.put(perm, Integer.valueOf(subcat.getId()));
-                } else {
-                    value |= subcat.getId();
-                    mAllPermissionsHash.put(perm, value);
-                }
-            }
-        }
-    }
-
-    private Category readCategory(XmlResourceParser parser)
-            throws XmlPullParserException, IOException {
-        parser.require(XmlResourceParser.START_TAG, null, "category");
-        String title = null, header = null, description = null, shortDescription = null, link = null;
-        int icon = 0;
-        boolean dataSend = false;
-        ArrayList<Subcategory> subCategories = new ArrayList<Subcategory>();
-
-        while (parser.next() != XmlResourceParser.END_TAG) {
-            if (parser.getEventType() != XmlResourceParser.START_TAG)
-                continue;
-            String name = parser.getName();
-            if (name.equals("title")) {
-                title = readTextElement(parser, name);
-            } else if (name.equals("header")) {
-                header = readTextElement(parser, name);
-            } else if (name.equals("short_description")) {
-                shortDescription = readTextElement(parser, name);
-            } else if (name.equals("description")) {
-                description = readTextElement(parser, name);
-            } else if (name.equals("icon")) {
-                icon = getContext().getResources().getIdentifier(
-                        readTextElement(parser, name), "drawable",
-                        getContext().getPackageName());
-            } else if (name.equals("link")) {
-                link = readTextElement(parser, name);
-            } else if (name.equals("dataSend")) {
-                dataSend = Boolean.parseBoolean(readTextElement(parser, name));
-            } else if (name.equals("subcategories")) {
-                while (parser.next() != XmlResourceParser.END_TAG) {
-                    subCategories.add(readSubCategory(parser));
-                }
-            } else
-                skip(parser);
-        }
-        return new Category(getContext(), title, header, shortDescription,
-                description, icon, link, dataSend, subCategories);
-    }
-
-    private Subcategory readSubCategory(XmlResourceParser parser)
-            throws XmlPullParserException, IOException {
-        parser.require(XmlResourceParser.START_TAG, null, "subcategory");
-        String header = null, description = null, icon = null;
-        ArrayList<String> permissions = new ArrayList<String>();
-
-        while (parser.next() != XmlResourceParser.END_TAG) {
-            if (parser.getEventType() != XmlResourceParser.START_TAG)
-                continue;
-            String name = parser.getName();
-            if (name.equals("header")) {
-                header = readTextElement(parser, name);
-            } else if (name.equals("description")) {
-                description = readTextElement(parser, name);
-            } else if (name.equals("icon")) {
-                icon = readTextElement(parser, name);
-            } else if (name.equals("permissions")) {
-                while (parser.next() != XmlResourceParser.END_TAG) {
-                    permissions.add(readTextElement(parser, "item"));
-                }
-            } else
-                skip(parser);
-        }
-
-        return new Subcategory(getContext(), header, description, icon,
-                permissions);
-    }
-
-    private String readTextElement(XmlResourceParser parser, String element)
-            throws XmlPullParserException, IOException {
-        parser.require(XmlResourceParser.START_TAG, null, element);
-        String title = readText(parser);
-        parser.require(XmlResourceParser.END_TAG, null, element);
-        return title;
-    }
-
-    private String readText(XmlResourceParser parser)
-            throws XmlPullParserException, IOException {
-        String result = "";
-        if (parser.next() == XmlResourceParser.TEXT) {
-            result = parser.getText();
-            parser.nextTag();
-        }
-        return result;
-    }
-
-    private void skip(XmlResourceParser parser) throws XmlPullParserException,
-            IOException {
-        if (parser.getEventType() != XmlResourceParser.START_TAG) {
-            throw new IllegalStateException();
-        }
-        int depth = 1;
-        while (depth != 0) {
-            switch (parser.next()) {
-            case XmlResourceParser.END_TAG:
-                depth--;
-                break;
-            case XmlResourceParser.START_TAG:
-                depth++;
-                break;
-            }
-        }
-    }
-
-    /**
-     * Get Signature keys of given package
-     * 
-     * @param packageName
-     *            package name to retrieve signature keys
-     * @return Signature[] containing given package name signature keys
-     */
-    private Signature[] getSignature(String packageName) {
-
-        try {
-            PackageInfo packageInfo = getPm().getPackageInfo(packageName,
-                    PackageManager.GET_SIGNATURES);
-            Signature[] sigs = packageInfo.signatures;
-            return sigs;
-        } catch (NameNotFoundException e) {
-            return null;
-        }
-
-    }
-
-    /**
-     * Get Signature keys for given PackageInfo
-     * 
-     * @param packageInfo
-     *            PackageInfo to retrieve signature keys
-     * @return Signature[] containing given PackageInfo signature keys
-     */
-    @SuppressWarnings("unused")
-    private Signature[] getSignature(PackageInfo packageInfo) {
-
-        Signature[] sigs = packageInfo.signatures;
-        return sigs;
-
-    }
-
-    /**
-     * Get Platform signature key. we check signature of SystemUI process or
-     * Phone process
-     * 
-     * @return Signature platform sign key or null if not found
-     */
-    @SuppressWarnings("unused")
-    private Signature getPlatformSignature() {
-        Signature sig = getSignature(SYSTEM_UI)[0];
-        if (sig == null) {
-            sig = getSignature(PHONE)[0];
-        }
-        return sig;
-    }
-
-    /**
-     * Filter given ApplicationInfo list only to apps that are not platform
-     * signed
-     * 
-     * @param appList
-     *            List<ApplicationInfo> with a list of apps to filter
-     * @return List<ApplicationInfo> filtred app list
-     */
-    private List<PackageInfo> filterToNotPlatformKeyAppList(List<PackageInfo> packageList) {
-        if (packageList != null) {
-
-            List<PackageInfo> noPlatformKeyAppList = new ArrayList<PackageInfo>();
-            for (PackageInfo packageInfo : packageList) {
-                try {
-                    packageInfo = mPm.getPackageInfo(packageInfo.packageName,
-                            PackageManager.GET_ACTIVITIES
-                                    | PackageManager.GET_PERMISSIONS
-                                    | PackageManager.GET_SIGNATURES);
-                } catch (NameNotFoundException e) {
-                    continue;
-                }
-                // Check signature match with SystemUI
-                if (((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0 || (packageInfo.activities != null && packageInfo.activities.length > 0))
-                        && getPm().checkSignatures(SYSTEM_UI,
-                                packageInfo.packageName) != PackageManager.SIGNATURE_MATCH) {
-                    noPlatformKeyAppList.add(packageInfo);
-                }
-            }
-            return noPlatformKeyAppList;
-        } else {
-            return null;
-        }
-    }
-
-    private PackageInfo getInstalledAppDetails(String packageName) {
-        PackageInfo info = null;
-        try {
-            info = getPm().getPackageInfo(
-                    packageName,
-                    PackageManager.GET_META_DATA
-                            | PackageManager.GET_PERMISSIONS
-                            | PackageManager.GET_SIGNATURES);
-        } catch (NameNotFoundException e) {
-            e.printStackTrace();
-        }
-        return info;
-    }
-
-    @Override
-    public List<AppDetails> loadInBackground() {
-        List<PackageInfo> appList = mPm.getInstalledPackages(0);
-
-        appList = filterToNotPlatformKeyAppList(appList);
-
-        HashMap<String, AppDetails> appDetailsHash = new HashMap<String, AppDetails>(
-                appList.size());
-        if (mSubcategories.size() == 0) {
-            for (PackageInfo pInfo : appList) {
-                appDetailsHash.put(pInfo.packageName, new AppDetails(this,
-                        pInfo));
-            }
-        } else {
-            for (PackageInfo packageInfo : appList) {
-                String[] requestedPermissions = packageInfo.requestedPermissions;
-                if (requestedPermissions != null) {
-                    AppDetails appDetails = appDetailsHash.get(packageInfo.packageName);
-                    for (String permissionName : requestedPermissions) {
-                        Integer subcategories = mAllPermissionsHash.get(permissionName);
-                        if (subcategories != null 
-                                && (appDetails == null || !appDetails.isInAllSubcategories(subcategories))
-                                && getPm().checkPermission(permissionName,
-                                        packageInfo.packageName) == PackageManager.PERMISSION_GRANTED) {
-                            if (appDetails == null) {
-                                appDetails = new AppDetails(this, packageInfo);
-                                appDetailsHash.put(packageInfo.packageName,
-                                        appDetails);
-                            }
-                            appDetails.addSubcategory(subcategories);
-                        }
-                    }
-                }
-            }
-        }
-        // Sort the list.
-        List<AppDetails> list = new ArrayList<AppDetails>(
-                appDetailsHash.values());
-        Collections.sort(list, AppDetails.SMART_COMPARATOR);
-
-        for (Category category : mCategories)
-            category.assignAppsToCategory(list);
-
-        mWasDataReloaded = true;
-        return list;
-    }
-
-    /**
-     * Called when there is new data to deliver to the client. The super class
-     * will take care of delivering it; the implementation here just adds a
-     * little more logic.
-     */
-    @Override
-    public void deliverResult(List<AppDetails> apps) {
-        if (isReset()) {
-            apps = null;
-        }
-        mAppDetailsList = apps;
-
-        if (isStarted()) {
-            // If the Loader is currently started, we can immediately
-            // deliver its results.
-            super.deliverResult(apps);
-        }
-    }
-
-    /**
-     * Handles a request to start the Loader.
-     */
-    @Override
-    protected void onStartLoading() {
-        if (mAppDetailsList != null) {
-            // If we currently have a result available, deliver it
-            // immediately.
-            deliverResult(mAppDetailsList);
-        }
-
-        // Start watching for changes in the app data.
-        if (mPackageObserver == null) {
-            mPackageObserver = new PackageIntentReceiver(this);
-        }
-
-        if (takeContentChanged() || mAppDetailsList == null) {
-            // If the data has changed since the last time it was loaded
-            // or is not currently available, start a load.
-            forceLoad();
-        }
-    }
-
-    /**
-     * Handles a request to stop the Loader.
-     */
-    @Override
-    protected void onStopLoading() {
-        // Attempt to cancel the current load task if possible.
-        cancelLoad();
-    }
-
-    /**
-     * Handles a request to completely reset the Loader.
-     */
-    @Override
-    protected void onReset() {
-
-        // Ensure the loader is stopped
-        onStopLoading();
-
-        // Stop monitoring for changes.
-        if (mPackageObserver != null) {
-            getContext().unregisterReceiver(mPackageObserver);
-            mPackageObserver = null;
-        }
-    }
-
-    /**
-     * Gets AppDetails from mAppDetailsList for a given PackageName
-     * 
-     * @param packageName
-     *            PackageName for which to get AppDetails
-     * @return AppDetails for given PackageName
-     */
-    public static AppDetails getAppDetails(String packageName) {
-        if (packageName != null && mAppDetailsList != null) {
-            for (AppDetails appDetails : mAppDetailsList) {
-                if (packageName.equals(appDetails.getAppPackageName())) {
-                    return appDetails;
-                }
-            }
-        }
-        return null;
-    }
-
-    public static void setOnChangeListener(OnAppRemoveListener listener) {
-        mChangeListener = listener;
-    }
-
-    /**
-     * @return the mAppDetailsList
-     */
-    public static List<AppDetails> getAppDetailsList() {
-        return mAppDetailsList;
-    }
-
-    /**
-     * @return the mCategories
-     */
-    static public List<Category> getCategories() {
-        return mCategories;
-    }
-
-    public static List<Subcategory> getSubcategoriesOfMask(int subcategoriesMask) {
-        ArrayList<Subcategory> list = new ArrayList<Subcategory>();
-        for (Subcategory subcategory : mSubcategories) {
-            if ((subcategoriesMask & subcategory.getId()) > 0) {
-                list.add(subcategory);
-            }
-        }
-        return list;
-    }
-
-    public PackageManager getPm() {
-        return mPm;
-    }
-
-    public interface OnAppRemoveListener {
-        public void onPackageRemoved(String packageName);
-    }
-
-    /**
-     * Helper class to look for interesting changes to the installed apps so
-     * that the loader can be updated.
-     */
-    public static class PackageIntentReceiver extends BroadcastReceiver {
-        private final AppListLoader mLoader;
-
-        public PackageIntentReceiver(AppListLoader loader) {
-            mLoader = loader;
-            IntentFilter filter = new IntentFilter(Intent.ACTION_PACKAGE_ADDED);
-            filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
-            filter.addAction(Intent.ACTION_PACKAGE_CHANGED);
-            filter.addDataScheme("package");
-            mLoader.getContext().registerReceiver(this, filter);
-            // Register for events related to sdcard installation.
-            IntentFilter sdFilter = new IntentFilter();
-            sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE);
-            sdFilter.addAction(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE);
-            mLoader.getContext().registerReceiver(this, sdFilter);
-        }
-
-        @Override
-        public void onReceive(Context context, Intent intent) {
-            if (intent.getAction().equals(
-                    Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE)) {
-                mLoader.onPackagesAdded(intent
-                        .getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST));
-            } else if (intent.getAction().equals(
-                    Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE)) {
-                mLoader.onPackagesRemoved(intent
-                        .getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST));
-            } else if (intent.getAction().equals(Intent.ACTION_PACKAGE_REMOVED))
-                mLoader.onPackageRemoved(intent.getData()
-                        .getSchemeSpecificPart(), true);
-            else if (intent.getAction().equals(Intent.ACTION_PACKAGE_ADDED))
-                mLoader.onPackageAdded(
-                        intent.getData().getSchemeSpecificPart(), true);
-            else if (intent.getAction().equals(Intent.ACTION_PACKAGE_CHANGED))
-                mLoader.onPackageChanged(intent.getData()
-                        .getSchemeSpecificPart());
-        }
-    }
-
-    public void onPackageRemoved(String packageName, boolean deliverResult) {
-        if (mChangeListener != null)
-            mChangeListener.onPackageRemoved(packageName);
-        for (AppDetails details : mAppDetailsList) {
-            if (details.getAppPackageName().equals(packageName)) {
-                mAppDetailsList.remove(details);
-                for (Category category : mCategories)
-                    category.removeAppFromList(details);
-                if (deliverResult)
-                    deliverResult(new ArrayList<AppDetails>(mAppDetailsList));
-                break;
-            }
-        }
-    }
-
-    public void onPackagesRemoved(String[] packageNames) {
-        for (String packageName : packageNames) {
-            onPackageRemoved(packageName, false);
-        }
-        deliverResult(new ArrayList<AppDetails>(mAppDetailsList));
-    }
-
-    public void onPackageChanged(String packageName) {
-        for (AppDetails details : mAppDetailsList) {
-            if (details.getAppPackageName().equals(packageName)) {
-                PackageInfo packageInfo = getInstalledAppDetails(packageName);
-                if (packageInfo == null)
-                    return;
-                details.setEnabled(packageInfo.applicationInfo.enabled);
-                deliverResult(new ArrayList<AppDetails>(mAppDetailsList));
-                break;
-            }
-        }
-    }
-
-    public void onPackageAdded(String packageName, boolean deliverResult) {
-        PackageInfo packageInfo = getInstalledAppDetails(packageName);
-        if (packageInfo == null)
-            return;
-        AppDetails newPackage = new AppDetails(this, packageInfo);
-
-        String[] requestedPermissions = packageInfo.requestedPermissions;
-        if (requestedPermissions != null && mSubcategories != null) {
-            for (String permissionName : requestedPermissions) {
-                Integer subcategories = mAllPermissionsHash.get(permissionName);
-                if (subcategories != null
-                        && getPm().checkPermission(permissionName,
-                                packageInfo.packageName) == PackageManager.PERMISSION_GRANTED) {
-                    newPackage.addSubcategory(subcategories);
-                }
-            }
-        }
-        mAppDetailsList.add(newPackage);
-
-        for (Category category : mCategories)
-            category.addApplicationToCategory(newPackage);
-        if (deliverResult)
-            deliverResult(new ArrayList<AppDetails>(mAppDetailsList));
-    }
-
-    public void onPackagesAdded(String[] packageNames) {
-        for (String packageStr : packageNames) {
-            onPackageAdded(packageStr, false);
-        }
-
-        deliverResult(new ArrayList<AppDetails>(mAppDetailsList));
-    }
-
-    public boolean wasDataReloaded() {
-        return mWasDataReloaded;
-    }
-
-    public void resetWasDataReloaded() {
-        mWasDataReloaded = false;
-    }
-}
\ No newline at end of file