package net.reichholf.dreamdroid.activities.abs;
import android.Manifest;
import android.app.Activity;
import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Base64;
import android.util.Log;
import android.widget.Toast;
import com.squareup.picasso.Picasso;
import com.squareup.picasso.UrlConnectionDownloader;
import net.reichholf.dreamdroid.DreamDroid;
import net.reichholf.dreamdroid.R;
import net.reichholf.dreamdroid.fragment.dialogs.ActionDialog;
import net.reichholf.dreamdroid.fragment.dialogs.PositiveNegativeDialog;
import net.reichholf.dreamdroid.helpers.ExtendedHashMap;
import net.reichholf.dreamdroid.helpers.PiconSyncService;
import net.reichholf.dreamdroid.helpers.Statics;
import net.reichholf.dreamdroid.util.IabException;
import net.reichholf.dreamdroid.util.IabHelper;
import net.reichholf.dreamdroid.util.IabResult;
import net.reichholf.dreamdroid.util.Inventory;
import net.reichholf.dreamdroid.util.Purchase;
import net.reichholf.dreamdroid.util.SkuDetails;
import org.piwik.sdk.DownloadTracker;
import org.piwik.sdk.PiwikApplication;
import org.piwik.sdk.TrackHelper;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.X509TrustManager;
import de.duenndns.ssl.JULHandler;
import de.duenndns.ssl.MemorizingTrustManager;
/**
* Created by Stephan on 06.11.13.
*/
public class BaseActivity extends AppCompatActivity implements ActionDialog.DialogActionListener, SharedPreferences.OnSharedPreferenceChangeListener {
public static final int REQUEST_PERMISSION_WRITE_EXTERNAL_STORAGE = 0;
public static final int REQUEST_PERMISSION_ACCESS_COARSE_LOCATION = 1;
private static String TAG = BaseActivity.class.getSimpleName();
private MemorizingTrustManager mTrustManager;
private IabHelper mIabHelper;
private Inventory mInventory;
private boolean mIabReady;
static {
MemorizingTrustManager.setKeyStoreFile("private", "sslkeys.bks");
}
IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() {
@Override
public void onIabPurchaseFinished(IabResult result, Purchase purchase) {
String text = null;
int response = result.getResponse();
if (response == IabHelper.BILLING_RESPONSE_RESULT_OK) {
Log.i(TAG, String.format("Purchase finished! %s", result.getMessage()));
mIabHelper.queryInventoryAsync(true, mQueryInventoryFinishedListener);
text = getString(R.string.donation_thanks);
} else if (response != IabHelper.BILLING_RESPONSE_RESULT_USER_CANCELED) {
Log.i(TAG, String.format("Purchase FAILED! %s", result.getMessage()));
text = getString(R.string.donation_error, response);
}
Toast t = Toast.makeText(BaseActivity.this, text, Toast.LENGTH_LONG);
t.show();
}
};
IabHelper.OnConsumeMultiFinishedListener mConsumeMultiFinishedListener = new IabHelper.OnConsumeMultiFinishedListener() {
@Override
public void onConsumeMultiFinished(List<Purchase> purchases, List<IabResult> results) {
Log.w(TAG, "Consuming finished!");
}
};
IabHelper.QueryInventoryFinishedListener mQueryInventoryFinishedListener = new IabHelper.QueryInventoryFinishedListener() {
@Override
public void onQueryInventoryFinished(IabResult result, Inventory inv) {
if (result.isSuccess()) {
mInventory = inv;
consumeAll(inv);
}
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
try {
// set location of the keystore
JULHandler.initialize();
JULHandler.setDebugLogSettings(new JULHandler.DebugLogSettings() {
@Override
public boolean isDebugLogEnabled() {
return false;
}
});
// register MemorizingTrustManager for HTTPS
mTrustManager = new MemorizingTrustManager(this);
SSLContext sc = SSLContext.getInstance("TLS");
sc.init(null, new X509TrustManager[]{mTrustManager},
new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(
mTrustManager.wrapHostnameVerifier(HttpsURLConnection.getDefaultHostnameVerifier()));
HttpsURLConnection.setFollowRedirects(false);
Picasso.Builder builder = new Picasso.Builder(getApplicationContext());
builder.downloader(new UrlConnectionDownloader(getApplicationContext()){
@Override
protected HttpURLConnection openConnection(Uri path) throws IOException {
HttpURLConnection connection = super.openConnection(path);
String userinfo = path.getUserInfo();
if(!userinfo.isEmpty()) {
connection.setRequestProperty("Authorization", "Basic " +
Base64.encodeToString(userinfo.getBytes(), Base64.NO_WRAP));
}
return connection;
}
});
try {
Picasso.setSingletonInstance(builder.build());
} catch (IllegalStateException ignored) {}
} catch (Exception e) {
e.printStackTrace();
}
super.onCreate(savedInstanceState);
if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean(
DreamDroid.PREFS_KEY_ENABLE_ANIMATIONS, true)) {
overridePendingTransition(R.anim.activity_open_translate, R.anim.activity_close_scale);
}
initIAB();
initPiwik();
initPermissions(false);
}
private void initIAB() {
if (getApplicationContext().getPackageName().endsWith("amazon"))
return;
mInventory = null;
mIabReady = false;
mIabHelper = new IabHelper(this, DreamDroid.IAB_PUB_KEY);
mIabHelper.enableDebugLogging(true);
mIabHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() {
public void onIabSetupFinished(IabResult result) {
if (!result.isSuccess()) {
// Oh noes, there was a problem.
Log.d(TAG, "Problem setting up In-app Billing: " + result);
String text = result.getMessage();
Toast toast = Toast.makeText(BaseActivity.this, text, Toast.LENGTH_LONG);
toast.show();
mIabReady = false;
return;
}
Log.w(TAG, "In-app Billing is ready!");
mIabReady = true;
ArrayList<String> skuList = new ArrayList<>(Arrays.asList(DreamDroid.SKU_LIST));
mIabHelper.queryInventoryAsync(true, skuList, mQueryInventoryFinishedListener);
}
});
}
public void showPrivacyStatement() {
PositiveNegativeDialog dialog = PositiveNegativeDialog.newInstance(getString(R.string.privacy_statement_title), R.string.privacy_statement, android.R.string.yes, Statics.ACTION_STATISTICS_AGREED, android.R.string.no, Statics.ACTION_STATISTICS_DENIED);
dialog.show(getSupportFragmentManager(), "privacy_statement_dialog");
}
private void initPiwik() {
if (!PreferenceManager.getDefaultSharedPreferences(this).getBoolean(DreamDroid.PREFS_KEY_PRIVACY_STATEMENT_SHOWN, false)) {
showPrivacyStatement();
return;
}
if (!DreamDroid.isTrackingEnabled(this))
return;
// do not send http requests
PiwikApplication papp = (PiwikApplication) getApplication();
papp.getPiwik().setDryRun(false);
TrackHelper.track().download().identifier(DownloadTracker.Extra.APK_CHECKSUM).with(papp.getTracker());
}
private void initPermissions(boolean rationaleShown) {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(this);
sp.registerOnSharedPreferenceChangeListener(this);
int currentTheme = Integer.parseInt(sp.getString("theme_type", "0"));
if (currentTheme != 0)
return;
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_COARSE_LOCATION) && !rationaleShown) {
PositiveNegativeDialog rationale = PositiveNegativeDialog.newInstance(getString(R.string.location_rationale_title), R.string.location_rationale, R.string.ok, Statics.ACTION_LOCATION_RATIONALE_DONE);
FragmentManager fm = getSupportFragmentManager();
rationale.show(fm, "location_rationale");
return;
}
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
REQUEST_PERMISSION_ACCESS_COARSE_LOCATION);
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.i(TAG, "onActivityResult(" + requestCode + "," + resultCode + "," + data);
if (mIabHelper == null) {
Log.i(TAG, "IABUtil not yet initialized.");
} else if (!mIabHelper.handleActivityResult(requestCode, resultCode, data)) {
super.onActivityResult(requestCode, resultCode, data);
} else {
Log.i(TAG, "onActivityResult handled by IABUtil.");
}
List<Fragment> fragments = getSupportFragmentManager().getFragments();
if(fragments == null)
return;
for (Fragment fragment : fragments) {
if (fragment == null)
continue;
fragment.onActivityResult(requestCode, resultCode, data);
}
}
public ExtendedHashMap getIabItems() {
ExtendedHashMap result = new ExtendedHashMap();
if (!mIabReady) {
initIAB();
return result;
}
ArrayList<String> skuList = new ArrayList<>(Arrays.asList(DreamDroid.SKU_LIST));
if (mInventory == null) {
try {
mInventory = mIabHelper.queryInventory(true, skuList);
} catch (IabException e) {
Log.e(TAG, "FAILED TO GET INVENTORY!");
e.printStackTrace();
}
}
if (mInventory == null)
return result;
for (String sku : skuList) {
SkuDetails details = mInventory.getSkuDetails(sku);
if (details == null) {
Log.w(TAG, String.format("Missing SKU Details for %s", sku));
continue;
}
String price = details.getPrice();
result.put(sku, price);
Log.d(TAG, getString(R.string.donate_sum, price));
}
return result;
}
public void purchase(String sku) {
mIabHelper.launchPurchaseFlow(this, sku, Statics.REQUEST_DONATE, mPurchaseFinishedListener);
}
public void consumeAll(Inventory inventory) {
if (inventory == null || mIabHelper == null)
return;
ArrayList<Purchase> purchases = new ArrayList<>();
for (String sku : DreamDroid.SKU_LIST) {
if (inventory.hasPurchase(sku)) {
purchases.add(inventory.getPurchase(sku));
Log.i(TAG, String.format("Consuming %s", sku));
}
}
mIabHelper.consumeAsync(purchases, mConsumeMultiFinishedListener);
}
@Override
public void onPause() {
mTrustManager.unbindDisplayActivity(this);
super.onPause();
if (PreferenceManager.getDefaultSharedPreferences(this).getBoolean(
DreamDroid.PREFS_KEY_ENABLE_ANIMATIONS, true))
overridePendingTransition(R.anim.activity_open_scale, R.anim.activity_close_translate);
}
@Override
public void onResume() {
mTrustManager.bindDisplayActivity(this);
super.onResume();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mIabHelper != null) mIabHelper.dispose();
mIabHelper = null;
PreferenceManager.getDefaultSharedPreferences(this).unregisterOnSharedPreferenceChangeListener(this);
}
@Override
public void onDialogAction(int action, Object details, String dialogTag) {
if (action == Statics.ACTION_STATISTICS_AGREED || action == Statics.ACTION_STATISTICS_DENIED) {
boolean enabled = action == Statics.ACTION_STATISTICS_AGREED;
SharedPreferences.Editor prefs = PreferenceManager.getDefaultSharedPreferences(this).edit();
prefs.putBoolean(DreamDroid.PREFS_KEY_ALLOW_TRACKING, enabled);
prefs.putBoolean(DreamDroid.PREFS_KEY_PRIVACY_STATEMENT_SHOWN, true);
prefs.commit();
initPiwik();
} else if (action == Statics.ACTION_LOCATION_RATIONALE_DONE) {
initPermissions(true);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
boolean granted = grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED;
switch (requestCode) {
case REQUEST_PERMISSION_WRITE_EXTERNAL_STORAGE:
if (granted)
callPiconSyncIntent();
break;
case REQUEST_PERMISSION_ACCESS_COARSE_LOCATION:
if (granted)
recreate();
break;
default:
break;
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
public void startPiconSync() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)
callPiconSyncIntent();
else
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_PERMISSION_WRITE_EXTERNAL_STORAGE);
}
protected void callPiconSyncIntent() {
if (isSyncServiceRunning()) {
Toast.makeText(this, R.string.picon_sync_running, Toast.LENGTH_LONG).show();
return;
}
Intent piconSyncIntent = new Intent(this, PiconSyncService.class);
startService(piconSyncIntent);
Toast.makeText(this, R.string.picon_sync_started, Toast.LENGTH_LONG).show();
}
private boolean isSyncServiceRunning() {
ActivityManager manager = (ActivityManager) getSystemService(Activity.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (PiconSyncService.class.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (DreamDroid.PREFS_KEY_THEME_TYPE.equals(key))
initPermissions(false);
}
public Context getContext() {
return this;
}
}