Program: 193035
Project: 193035
Buggy source:
/** 
 * Make sure the given activity matches the current configuration.  Returns false if the activity had to be destroyed.  Returns true if the configuration is the same, or the activity will remain running as-is for whatever reason.  Ensures the HistoryRecord is updated with the correct configuration and all other bookkeeping is handled.
 */
final boolean ensureActivityConfigurationLocked(ActivityRecord r,int globalChanges,boolean preserveWindow){
  if (mConfigWillChange) {
    if (DEBUG_SWITCH || DEBUG_CONFIGURATION)     Slog.v(TAG_CONFIGURATION,"String_Node_Str" + r);
    return true;
  }
  if (DEBUG_SWITCH || DEBUG_CONFIGURATION)   Slog.v(TAG_CONFIGURATION,"String_Node_Str" + r);
  final Configuration newConfig=mService.mConfiguration;
  final Configuration taskConfig=r.task.mOverrideConfig;
  if (r.configuration == newConfig && r.taskConfigOverride == taskConfig && !r.forceNewConfig) {
    if (DEBUG_SWITCH || DEBUG_CONFIGURATION)     Slog.v(TAG_CONFIGURATION,"String_Node_Str" + r);
    return true;
  }
  if (r.finishing) {
    if (DEBUG_SWITCH || DEBUG_CONFIGURATION)     Slog.v(TAG_CONFIGURATION,"String_Node_Str" + r);
    r.stopFreezingScreenLocked(false);
    return true;
  }
  final Configuration oldConfig=r.configuration;
  final Configuration oldTaskOverride=r.taskConfigOverride;
  r.configuration=newConfig;
  r.taskConfigOverride=taskConfig;
  int taskChanges=getTaskConfigurationChanges(r,taskConfig,oldTaskOverride);
  final int changes=oldConfig.diff(newConfig) | taskChanges;
  if (changes == 0 && !r.forceNewConfig) {
    if (DEBUG_SWITCH || DEBUG_CONFIGURATION)     Slog.v(TAG_CONFIGURATION,"String_Node_Str" + r);
    r.scheduleConfigurationChanged(taskConfig,false);
    return true;
  }
  if (DEBUG_SWITCH || DEBUG_CONFIGURATION)   Slog.v(TAG_CONFIGURATION,"String_Node_Str" + r + "String_Node_Str"+ Configuration.configurationDiffToString(taskChanges)+ "String_Node_Str"+ Configuration.configurationDiffToString(changes));
  if (r.app == null || r.app.thread == null) {
    if (DEBUG_SWITCH || DEBUG_CONFIGURATION)     Slog.v(TAG_CONFIGURATION,"String_Node_Str" + r);
    r.stopFreezingScreenLocked(false);
    r.forceNewConfig=false;
    return true;
  }
  if (DEBUG_SWITCH || DEBUG_CONFIGURATION)   Slog.v(TAG_CONFIGURATION,"String_Node_Str" + r.info.name + "String_Node_Str"+ Integer.toHexString(changes)+ "String_Node_Str"+ Integer.toHexString(r.info.getRealConfigChanged())+ "String_Node_Str"+ newConfig+ "String_Node_Str"+ taskConfig);
  if ((changes & (~r.info.getRealConfigChanged())) != 0 || r.forceNewConfig) {
    r.configChangeFlags|=changes;
    r.startFreezingScreenLocked(r.app,globalChanges);
    r.forceNewConfig=false;
    if (r.app == null || r.app.thread == null) {
      if (DEBUG_SWITCH || DEBUG_CONFIGURATION)       Slog.v(TAG_CONFIGURATION,"String_Node_Str" + r);
      destroyActivityLocked(r,true,"String_Node_Str");
    }
 else     if (r.state == ActivityState.PAUSING) {
      if (DEBUG_SWITCH || DEBUG_CONFIGURATION)       Slog.v(TAG_CONFIGURATION,"String_Node_Str" + r);
      r.configDestroy=true;
      return true;
    }
 else     if (r.state == ActivityState.RESUMED) {
      if (DEBUG_SWITCH || DEBUG_CONFIGURATION)       Slog.v(TAG_CONFIGURATION,"String_Node_Str" + r);
      relaunchActivityLocked(r,r.configChangeFlags,true,preserveWindow && isResizeOnlyChange(changes));
      r.configChangeFlags=0;
    }
 else {
      if (DEBUG_SWITCH || DEBUG_CONFIGURATION)       Slog.v(TAG_CONFIGURATION,"String_Node_Str" + r);
      relaunchActivityLocked(r,r.configChangeFlags,false,preserveWindow && isResizeOnlyChange(changes));
      r.configChangeFlags=0;
    }
    return false;
  }
  r.scheduleConfigurationChanged(taskConfig,true);
  r.stopFreezingScreenLocked(false);
  return true;
}

Fixed version (ground truth):
/** 
 * Make sure the given activity matches the current configuration.  Returns false if the activity had to be destroyed.  Returns true if the configuration is the same, or the activity will remain running as-is for whatever reason.  Ensures the HistoryRecord is updated with the correct configuration and all other bookkeeping is handled.
 */
final boolean ensureActivityConfigurationLocked(ActivityRecord r,int globalChanges,boolean preserveWindow){
  if (mConfigWillChange) {
    if (DEBUG_SWITCH || DEBUG_CONFIGURATION)     Slog.v(TAG_CONFIGURATION,"String_Node_Str" + r);
    return true;
  }
  if (DEBUG_SWITCH || DEBUG_CONFIGURATION)   Slog.v(TAG_CONFIGURATION,"String_Node_Str" + r);
  final Configuration newConfig=mService.mConfiguration;
  final Configuration taskConfig=r.task.mOverrideConfig;
  if (r.configuration == newConfig && r.taskConfigOverride == taskConfig && !r.forceNewConfig) {
    if (DEBUG_SWITCH || DEBUG_CONFIGURATION)     Slog.v(TAG_CONFIGURATION,"String_Node_Str" + r);
    return true;
  }
  if (r.finishing) {
    if (DEBUG_SWITCH || DEBUG_CONFIGURATION)     Slog.v(TAG_CONFIGURATION,"String_Node_Str" + r);
    r.stopFreezingScreenLocked(false);
    return true;
  }
  final Configuration oldConfig=r.configuration;
  final Configuration oldTaskOverride=r.taskConfigOverride;
  r.configuration=newConfig;
  r.taskConfigOverride=taskConfig;
  int taskChanges=getTaskConfigurationChanges(r,taskConfig,oldTaskOverride);
  final int changes=oldConfig.diff(newConfig) | taskChanges;
  if (changes == 0 && !r.forceNewConfig) {
    if (DEBUG_SWITCH || DEBUG_CONFIGURATION)     Slog.v(TAG_CONFIGURATION,"String_Node_Str" + r);
    r.scheduleConfigurationChanged(taskConfig,false);
    return true;
  }
  if (DEBUG_SWITCH || DEBUG_CONFIGURATION)   Slog.v(TAG_CONFIGURATION,"String_Node_Str" + r + "String_Node_Str"+ Configuration.configurationDiffToString(taskChanges)+ "String_Node_Str"+ Configuration.configurationDiffToString(changes));
  if (r.app == null || r.app.thread == null) {
    if (DEBUG_SWITCH || DEBUG_CONFIGURATION)     Slog.v(TAG_CONFIGURATION,"String_Node_Str" + r);
    r.stopFreezingScreenLocked(false);
    r.forceNewConfig=false;
    return true;
  }
  if (DEBUG_SWITCH || DEBUG_CONFIGURATION)   Slog.v(TAG_CONFIGURATION,"String_Node_Str" + r.info.name + "String_Node_Str"+ Integer.toHexString(changes)+ "String_Node_Str"+ Integer.toHexString(r.info.getRealConfigChanged())+ "String_Node_Str"+ newConfig+ "String_Node_Str"+ taskConfig);
  if ((changes & (~r.info.getRealConfigChanged())) != 0 || r.forceNewConfig) {
    r.configChangeFlags|=changes;
    r.startFreezingScreenLocked(r.app,globalChanges);
    r.forceNewConfig=false;
    preserveWindow&=isResizeOnlyChange(changes);
    if (r.app == null || r.app.thread == null) {
      if (DEBUG_SWITCH || DEBUG_CONFIGURATION)       Slog.v(TAG_CONFIGURATION,"String_Node_Str" + r);
      destroyActivityLocked(r,true,"String_Node_Str");
    }
 else     if (r.state == ActivityState.PAUSING) {
      if (DEBUG_SWITCH || DEBUG_CONFIGURATION)       Slog.v(TAG_CONFIGURATION,"String_Node_Str" + r);
      r.deferRelaunchUntilPaused=true;
      r.preserveWindowOnDeferredRelaunch=preserveWindow;
      return true;
    }
 else     if (r.state == ActivityState.RESUMED) {
      if (DEBUG_SWITCH || DEBUG_CONFIGURATION)       Slog.v(TAG_CONFIGURATION,"String_Node_Str" + r);
      relaunchActivityLocked(r,r.configChangeFlags,true,preserveWindow);
    }
 else {
      if (DEBUG_SWITCH || DEBUG_CONFIGURATION)       Slog.v(TAG_CONFIGURATION,"String_Node_Str" + r);
      relaunchActivityLocked(r,r.configChangeFlags,false,preserveWindow);
    }
    return false;
  }
  r.scheduleConfigurationChanged(taskConfig,true);
  r.stopFreezingScreenLocked(false);
  return true;
}