Fix crash in time zone picker due to race condition on view updates

- Can't reproduce the race condition with manual test, probably the view
  updates are fast enough that only monkey test can reproduce the issue.
- Reproduced a similar stacktrace and IndexOutOfBoundsException with
  Robolectric test by assuming that the race condition happens after
  text filtering and view updates. Try to fix the bug with this assumption
- The fix is to bind the data (data position in adapter) with ViewHolder.

Bug: 75322108
Test: m RunSettingsRoboTests ROBOTEST_FILTER=com.android.settings.datetime.timezone
Change-Id: Ie5d932bce30590b8067e042c3380911c9608872f
This commit is contained in:
Victor Chang
2018-03-24 18:07:50 +00:00
parent d7ea524e81
commit 201c629fcc
5 changed files with 138 additions and 43 deletions

View File

@@ -18,15 +18,16 @@ package com.android.settings.datetime.timezone;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Paint;
import android.icu.text.Collator;
import android.icu.text.LocaleDisplayNames;
import android.os.Bundle;
import android.support.annotation.VisibleForTesting;
import android.util.Log;
import com.android.internal.logging.nano.MetricsProto;
import com.android.settings.R;
import com.android.settings.core.SubSettingLauncher;
import com.android.settings.datetime.timezone.BaseTimeZoneAdapter.AdapterItem;
import com.android.settings.datetime.timezone.model.FilteredCountryTimeZones;
import com.android.settings.datetime.timezone.model.TimeZoneData;
@@ -63,8 +64,8 @@ public class RegionSearchPicker extends BaseTimeZonePicker {
return mAdapter;
}
private void onListItemClick(int position) {
final String regionId = mAdapter.getItem(position).getId();
private void onListItemClick(RegionItem item) {
final String regionId = item.getId();
final FilteredCountryTimeZones countryTimeZones = mTimeZoneData.lookupCountryTimeZones(
regionId);
final Activity activity = getActivity();
@@ -119,7 +120,8 @@ public class RegionSearchPicker extends BaseTimeZonePicker {
return new ArrayList<>(items);
}
private static class RegionItem implements BaseTimeZoneAdapter.AdapterItem {
@VisibleForTesting
static class RegionItem implements AdapterItem {
private final String mId;
private final String mName;