package com.mercandalli.android.apps.files.main.version;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.mercandalli.android.apps.files.main.network.RetrofitUtils;
import com.mercandalli.android.library.base.precondition.Preconditions;
import java.util.ArrayList;
import java.util.List;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
/**
* A simple manager to manage the current
* {@link com.mercandalli.android.apps.files.BuildConfig#VERSION_CODE}.
*/
public class VersionManager {
@Nullable
private static VersionManager sInstance;
@NonNull
public static VersionManager getInstance(@NonNull final Context context) {
if (sInstance == null) {
sInstance = new VersionManager(context);
}
return sInstance;
}
@NonNull
@SuppressWarnings({"unused", "FieldCanBeLocal"})
private final Context mContextApp;
/**
* The network API.
*/
@NonNull
private final VersionApi mVersionApi;
/**
* Is the update already called.
*/
private boolean mIsUpdateCalledSucceeded = false;
private boolean mIsUpdateNeeded = false;
private boolean mIsUpdateChecking = false;
/**
* A {@link List} of listeners called after {@link #checkIfUpdateNeeded()}.
*/
@NonNull
private final List<UpdateCheckedListener> mUpdateCheckedListeners = new ArrayList<>();
/* package */ VersionManager(@NonNull final Context context) {
Preconditions.checkNotNull(context);
mContextApp = context.getApplicationContext();
mVersionApi = RetrofitUtils.getRetrofit().create(VersionApi.class);
}
/**
* Check if an update is needed. You need to call
* {@link #registerUpdateCheckedListener(UpdateCheckedListener)} and
* {@link #unregisterUpdateCheckedListener(UpdateCheckedListener)}.
*/
public void checkIfUpdateNeeded() {
if (mIsUpdateChecking || mIsUpdateCalledSucceeded && !mIsUpdateNeeded) {
return;
}
mIsUpdateChecking = true;
final Call<VersionResponse> call = mVersionApi.getVersionSupported();
call.enqueue(new Callback<VersionResponse>() {
@Override
public void onResponse(Call<VersionResponse> call, Response<VersionResponse> response) {
if (!response.isSuccessful()) {
mIsUpdateChecking = false;
return;
}
mIsUpdateChecking = false;
mIsUpdateCalledSucceeded = true;
mIsUpdateNeeded = response.body().isUpdateNeeded();
if (mIsUpdateNeeded) {
notifyUpdateNeeded();
}
}
@Override
public void onFailure(Call<VersionResponse> call, Throwable t) {
}
});
}
public boolean registerUpdateCheckedListener(final UpdateCheckedListener updateCheckedListener) {
synchronized (mUpdateCheckedListeners) {
//noinspection SimplifiableIfStatement
if (updateCheckedListener == null || mUpdateCheckedListeners.contains(updateCheckedListener)) {
// We don't allow to register null listener
// And a listener can only be added once.
return false;
}
return mUpdateCheckedListeners.add(updateCheckedListener);
}
}
public boolean unregisterUpdateCheckedListener(final UpdateCheckedListener updateCheckedListener) {
synchronized (mUpdateCheckedListeners) {
return mUpdateCheckedListeners.remove(updateCheckedListener);
}
}
private void notifyUpdateNeeded() {
synchronized (mUpdateCheckedListeners) {
for (int i = 0, size = mUpdateCheckedListeners.size(); i < size; i++) {
mUpdateCheckedListeners.get(i).onUpdateNeeded();
}
}
}
/**
* An simple interface used with {@link #checkIfUpdateNeeded()}.
*/
public interface UpdateCheckedListener {
/**
* Is an update needed. The user should update this app.
*/
void onUpdateNeeded();
}
}