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

Commit efa19038 authored by d34d's avatar d34d Committed by Brint E. Kriebel
Browse files

Themes: Switch themes when user changes

This patch grabs the theme config for the new user and then
creates a ThemeChangeRequest from that config.  This request is
then processed and applied for the new user.

Secondary users will not be able to change themes at this time.
This patch helps pave the way for that ability and provides a better
user experience when switching users.

Change-Id: I6d7e2ab312b8e3e5c099d1e9e2e62892bead10da
(cherry picked from commit b6935c4d)
parent 581ede86
Loading
Loading
Loading
Loading
+33 −0
Original line number Original line Diff line number Diff line
@@ -15,6 +15,7 @@
 */
 */
package android.content.res;
package android.content.res;


import android.content.pm.ThemeUtils;
import android.os.Parcel;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.Parcelable;


@@ -171,6 +172,12 @@ public final class ThemeChangeRequest implements Parcelable {


        public Builder() {}
        public Builder() {}


        public Builder(ThemeConfig themeConfig) {
            if (themeConfig != null) {
                buildChangeRequestFromThemeConfig(themeConfig);
            }
        }

        public Builder setOverlay(String pkgName) {
        public Builder setOverlay(String pkgName) {
            return setComponent(MODIFIES_OVERLAYS, pkgName);
            return setComponent(MODIFIES_OVERLAYS, pkgName);
        }
        }
@@ -244,5 +251,31 @@ public final class ThemeChangeRequest implements Parcelable {
        public ThemeChangeRequest build() {
        public ThemeChangeRequest build() {
            return new ThemeChangeRequest(mThemeComponents, mPerAppOverlays, mRequestType);
            return new ThemeChangeRequest(mThemeComponents, mPerAppOverlays, mRequestType);
        }
        }

        private void buildChangeRequestFromThemeConfig(ThemeConfig themeConfig) {
            if (themeConfig.getFontPkgName() != null) {
                this.setFont(themeConfig.getFontPkgName());
            }
            if (themeConfig.getIconPackPkgName() != null) {
                this.setIcons(themeConfig.getIconPackPkgName());
            }
            if (themeConfig.getOverlayPkgName() != null) {
                this.setOverlay(themeConfig.getOverlayPkgName());
            }
            if (themeConfig.getOverlayForStatusBar() != null) {
                this.setStatusBar(themeConfig.getOverlayForStatusBar());
            }
            if (themeConfig.getOverlayForNavBar() != null) {
                this.setNavBar(themeConfig.getOverlayForNavBar());
            }

            // Check if there are any per-app overlays using this theme
            final Map<String, ThemeConfig.AppTheme> themes = themeConfig.getAppThemes();
            for (String appPkgName : themes.keySet()) {
                if (ThemeUtils.isPerAppThemeComponent(appPkgName)) {
                    this.setAppOverlay(appPkgName, themes.get(appPkgName).getOverlayPkgName());
                }
            }
        }
    }
    }
}
}
+13 −8
Original line number Original line Diff line number Diff line
@@ -20,6 +20,7 @@ import android.content.ContentResolver;
import android.content.res.ThemeChangeRequest.RequestType;
import android.content.res.ThemeChangeRequest.RequestType;
import android.os.Parcel;
import android.os.Parcel;
import android.os.Parcelable;
import android.os.Parcelable;
import android.os.UserHandle;
import android.provider.Settings;
import android.provider.Settings;
import android.text.TextUtils;
import android.text.TextUtils;
import android.util.JsonReader;
import android.util.JsonReader;
@@ -177,20 +178,24 @@ public class ThemeConfig implements Cloneable, Parcelable, Comparable<ThemeConfi
     * preference until the theme is switched at runtime.
     * preference until the theme is switched at runtime.
     */
     */
    public static ThemeConfig getBootTheme(ContentResolver resolver) {
    public static ThemeConfig getBootTheme(ContentResolver resolver) {
        return getBootThemeForUser(resolver, UserHandle.USER_OWNER);
    }

    public static ThemeConfig getBootThemeForUser(ContentResolver resolver, int userHandle) {
        ThemeConfig bootTheme = mSystemConfig;
        ThemeConfig bootTheme = mSystemConfig;
        try {
        try {
            String json = Settings.Secure.getString(resolver,
            String json = Settings.Secure.getStringForUser(resolver,
                    Configuration.THEME_PKG_CONFIGURATION_PERSISTENCE_PROPERTY);
                    Configuration.THEME_PKG_CONFIGURATION_PERSISTENCE_PROPERTY, userHandle);
            bootTheme = ThemeConfig.fromJson(json);
            bootTheme = ThemeConfig.fromJson(json);


            // Handle upgrade Case: Previously the theme configuration was in separate fields
            // Handle upgrade Case: Previously the theme configuration was in separate fields
            if (bootTheme == null) {
            if (bootTheme == null) {
                String overlayPkgName =  Settings.Secure.getString(resolver,
                String overlayPkgName =  Settings.Secure.getStringForUser(resolver,
                        Configuration.THEME_PACKAGE_NAME_PERSISTENCE_PROPERTY);
                        Configuration.THEME_PACKAGE_NAME_PERSISTENCE_PROPERTY, userHandle);
                String iconPackPkgName = Settings.Secure.getString(resolver,
                String iconPackPkgName = Settings.Secure.getStringForUser(resolver,
                        Configuration.THEME_ICONPACK_PACKAGE_NAME_PERSISTENCE_PROPERTY);
                        Configuration.THEME_ICONPACK_PACKAGE_NAME_PERSISTENCE_PROPERTY, userHandle);
                String fontPkgName = Settings.Secure.getString(resolver,
                String fontPkgName = Settings.Secure.getStringForUser(resolver,
                        Configuration.THEME_FONT_PACKAGE_NAME_PERSISTENCE_PROPERTY);
                        Configuration.THEME_FONT_PACKAGE_NAME_PERSISTENCE_PROPERTY, userHandle);


                Builder builder = new Builder();
                Builder builder = new Builder();
                builder.defaultOverlay(overlayPkgName);
                builder.defaultOverlay(overlayPkgName);
+42 −0
Original line number Original line Diff line number Diff line
@@ -240,6 +240,9 @@ public class ThemeService extends IThemeService.Stub {
        IntentFilter filter = new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED);
        IntentFilter filter = new IntentFilter(Intent.ACTION_WALLPAPER_CHANGED);
        mContext.registerReceiver(mWallpaperChangeReceiver, filter);
        mContext.registerReceiver(mWallpaperChangeReceiver, filter);


        filter = new IntentFilter(Intent.ACTION_USER_SWITCHED);
        mContext.registerReceiver(mUserChangeReceiver, filter);

        mPM = mContext.getPackageManager();
        mPM = mContext.getPackageManager();


        processInstalledThemes();
        processInstalledThemes();
@@ -726,6 +729,24 @@ public class ThemeService extends IThemeService.Stub {
        return true;
        return true;
    }
    }


    private boolean updateConfiguration(ThemeConfig themeConfig) {
        final IActivityManager am = ActivityManagerNative.getDefault();
        if (am != null) {
            final long token = Binder.clearCallingIdentity();
            try {
                Configuration config = am.getConfiguration();

                config.themeConfig = themeConfig;
                am.updateConfiguration(config);
            } catch (RemoteException e) {
                return false;
            } finally {
                Binder.restoreCallingIdentity(token);
            }
        }
        return true;
    }

    private boolean shouldUpdateConfiguration(ThemeChangeRequest request) {
    private boolean shouldUpdateConfiguration(ThemeChangeRequest request) {
        return request.getOverlayThemePackageName() != null ||
        return request.getOverlayThemePackageName() != null ||
                request.getFontThemePackageName() != null ||
                request.getFontThemePackageName() != null ||
@@ -1122,6 +1143,27 @@ public class ThemeService extends IThemeService.Stub {
        }
        }
    };
    };


    private BroadcastReceiver mUserChangeReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            int userHandle = intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1);
            if (userHandle >= 0) {
                ThemeConfig config = ThemeConfig.getBootThemeForUser(mContext.getContentResolver(),
                        userHandle);
                if (DEBUG) {
                    Log.d(TAG,
                            "Changing theme for user " + userHandle + " to " + config.toString());
                }
                ThemeChangeRequest request = new ThemeChangeRequest.Builder(config).build();
                try {
                    requestThemeChange(request, true);
                } catch (RemoteException e) {
                    Log.e(TAG, "Unable to change theme for user change", e);
                }
            }
        }
    };

    private Comparator<File> mOldestFilesFirstComparator = new Comparator<File>() {
    private Comparator<File> mOldestFilesFirstComparator = new Comparator<File>() {
        @Override
        @Override
        public int compare(File lhs, File rhs) {
        public int compare(File lhs, File rhs) {
+3 −2
Original line number Original line Diff line number Diff line
@@ -16606,8 +16606,9 @@ public final class ActivityManagerService extends ActivityManagerNative
    private void saveThemeResourceLocked(ThemeConfig t, boolean isDiff){
    private void saveThemeResourceLocked(ThemeConfig t, boolean isDiff){
        if(isDiff) {
        if(isDiff) {
            Settings.Secure.putString(mContext.getContentResolver(),
            Settings.Secure.putStringForUser(mContext.getContentResolver(),
                    Configuration.THEME_PKG_CONFIGURATION_PERSISTENCE_PROPERTY, t.toJson());
                    Configuration.THEME_PKG_CONFIGURATION_PERSISTENCE_PROPERTY, t.toJson(),
                    UserHandle.USER_CURRENT);
        }
        }
    }
    }