X-Git-Url: https://git.mdrn.pl/mobilnebezpieczenstwo.git/blobdiff_plain/4b08fd3d054a0b4872d60adc7627bfdef069c39b..be45943134f44b96728f516e91a66149e51443c0:/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 index 3dfdb0f..0000000 --- a/src/com/samsung/srpol/loader/AppListLoader.java +++ /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 . -*/ - -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> { - 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 mAppDetailsList = null; - private static List mCategories; - private static ArrayList mSubcategories; - private static HashMap 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(); - mSubcategories = new ArrayList(); - 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(); - 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 subCategories = new ArrayList(); - - 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 permissions = new ArrayList(); - - 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 with a list of apps to filter - * @return List filtred app list - */ - private List filterToNotPlatformKeyAppList(List packageList) { - if (packageList != null) { - - List noPlatformKeyAppList = new ArrayList(); - 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 loadInBackground() { - List appList = mPm.getInstalledPackages(0); - - appList = filterToNotPlatformKeyAppList(appList); - - HashMap appDetailsHash = new HashMap( - 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 list = new ArrayList( - 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 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 getAppDetailsList() { - return mAppDetailsList; - } - - /** - * @return the mCategories - */ - static public List getCategories() { - return mCategories; - } - - public static List getSubcategoriesOfMask(int subcategoriesMask) { - ArrayList list = new ArrayList(); - 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(mAppDetailsList)); - break; - } - } - } - - public void onPackagesRemoved(String[] packageNames) { - for (String packageName : packageNames) { - onPackageRemoved(packageName, false); - } - deliverResult(new ArrayList(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(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(mAppDetailsList)); - } - - public void onPackagesAdded(String[] packageNames) { - for (String packageStr : packageNames) { - onPackageAdded(packageStr, false); - } - - deliverResult(new ArrayList(mAppDetailsList)); - } - - public boolean wasDataReloaded() { - return mWasDataReloaded; - } - - public void resetWasDataReloaded() { - mWasDataReloaded = false; - } -} \ No newline at end of file