forked from organicmaps/organicmaps
[android] Added 3g warning handling before doing update maps on 3g
[android] Made storage callback detachable to handle update status/progress correctly, i.e. don't miss update status while app in background, and avoid memory leaks [android] Fixed discarding the 'ToDoafterUpdate' status during screen rotation
This commit is contained in:
parent
8af1a59abc
commit
614988ab5f
1 changed files with 172 additions and 90 deletions
|
@ -22,6 +22,8 @@ import com.mapswithme.util.Constants;
|
|||
import com.mapswithme.util.StringUtils;
|
||||
import com.mapswithme.util.UiUtils;
|
||||
import com.mapswithme.util.Utils;
|
||||
import com.mapswithme.util.log.Logger;
|
||||
import com.mapswithme.util.log.LoggerFactory;
|
||||
import com.mapswithme.util.statistics.Statistics;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
@ -38,6 +40,10 @@ import static com.mapswithme.util.statistics.Statistics.EventName.DOWNLOADER_DIA
|
|||
|
||||
public class UpdaterDialogFragment extends BaseMwmDialogFragment
|
||||
{
|
||||
private static final Logger LOGGER = LoggerFactory.INSTANCE.getLogger(LoggerFactory.Type.DOWNLOADER);
|
||||
private static final String TAG = UpdaterDialogFragment.class.getSimpleName();
|
||||
|
||||
private static final String EXTRA_LEFTOVER_MAPS = "extra_leftover_maps";
|
||||
|
||||
private static final String ARG_UPDATE_IMMEDIATELY = "arg_update_immediately";
|
||||
private static final String ARG_TOTAL_SIZE = "arg_total_size";
|
||||
|
@ -60,83 +66,13 @@ public class UpdaterDialogFragment extends BaseMwmDialogFragment
|
|||
* Stores maps which are left to finish autoupdating process.
|
||||
*/
|
||||
@Nullable
|
||||
private Set<String> mLeftoverMaps;
|
||||
private HashSet<String> mLeftoverMaps;
|
||||
|
||||
@Nullable
|
||||
private BaseNewsFragment.NewsDialogListener mDoneListener;
|
||||
|
||||
@NonNull
|
||||
private final MapManager.StorageCallback mStorageCallback = new MapManager.StorageCallback()
|
||||
{
|
||||
|
||||
@Override
|
||||
public void onStatusChanged(List<MapManager.StorageCallbackData> data)
|
||||
{
|
||||
if (mOutdatedMaps == null)
|
||||
return;
|
||||
|
||||
for (MapManager.StorageCallbackData item : data)
|
||||
{
|
||||
if (item.isLeafNode && item.newStatus == CountryItem.STATUS_FAILED)
|
||||
{
|
||||
String text;
|
||||
switch (item.errorCode)
|
||||
{
|
||||
case CountryItem.ERROR_NO_INTERNET:
|
||||
text = getString(R.string.common_check_internet_connection_dialog);
|
||||
break;
|
||||
|
||||
case CountryItem.ERROR_OOM:
|
||||
text = getString(R.string.downloader_no_space_title);
|
||||
break;
|
||||
|
||||
default:
|
||||
text = String.valueOf(item.errorCode);
|
||||
}
|
||||
Statistics.INSTANCE.trackDownloaderDialogError(mTotalSizeMb, text);
|
||||
MapManager.showErrorDialog(getActivity(), item, new Utils.Proc<Boolean>()
|
||||
{
|
||||
@Override
|
||||
public void invoke(@NonNull Boolean result)
|
||||
{
|
||||
if (result)
|
||||
{
|
||||
MapManager.nativeUpdate(CountryItem.getRootId());
|
||||
}
|
||||
else
|
||||
{
|
||||
finish();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
else if (item.isLeafNode && item.newStatus == CountryItem.STATUS_DONE)
|
||||
{
|
||||
if (mLeftoverMaps == null)
|
||||
throw new AssertionError("mLeftoverMaps can't be null if mOutdatedMaps != null");
|
||||
mLeftoverMaps.remove(item.countryId);
|
||||
}
|
||||
}
|
||||
|
||||
if (!isAllUpdated())
|
||||
return;
|
||||
|
||||
finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgress(String countryId, long localSize, long remoteSize)
|
||||
{
|
||||
if (mOutdatedMaps == null)
|
||||
return;
|
||||
|
||||
int progress = MapManager.nativeGetOverallProgress(mOutdatedMaps);
|
||||
mTitle.setText(String.format(Locale.getDefault(), "%s %d%%",
|
||||
getString(R.string.whats_new_auto_update_updating_maps), progress));
|
||||
}
|
||||
};
|
||||
@Nullable
|
||||
private DetachableStorageCallback mStorageCallback;
|
||||
|
||||
private void finish()
|
||||
{
|
||||
|
@ -169,15 +105,22 @@ public class UpdaterDialogFragment extends BaseMwmDialogFragment
|
|||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
MapManager.nativeUpdate(CountryItem.getRootId());
|
||||
UiUtils.show(mProgressBar);
|
||||
UiUtils.hide(mUpdateBtn);
|
||||
mTitle.setText(String.format(Locale.getDefault(), "%s %d%%",
|
||||
getString(R.string.whats_new_auto_update_updating_maps), 0));
|
||||
mCancelBtn.setText(R.string.cancel);
|
||||
MapManager.warnOn3gUpdate(getActivity(), CountryItem.getRootId(), new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
MapManager.nativeUpdate(CountryItem.getRootId());
|
||||
UiUtils.show(mProgressBar);
|
||||
UiUtils.hide(mUpdateBtn);
|
||||
mTitle.setText(String.format(Locale.getDefault(), "%s %d%%",
|
||||
getString(R.string.whats_new_auto_update_updating_maps), 0));
|
||||
mCancelBtn.setText(R.string.cancel);
|
||||
|
||||
Statistics.INSTANCE.trackDownloaderDialogEvent(DOWNLOADER_DIALOG_MANUAL_DOWNLOAD,
|
||||
mTotalSizeMb);
|
||||
Statistics.INSTANCE.trackDownloaderDialogEvent(DOWNLOADER_DIALOG_MANUAL_DOWNLOAD,
|
||||
mTotalSizeMb);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -199,9 +142,8 @@ public class UpdaterDialogFragment extends BaseMwmDialogFragment
|
|||
Fragment f = fm.findFragmentByTag(UpdaterDialogFragment.class.getName());
|
||||
if (f != null)
|
||||
{
|
||||
fm.beginTransaction().remove(f).commitAllowingStateLoss();
|
||||
fm.executePendingTransactions();
|
||||
result = Framework.DO_AFTER_UPDATE_AUTO_UPDATE;
|
||||
((UpdaterDialogFragment)f).mDoneListener = doneListener;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -238,8 +180,20 @@ public class UpdaterDialogFragment extends BaseMwmDialogFragment
|
|||
public void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
if (savedInstanceState != null)
|
||||
{ // As long as we use HashSet to store leftover maps this cast is safe.
|
||||
//noinspection unchecked
|
||||
mLeftoverMaps = (HashSet<String>) savedInstanceState.getSerializable(EXTRA_LEFTOVER_MAPS);
|
||||
}
|
||||
readArguments();
|
||||
mStorageCallback = new DetachableStorageCallback(this, mLeftoverMaps, mOutdatedMaps);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState)
|
||||
{
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putSerializable(EXTRA_LEFTOVER_MAPS, mLeftoverMaps);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
|
@ -273,25 +227,44 @@ public class UpdaterDialogFragment extends BaseMwmDialogFragment
|
|||
return;
|
||||
}
|
||||
|
||||
// The storage callback must be non-null at this point.
|
||||
//noinspection ConstantConditions
|
||||
mStorageCallback.attach(this);
|
||||
mListenerSlot = MapManager.nativeSubscribe(mStorageCallback);
|
||||
|
||||
if (mAutoUpdate && !MapManager.nativeIsDownloading())
|
||||
{
|
||||
MapManager.nativeUpdate(CountryItem.getRootId());
|
||||
Statistics.INSTANCE.trackDownloaderDialogEvent(DOWNLOADER_DIALOG_DOWNLOAD,
|
||||
mTotalSizeMb);
|
||||
MapManager.warnOn3gUpdate(getActivity(), CountryItem.getRootId(), new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
MapManager.nativeUpdate(CountryItem.getRootId());
|
||||
Statistics.INSTANCE.trackDownloaderDialogEvent(DOWNLOADER_DIALOG_DOWNLOAD,
|
||||
mTotalSizeMb);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause()
|
||||
{
|
||||
if (mStorageCallback != null)
|
||||
mStorageCallback.detach();
|
||||
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy()
|
||||
{
|
||||
if (mListenerSlot != 0)
|
||||
{
|
||||
MapManager.nativeUnsubscribe(mListenerSlot);
|
||||
mListenerSlot = 0;
|
||||
}
|
||||
super.onPause();
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -319,8 +292,10 @@ public class UpdaterDialogFragment extends BaseMwmDialogFragment
|
|||
mTotalSize = args.getString(ARG_TOTAL_SIZE);
|
||||
mTotalSizeMb = args.getLong(ARG_TOTAL_SIZE_MB, 0L);
|
||||
mOutdatedMaps = args.getStringArray(ARG_OUTDATED_MAPS);
|
||||
if (mOutdatedMaps != null && mOutdatedMaps.length > 0)
|
||||
if (mLeftoverMaps == null && mOutdatedMaps != null && mOutdatedMaps.length > 0)
|
||||
{
|
||||
mLeftoverMaps = new HashSet<>(Arrays.asList(mOutdatedMaps));
|
||||
}
|
||||
}
|
||||
|
||||
private void initViews()
|
||||
|
@ -342,4 +317,111 @@ public class UpdaterDialogFragment extends BaseMwmDialogFragment
|
|||
{
|
||||
return mOutdatedMaps == null || mLeftoverMaps == null || mLeftoverMaps.isEmpty();
|
||||
}
|
||||
|
||||
private static class DetachableStorageCallback implements MapManager.StorageCallback
|
||||
{
|
||||
@Nullable
|
||||
private UpdaterDialogFragment mFragment;
|
||||
@Nullable
|
||||
private final Set<String> mLeftoverMaps;
|
||||
@Nullable
|
||||
private final String[] mOutdatedMaps;
|
||||
|
||||
DetachableStorageCallback(@Nullable UpdaterDialogFragment fragment,
|
||||
@Nullable Set<String> leftoverMaps,
|
||||
@Nullable String[] outdatedMaps)
|
||||
{
|
||||
mFragment = fragment;
|
||||
mLeftoverMaps = leftoverMaps;
|
||||
mOutdatedMaps = outdatedMaps;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStatusChanged(List<MapManager.StorageCallbackData> data)
|
||||
{
|
||||
for (MapManager.StorageCallbackData item : data)
|
||||
{
|
||||
if (item.isLeafNode && item.newStatus == CountryItem.STATUS_FAILED)
|
||||
{
|
||||
showErrorDialog(item);
|
||||
return;
|
||||
}
|
||||
else if (item.isLeafNode && item.newStatus == CountryItem.STATUS_DONE)
|
||||
{
|
||||
LOGGER.i(TAG, "Update finished for: " + item.countryId);
|
||||
if (mLeftoverMaps != null)
|
||||
mLeftoverMaps.remove(item.countryId);
|
||||
}
|
||||
}
|
||||
|
||||
if (mFragment != null && mFragment.isAdded() && mFragment.isAllUpdated())
|
||||
mFragment.finish();
|
||||
}
|
||||
|
||||
private void showErrorDialog(MapManager.StorageCallbackData item)
|
||||
{
|
||||
if (mFragment == null || !mFragment.isAdded())
|
||||
return;
|
||||
|
||||
String text;
|
||||
switch (item.errorCode)
|
||||
{
|
||||
case CountryItem.ERROR_NO_INTERNET:
|
||||
text = mFragment.getString(R.string.common_check_internet_connection_dialog);
|
||||
break;
|
||||
|
||||
case CountryItem.ERROR_OOM:
|
||||
text = mFragment.getString(R.string.downloader_no_space_title);
|
||||
break;
|
||||
|
||||
default:
|
||||
text = String.valueOf(item.errorCode);
|
||||
}
|
||||
Statistics.INSTANCE.trackDownloaderDialogError(mFragment.mTotalSizeMb, text);
|
||||
MapManager.showErrorDialog(mFragment.getActivity(), item, new Utils.Proc<Boolean>()
|
||||
{
|
||||
@Override
|
||||
public void invoke(@NonNull Boolean result)
|
||||
{
|
||||
if (result)
|
||||
{
|
||||
MapManager.warnOn3gUpdate(mFragment.getActivity(), CountryItem.getRootId(), new Runnable()
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
MapManager.nativeUpdate(CountryItem.getRootId());
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
mFragment.finish();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgress(String countryId, long localSize, long remoteSize)
|
||||
{
|
||||
if (mOutdatedMaps == null || mFragment == null || !mFragment.isAdded())
|
||||
return;
|
||||
|
||||
int progress = MapManager.nativeGetOverallProgress(mOutdatedMaps);
|
||||
mFragment.mTitle.setText(String.format(Locale.getDefault(), "%s %d%%",
|
||||
mFragment.getString(R.string.whats_new_auto_update_updating_maps),
|
||||
progress));
|
||||
}
|
||||
|
||||
void attach(@NonNull UpdaterDialogFragment fragment)
|
||||
{
|
||||
mFragment = fragment;
|
||||
}
|
||||
|
||||
void detach()
|
||||
{
|
||||
mFragment = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue