diff --git a/android/jni/com/mapswithme/maps/Framework.cpp b/android/jni/com/mapswithme/maps/Framework.cpp index 4476d87da5..b1a097bf41 100644 --- a/android/jni/com/mapswithme/maps/Framework.cpp +++ b/android/jni/com/mapswithme/maps/Framework.cpp @@ -78,7 +78,8 @@ namespace android m_wasLongClick(false), m_densityDpi(0), m_screenWidth(0), - m_screenHeight(0) + m_screenHeight(0), + m_currentSlotID(0) { ASSERT_EQUAL ( g_framework, 0, () ); g_framework = this; diff --git a/android/src/com/mapswithme/country/BaseDownloadAdapter.java b/android/src/com/mapswithme/country/BaseDownloadAdapter.java index d84f7d40af..c16ae998f3 100644 --- a/android/src/com/mapswithme/country/BaseDownloadAdapter.java +++ b/android/src/com/mapswithme/country/BaseDownloadAdapter.java @@ -42,7 +42,6 @@ public abstract class BaseDownloadAdapter extends BaseAdapter static final int TYPE_COUNTRY_READY = 3; static final int TYPE_COUNTRY_NOT_DOWNLOADED = 4; static final int TYPES_COUNT = 5; - static final int INVALID_POSITION = -1; private int mActiveAnimationsCount; public static final String PROPERTY_TRANSLATION_X = "translationX"; diff --git a/android/src/com/mapswithme/country/CountryItem.java b/android/src/com/mapswithme/country/CountryItem.java index f6d3aff876..9181a3da02 100644 --- a/android/src/com/mapswithme/country/CountryItem.java +++ b/android/src/com/mapswithme/country/CountryItem.java @@ -6,6 +6,8 @@ import com.mapswithme.maps.MapStorage; public class CountryItem { + public static final CountryItem EMPTY = new CountryItem("", MapStorage.NOT_DOWNLOADED, StorageOptions.MAP_OPTION_MAP_ONLY, false); + private String mName; private int mOptions; private int mStatus; diff --git a/android/src/com/mapswithme/country/DownloadedAdapter.java b/android/src/com/mapswithme/country/DownloadedAdapter.java index ac180837fc..a192a0a0ab 100644 --- a/android/src/com/mapswithme/country/DownloadedAdapter.java +++ b/android/src/com/mapswithme/country/DownloadedAdapter.java @@ -1,14 +1,26 @@ package com.mapswithme.country; +import android.util.Log; +import android.util.Pair; import android.view.View; import android.view.ViewGroup; +import com.mapswithme.maps.BuildConfig; import com.mapswithme.maps.R; public class DownloadedAdapter extends BaseDownloadAdapter implements ActiveCountryTree.ActiveCountryListener { + private static final String TAG = DownloadedAdapter.class.getSimpleName(); private static final int TYPE_HEADER = 5; private static final int VIEW_TYPE_COUNT = 6; + + /* + * Invalid position indicates, that country group(downloaded, new or outdated) and position in that group cannot be determined correctly. + * Normally we shouldn't fall into that case. However, due to some problems with callbacks it can happen. + * TODO remove constant & code where it appears after ActiveMapsLayout refactoring. + */ + private static final int INVALID_POSITION = -1; + private int mUpdatedCount; private int mOutdatedCount; private int mInProgressCount; @@ -61,28 +73,43 @@ public class DownloadedAdapter extends BaseDownloadAdapter implements ActiveCoun @Override protected long[] getRemoteItemSizes(int position) { - final int group = getGroupByAbsPosition(position); - final int pos = getPositionInGroup(position); - long mapOnly = ActiveCountryTree.getCountrySize(group, pos, StorageOptions.MAP_OPTION_MAP_ONLY, false); - return new long[] { mapOnly, mapOnly + ActiveCountryTree.getCountrySize(group, pos, StorageOptions.MAP_OPTION_CAR_ROUTING, false)}; + final Pair groupAndPosition = splitAbsolutePosition(position, "getRemoteItemSizes. Cannot get correct positions."); + if (groupAndPosition != null) + { + long mapSize = ActiveCountryTree.getCountrySize(groupAndPosition.first, groupAndPosition.second, StorageOptions.MAP_OPTION_MAP_ONLY, false); + long routingSize = ActiveCountryTree.getCountrySize(groupAndPosition.first, groupAndPosition.second, StorageOptions.MAP_OPTION_CAR_ROUTING, false); + return new long[]{mapSize, mapSize + routingSize}; + } + + return new long[]{0, 0}; } @Override protected long[] getDownloadableItemSizes(int position) { - final int group = getGroupByAbsPosition(position); - final int pos = getPositionInGroup(position); - return new long[] { ActiveCountryTree.getCountrySize(group, pos, -1, true), - ActiveCountryTree.getCountrySize(group, pos, -1, false)}; + final Pair groupAndPosition = splitAbsolutePosition(position, "getDownloadableItemSizes. Cannot get correct positions."); + if (groupAndPosition != null) + { + long currentSize = ActiveCountryTree.getCountrySize(groupAndPosition.first, groupAndPosition.second, -1, true); + long totalSize = ActiveCountryTree.getCountrySize(groupAndPosition.first, groupAndPosition.second, -1, false); + return new long[]{currentSize, totalSize}; + } + + return new long[]{0, 0}; } @Override public int getCount() + { + updateGroupCounters(); + return mInProgressCount + (mUpdatedCount == 0 ? 0 : mUpdatedCount + 1) + (mOutdatedCount == 0 ? 0 : mOutdatedCount + 1); + } + + private void updateGroupCounters() { mInProgressCount = ActiveCountryTree.getCountInGroup(ActiveCountryTree.GROUP_NEW); mUpdatedCount = ActiveCountryTree.getCountInGroup(ActiveCountryTree.GROUP_UP_TO_DATE); mOutdatedCount = ActiveCountryTree.getCountInGroup(ActiveCountryTree.GROUP_OUT_OF_DATE); - return mInProgressCount + (mUpdatedCount == 0 ? 0 : mUpdatedCount + 1) + (mOutdatedCount == 0 ? 0 : mOutdatedCount + 1); } @Override @@ -91,9 +118,11 @@ public class DownloadedAdapter extends BaseDownloadAdapter implements ActiveCoun if (isHeader(position)) return null; - final int group = getGroupByAbsPosition(position); - final int positionInGroup = getPositionInGroup(position); - return ActiveCountryTree.getCountryItem(group, positionInGroup); + final Pair groupAndPosition = splitAbsolutePosition(position, "getItem. Cannot get correct positions."); + if (groupAndPosition != null) + return ActiveCountryTree.getCountryItem(groupAndPosition.first, groupAndPosition.second); + + return CountryItem.EMPTY; } @Override @@ -206,19 +235,24 @@ public class DownloadedAdapter extends BaseDownloadAdapter implements ActiveCoun @Override protected void cancelDownload(int position) { - ActiveCountryTree.cancelDownloading(getGroupByAbsPosition(position), getPositionInGroup(position)); + final Pair groupAndPosition = splitAbsolutePosition(position, "cancelDownload. Cannot get correct positions."); + if (groupAndPosition != null) + ActiveCountryTree.cancelDownloading(groupAndPosition.first, groupAndPosition.second); } @Override protected void retryDownload(int position) { - ActiveCountryTree.retryDownloading(getGroupByAbsPosition(position), getPositionInGroup(position)); + final Pair groupAndPosition = splitAbsolutePosition(position, "retryDownload. Cannot get correct positions."); + if (groupAndPosition != null) + ActiveCountryTree.retryDownloading(groupAndPosition.first, groupAndPosition.second); } @Override protected void setCountryListener() { - mListenerSlotId = ActiveCountryTree.addListener(this); + if (mListenerSlotId == 0) + mListenerSlotId = ActiveCountryTree.addListener(this); } @Override @@ -230,27 +264,37 @@ public class DownloadedAdapter extends BaseDownloadAdapter implements ActiveCoun @Override protected void updateCountry(int position, int options) { - ActiveCountryTree.downloadMap(getGroupByAbsPosition(position), getPositionInGroup(position), options); + final Pair groupAndPosition = splitAbsolutePosition(position, "updateCountry. Cannot get correct positions."); + if (groupAndPosition != null) + ActiveCountryTree.downloadMap(groupAndPosition.first, groupAndPosition.second, options); } @Override protected void downloadCountry(int position, int options) { - ActiveCountryTree.downloadMap(getGroupByAbsPosition(position), getPositionInGroup(position), options); + final Pair groupAndPosition = splitAbsolutePosition(position, "downloadCountry. Cannot get correct positions."); + if (groupAndPosition != null) + ActiveCountryTree.downloadMap(groupAndPosition.first, groupAndPosition.second, options); } @Override protected void deleteCountry(int position, int options) { - ActiveCountryTree.deleteMap(getGroupByAbsPosition(position), getPositionInGroup(position), options); + final Pair groupAndPosition = splitAbsolutePosition(position, "downloadCountry. Cannot get correct positions."); + if (groupAndPosition != null) + ActiveCountryTree.deleteMap(groupAndPosition.first, groupAndPosition.second, options); } @Override protected void showCountry(int position) { - ActiveCountryTree.showOnMap(getGroupByAbsPosition(position), getPositionInGroup(position)); - resetCountryListener(); - mFragment.navigateUpToParent(); + final Pair groupAndPosition = splitAbsolutePosition(position, "showCountry. Cannot get correct positions."); + if (groupAndPosition != null) + { + ActiveCountryTree.showOnMap(groupAndPosition.first, groupAndPosition.second); + resetCountryListener(); + mFragment.navigateUpToParent(); + } } @Override @@ -262,6 +306,7 @@ public class DownloadedAdapter extends BaseDownloadAdapter implements ActiveCoun @Override public void onCountryStatusChanged(int group, int position, int oldStatus, int newStatus) { + updateGroupCounters(); onCountryStatusChanged(getAbsolutePosition(group, position)); } @@ -274,6 +319,42 @@ public class DownloadedAdapter extends BaseDownloadAdapter implements ActiveCoun @Override public void onCountryOptionsChanged(int group, int position, int newOpt, int requestOpt) { + updateGroupCounters(); notifyDataSetChanged(); } + + /** + * Splits absolute position to pair of (group, position in group) + * + * @param position absolute position + * @param errorMessage message for the log if split fails + * @return splitted pair. null if split failed + */ + private Pair splitAbsolutePosition(int position, String errorMessage) + { + final int group = getGroupByAbsPosition(position); + final int positionInGroup = getPositionInGroup(position); + + if (group == INVALID_POSITION || positionInGroup == INVALID_POSITION) + { + handleInvalidPosition(errorMessage, position, group, positionInGroup); + return null; + } + + return new Pair<>(group, positionInGroup); + } + + private void handleInvalidPosition(String message, int position, int group, int positionInGroup) + { + Log.d(TAG, message); + Log.d(TAG, "Current position : " + position); + Log.d(TAG, "Current group : " + group); + Log.d(TAG, "Current position in group : " + positionInGroup); + Log.d(TAG, "InProgress count : " + mInProgressCount); + Log.d(TAG, "Updated count: " + mUpdatedCount); + Log.d(TAG, "Outdated count : " + mOutdatedCount); + + if (BuildConfig.DEBUG) + throw new IllegalStateException(message); + } }