[android] Fixed review notes

This commit is contained in:
Dmitry Donskoy 2018-05-31 14:25:13 +03:00 committed by Arsentiy Milchakov
parent 0e07e10e42
commit ca292e62a7
15 changed files with 307 additions and 274 deletions

View file

@ -786,8 +786,8 @@ public class DownloadResourcesLegacyActivity extends BaseMwmFragmentActivity
LOGGER.w(TAG, "Attachment not found or io error: " + ex, ex);
} finally
{
Utils.closeStream(input);
Utils.closeStream(output);
Utils.closeSafely(input);
Utils.closeSafely(output);
}
}
else

View file

@ -0,0 +1,48 @@
package com.mapswithme.maps.background;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;
import com.mapswithme.util.CrashlyticsUtils;
import com.mapswithme.util.log.Logger;
import com.mapswithme.util.log.LoggerFactory;
import static com.mapswithme.maps.MwmApplication.backgroundTracker;
public abstract class AbstractLogBroadcastReceiver extends BroadcastReceiver
{
private static final Logger LOGGER = LoggerFactory.INSTANCE.getLogger(LoggerFactory.Type.MISC);
@Override
public final void onReceive(Context context, Intent intent)
{
String action = intent != null ? intent.getAction() : null;
if (!TextUtils.equals(getAssertAction(), action))
{
LOGGER.w(getTag(), "An intent with wrong action detected: " + action);
return;
}
String msg = "onReceive: " + intent + " app in background = "
+ !backgroundTracker().isForeground();
LOGGER.i(getTag(), msg);
CrashlyticsUtils.log(Log.INFO, getTag(), msg);
}
@NonNull
protected String getTag()
{
return getClass().getSimpleName();
}
@NonNull
protected abstract String getAssertAction();
@SuppressWarnings("unused")
public abstract void onReceiveInternal(@NonNull Context context, @NonNull Intent intent);
}

View file

@ -1,36 +1,23 @@
package com.mapswithme.maps.background;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.net.ConnectivityManager;
import android.support.annotation.NonNull;
import com.mapswithme.util.CrashlyticsUtils;
import com.mapswithme.util.log.Logger;
import com.mapswithme.util.log.LoggerFactory;
import static android.net.ConnectivityManager.CONNECTIVITY_ACTION;
import static com.mapswithme.maps.MwmApplication.backgroundTracker;
public class ConnectivityChangedReceiver extends BroadcastReceiver
public class ConnectivityChangedReceiver extends AbstractLogBroadcastReceiver
{
private static final Logger LOGGER = LoggerFactory.INSTANCE.getLogger(LoggerFactory.Type.MISC);
private static final String TAG = ConnectivityChangedReceiver.class.getSimpleName();
@Override
public void onReceive(Context context, Intent intent)
public void onReceiveInternal(@NonNull Context context, @NonNull Intent intent)
{
String action = intent != null ? intent.getAction() : null;
if (!CONNECTIVITY_ACTION.equals(action))
{
LOGGER.w(TAG, "An intent with wrong action detected: " + action);
return;
}
String msg = "onReceive: " + intent + " app in background = "
+ !backgroundTracker().isForeground();
LOGGER.i(TAG, msg);
CrashlyticsUtils.log(Log.INFO, TAG, msg);
NotificationService.startOnConnectivityChanged(context);
}
@NonNull
@Override
protected String getAssertAction()
{
return ConnectivityManager.CONNECTIVITY_ACTION;
}
}

View file

@ -4,13 +4,11 @@ import android.app.DownloadManager;
import android.content.Context;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Pair;
import com.mapswithme.maps.bookmarks.data.BookmarkManager;
import java.io.IOException;
import java.util.Set;
public class BookmarksDownloadManager
@ -20,65 +18,63 @@ public class BookmarksDownloadManager
@NonNull
private final Context mContext;
@Nullable
private final DownloadManager mWrapped;
private BookmarksDownloadManager(@NonNull Context context)
{
mContext = context.getApplicationContext();
mWrapped = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
}
public long enqueueRequest(@NonNull String url) throws IOException
public long enqueueRequest(@NonNull String url)
{
if (mWrapped == null){
throw new IOException("system DownloadManager is null");
DownloadManager downloadManager =
(DownloadManager) mContext.getSystemService(Context.DOWNLOAD_SERVICE);
if (downloadManager == null)
{
throw new NullPointerException(
"Download manager is null, failed to download url = " + url);
}
Pair<Uri, Uri> uriPair = onPrepareUriPair(url);
Pair<Uri, Uri> uriPair = prepareUriPair(url);
Uri srcUri = uriPair.first;
Uri dstUri = uriPair.second;
String title = getTitle(srcUri);
String title = makeTitle(srcUri);
DownloadManager.Request request = new DownloadManager
.Request(dstUri)
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE)
.setTitle(title)
.setDestinationInExternalFilesDir(
mContext,
null,
dstUri.getLastPathSegment());
return mWrapped.enqueue(request);
.setDestinationInExternalFilesDir(mContext,null, dstUri.getLastPathSegment());
return downloadManager.enqueue(request);
}
@NonNull
private String getTitle(Uri srcUri)
private static String makeTitle(@NonNull Uri srcUri)
{
String title;
return TextUtils.isEmpty((title = srcUri.getQueryParameter(QUERY_PARAM_NAME_KEY)))
? srcUri.getQueryParameter(QUERY_PARAM_ID_KEY)
: title;
String title = srcUri.getQueryParameter(QUERY_PARAM_NAME_KEY);
return TextUtils.isEmpty(title) ? srcUri.getQueryParameter(QUERY_PARAM_ID_KEY) : title;
}
private Pair<Uri, Uri> onPrepareUriPair(String url)
@NonNull
private static Pair<Uri, Uri> prepareUriPair(@NonNull String url)
{
Uri srcUri = Uri.parse(url);
String fileId = srcUri.getQueryParameter(QUERY_PARAM_ID_KEY);
if (TextUtils.isEmpty(fileId)){
throw new IllegalArgumentException("query param id not found");
}
if (TextUtils.isEmpty(fileId))
throw new IllegalArgumentException("File id not found");
String downloadUrl = BookmarkManager.INSTANCE.getCatalogDownloadUrl(fileId);
Uri.Builder builder = Uri.parse(downloadUrl).buildUpon();
Set<String> paramNames = srcUri.getQueryParameterNames();
for (String each : paramNames){
for (String each : srcUri.getQueryParameterNames())
{
builder.appendQueryParameter(each, srcUri.getQueryParameter(each));
}
Uri dstUri = builder.build();
return new Pair<>(srcUri, dstUri);
}
public static BookmarksDownloadManager from(Context context)
@NonNull
public static BookmarksDownloadManager from(@NonNull Context context)
{
return new BookmarksDownloadManager(context);
}

View file

@ -1,152 +0,0 @@
package com.mapswithme.maps.bookmarks;
import android.app.DownloadManager;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.mapswithme.maps.bookmarks.data.BookmarkManager;
import com.mapswithme.util.Utils;
import java.io.IOException;
class GetFileMetaDataTask extends AsyncTask<Intent, Void, OperationStatus<GetFileMetaDataTask.Result,
GetFileMetaDataTask.Error>>
{
@NonNull
private final DownloadManager mDownloadManager;
private GetFileMetaDataTask(@NonNull DownloadManager downloadManager)
{
mDownloadManager = downloadManager;
}
@Override
protected OperationStatus<Result, Error> doInBackground(Intent... intents)
{
Intent intent = intents[0];
try
{
Result result = doInBackgroundInternal(intent);
return new OperationStatus<>(result, null);
}
catch (IOException e)
{
return new OperationStatus<>(null, new Error(e));
}
}
@Override
protected void onPostExecute(OperationStatus<Result, Error> status)
{
if (status.isOk())
{
Result result = status.getResult();
BookmarkManager.INSTANCE.importFromCatalog(result.getArchiveId(), result.getFilePath());
}
}
public static GetFileMetaDataTask create(DownloadManager manager)
{
return new GetFileMetaDataTask(manager);
}
public static class Result
{
@Nullable
private final String mFilePath;
@Nullable
private final String mArchiveId;
public Result(@Nullable String filePath, @Nullable String archiveId)
{
mFilePath = filePath;
mArchiveId = archiveId;
}
@Nullable
public String getFilePath()
{
return mFilePath;
}
@Nullable
public String getArchiveId()
{
return mArchiveId;
}
}
public static class Error
{
@Nullable
private Throwable mThrowable;
public Error(@Nullable Throwable throwable)
{
mThrowable = throwable;
}
@Nullable
public Throwable getThrowable()
{
return mThrowable;
}
}
@NonNull
private Result doInBackgroundInternal(@NonNull Intent intent) throws IOException
{
Cursor cursor = null;
try
{
final long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0);
DownloadManager.Query query = new DownloadManager.Query().setFilterById(id);
cursor = mDownloadManager.query(query);
if (cursor.moveToFirst())
{
String filePath = getFilePath(cursor);
String archiveId = getArchiveId(cursor);
return new Result(filePath, archiveId);
}
else
{
throw new IOException("Failed to move the cursor at first row");
}
}
finally
{
Utils.closeSafely(cursor);
}
}
private String getFilePath(Cursor cursor) throws IOException
{
return getColumnValue(cursor, DownloadManager.COLUMN_LOCAL_FILENAME);
}
private String getArchiveId(Cursor cursor) throws IOException
{
return Uri.parse(getColumnValue(cursor, DownloadManager.COLUMN_URI)).getLastPathSegment();
}
@Nullable
private String getColumnValue(@NonNull Cursor cursor, @NonNull String columnName)
throws IOException
{
int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
if (status == DownloadManager.STATUS_SUCCESSFUL)
{
return cursor.getString(cursor.getColumnIndex(columnName));
}
else
{
throw new IOException(new StringBuilder().append("Failed to download archive, status code = ")
.append(status)
.toString());
}
}
}

View file

@ -2,30 +2,33 @@ package com.mapswithme.maps.bookmarks;
import android.support.annotation.Nullable;
public class OperationStatus<R, E> {
@Nullable private final R mResult;
@Nullable private final E mError;
public class OperationStatus<R, E>
{
@Nullable
private final R mResult;
@Nullable
private final E mError;
OperationStatus(@Nullable R result, @Nullable E error) {
OperationStatus(@Nullable R result, @Nullable E error)
{
mResult = result;
mError = error;
}
public boolean isOk() {
public boolean isOk()
{
return mError == null;
}
public boolean isNotOk() {
return !isOk();
}
@Nullable
public R getResult() {
public R getResult()
{
return mResult;
}
@Nullable
public E getError() {
public E getError()
{
return mError;
}
}

View file

@ -4,15 +4,25 @@ import android.app.DownloadManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
public class SystemDownloadCompletedReceiver extends BroadcastReceiver
import com.mapswithme.maps.background.AbstractLogBroadcastReceiver;
public class SystemDownloadCompletedReceiver extends AbstractLogBroadcastReceiver
{
@NonNull
@Override
public void onReceive(Context context, Intent intent)
protected String getAssertAction()
{
return DownloadManager.ACTION_DOWNLOAD_COMPLETE;
}
@Override
public void onReceiveInternal(@NonNull Context context, @Nullable Intent intent)
{
DownloadManager manager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
if (manager == null
|| intent == null
if (manager == null || intent == null
|| !DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(intent.getAction()))
{
return;

View file

@ -1,33 +1,136 @@
package com.mapswithme.maps.bookmarks;
import android.app.DownloadManager;
import android.app.Service;
import android.app.IntentService;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.database.Cursor;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.widget.Toast;
public class SystemDownloadCompletedService extends Service
import com.mapswithme.maps.R;
import com.mapswithme.maps.bookmarks.data.BookmarkManager;
import com.mapswithme.maps.bookmarks.data.Error;
import com.mapswithme.maps.bookmarks.data.Result;
import com.mapswithme.util.Utils;
import com.mapswithme.util.concurrency.UiThread;
import java.io.IOException;
public class SystemDownloadCompletedService extends IntentService
{
@Nullable
@Override
public IBinder onBind(Intent intent)
public SystemDownloadCompletedService()
{
return null;
super("GetFileMetaDataService");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
requestArchiveMetadata(intent);
return START_REDELIVER_INTENT;
}
private void requestArchiveMetadata(Intent intent)
protected void onHandleIntent(@Nullable Intent intent)
{
DownloadManager manager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
if (manager != null)
if (manager == null)
throw new IllegalStateException("Failed to get a download manager");
final OperationStatus<Result, Error> status = doInBackground(manager, intent);
UiThread.run(new NotifyCoreTask(getApplicationContext(), status));
}
@NonNull
private OperationStatus<Result, Error> doInBackground(@NonNull DownloadManager manager,
@Nullable Intent intent)
{
if (intent == null)
{
GetFileMetaDataTask.create(manager).execute(intent);
NullPointerException npe = new NullPointerException("Intent is null");
return new OperationStatus<>(null, new Error(npe));
}
try
{
Result result = doInBackgroundInternal(manager, intent);
return new OperationStatus<>(result, null);
}
catch (IOException e)
{
return new OperationStatus<>(null, new Error(e));
}
}
@NonNull
private static Result doInBackgroundInternal(@NonNull DownloadManager manager,
@NonNull Intent intent) throws IOException
{
Cursor cursor = null;
try
{
final long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0);
DownloadManager.Query query = new DownloadManager.Query().setFilterById(id);
cursor = manager.query(query);
if (cursor.moveToFirst())
{
return new Result(getFilePath(cursor), getArchiveId(cursor));
}
throw new IOException("Failed to move the cursor at first row");
}
finally
{
Utils.closeSafely(cursor);
}
}
@Nullable
private static String getFilePath(@NonNull Cursor cursor) throws IOException
{
return getColumnValue(cursor, DownloadManager.COLUMN_LOCAL_FILENAME);
}
@Nullable
private static String getArchiveId(@NonNull Cursor cursor) throws IOException
{
return Uri.parse(getColumnValue(cursor, DownloadManager.COLUMN_URI)).getLastPathSegment();
}
@Nullable
private static String getColumnValue(@NonNull Cursor cursor, @NonNull String columnName)
throws IOException
{
int status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
if (status == DownloadManager.STATUS_SUCCESSFUL)
{
return cursor.getString(cursor.getColumnIndex(columnName));
}
throw new IOException(new StringBuilder().append("Failed to download archive, status code = ")
.append(status)
.toString());
}
private static class NotifyCoreTask implements Runnable
{
@NonNull
private final Context mAppContext;
@NonNull
private final OperationStatus<Result, Error> mStatus;
private NotifyCoreTask(@NonNull Context applicationContext,
@NonNull OperationStatus<Result, Error> status)
{
mAppContext = applicationContext;
mStatus = status;
}
@Override
public void run()
{
if (mStatus.isOk())
{
Result result = mStatus.getResult();
BookmarkManager.INSTANCE.importFromCatalog(result.getArchiveId(), result.getFilePath());
}
else
{
Toast.makeText(mAppContext, R.string.download_failed, Toast.LENGTH_SHORT).show();
}
}
}
}

View file

@ -0,0 +1,20 @@
package com.mapswithme.maps.bookmarks.data;
import android.support.annotation.Nullable;
public class Error
{
@Nullable
private final Throwable mThrowable;
public Error(@Nullable Throwable throwable)
{
mThrowable = throwable;
}
@Nullable
public Throwable getThrowable()
{
return mThrowable;
}
}

View file

@ -0,0 +1,29 @@
package com.mapswithme.maps.bookmarks.data;
import android.support.annotation.Nullable;
public class Result
{
@Nullable
private final String mFilePath;
@Nullable
private final String mArchiveId;
public Result(@Nullable String filePath, @Nullable String archiveId)
{
mFilePath = filePath;
mArchiveId = archiveId;
}
@Nullable
public String getFilePath()
{
return mFilePath;
}
@Nullable
public String getArchiveId()
{
return mArchiveId;
}
}

View file

@ -3,6 +3,12 @@ package com.mapswithme.maps.downloader;
import android.os.AsyncTask;
import android.util.Base64;
import com.mapswithme.util.Constants;
import com.mapswithme.util.StringUtils;
import com.mapswithme.util.Utils;
import com.mapswithme.util.log.Logger;
import com.mapswithme.util.log.LoggerFactory;
import java.io.BufferedInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
@ -14,12 +20,6 @@ import java.util.Map;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import com.mapswithme.util.Constants;
import com.mapswithme.util.StringUtils;
import com.mapswithme.util.Utils;
import com.mapswithme.util.log.Logger;
import com.mapswithme.util.log.LoggerFactory;
@SuppressWarnings("unused")
class ChunkTask extends AsyncTask<Void, byte[], Boolean>
{
@ -176,7 +176,7 @@ class ChunkTask extends AsyncTask<Void, byte[], Boolean>
os.write(mPostBody);
os.flush();
mPostBody = null;
Utils.closeStream(os);
Utils.closeSafely(os);
}
if (isCancelled())
@ -262,7 +262,7 @@ class ChunkTask extends AsyncTask<Void, byte[], Boolean>
if (ret < 0)
mHttpErrorCode = IO_ERROR;
Utils.closeStream(stream);
Utils.closeSafely(stream);
return (ret == 0);
}

View file

@ -131,7 +131,7 @@ final class StorageUtils
LOGGER.w(TAG, "Can't read file: " + file, e);
} finally
{
Utils.closeStream(reader);
Utils.closeSafely(reader);
}
}
@ -210,8 +210,8 @@ final class StorageUtils
}
} finally
{
Utils.closeStream(inputChannel);
Utils.closeStream(outputChannel);
Utils.closeSafely(inputChannel);
Utils.closeSafely(outputChannel);
}
}

View file

@ -121,8 +121,8 @@ public final class HttpUploader
}
finally
{
Utils.closeStream(writer);
Utils.closeStream(reader);
Utils.closeSafely(writer);
Utils.closeSafely(reader);
if (connection != null)
connection.disconnect();
}
@ -174,7 +174,7 @@ public final class HttpUploader
}
finally
{
Utils.closeStream(reader);
Utils.closeSafely(reader);
}
return null;
}
@ -237,7 +237,7 @@ public final class HttpUploader
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1)
outputStream.write(buffer, 0, bytesRead);
Utils.closeStream(inputStream);
Utils.closeSafely(inputStream);
}
private void writeEndPart(@NonNull PrintWriter writer)

View file

@ -64,20 +64,6 @@ public class Utils
private Utils() {}
public static void closeStream(@Nullable Closeable stream)
{
if (stream != null)
{
try
{
stream.close();
} catch (final IOException e)
{
LOGGER.e(TAG, "Can't close stream", e);
}
}
}
public static boolean isAmazonDevice()
{
return "Amazon".equalsIgnoreCase(Build.MANUFACTURER);
@ -233,28 +219,31 @@ public class Utils
}
}
public static <T> T castTo(Object instance)
@NonNull
public static <T> T castTo(@NonNull Object instance)
{
return (T)instance;
//noinspection unchecked
return (T) instance;
}
public static void closeSafely(Closeable... closeable)
public static void closeSafely(@NonNull Closeable... closeable)
{
for (Closeable each : closeable){
if (each != null){
for (Closeable each : closeable)
{
if (each != null)
{
try
{
each.close();
}
catch (IOException e)
{
LOGGER.e(TAG, "there's something wrong = " + e);
LOGGER.e(TAG, "Failed to close '" + each + "'" , e);
}
}
}
}
public static void sendSupportMail(@NonNull Activity activity, @NonNull String subject)
{
LoggerFactory.INSTANCE.zipLogs(new OnZipCompletedCallback(activity, subject));

View file

@ -149,8 +149,8 @@ class ZipLogsTask implements Runnable
}
finally
{
Utils.closeStream(writer);
Utils.closeStream(reader);
Utils.closeSafely(writer);
Utils.closeSafely(reader);
}
}
}