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
This commit is contained in:
@@ -331,7 +331,8 @@ public class ManageApplications extends InstrumentedPreferenceFragment
|
|||||||
mApplications.setExtraViewController(new MusicViewHolderController(
|
mApplications.setExtraViewController(new MusicViewHolderController(
|
||||||
context,
|
context,
|
||||||
new StorageStatsSource(context),
|
new StorageStatsSource(context),
|
||||||
mVolumeUuid));
|
mVolumeUuid,
|
||||||
|
UserHandle.of(UserHandle.getUserId(mCurrentUid))));
|
||||||
}
|
}
|
||||||
mListView.setAdapter(mApplications);
|
mListView.setAdapter(mApplications);
|
||||||
mListView.setRecyclerListener(mApplications);
|
mListView.setRecyclerListener(mApplications);
|
||||||
@@ -870,6 +871,12 @@ public class ManageApplications extends InstrumentedPreferenceFragment
|
|||||||
|
|
||||||
public void setExtraViewController(FileViewHolderController extraViewController) {
|
public void setExtraViewController(FileViewHolderController extraViewController) {
|
||||||
mExtraViewController = extraViewController;
|
mExtraViewController = extraViewController;
|
||||||
|
mBgHandler.post(() -> {
|
||||||
|
mExtraViewController.queryStats();
|
||||||
|
mFgHandler.post(() -> {
|
||||||
|
onExtraViewCompleted();
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resume(int sort) {
|
public void resume(int sort) {
|
||||||
@@ -957,10 +964,6 @@ public class ManageApplications extends InstrumentedPreferenceFragment
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mExtraViewController != null) {
|
|
||||||
mExtraViewController.queryStats();
|
|
||||||
}
|
|
||||||
|
|
||||||
filterObj = new CompoundFilter(filterObj, ApplicationsState.FILTER_NOT_HIDE);
|
filterObj = new CompoundFilter(filterObj, ApplicationsState.FILTER_NOT_HIDE);
|
||||||
AppFilter finalFilterObj = filterObj;
|
AppFilter finalFilterObj = filterObj;
|
||||||
mBgHandler.post(() -> {
|
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() {
|
public int getCount() {
|
||||||
if (mEntries == null) {
|
if (mEntries == null) {
|
||||||
return 0;
|
return 0;
|
||||||
|
@@ -38,18 +38,20 @@ public class MusicViewHolderController implements FileViewHolderController {
|
|||||||
private StorageStatsSource mSource;
|
private StorageStatsSource mSource;
|
||||||
private String mVolumeUuid;
|
private String mVolumeUuid;
|
||||||
private long mMusicSize;
|
private long mMusicSize;
|
||||||
|
private UserHandle mUser;
|
||||||
|
|
||||||
public MusicViewHolderController(
|
public MusicViewHolderController(
|
||||||
Context context, StorageStatsSource source, String volumeUuid) {
|
Context context, StorageStatsSource source, String volumeUuid, UserHandle user) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mSource = source;
|
mSource = source;
|
||||||
mVolumeUuid = volumeUuid;
|
mVolumeUuid = volumeUuid;
|
||||||
|
mUser = user;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@WorkerThread
|
@WorkerThread
|
||||||
public void queryStats() {
|
public void queryStats() {
|
||||||
mMusicSize = mSource.getExternalStorageStats(mVolumeUuid, UserHandle.CURRENT).audioBytes;
|
mMusicSize = mSource.getExternalStorageStats(mVolumeUuid, mUser).audioBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -69,7 +71,7 @@ public class MusicViewHolderController implements FileViewHolderController {
|
|||||||
Intent intent = new Intent(DocumentsContract.ACTION_BROWSE);
|
Intent intent = new Intent(DocumentsContract.ACTION_BROWSE);
|
||||||
intent.setData(DocumentsContract.buildRootUri(AUTHORITY_MEDIA, "audio_root"));
|
intent.setData(DocumentsContract.buildRootUri(AUTHORITY_MEDIA, "audio_root"));
|
||||||
intent.addCategory(Intent.CATEGORY_DEFAULT);
|
intent.addCategory(Intent.CATEGORY_DEFAULT);
|
||||||
intent.putExtra(Intent.EXTRA_USER_ID, UserHandle.CURRENT);
|
intent.putExtra(Intent.EXTRA_USER_ID, mUser);
|
||||||
Utils.launchIntent(fragment, intent);
|
Utils.launchIntent(fragment, intent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -66,7 +66,8 @@ public class MusicViewHolderControllerTest {
|
|||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
mContext = RuntimeEnvironment.application;
|
mContext = RuntimeEnvironment.application;
|
||||||
mVolume = new VolumeInfo("id", 0, null, "id");
|
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);
|
LayoutInflater inflater = LayoutInflater.from(mContext);
|
||||||
mHolder = AppViewHolder.createOrRecycle(inflater, null);
|
mHolder = AppViewHolder.createOrRecycle(inflater, null);
|
||||||
|
Reference in New Issue
Block a user