1/* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file 5 * except in compliance with the License. You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software distributed under the 10 * License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 11 * KIND, either express or implied. See the License for the specific language governing 12 * permissions and limitations under the License. 13 */ 14 15package com.android.systemui.statusbar.phone; 16 17import android.content.Context; 18import android.content.om.IOverlayManager; 19import android.content.pm.ActivityInfo; 20import android.content.res.Configuration; 21import android.os.LocaleList; 22import android.os.RemoteException; 23import android.os.ServiceManager; 24import android.os.UserHandle; 25 26import com.android.systemui.ConfigurationChangedReceiver; 27import com.android.systemui.statusbar.policy.ConfigurationController; 28 29import java.util.ArrayList; 30import java.util.HashMap; 31import java.util.Map; 32 33public class ConfigurationControllerImpl implements ConfigurationController, 34 ConfigurationChangedReceiver { 35 36 private final ArrayList<ConfigurationListener> mListeners = new ArrayList<>(); 37 private final Configuration mLastConfig = new Configuration(); 38 private int mDensity; 39 private float mFontScale; 40 private boolean mInCarMode; 41 private int mUiMode; 42 private LocaleList mLocaleList; 43 44 public ConfigurationControllerImpl(Context context) { 45 Configuration currentConfig = context.getResources().getConfiguration(); 46 mFontScale = currentConfig.fontScale; 47 mDensity = currentConfig.densityDpi; 48 mInCarMode = (currentConfig.uiMode & Configuration.UI_MODE_TYPE_MASK) 49 == Configuration.UI_MODE_TYPE_CAR; 50 mUiMode = currentConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK; 51 mLocaleList = currentConfig.getLocales(); 52 } 53 54 @Override 55 public void onConfigurationChanged(Configuration newConfig) { 56 // Avoid concurrent modification exception 57 ArrayList<ConfigurationListener> listeners = new ArrayList<>(mListeners); 58 59 listeners.forEach(l -> { 60 if (mListeners.contains(l)) { 61 l.onConfigChanged(newConfig); 62 } 63 }); 64 final float fontScale = newConfig.fontScale; 65 final int density = newConfig.densityDpi; 66 int uiMode = newConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK; 67 if (density != mDensity || fontScale != mFontScale 68 || (mInCarMode && uiMode != mUiMode)) { 69 listeners.forEach(l -> { 70 if (mListeners.contains(l)) { 71 l.onDensityOrFontScaleChanged(); 72 } 73 }); 74 mDensity = density; 75 mFontScale = fontScale; 76 mUiMode = uiMode; 77 } 78 79 final LocaleList localeList = newConfig.getLocales(); 80 if (!localeList.equals(mLocaleList)) { 81 mLocaleList = localeList; 82 listeners.forEach(l -> { 83 if (mListeners.contains(l)) { 84 l.onLocaleListChanged(); 85 } 86 }); 87 } 88 89 if ((mLastConfig.updateFrom(newConfig) & ActivityInfo.CONFIG_ASSETS_PATHS) != 0) { 90 listeners.forEach(l -> { 91 if (mListeners.contains(l)) { 92 l.onOverlayChanged(); 93 } 94 }); 95 } 96 } 97 98 @Override 99 public void addCallback(ConfigurationListener listener) { 100 mListeners.add(listener); 101 listener.onDensityOrFontScaleChanged(); 102 } 103 104 @Override 105 public void removeCallback(ConfigurationListener listener) { 106 mListeners.remove(listener); 107 } 108} 109