/* * Copyright (C) 2008 The Android Open Source Project * * Modifications to original by Jeff Corcoran * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package ca.mimic.apphangar; import android.app.ActivityManager; import android.content.ComponentName; import android.content.Context; import android.content.SharedPreferences; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.drawable.Drawable; import android.text.TextUtils; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.lang.reflect.Method; public class IconCacheHelper { private static final String RESOURCE_FILE_PREFIX = "icon_"; private IconPackHelper mIconPackHelper; private final Context mContext; private final PackageManager mPackageManager; private int mIconDpi; public IconCacheHelper(Context context) { ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); mContext = context; mPackageManager = context.getPackageManager(); mIconDpi = activityManager.getLauncherLargeIconDensity(); // need to set mIconDpi before getting default icon mIconPackHelper = new IconPackHelper(context); loadIconPack(); } private void loadIconPack() { mIconPackHelper.unloadIconPack(); Settings.PrefsGet prefs = new Settings.PrefsGet(mContext.getSharedPreferences(mContext.getPackageName(), Context.MODE_MULTI_PROCESS)); SharedPreferences mPrefs = prefs.prefsGet(); String iconPack = mPrefs.getString(Settings.ICON_PACK_PREFERENCE, ""); if (!TextUtils.isEmpty(iconPack) && !mIconPackHelper.loadIconPack(iconPack)) { SharedPreferences.Editor mEditor = prefs.editorGet(); mEditor.putString(Settings.ICON_PACK_PREFERENCE, ""); mEditor.apply(); } } public Drawable getFullResDefaultActivityIcon() { return getFullResIcon(Resources.getSystem(), android.R.mipmap.sym_def_app_icon); } public Drawable getFullResIcon(Resources resources, int iconId) { Drawable d; try { d = resources.getDrawableForDensity(iconId, mIconDpi); } catch (Resources.NotFoundException e) { d = null; } return (d != null) ? d : getFullResDefaultActivityIcon(); } public Drawable getFullResIcon(ResolveInfo info) { return getFullResIcon(info.activityInfo); } public Drawable getFullResIcon(ActivityInfo info, boolean getStock) { Resources resources; try { resources = mPackageManager.getResourcesForApplication( info.applicationInfo); } catch (PackageManager.NameNotFoundException e) { resources = null; } if (resources != null) { int iconId; if (mIconPackHelper != null && mIconPackHelper.isIconPackLoaded() && !getStock) { iconId = mIconPackHelper.getResourceIdForActivityIcon(info); if (iconId != 0) { return getFullResIcon(mIconPackHelper.getIconPackResources(), iconId); } } iconId = info.getIconResource(); if (iconId != 0) { return getFullResIcon(resources, iconId); } } return getFullResDefaultActivityIcon(); } public Drawable getFullResIcon(ActivityInfo info) { return getFullResIcon(info, false); } public static int chmod(File path, int mode) { try { Class fileUtils = Class.forName("android.os.FileUtils"); Method setPermissions = fileUtils.getMethod("setPermissions", String.class, int.class, int.class, int.class); return (Integer) setPermissions.invoke(null, path.getAbsolutePath(), mode, -1, -1); } catch (Exception e) { Tools.HangarLog("chmod Exception: " + e); return 0; } } public static String preloadIcon(Context context, String resourceName, Bitmap icon, int size) { FileOutputStream resourceFile = null; File file = null; try { file = new File(context.getCacheDir(), getResourceName(resourceName)); resourceFile = new FileOutputStream(file); ByteArrayOutputStream os = new ByteArrayOutputStream(); if (Bitmap.createScaledBitmap(icon, size, size, true).compress(android.graphics.Bitmap.CompressFormat.PNG, 75, os)) { byte[] buffer = os.toByteArray(); resourceFile.write(buffer, 0, buffer.length); } else { Tools.HangarLog("failed to encode cache for " + resourceName); return null; } } catch (FileNotFoundException e) { Tools.HangarLog("failed to pre-load cache for " + resourceName); } catch (IOException e) { Tools.HangarLog("failed to pre-load cache for " + resourceName); } finally { if (resourceFile != null) { try { resourceFile.flush(); resourceFile.close(); chmod(file, 0664); } catch (IOException e) { Tools.HangarLog("failed to save restored icon for: " + resourceName); } } } return file.getPath(); } public static String preloadComponent(Context context, ComponentName componentName, Bitmap icon, int size) { return preloadIcon(context, getResourceFilename(componentName), icon, size); } protected static String getPreloadedIconUri(Context context, String resourceName) { File file = new File(context.getCacheDir(), getResourceName(resourceName)); if (file.exists()) { return file.getPath(); } else { return null; } } protected static String getPreloadedComponentUri(Context context, ComponentName componentName) { return getPreloadedIconUri(context, getResourceFilename(componentName)); } protected static Bitmap getPreloadedIcon(Context context, String resourceName) { Bitmap icon = null; FileInputStream resourceFile = null; try { File file = new File(context.getCacheDir(), getResourceName(resourceName)); resourceFile = new FileInputStream(file); byte[] buffer = new byte[1024]; ByteArrayOutputStream bytes = new ByteArrayOutputStream(); int bytesRead = 0; while(bytesRead >= 0) { bytes.write(buffer, 0, bytesRead); bytesRead = resourceFile.read(buffer, 0, buffer.length); } icon = BitmapFactory.decodeByteArray(bytes.toByteArray(), 0, bytes.size()); if (icon == null) { Tools.HangarLog("failed to decode pre-load icon for " + resourceName); } } catch (FileNotFoundException e) { Tools.HangarLog("there is no restored icon for: " + resourceName); } catch (IOException e) { Tools.HangarLog("failed to read pre-load icon for: " + resourceName); } finally { if(resourceFile != null) { try { resourceFile.close(); } catch (IOException e) { Tools.HangarLog("failed to manage pre-load icon file: " + resourceName); } } } if (icon != null) { // TODO: handle alpha mask in the view layer Bitmap b = Bitmap.createBitmap(Math.max(icon.getWidth(), 1), Math.max(icon.getHeight(), 1), Bitmap.Config.ARGB_8888); Canvas c = new Canvas(b); Paint paint = new Paint(); // paint.setAlpha(127); c.drawBitmap(icon, 0, 0, paint); c.setBitmap(null); icon.recycle(); icon = b; } return icon; } protected static Bitmap getPreloadedComponent(Context context, ComponentName componentName) { return getPreloadedIcon(context, getResourceFilename(componentName)); } protected static String getResourceName(String resourceName) { String filename = resourceName.replace(File.separatorChar, '_'); return RESOURCE_FILE_PREFIX + filename; } protected static String getResourceFilename(ComponentName component) { return component.flattenToShortString(); } }