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

Commit 281712a3 authored by Clark Scheff's avatar Clark Scheff Committed by Gerrit Code Review
Browse files

Themes: Let ThemeService handle all theme processing [1/3]

Only themes that are applied will be processed inside of the
PackageManagerService, all others will be sent off to the
ThemeService.

Change-Id: I5f2ec628e1d22a05accc6727efb0c1387455f82f
parent 8789e08a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -128,6 +128,7 @@ LOCAL_SRC_FILES += \
	core/java/android/content/pm/IPackageMoveObserver.aidl \
	core/java/android/content/pm/IPackageStatsObserver.aidl \
	core/java/android/content/res/IThemeChangeListener.aidl \
	core/java/android/content/res/IThemeProcessingListener.aidl \
	core/java/android/content/res/IThemeService.aidl \
	core/java/android/database/IContentObserver.aidl \
	core/java/android/hardware/ICameraService.aidl \
+33 −0
Original line number Diff line number Diff line
@@ -2749,6 +2749,19 @@ public class Intent implements Parcelable, Cloneable {
    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
    public static final String ACTION_CREATE_DOCUMENT = "android.intent.action.CREATE_DOCUMENT";

    /**
     * Broadcast Action:  A theme's resources were cached.  Includes two extra fields,
     * {@link #EXTRA_THEME_PACKAGE_NAME}, containing the package name of the theme that was
     * processed, and {@link #EXTRA_THEME_RESULT}, containing the result code.
     *
     * <p class="note">This is a protected intent that can only be sent
     * by the system.</p>
     *
     * @hide
     */
    public static final String ACTION_THEME_RESOURCES_CACHED =
            "android.intent.action.THEME_RESOURCES_CACHED";

    // ---------------------------------------------------------------------
    // ---------------------------------------------------------------------
    // Standard intent categories (see addCategory()).
@@ -3393,6 +3406,26 @@ public class Intent implements Parcelable, Cloneable {
    public static final String EXTRA_SHUTDOWN_USERSPACE_ONLY
            = "android.intent.extra.SHUTDOWN_USERSPACE_ONLY";

    /**
     * Extra for {@link #ACTION_THEME_RESOURCES_CACHED} that provides the return value
     * from processThemeResources. A value of 0 indicates a successful caching of resources.
     * Error results are:
     * {@link android.content.pm.PackageManager#INSTALL_FAILED_THEME_AAPT_ERROR}
     * {@link android.content.pm.PackageManager#INSTALL_FAILED_THEME_IDMAP_ERROR}
     * {@link android.content.pm.PackageManager#INSTALL_FAILED_THEME_UNKNOWN_ERROR}
     *
     * @hide
     */
    public static final String EXTRA_THEME_RESULT = "android.intent.extra.RESULT";

    /**
     * Extra for {@link #ACTION_THEME_RESOURCES_CACHED} that provides the package name of the
     * theme that was processed.
     *
     * @hide
     */
    public static final String EXTRA_THEME_PACKAGE_NAME = "android.intent.extra.PACKAGE_NAME";

    // ---------------------------------------------------------------------
    // ---------------------------------------------------------------------
    // Intent flags (see mFlags variable).
+21 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2014 The CyanogenMod Project
 *
 * 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 android.content.res;

/** {@hide} */
oneway interface IThemeProcessingListener {
    void onFinishedProcessing(String pkgName);
}
+6 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
package android.content.res;

import android.content.res.IThemeChangeListener;
import android.content.res.IThemeProcessingListener;
import android.graphics.Bitmap;

import java.util.Map;
@@ -31,4 +32,9 @@ interface IThemeService {
    int getProgress();

    boolean cacheComposedIcon(in Bitmap icon, String path);

    boolean processThemeResources(String themePkgName);
    boolean isThemeBeingProcessed(String themePkgName);
    void registerThemeProcessingListener(in IThemeProcessingListener listener);
    void unregisterThemeProcessingListener(in IThemeProcessingListener listener);
}
+97 −12
Original line number Diff line number Diff line
@@ -38,9 +38,12 @@ public class ThemeManager {
    private IThemeService mService;
    private Handler mHandler;

    private Set<ThemeChangeListener> mListeners =
    private Set<ThemeChangeListener> mChangeListeners =
            new HashSet<ThemeChangeListener>();

    private Set<ThemeProcessingListener> mProcessingListeners =
            new HashSet<ThemeProcessingListener>();

    public ThemeManager(Context context, IThemeService service) {
        mContext = context;
        mService = service;
@@ -53,7 +56,7 @@ public class ThemeManager {
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    Iterator<ThemeChangeListener> iterator = mListeners.iterator();
                    Iterator<ThemeChangeListener> iterator = mChangeListeners.iterator();
                    while(iterator.hasNext()) {
                        try {
                            iterator.next().onProgress(progress);
@@ -71,7 +74,7 @@ public class ThemeManager {
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    Iterator<ThemeChangeListener> iterator = mListeners.iterator();
                    Iterator<ThemeChangeListener> iterator = mChangeListeners.iterator();
                    while(iterator.hasNext()) {
                        try {
                            iterator.next().onFinish(isSuccess);
@@ -85,23 +88,45 @@ public class ThemeManager {
        }
    };

    private final IThemeProcessingListener mThemeProcessingListener =
            new IThemeProcessingListener.Stub() {
        @Override
        public void onFinishedProcessing(final String pkgName) throws RemoteException {
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    Iterator<ThemeProcessingListener> iterator = mProcessingListeners.iterator();
                    while(iterator.hasNext()) {
                        try {
                            iterator.next().onFinishedProcessing(pkgName);
                        } catch (Throwable e) {
                            Log.w(TAG, "Unable to update theme change progress", e);
                            iterator.remove();
                        }
                    }
                }
            });
        }
    };


    public void addClient(ThemeChangeListener listener) {
        if (mListeners.contains(listener)) {
        if (mChangeListeners.contains(listener)) {
            throw new IllegalArgumentException("Client was already added ");
        }
        if (mListeners.size() == 0) {
        if (mChangeListeners.size() == 0) {
            try {
                mService.requestThemeChangeUpdates(mThemeChangeListener);
            } catch (RemoteException e) {
                Log.w(TAG, "Unable to register listener", e);
            }
        }
        mListeners.add(listener);
        mChangeListeners.add(listener);
    }

    public void removeClient(ThemeChangeListener listener) {
        mListeners.remove(listener);
        if (mListeners.size() == 0) {
        mChangeListeners.remove(listener);
        if (mChangeListeners.size() == 0) {
            try {
                mService.removeUpdates(mThemeChangeListener);
            } catch (RemoteException e) {
@@ -122,6 +147,39 @@ public class ThemeManager {
        removeClient(listener);
    }

    /**
     * Register a ThemeProcessingListener to be notified when a theme is done being processed.
     * @param listener ThemeChangeListener to register
     */
    public void registerProcessingListener(ThemeProcessingListener listener) {
        if (mProcessingListeners.contains(listener)) {
            throw new IllegalArgumentException("Listener was already added ");
        }
        if (mProcessingListeners.size() == 0) {
            try {
                mService.registerThemeProcessingListener(mThemeProcessingListener);
            } catch (RemoteException e) {
                Log.w(TAG, "Unable to register listener", e);
            }
        }
        mProcessingListeners.add(listener);
    }

    /**
     * Unregister a ThemeChangeListener.
     * @param listener ThemeChangeListener to unregister
     */
    public void unregisterProcessingListener(ThemeChangeListener listener) {
        mProcessingListeners.remove(listener);
        if (mProcessingListeners.size() == 0) {
            try {
                mService.unregisterThemeProcessingListener(mThemeProcessingListener);
            } catch (RemoteException e) {
                Log.w(TAG, "Unable to remove listener", e);
            }
        }
    }

    /**
     * Convenience method. Applies the entire theme.
     */
@@ -142,7 +200,7 @@ public class ThemeManager {
        try {
            mService.requestThemeChange(componentMap);
        } catch (RemoteException e) {
            Log.w(TAG, "Unable to access ThemeService", e);
            logThemeServiceException(e);
        }
    }

@@ -150,7 +208,7 @@ public class ThemeManager {
        try {
            mService.applyDefaultTheme();
        } catch (RemoteException e) {
            Log.w(TAG, "Unable to access ThemeService", e);
            logThemeServiceException(e);
        }
    }

@@ -158,23 +216,50 @@ public class ThemeManager {
        try {
            return mService.isThemeApplying();
        } catch (RemoteException e) {
            Log.w(TAG, "Unable to access ThemeService", e);
            logThemeServiceException(e);
        }

        return false;
    }

    public boolean isThemeBeingProcessed(String themePkgName) {
        try {
            return mService.isThemeBeingProcessed(themePkgName);
        } catch (RemoteException e) {
            logThemeServiceException(e);
        }
        return false;
    }

    public int getProgress() {
        try {
            return mService.getProgress();
        } catch (RemoteException e) {
            Log.w(TAG, "Unable to access ThemeService", e);
            logThemeServiceException(e);
        }
        return -1;
    }

    public boolean processThemeResources(String themePkgName) {
        try {
            return mService.processThemeResources(themePkgName);
        } catch (RemoteException e) {
            logThemeServiceException(e);
        }
        return false;
    }

    private void logThemeServiceException(Exception e) {
        Log.w(TAG, "Unable to access ThemeService", e);
    }

    public interface ThemeChangeListener {
        void onProgress(int progress);
        void onFinish(boolean isSuccess);
    }

    public interface ThemeProcessingListener {
        void onFinishedProcessing(String pkgName);
    }
}
Loading