package com.whatscloud.activities; import android.app.AlertDialog; import android.app.Dialog; import android.app.ProgressDialog; import android.content.DialogInterface; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.content.res.Configuration; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.EditText; import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.Toast; import com.actionbarsherlock.app.SherlockActivity; import com.actionbarsherlock.view.Menu; import com.actionbarsherlock.view.MenuItem; import com.bugsense.trace.BugSenseHandler; import com.google.android.gms.ads.AdRequest; import com.google.android.gms.ads.AdSize; import com.google.android.gms.ads.AdView; import com.whatscloud.R; import com.whatscloud.activities.tutorial.DeleteAccount; import com.whatscloud.activities.tutorial.NoRoot; import com.whatscloud.activities.tutorial.SuperuserTutorial; import com.whatscloud.config.ads.AdMob; import com.whatscloud.config.app.WhatsCloud; import com.whatscloud.config.debug.Logging; import com.whatscloud.config.integration.WhatsAppInterface; import com.whatscloud.config.reporting.BugSense; import com.whatscloud.logic.auth.User; import com.whatscloud.logic.sync.SyncStatus; import com.whatscloud.logic.sync.manager.SyncManager; import com.whatscloud.root.RootTools; import com.whatscloud.utils.strings.StringUtils; import com.whatscloud.utils.networking.HTTP; import com.whatscloud.utils.objects.Singleton; import com.whatscloud.ui.dialogs.DialogManager; import com.whatscloud.receivers.SyncScheduler; import org.json.JSONObject; import me.pushy.sdk.Pushy; public class Main extends SherlockActivity { ImageView mIcon; EditText mEncryptionKey; RelativeLayout mAdContainer; public static int MENU_SIGN_OUT = 1; public static int MENU_DELETE_ACCOUNT = 3; public static int MENU_SUPERUSER_TUTORIAL = 2; @Override public void onCreate(Bundle savedInstanceState) { //--------------------------------- // Call super //--------------------------------- super.onCreate(savedInstanceState); //--------------------------------- // Initialize bug tracking //--------------------------------- BugSenseHandler.initAndStartSession(this, BugSense.API_KEY); //-------------------------------- // Make sure we have root! //-------------------------------- if (!RootTools.isRootAvailable()) { //--------------------------------- // Show error //--------------------------------- showNoRootScreen(); //--------------------------------- // Stop execution //--------------------------------- return; } //--------------------------------- // No WhatsApp? //--------------------------------- if ( ! isWhatsAppInstalled() ) { //--------------------------------- // Go to market //--------------------------------- downloadWhatsApp(); //--------------------------------- // Stop execution //--------------------------------- return; } //--------------------------------- // Verify WhatsApp is installed //--------------------------------- if ( ! isWhatsAppInstalled() ) { //--------------------------------- // Go to market //--------------------------------- downloadWhatsApp(); //--------------------------------- // Stop execution //--------------------------------- return; } //----------------------------- // Make sure we are logged in //----------------------------- initializeAccount(); //----------------------------- // Load UI elements //----------------------------- initializeUI(); //--------------------------------- // Initialize advertisements //--------------------------------- initializeAds(); //--------------------------------- // Initialize push notifications //--------------------------------- initializePushListener(); } void initializePushListener() { //----------------------------- // Restart listening, in case // we force-closed the app //----------------------------- Pushy.listen(this); } void initializeAds() { //--------------------------------- // Create an ad view //--------------------------------- AdView adView = new AdView(this); //--------------------------------- // Set size to smart //--------------------------------- adView.setAdSize(AdSize.SMART_BANNER); //--------------------------------- // Set UNIT ID //--------------------------------- adView.setAdUnitId(AdMob.UNIT_ID); //--------------------------------- // Load an advertisement //--------------------------------- adView.loadAd(new AdRequest.Builder().build() ); //--------------------------------- // Remove previous ads (if any) //--------------------------------- mAdContainer.removeAllViews(); //--------------------------------- // Add this ad view //--------------------------------- mAdContainer.addView(adView); } void downloadWhatsApp() { //----------------------------- // Show toast //----------------------------- Toast.makeText(this, getString(R.string.installWhatsApp), Toast.LENGTH_LONG).show(); //----------------------------- // Go to market (May fail!) //----------------------------- try { startActivity( new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + WhatsAppInterface.PACKAGE) ) ); } catch( Exception exc ) { //----------------------------- // Show error dialog //----------------------------- showDialog(DialogManager.NO_WHATSAPP); } //----------------------------- // Finish up //----------------------------- finish(); } void showNoRootScreen() { //----------------------------- // Start splash activity //----------------------------- startActivity(new Intent().setClass(Main.this, NoRoot.class)); //----------------------------- // Exit this one //----------------------------- finish(); } private boolean isWhatsAppInstalled() { //----------------------------- // Get package manager //----------------------------- PackageManager packages = getPackageManager(); try { //----------------------------- // Locate package by name //----------------------------- packages.getPackageInfo(WhatsAppInterface.PACKAGE, PackageManager.GET_ACTIVITIES); //----------------------------- // If we are still here, // the app exists //----------------------------- return true; } catch (Exception exc) { //----------------------------- // Failed - no such package //----------------------------- return false; } } void initializeAccount() { //----------------------------- // Both empty? Go to sign in //----------------------------- if (!User.isSignedIn(this)) { splashScreen(); } } void sync() { //-------------------------------- // Logged in? //-------------------------------- if ( User.isSignedIn(this) ) { //-------------------------------- // Not syncing? //-------------------------------- if ( ! SyncStatus.isSyncing(this) ) { //-------------------------------- // First time? Sync with progress //-------------------------------- if ( ! User.isInitialSyncComplete(this) ) { //-------------------------------- // Show initial dialog //-------------------------------- showInitialSyncDialog(); } else { //-------------------------------- // Sync pending outgoing messages //-------------------------------- new syncPendingMessages().execute(); //-------------------------------- // Sync changes every X seconds //-------------------------------- SyncScheduler.scheduleSync(Main.this); } } } } @Override protected void onResume() { //-------------------------------- // Call parent function //-------------------------------- super.onResume(); //-------------------------------- // Sync WhatsApp //-------------------------------- sync(); } void showInitialSyncDialog() { //-------------------------------- // Create dialog builder //-------------------------------- AlertDialog.Builder builder = new AlertDialog.Builder(this); //-------------------------------- // Set title, message and buttons //-------------------------------- builder.setTitle(R.string.rootAccess).setMessage(R.string.rootAccessDesc).setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { //-------------------------------- // Sync asynchronously //-------------------------------- new InitialSync().execute(); } }).setNegativeButton(R.string.cancel, null); //-------------------------------- // Prevent cancellation //-------------------------------- builder.setCancelable(false); //-------------------------------- // Show the dialog //-------------------------------- builder.show(); } public class InitialSync extends AsyncTask<Integer, String, Integer> { ProgressDialog mLoading; public InitialSync() { //-------------------------------- // Prevent simultaneous sync //-------------------------------- SyncStatus.setSyncing(Main.this, true); //------------------------------- // Register for changes //------------------------------- Singleton.getSettings(Main.this).registerOnSharedPreferenceChangeListener(mPropertyChanged); //-------------------------------- // Progress bar //-------------------------------- mLoading = new ProgressDialog( Main.this ); //-------------------------------- // Prevent cancel //-------------------------------- mLoading.setCancelable(false); //-------------------------------- // Set default message //-------------------------------- mLoading.setMessage(getString(R.string.syncing)); //-------------------------------- // Show the progress dialog //-------------------------------- mLoading.show(); } @Override protected Integer doInBackground(Integer...parameter) { //-------------------------------- // Call upon our sync manager //-------------------------------- SyncManager manager = new SyncManager(Main.this, false); //-------------------------------- // Actually sync! //-------------------------------- try { manager.sync(); } catch( Exception exc ) { //--------------------------------- // Set error message //--------------------------------- DialogManager.setErrorMessage(getString(R.string.syncFailed) + ": " + exc.getMessage() + getString(R.string.syncFailedDesc)); //--------------------------------- // Return hash for unique dialog //--------------------------------- return exc.getMessage().hashCode(); } //-------------------------------- // Initial sync done! //-------------------------------- User.setInitialSyncComplete(Main.this, true); //-------------------------------- // Success! //-------------------------------- return 0; } @Override protected void onPostExecute(Integer errorCode) { //-------------------------------- // No longer syncing //-------------------------------- SyncStatus.setSyncing(Main.this, false); //-------------------------------- // Activity dead? //-------------------------------- if ( isFinishing() ) { return; } //-------------------------------- // Hide loading //-------------------------------- if (mLoading.isShowing()) { mLoading.dismiss(); } //------------------------------- // Unregister for changes //------------------------------- Singleton.getSettings(getBaseContext()).unregisterOnSharedPreferenceChangeListener(mPropertyChanged); //-------------------------------- // Show error //-------------------------------- if ( errorCode == 0 ) { //-------------------------------- // Start syncing every X seconds //-------------------------------- SyncScheduler.scheduleSync(Main.this); //-------------------------------- // Go to superuser tutorial //-------------------------------- superuserTutorialScreen(); } else { //-------------------------------- // Show error //-------------------------------- showDialog(errorCode); } } SharedPreferences.OnSharedPreferenceChangeListener mPropertyChanged = new SharedPreferences.OnSharedPreferenceChangeListener() { @Override public void onSharedPreferenceChanged(SharedPreferences preferences, String key) { //------------------------------- // Register for progress changed //------------------------------- if (key.equalsIgnoreCase("SyncProgress")) { //------------------------------- // Get message //------------------------------- String message = Singleton.getSettings(Main.this).getString("sync_message", getString(R.string.syncing)); //------------------------------- // Update loading text //------------------------------- mLoading.setMessage(message); } } }; } public class SignOutAsync extends AsyncTask<Integer, String, Integer> { ProgressDialog mLoading; public SignOutAsync() { //-------------------------------- // Progress bar //-------------------------------- mLoading = new ProgressDialog( Main.this ); //-------------------------------- // Prevent cancel //-------------------------------- mLoading.setCancelable(false); //-------------------------------- // Set default message //-------------------------------- mLoading.setMessage(getString(R.string.loggingOut)); //-------------------------------- // Show the progress dialog //-------------------------------- mLoading.show(); } @Override protected Integer doInBackground(Integer...parameter) { //--------------------------------- // Try to sign out! //--------------------------------- try { signOut(); } catch( Exception exc ) { //--------------------------------- // Set server message //--------------------------------- DialogManager.setErrorMessage(exc.getMessage()); //--------------------------------- // Return hash for unique dialog //--------------------------------- return exc.getMessage().hashCode(); } //-------------------------------- // Success! //-------------------------------- return 0; } @Override protected void onPostExecute(Integer errorCode) { //-------------------------------- // Activity dead? //-------------------------------- if ( isFinishing() ) { return; } //-------------------------------- // Hide loading //-------------------------------- if (mLoading.isShowing()) { mLoading.dismiss(); } //-------------------------------- // Show error //-------------------------------- if ( errorCode == 0 ) { //---------------------------------- // Show sign in form //---------------------------------- initializeAccount(); } else { //---------------------------------- // Show error //---------------------------------- showDialog(errorCode); } } SharedPreferences.OnSharedPreferenceChangeListener mPropertyChanged = new SharedPreferences.OnSharedPreferenceChangeListener() { @Override public void onSharedPreferenceChanged(SharedPreferences preferences, String key) { //------------------------------- // Register for progress changed //------------------------------- if (key.equalsIgnoreCase("SyncProgress")) { //------------------------------- // Get done and total //------------------------------- int done = Singleton.getSettings(Main.this).getInt("sync_done", 0); int total = Singleton.getSettings(Main.this).getInt("sync_total", 1); //------------------------------- // Update loading text //------------------------------- mLoading.setMessage(getString(R.string.syncing) + " (" + (int) (100 * (double) done / total) + "%)"); } } }; } public class syncPendingMessages extends AsyncTask<Integer, String, Integer> { public syncPendingMessages() { //-------------------------------- // Prevent simultaneous sync //-------------------------------- SyncStatus.setSyncing(Main.this, true); } @Override protected Integer doInBackground(Integer...parameter) { //-------------------------------- // Get back pending messages //-------------------------------- String responseJSON = HTTP.get(WhatsCloud.API_URL + "/messages?do=pending&key=" + User.getAPIKey(Main.this)); //-------------------------------- // Call upon our sync manager //-------------------------------- SyncManager manager = new SyncManager(Main.this, false); //-------------------------------- // Catch exceptions //-------------------------------- try { //-------------------------------- // Actually send the messages //-------------------------------- manager.sendPendingMessages(responseJSON); //-------------------------------- // Sync other things //-------------------------------- manager.sync(); } catch( Exception exc ) { //--------------------------------- // Set error message //--------------------------------- DialogManager.setErrorMessage(getString(R.string.syncFailed) + ": " + exc.getMessage() + getString(R.string.syncFailedDesc)); //--------------------------------- // Return hash for unique dialog //--------------------------------- return exc.getMessage().hashCode(); } //-------------------------------- // Success! //-------------------------------- return 0; } @Override protected void onPostExecute(Integer errorCode) { //-------------------------------- // No longer syncing //-------------------------------- SyncStatus.setSyncing(Main.this, false); //-------------------------------- // Activity dead? //-------------------------------- if ( isFinishing() ) { return; } //-------------------------------- // Show error //-------------------------------- if ( errorCode != 0 ) { showDialog(errorCode); } } } void splashScreen() { //----------------------------- // Start splash activity //----------------------------- startActivity(new Intent().setClass(Main.this, Splash.class)); //----------------------------- // Exit this one //----------------------------- finish(); } void superuserTutorialScreen() { //----------------------------- // Start superuser activity //----------------------------- startActivity(new Intent().setClass(Main.this, SuperuserTutorial.class)); } void deleteAccountScreen() { //----------------------------- // Start activity //----------------------------- startActivity(new Intent().setClass(Main.this, DeleteAccount.class)); //----------------------------- // Done //----------------------------- finish(); } void initializeUI() { //----------------------------- // Set default layout //----------------------------- setContentView(R.layout.main); //----------------------------- // Get icon & ad layout //----------------------------- mIcon = (ImageView)findViewById(R.id.icon); mEncryptionKey = (EditText)findViewById(R.id.encryptionKey); mAdContainer = (RelativeLayout)findViewById(R.id.adContainer); //--------------------------------- // Display encryption key //--------------------------------- mEncryptionKey.setText(User.getEncryptionKey(this)); //-------------------------------- // Set click listeners //-------------------------------- initializeListeners(); } void initializeListeners() { //-------------------------------- // Set app icon click //-------------------------------- mIcon.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { //-------------------------------- // Sync WhatsApp //-------------------------------- sync(); } }); } @Override public void onConfigurationChanged(Configuration newConfig) { //-------------------------------- // Call super function //-------------------------------- super.onConfigurationChanged(newConfig); //--------------------------------- // Reload the Smart Banner //--------------------------------- initializeAds(); } public boolean onCreateOptionsMenu(Menu menu) { //-------------------------------- // Create menu items //-------------------------------- menu.add(0, MENU_SIGN_OUT, 0, getString(R.string.signOut)); menu.add(0, MENU_SUPERUSER_TUTORIAL, 0, getString(R.string.tutorialItem)); menu.add(0, MENU_DELETE_ACCOUNT, 0, getString(R.string.deleteAccount)); //-------------------------------- // Handled //-------------------------------- return true; } public boolean onOptionsItemSelected(MenuItem item) { //-------------------------------- // Did we sign out? //-------------------------------- if (item.getItemId() == MENU_SIGN_OUT) { //-------------------------------- // Sign out of app //-------------------------------- new SignOutAsync().execute(); //-------------------------------- // Handle event //-------------------------------- return true; } //-------------------------------- // Did we click tutorial? //-------------------------------- else if (item.getItemId() == MENU_SUPERUSER_TUTORIAL) { //-------------------------------- // Show tutorial //-------------------------------- superuserTutorialScreen(); //-------------------------------- // Handle event //-------------------------------- return true; } //-------------------------------- // Did we click delete account? //-------------------------------- else if (item.getItemId() == MENU_DELETE_ACCOUNT) { //-------------------------------- // Show delete account //-------------------------------- deleteAccountScreen(); //-------------------------------- // Handle event //-------------------------------- return true; } //-------------------------------- // Unhandled event //-------------------------------- return false; } void signOut() throws Exception { //-------------------------------- // Sign out from server //-------------------------------- String responseJSON = HTTP.get(WhatsCloud.API_URL + "/users?do=logout&key=" + User.getAPIKey(this)); //--------------------------------- // Empty string - no internet //--------------------------------- if ( StringUtils.stringIsNullOrEmpty(responseJSON) ) { //--------------------------------- // Log error //--------------------------------- throw new Exception(getString(R.string.noInternetDesc)); } //----------------------------- // Create a JSON object //----------------------------- JSONObject signInJSON = new JSONObject(responseJSON); //----------------------------- // Did we get back an error? //----------------------------- if ( responseJSON.contains( "error" ) ) { //---------------------------------- // Extract server error //---------------------------------- String serverMessage = signInJSON.get("error").toString(); //-------------------------------- // Log error, but don't stop //-------------------------------- Log.e(Logging.TAG_NAME, serverMessage); } //---------------------------------- // Reset all credentials //---------------------------------- User.saveCredentials(this, null, null, null, null); } @Override protected Dialog onCreateDialog( int resource ) { //--------------------------------- // Create a dialog with error icon //--------------------------------- AlertDialog dialog = new AlertDialog.Builder(this) .setIcon(R.drawable.ic_error) .setPositiveButton(getString(R.string.ok), null) .create(); //----------------------------- // Build dialog message //----------------------------- DialogManager.BuildDialog(dialog, resource, this); //----------------------------- // Return dialog object //---------------------------- return dialog; } }