From a412c30d90d809319832f01d907cc46c83e6089e Mon Sep 17 00:00:00 2001 From: Daniel Nishi Date: Wed, 8 Feb 2017 12:29:24 -0800 Subject: [PATCH] Fix a race condition where the extra view may not update timely. Previously, we queried for the extra view's stats during the rebuild. The full rebuild can take an arduous amount of time. By moving the background calculation outside of the rebuild code path, we can load the stats in the background and update the view outside of the app loading cycle. Bug: 35144044 Test: Manual -- this was race condition-y, so I just tested several times. Change-Id: Id2f92e32c3b3f9c5d5cf4a7308cca38c2e52789c --- .../applications/ManageApplications.java | 30 +++++++++++++++---- .../MusicViewHolderController.java | 8 +++-- .../MusicViewHolderControllerTest.java | 3 +- 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/src/com/android/settings/applications/ManageApplications.java b/src/com/android/settings/applications/ManageApplications.java index 146e1ff1afa..e4616cfd05a 100644 --- a/src/com/android/settings/applications/ManageApplications.java +++ b/src/com/android/settings/applications/ManageApplications.java @@ -331,7 +331,8 @@ public class ManageApplications extends InstrumentedPreferenceFragment mApplications.setExtraViewController(new MusicViewHolderController( context, new StorageStatsSource(context), - mVolumeUuid)); + mVolumeUuid, + UserHandle.of(UserHandle.getUserId(mCurrentUid)))); } mListView.setAdapter(mApplications); mListView.setRecyclerListener(mApplications); @@ -870,6 +871,12 @@ public class ManageApplications extends InstrumentedPreferenceFragment public void setExtraViewController(FileViewHolderController extraViewController) { mExtraViewController = extraViewController; + mBgHandler.post(() -> { + mExtraViewController.queryStats(); + mFgHandler.post(() -> { + onExtraViewCompleted(); + }); + }); } public void resume(int sort) { @@ -957,10 +964,6 @@ public class ManageApplications extends InstrumentedPreferenceFragment break; } - if (mExtraViewController != null) { - mExtraViewController.queryStats(); - } - filterObj = new CompoundFilter(filterObj, ApplicationsState.FILTER_NOT_HIDE); AppFilter finalFilterObj = filterObj; mBgHandler.post(() -> { @@ -1178,6 +1181,23 @@ public class ManageApplications extends InstrumentedPreferenceFragment } } + public void onExtraViewCompleted() { + int size = mActive.size(); + // If we have no elements, don't do anything. + if (size < 1) { + return; + } + AppViewHolder holder = (AppViewHolder) mActive.get(size - 1).getTag(); + + // HACK: The extra view has no AppEntry -- and should be the only element without one. + // Thus, if the last active element has no AppEntry, it is the extra view. + if (holder == null || holder.entry != null) { + return; + } + + mExtraViewController.setupView(holder); + } + public int getCount() { if (mEntries == null) { return 0; diff --git a/src/com/android/settings/applications/MusicViewHolderController.java b/src/com/android/settings/applications/MusicViewHolderController.java index 18c87dbcc62..fd7e3205a93 100644 --- a/src/com/android/settings/applications/MusicViewHolderController.java +++ b/src/com/android/settings/applications/MusicViewHolderController.java @@ -38,18 +38,20 @@ public class MusicViewHolderController implements FileViewHolderController { private StorageStatsSource mSource; private String mVolumeUuid; private long mMusicSize; + private UserHandle mUser; public MusicViewHolderController( - Context context, StorageStatsSource source, String volumeUuid) { + Context context, StorageStatsSource source, String volumeUuid, UserHandle user) { mContext = context; mSource = source; mVolumeUuid = volumeUuid; + mUser = user; } @Override @WorkerThread public void queryStats() { - mMusicSize = mSource.getExternalStorageStats(mVolumeUuid, UserHandle.CURRENT).audioBytes; + mMusicSize = mSource.getExternalStorageStats(mVolumeUuid, mUser).audioBytes; } @Override @@ -69,7 +71,7 @@ public class MusicViewHolderController implements FileViewHolderController { Intent intent = new Intent(DocumentsContract.ACTION_BROWSE); intent.setData(DocumentsContract.buildRootUri(AUTHORITY_MEDIA, "audio_root")); intent.addCategory(Intent.CATEGORY_DEFAULT); - intent.putExtra(Intent.EXTRA_USER_ID, UserHandle.CURRENT); + intent.putExtra(Intent.EXTRA_USER_ID, mUser); Utils.launchIntent(fragment, intent); } } diff --git a/tests/robotests/src/com/android/settings/applications/MusicViewHolderControllerTest.java b/tests/robotests/src/com/android/settings/applications/MusicViewHolderControllerTest.java index 2a2de66012e..4af07077fbd 100644 --- a/tests/robotests/src/com/android/settings/applications/MusicViewHolderControllerTest.java +++ b/tests/robotests/src/com/android/settings/applications/MusicViewHolderControllerTest.java @@ -66,7 +66,8 @@ public class MusicViewHolderControllerTest { MockitoAnnotations.initMocks(this); mContext = RuntimeEnvironment.application; mVolume = new VolumeInfo("id", 0, null, "id"); - mController = new MusicViewHolderController(mContext, mSource, mVolume.fsUuid); + mController = new MusicViewHolderController(mContext, mSource, mVolume.fsUuid, + new UserHandle(0)); LayoutInflater inflater = LayoutInflater.from(mContext); mHolder = AppViewHolder.createOrRecycle(inflater, null);