Skip to main content

ActivityManager: Configuration Management

Configuration describes all device configuration information that can impact the resources the application retrieves.  This includes both user-specified configuration options (locale and scaling) as well as device configurations (such as input modes, screen size and screen orientation).

Configuration is defined in:
frameworks/base/core/java/android/content/res/Configuration.java

You can get the value for an activity by - Configuration config = getResources().getConfiguration();
These include values like:
  • MCC
  • MNC
  • Locale
  • Orientation
  • colormode
  • densitydpi
  • fontscale
  • keyboard
  • hardkeyboardHidden
  • keyboard
  • keyboardHidden
  • navigation
  • navigatioHidden
  • screenHeightDp
  • screenLayout
  • screenwidthDp
  • touchscreen
  • uimode

android:configChanges: flag that lists configuration changes that the activity will handle itself. When a configuration change occurs at runtime, the activity is shut down and restarted by default, but declaring a configuration with this attribute will prevent the activity from being restarted. 
Instead, the activity remains running and its onConfigurationChanged() method is called.


At ActivityManager level we have the following methods to access/modify configuration.
updateConfiguration
getDeviceConfiguration
updatePersistentConfiguration

To modify configuration we need to have the below mentioned permission. As this is signature/privileged. Normally third party apps cannot modify these.
   <permission android:name="android.permission.CHANGE_CONFIGURATION"
       android:protectionLevel="signature|privileged|development" />

Call to update a configuration in AMS would end up in the below code flow:
UpdateConfiguartionLocked()
      //To update system level resources being accessed.
      ac.updateConfiguration(configCopy);
      mSystemThread.applyConfigurationToResources(configCopy);
   
 
     app.thread.scheduleConfigurationChanged(configCopy); This call is made on all LRU applications.  This results in the following call is ActivityThread.java
                public void scheduleConfigurationChanged(Configuration config) {
updatePendingConfiguration(config);
sendMessage(H.CONFIGURATION_CHANGED, config);
                on CONFIGURATION_CHANGED
handleConfigurationChanged() is called
   for all callbacks of resumed activities If the activity can handle configuration                                  change call onConfigurationChanged()  and Update the config values
                    mResourcesManager.applyConfigurationToResourcesLocked()
                    configDiff = mConfiguration.updateFrom(config);
 config = applyCompatConfiguration(mCurDefaultDisplayDpi);
                        ArrayList<ComponentCallbacks2> callbacks = collectComponentCallbacks(config);
                     freeTextLayoutCachesIfNeeded(configDiff);
                     performConfigurationChanged(callbacks.get(i), config);

Broadcast the locale and config changed intents if required intents
  Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
                intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
                        | Intent.FLAG_RECEIVER_REPLACE_PENDING
                        | Intent.FLAG_RECEIVER_FOREGROUND);

            intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
                    intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
                    if (!mProcessesReady) {
                        intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
                    }


  //Get the Focussed stack and update its configuration
  mStackSupervisor.getFocusedStack();
  mainStack.ensureActivityConfigurationLocked(starting, changes);
  mWindowManager.setNewConfiguration(mConfiguration);


Comments