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

Commit 3e4b494f authored by Clark Scheff's avatar Clark Scheff Committed by Gerrit Code Review
Browse files

Themes: Handle processing themes in separate thread

If themes are being processed and the user attempts to apply a theme
they will be forced to wait for themes to finish processing before
the theme is applied.  This patch moves processing of theme resources
into a separate handler/thread.

Change-Id: Ib30a1be75915364c2867df04d63700be63c9f2c5
parent e6d70ebf
Loading
Loading
Loading
Loading
+35 −10
Original line number Diff line number Diff line
@@ -102,6 +102,7 @@ public class ThemeService extends IThemeService.Stub {

    private HandlerThread mWorker;
    private ThemeWorkerHandler mHandler;
    private ResourceProcessingHandler mResourceProcessingHandler;
    private Context mContext;
    private PackageManager mPM;
    private int mProgress;
@@ -121,8 +122,6 @@ public class ThemeService extends IThemeService.Stub {
    private class ThemeWorkerHandler extends Handler {
        private static final int MESSAGE_CHANGE_THEME = 1;
        private static final int MESSAGE_APPLY_DEFAULT_THEME = 2;
        private static final int MESSAGE_QUEUE_THEME_FOR_PROCESSING = 3;
        private static final int MESSAGE_DEQUEUE_AND_PROCESS_THEME = 4;

        public ThemeWorkerHandler(Looper looper) {
            super(looper);
@@ -138,6 +137,24 @@ public class ThemeService extends IThemeService.Stub {
                case MESSAGE_APPLY_DEFAULT_THEME:
                    doApplyDefaultTheme();
                    break;
                default:
                    Log.w(TAG, "Unknown message " + msg.what);
                    break;
            }
        }
    }

    private class ResourceProcessingHandler extends Handler {
        private static final int MESSAGE_QUEUE_THEME_FOR_PROCESSING = 3;
        private static final int MESSAGE_DEQUEUE_AND_PROCESS_THEME = 4;

        public ResourceProcessingHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MESSAGE_QUEUE_THEME_FOR_PROCESSING:
                    String pkgName = (String) msg.obj;
                    synchronized (mThemesToProcessQueue) {
@@ -195,6 +212,12 @@ public class ThemeService extends IThemeService.Stub {
        mHandler = new ThemeWorkerHandler(mWorker.getLooper());
        Log.i(TAG, "Spawned worker thread");

        HandlerThread processingThread = new HandlerThread("ResourceProcessingThread",
                Process.THREAD_PRIORITY_BACKGROUND);
        processingThread.start();
        mResourceProcessingHandler =
                new ResourceProcessingHandler(processingThread.getLooper());

        // create the theme directory if it does not exist
        ThemeUtils.createThemeDirIfNotExists();
        ThemeUtils.createFontDirIfNotExists();
@@ -882,7 +905,7 @@ public class ThemeService extends IThemeService.Stub {
                        // We want to make sure these resources are taken care of first so
                        // send the dequeue message and place it in the front of the queue
                        msg = mHandler.obtainMessage(
                                ThemeWorkerHandler.MESSAGE_DEQUEUE_AND_PROCESS_THEME);
                                ResourceProcessingHandler.MESSAGE_DEQUEUE_AND_PROCESS_THEME);
                        mHandler.sendMessageAtFrontOfQueue(msg);
                    }
                }
@@ -958,9 +981,9 @@ public class ThemeService extends IThemeService.Stub {
            return false;
        }
        // Obtain a message and send it to the handler to process this theme
        Message msg = mHandler.obtainMessage(ThemeWorkerHandler.MESSAGE_QUEUE_THEME_FOR_PROCESSING,
                                     0, 0, themePkgName);
        mHandler.sendMessage(msg);
        Message msg = mResourceProcessingHandler.obtainMessage(
                ResourceProcessingHandler.MESSAGE_QUEUE_THEME_FOR_PROCESSING, 0, 0, themePkgName);
        mResourceProcessingHandler.sendMessage(msg);
        return true;
    }

@@ -1058,18 +1081,20 @@ public class ThemeService extends IThemeService.Stub {
        Message msg;
        // Make sure the default theme is the first to get processed!
        if (!ThemeConfig.HOLO_DEFAULT.equals(defaultTheme)) {
            msg = mHandler.obtainMessage(ThemeWorkerHandler.MESSAGE_QUEUE_THEME_FOR_PROCESSING,
            msg = mHandler.obtainMessage(
                    ResourceProcessingHandler.MESSAGE_QUEUE_THEME_FOR_PROCESSING,
                    0, 0, defaultTheme);
            mHandler.sendMessage(msg);
            mResourceProcessingHandler.sendMessage(msg);
        }
        // Iterate over all installed packages and queue up the ones that are themes or icon packs
        List<PackageInfo> packages = mPM.getInstalledPackages(0);
        for (PackageInfo info : packages) {
            if (!defaultTheme.equals(info.packageName) &&
                    (info.isThemeApk || info.isLegacyThemeApk || info.isLegacyIconPackApk)) {
                msg = mHandler.obtainMessage(ThemeWorkerHandler.MESSAGE_QUEUE_THEME_FOR_PROCESSING,
                msg = mHandler.obtainMessage(
                        ResourceProcessingHandler.MESSAGE_QUEUE_THEME_FOR_PROCESSING,
                        0, 0, info.packageName);
                mHandler.sendMessage(msg);
                mResourceProcessingHandler.sendMessage(msg);
            }
        }
    }