use of android.content.res.Configuration in project android_frameworks_base by ParanoidAndroid.
the class ActivityThread method applyConfigurationToResourcesLocked.
final int applyConfigurationToResourcesLocked(Configuration config, CompatibilityInfo compat) {
if (mResConfiguration == null) {
mResConfiguration = new Configuration();
}
if (!mResConfiguration.isOtherSeqNewer(config) && compat == null) {
if (DEBUG_CONFIGURATION)
Slog.v(TAG, "Skipping new config: curSeq=" + mResConfiguration.seq + ", newSeq=" + config.seq);
return 0;
}
int changes = mResConfiguration.updateFrom(config);
flushDisplayMetricsLocked();
DisplayMetrics defaultDisplayMetrics = getDisplayMetricsLocked(Display.DEFAULT_DISPLAY, null);
if (compat != null && (mResCompatibilityInfo == null || !mResCompatibilityInfo.equals(compat))) {
mResCompatibilityInfo = compat;
changes |= ActivityInfo.CONFIG_SCREEN_LAYOUT | ActivityInfo.CONFIG_SCREEN_SIZE | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE;
}
// set it for java, this also affects newly created Resources
if (config.locale != null) {
Locale.setDefault(config.locale);
}
Resources.updateSystemConfiguration(config, defaultDisplayMetrics, compat);
ApplicationPackageManager.configurationChanged();
//Slog.i(TAG, "Configuration changed in " + currentPackageName());
Configuration tmpConfig = null;
Iterator<Map.Entry<ResourcesKey, WeakReference<Resources>>> it = mActiveResources.entrySet().iterator();
while (it.hasNext()) {
Map.Entry<ResourcesKey, WeakReference<Resources>> entry = it.next();
Resources r = entry.getValue().get();
if (r != null) {
if (DEBUG_CONFIGURATION)
Slog.v(TAG, "Changing resources " + r + " config to: " + config);
int displayId = entry.getKey().mDisplayId;
boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
DisplayMetrics dm = defaultDisplayMetrics;
Configuration overrideConfig = entry.getKey().mOverrideConfiguration;
boolean themeChanged = (changes & ActivityInfo.CONFIG_THEME_RESOURCE) != 0;
if (themeChanged) {
AssetManager am = r.getAssets();
if (am.hasThemeSupport()) {
detachThemeAssets(am);
if (!TextUtils.isEmpty(config.customTheme.getThemePackageName())) {
attachThemeAssets(am, config.customTheme);
}
}
}
if (!isDefaultDisplay || overrideConfig != null) {
if (tmpConfig == null) {
tmpConfig = new Configuration();
}
tmpConfig.setTo(config);
if (!isDefaultDisplay) {
dm = getDisplayMetricsLocked(displayId, null);
applyNonDefaultDisplayMetricsToConfigurationLocked(dm, tmpConfig);
}
if (overrideConfig != null) {
tmpConfig.updateFrom(overrideConfig);
}
r.updateConfiguration(tmpConfig, dm, compat);
} else {
r.updateConfiguration(config, dm, compat);
}
if (themeChanged) {
r.updateStringCache();
}
//Slog.i(TAG, "Updated app resources " + v.getKey()
// + " " + r + ": " + r.getConfiguration());
} else {
//Slog.i(TAG, "Removing old resources " + v.getKey());
it.remove();
}
}
return changes;
}
use of android.content.res.Configuration in project android_frameworks_base by ParanoidAndroid.
the class ActivityThread method handleRelaunchActivity.
private void handleRelaunchActivity(ActivityClientRecord tmp) {
// If we are getting ready to gc after going to the background, well
// we are back active so skip it.
unscheduleGcIdler();
Configuration changedConfig = null;
int configChanges = 0;
// had taken a more recent version.
synchronized (mPackages) {
int N = mRelaunchingActivities.size();
IBinder token = tmp.token;
tmp = null;
for (int i = 0; i < N; i++) {
ActivityClientRecord r = mRelaunchingActivities.get(i);
if (r.token == token) {
tmp = r;
configChanges |= tmp.pendingConfigChanges;
mRelaunchingActivities.remove(i);
i--;
N--;
}
}
if (tmp == null) {
if (DEBUG_CONFIGURATION)
Slog.v(TAG, "Abort, activity not relaunching!");
return;
}
if (DEBUG_CONFIGURATION)
Slog.v(TAG, "Relaunching activity " + tmp.token + " with configChanges=0x" + Integer.toHexString(configChanges));
if (mPendingConfiguration != null) {
changedConfig = mPendingConfiguration;
mPendingConfiguration = null;
}
}
if (tmp.createdConfig != null) {
// may have pending.
if (mConfiguration == null || (tmp.createdConfig.isOtherSeqNewer(mConfiguration) && mConfiguration.diff(tmp.createdConfig) != 0)) {
if (changedConfig == null || tmp.createdConfig.isOtherSeqNewer(changedConfig)) {
changedConfig = tmp.createdConfig;
}
}
}
if (DEBUG_CONFIGURATION)
Slog.v(TAG, "Relaunching activity " + tmp.token + ": changedConfig=" + changedConfig);
// If there was a pending configuration change, execute it first.
if (changedConfig != null) {
mCurDefaultDisplayDpi = changedConfig.densityDpi;
updateDefaultDensity();
handleConfigurationChanged(changedConfig, null);
}
ActivityClientRecord r = mActivities.get(tmp.token);
if (DEBUG_CONFIGURATION)
Slog.v(TAG, "Handling relaunch of " + r);
if (r == null) {
return;
}
r.activity.mConfigChangeFlags |= configChanges;
r.onlyLocalRequest = tmp.onlyLocalRequest;
Intent currentIntent = r.activity.mIntent;
r.activity.mChangingConfigurations = true;
// Need to ensure state is saved.
if (!r.paused) {
performPauseActivity(r.token, false, r.isPreHoneycomb());
}
if (r.state == null && !r.stopped && !r.isPreHoneycomb()) {
r.state = new Bundle();
r.state.setAllowFds(false);
mInstrumentation.callActivityOnSaveInstanceState(r.activity, r.state);
}
handleDestroyActivity(r.token, false, configChanges, true);
r.activity = null;
r.window = null;
r.hideForNow = false;
r.nextIdle = null;
// Merge any pending results and pending intents; don't just replace them
if (tmp.pendingResults != null) {
if (r.pendingResults == null) {
r.pendingResults = tmp.pendingResults;
} else {
r.pendingResults.addAll(tmp.pendingResults);
}
}
if (tmp.pendingIntents != null) {
if (r.pendingIntents == null) {
r.pendingIntents = tmp.pendingIntents;
} else {
r.pendingIntents.addAll(tmp.pendingIntents);
}
}
r.startsNotResumed = tmp.startsNotResumed;
handleLaunchActivity(r, currentIntent);
}
use of android.content.res.Configuration in project android_frameworks_base by ParanoidAndroid.
the class ActivityThread method performConfigurationChanged.
private static void performConfigurationChanged(ComponentCallbacks2 cb, Configuration config) {
// Only for Activity objects, check that they actually call up to their
// superclass implementation. ComponentCallbacks2 is an interface, so
// we check the runtime type and act accordingly.
Activity activity = (cb instanceof Activity) ? (Activity) cb : null;
if (activity != null) {
activity.mCalled = false;
}
boolean shouldChangeConfig = false;
if ((activity == null) || (activity.mCurrentConfig == null)) {
shouldChangeConfig = true;
} else {
// If the new config is the same as the config this Activity
// is already running with then don't bother calling
// onConfigurationChanged
int diff = activity.mCurrentConfig.diff(config);
if (diff != 0) {
// going to destroy it.
if ((~activity.mActivityInfo.getRealConfigChanged() & diff) == 0) {
shouldChangeConfig = true;
}
}
}
if (DEBUG_CONFIGURATION)
Slog.v(TAG, "Config callback " + cb + ": shouldChangeConfig=" + shouldChangeConfig);
if (shouldChangeConfig) {
cb.onConfigurationChanged(config);
if (activity != null) {
if (!activity.mCalled) {
throw new SuperNotCalledException("Activity " + activity.getLocalClassName() + " did not call through to super.onConfigurationChanged()");
}
activity.mConfigChangeFlags = 0;
activity.mCurrentConfig = new Configuration(config);
}
}
}
use of android.content.res.Configuration in project android_frameworks_base by ParanoidAndroid.
the class ActivityThread method getTopLevelResources.
/**
* Creates the top level Resources for applications with the given compatibility info.
*
* @param resDir the resource directory.
* @param compInfo the compability info. It will use the default compatibility info when it's
* null.
*/
Resources getTopLevelResources(String resDir, int displayId, Configuration overrideConfiguration, CompatibilityInfo compInfo) {
ResourcesKey key = new ResourcesKey(resDir, displayId, overrideConfiguration, compInfo.applicationScale, compInfo.isThemeable);
Resources r;
synchronized (mPackages) {
// Resources is app scale dependent.
if (false) {
Slog.w(TAG, "getTopLevelResources: " + resDir + " / " + compInfo.applicationScale);
}
WeakReference<Resources> wr = mActiveResources.get(key);
r = wr != null ? wr.get() : null;
//if (r != null) Slog.i(TAG, "isUpToDate " + resDir + ": " + r.getAssets().isUpToDate());
if (r != null && r.getAssets().isUpToDate()) {
if (false) {
Slog.w(TAG, "Returning cached resources " + r + " " + resDir + ": appScale=" + r.getCompatibilityInfo().applicationScale);
}
return r;
}
}
//if (r != null) {
// Slog.w(TAG, "Throwing away out-of-date resources!!!! "
// + r + " " + resDir);
//}
AssetManager assets = new AssetManager();
assets.overrideHook(resDir, ExtendedPropertiesUtils.OverrideMode.FullNameExclude);
assets.setThemeSupport(compInfo.isThemeable);
if (assets.addAssetPath(resDir) == 0) {
return null;
}
//Slog.i(TAG, "Resource: key=" + key + ", display metrics=" + metrics);
DisplayMetrics dm = getDisplayMetricsLocked(displayId, null);
dm.overrideHook(assets, ExtendedPropertiesUtils.OverrideMode.ExtendedProperties);
Configuration config;
boolean isDefaultDisplay = (displayId == Display.DEFAULT_DISPLAY);
if (!isDefaultDisplay || key.mOverrideConfiguration != null) {
config = new Configuration(getConfiguration());
if (!isDefaultDisplay) {
applyNonDefaultDisplayMetricsToConfigurationLocked(dm, config);
}
if (key.mOverrideConfiguration != null) {
config.updateFrom(key.mOverrideConfiguration);
}
} else {
config = getConfiguration();
}
/* Attach theme information to the resulting AssetManager when appropriate. */
if (compInfo.isThemeable && config != null) {
if (config.customTheme == null) {
config.customTheme = CustomTheme.getBootTheme();
}
if (!TextUtils.isEmpty(config.customTheme.getThemePackageName())) {
attachThemeAssets(assets, config.customTheme);
}
}
r = new Resources(assets, dm, config, compInfo);
if (false) {
Slog.i(TAG, "Created app resources " + resDir + " " + r + ": " + r.getConfiguration() + " appScale=" + r.getCompatibilityInfo().applicationScale);
}
synchronized (mPackages) {
WeakReference<Resources> wr = mActiveResources.get(key);
Resources existing = wr != null ? wr.get() : null;
if (existing != null && existing.getAssets().isUpToDate()) {
// Someone else already created the resources while we were
// unlocked; go ahead and use theirs.
r.getAssets().close();
return existing;
}
// XXX need to remove entries when weak references go away
mActiveResources.put(key, new WeakReference<Resources>(r));
return r;
}
}
use of android.content.res.Configuration in project android_frameworks_base by ParanoidAndroid.
the class ActivityThread method handleConfigurationChanged.
final void handleConfigurationChanged(Configuration config, CompatibilityInfo compat) {
int configDiff = 0;
int diff = 0;
synchronized (mPackages) {
if (mPendingConfiguration != null) {
if (!mPendingConfiguration.isOtherSeqNewer(config)) {
config = mPendingConfiguration;
mCurDefaultDisplayDpi = config.densityDpi;
updateDefaultDensity();
}
mPendingConfiguration = null;
}
if (config == null) {
return;
}
if (DEBUG_CONFIGURATION)
Slog.v(TAG, "Handle configuration changed: " + config);
diff = applyConfigurationToResourcesLocked(config, compat);
if (mConfiguration == null) {
mConfiguration = new Configuration();
}
if (!mConfiguration.isOtherSeqNewer(config) && compat == null) {
return;
}
configDiff = mConfiguration.diff(config);
mConfiguration.updateFrom(config);
config = applyCompatConfiguration(mCurDefaultDisplayDpi);
}
ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(false, config);
// Cleanup hardware accelerated stuff
WindowManagerGlobal.getInstance().trimLocalMemory();
freeTextLayoutCachesIfNeeded(configDiff);
if (callbacks != null) {
final int N = callbacks.size();
for (int i = 0; i < N; i++) {
ComponentCallbacks2 cb = callbacks.get(i);
// cache, now we need to trigger an update for each application.
if ((diff & ActivityInfo.CONFIG_THEME_RESOURCE) != 0) {
if (cb instanceof ContextWrapper) {
Context context = ((ContextWrapper) cb).getBaseContext();
if (context instanceof ContextImpl) {
((ContextImpl) context).refreshResourcesIfNecessary();
}
}
}
performConfigurationChanged(cb, config);
}
}
}
Aggregations