Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8ff18678 authored by Amit Kumar's avatar Amit Kumar 💻
Browse files

Add support for sdcard apps

parent 10356170
Loading
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@ import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Paint;
import android.os.Build;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.TypedValue;
@@ -12,6 +13,7 @@ import android.view.ViewGroup;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.regex.Matcher;
@@ -157,4 +159,22 @@ public class Utilities {
        return result;
    }

    public static boolean isBootCompleted() {
        return "1".equals(getSystemProperty("sys.boot_completed", "1"));
    }

    public static String getSystemProperty(String property, String defaultValue) {
        try {
            Class clazz = Class.forName("android.os.SystemProperties");
            Method getter = clazz.getDeclaredMethod("get", String.class);
            String value = (String) getter.invoke(null, property);
            if (!TextUtils.isEmpty(value)) {
                return value;
            }
        } catch (Exception e) {
            Log.d(TAG, "Unable to read system properties");
        }
        return defaultValue;
    }

}
+10 −1
Original line number Diff line number Diff line
@@ -6,7 +6,6 @@ import android.content.Intent;
import android.os.Process;
import android.util.Log;


import foundation.e.blisslauncher.BlissLauncher;
import foundation.e.blisslauncher.core.events.AppAddEvent;
import foundation.e.blisslauncher.core.events.AppChangeEvent;
@@ -57,6 +56,16 @@ public class PackageAddedRemovedHandler extends BroadcastReceiver {
            EventRelay.getInstance().push(event);
            BlissLauncher.getApplication(ctx).getAppProvider().reload();
        }

        if("android.intent.action.MEDIA_MOUNTED".equals(action)) {
            Intent launchIntent = ctx.getPackageManager().getLaunchIntentForPackage(packageName);
            if (launchIntent != null) {
                BlissLauncher.getApplication(ctx).getIconsHandler().resetIconDrawableForPackage(
                        launchIntent.getComponent(), user);
                AppChangeEvent appChangeEvent = new AppChangeEvent(packageName, user);
                EventRelay.getInstance().push(appChangeEvent);
            }
        }
    }

    @Override
+2 −0
Original line number Diff line number Diff line
@@ -25,6 +25,8 @@ public class ApplicationItem extends LauncherItem {
    public static final int TYPE_CALENDAR = 746;
    public static final int TYPE_DEFAULT = 111;

    public boolean isDisabled = false;

    /**
     * Indicates the type of app item ie. Clock or Calendar (in case of none, It will be )
     */
+33 −0
Original line number Diff line number Diff line
package foundation.e.blisslauncher.core.utils;

import java.util.ArrayList;
import java.util.HashMap;

public class MultiHashMap<K, V> extends HashMap<K, ArrayList<V>> {

    public MultiHashMap() { }

    public MultiHashMap(int size) {
        super(size);
    }

    public void addToList(K key, V value) {
        ArrayList<V> list = get(key);
        if (list == null) {
            list = new ArrayList<>();
            list.add(value);
            put(key, list);
        } else {
            list.add(value);
        }
    }

    @Override
    public MultiHashMap<K, V> clone() {
        MultiHashMap<K, V> map = new MultiHashMap<>(size());
        for (Entry<K, ArrayList<V>> entry : entrySet()) {
            map.put(entry.getKey(), new ArrayList<V>(entry.getValue()));
        }
        return map;
    }
}
+62 −4
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@ package foundation.e.blisslauncher.features.launcher;

import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.LauncherActivityInfo;
import android.content.pm.LauncherApps;
import android.content.pm.PackageManager;
@@ -10,6 +11,7 @@ import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.os.Process;
import android.os.UserManager;
import android.provider.MediaStore;
@@ -25,6 +27,7 @@ import java.util.List;
import java.util.Map;

import foundation.e.blisslauncher.BlissLauncher;
import foundation.e.blisslauncher.R;
import foundation.e.blisslauncher.core.Utilities;
import foundation.e.blisslauncher.core.broadcast.PackageAddedRemovedHandler;
import foundation.e.blisslauncher.core.database.DatabaseManager;
@@ -36,6 +39,7 @@ import foundation.e.blisslauncher.core.executors.AppExecutors;
import foundation.e.blisslauncher.core.utils.AppUtils;
import foundation.e.blisslauncher.core.utils.Constants;
import foundation.e.blisslauncher.core.utils.GraphicsUtil;
import foundation.e.blisslauncher.core.utils.MultiHashMap;
import foundation.e.blisslauncher.core.utils.UserHandle;
import foundation.e.blisslauncher.features.launcher.tasks.LoadAppsTask;
import foundation.e.blisslauncher.features.launcher.tasks.LoadDatabaseTask;
@@ -81,6 +85,8 @@ public class AppProvider {

    public static HashSet<String> DISABLED_PACKAGES = new HashSet<>();

    private MultiHashMap<UserHandle, String> pendingPackages = new MultiHashMap<>();

    static {
        DISABLED_PACKAGES.add(MICROG_PACKAGE);
        DISABLED_PACKAGES.add(MUPDF_PACKAGE);
@@ -93,6 +99,7 @@ public class AppProvider {
    private static AppProvider sInstance;
    private boolean isLoading;
    private boolean mStopped;
    private boolean isSdCardReady;

    private AppProvider(Context context) {
        this.mContext = context;
@@ -206,6 +213,8 @@ public class AppProvider {
    public synchronized void reload() {
        Log.d(TAG, "reload() called");

        isSdCardReady = Utilities.isBootCompleted();

        if (mLauncherItems != null && mLauncherItems.size() > 0) {
            mAppsRepository.updateAppsRelay(mLauncherItems);
        }
@@ -288,9 +297,39 @@ public class AppProvider {
            if (databaseItem.itemType == Constants.ITEM_TYPE_APPLICATION) {
                ApplicationItem applicationItem = mApplicationItems.get(databaseItem.id);
                if (applicationItem == null) {
                    UserHandle userHandle = null;
                    int index = databaseItem.id.lastIndexOf((int) '/');
                    if (index > -1) {
                        String serialText = databaseItem.id.substring(index);
                        try {
                            long serial = Long.parseLong(serialText);
                            userHandle = new UserHandle(serial, Process.myUserHandle());
                        } catch (NumberFormatException e) {
                            e.printStackTrace();
                        }
                    }
                    if(userHandle == null){
                        userHandle = new UserHandle();
                    }
                    if (isAppOnSdcard(databaseItem.packageName, userHandle) || !isSdCardReady) {
                        Log.d(TAG, "Missing package: " + databaseItem.packageName);
                        Log.d(TAG, "Is App on Sdcard " + isAppOnSdcard(databaseItem.packageName, databaseItem.user));
                        Log.d(TAG, "Is Sdcard ready " + isSdCardReady);


                        pendingPackages.addToList(userHandle, databaseItem.packageName);
                        applicationItem = new ApplicationItem();
                        applicationItem.title = databaseItem.title;
                        applicationItem.user = userHandle;
                        applicationItem.componentName = databaseItem.getTargetComponent();
                        applicationItem.packageName = databaseItem.packageName;
                        applicationItem.icon = getContext().getDrawable(R.drawable.default_icon);
                        applicationItem.isDisabled = true;
                    } else {
                        DatabaseManager.getManager(mContext).removeLauncherItem(databaseItem.id);
                        continue;
                    }
                }

                applicationItem.container = databaseItem.container;
                applicationItem.screenId = databaseItem.screenId;
@@ -368,6 +407,25 @@ public class AppProvider {
        return mLauncherItems;
    }

    private boolean isAppOnSdcard(String packageName, UserHandle userHandle) {
        ApplicationInfo info = null;
        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                info = ((LauncherApps) mContext.getSystemService(
                        Context.LAUNCHER_APPS_SERVICE)).getApplicationInfo(
                        packageName, PackageManager.MATCH_UNINSTALLED_PACKAGES, userHandle.getRealHandle());
                return info != null && (info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
            } else {
                info = getContext().getPackageManager()
                        .getApplicationInfo(packageName, PackageManager.MATCH_UNINSTALLED_PACKAGES);
                return info != null && info.enabled;
            }
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
            return false;
        }
    }

    private ShortcutItem prepareShortcutForNougat(LauncherItem databaseItem) {
        ShortcutItem shortcutItem = new ShortcutItem();
        shortcutItem.id = databaseItem.id;
Loading