package org.witness.informacam.app;
import info.guardianproject.cacheword.CacheWordHandler;
import info.guardianproject.cacheword.ICacheWordSubscriber;
import info.guardianproject.odkparser.widgets.ODKSeekBar.OnMediaRecorderStopListener;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Vector;
import org.witness.informacam.InformaCam;
import org.witness.informacam.app.screens.CameraFragment;
import org.witness.informacam.app.screens.GalleryFragment;
import org.witness.informacam.app.screens.HomeFragment;
import org.witness.informacam.app.screens.UserManagementFragment;
import org.witness.informacam.app.screens.menus.MediaActionMenu;
import org.witness.informacam.app.screens.popups.PopupClickListener;
import org.witness.informacam.app.screens.popups.TextareaPopup;
import org.witness.informacam.app.utils.Constants;
import org.witness.informacam.app.utils.Constants.App.Home;
import org.witness.informacam.app.utils.Constants.Codes;
import org.witness.informacam.app.utils.Constants.Codes.Routes;
import org.witness.informacam.app.utils.Constants.HomeActivityListener;
import org.witness.informacam.app.utils.Constants.Preferences;
import org.witness.informacam.app.utils.actions.ContextMenuAction;
import org.witness.informacam.models.media.IMedia;
import org.witness.informacam.models.notifications.INotification;
import org.witness.informacam.models.organizations.IOrganization;
import org.witness.informacam.ui.CameraActivity;
import org.witness.informacam.utils.Constants.InformaCamEventListener;
import org.witness.informacam.utils.Constants.ListAdapterListener;
import org.witness.informacam.utils.Constants.Models;
import android.annotation.SuppressLint;
import android.app.ActionBar;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.drawable.BitmapDrawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.PopupWindow;
import android.widget.Toast;
@SuppressLint("HandlerLeak")
public class HomeActivity extends FragmentActivity implements HomeActivityListener, InformaCamEventListener,
ListAdapterListener, OnMediaRecorderStopListener, ICacheWordSubscriber
{
Intent init, route;
private final static String LOG = Constants.App.Home.LOG;
private static final int USE_USER_MANAGEMENT_FRAGMENT = 0;
private static final int INDEX_MAIN = 0;
private static final int INDEX_USER_MANAGEMENT = 1;
private static final int INDEX_GALLERY = 1 + USE_USER_MANAGEMENT_FRAGMENT;
private static final int INDEX_CAMERA = 2 + USE_USER_MANAGEMENT_FRAGMENT;
private String lastLocale = null;
List<Fragment> fragments = new Vector<Fragment>();
HomeFragment mainFragment;
GalleryFragment galleryFragment;
Fragment userManagementFragment, cameraFragment;
boolean initGallery = false;
int visibility = View.VISIBLE;
ViewPager viewPager;
TabPager pager;
InformaCam informaCam;
MediaActionMenu mam;
// WaitPopup waiter;
Intent toEditor, toCamera;
CacheWordHandler cacheWord;
private boolean mFirstTime = false;
@SuppressWarnings("unused")
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
cacheWord = new CacheWordHandler(this, this);
cacheWord.connectToService();
informaCam = (InformaCam)getApplication();
informaCam.setEventListener(this);
if(PreferenceManager.getDefaultSharedPreferences(this).getBoolean("prefBlockScreenshots", false))
{
getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE,
WindowManager.LayoutParams.FLAG_SECURE);
}
setContentView(R.layout.activity_home);
try
{
Iterator<String> i = savedInstanceState.keySet().iterator();
while (i.hasNext())
{
String outState = i.next();
if (outState.equals(Home.TAG) && savedInstanceState.getBoolean(Home.TAG))
{
initGallery = true;
}
}
}
catch (NullPointerException e)
{
}
toEditor = new Intent(this, EditorActivity.class);
toCamera = new Intent(this, CameraActivity.class);
route = null;
mainFragment = (HomeFragment) Fragment.instantiate(this, HomeFragment.class.getName());
if (USE_USER_MANAGEMENT_FRAGMENT == 1)
userManagementFragment = Fragment.instantiate(this, UserManagementFragment.class.getName());
galleryFragment = (GalleryFragment) Fragment.instantiate(this, GalleryFragment.class.getName());
cameraFragment = Fragment.instantiate(this, CameraFragment.class.getName());
fragments.add(mainFragment);
if (USE_USER_MANAGEMENT_FRAGMENT == 1)
fragments.add(userManagementFragment);
fragments.add(galleryFragment);
fragments.add(cameraFragment);
init = getIntent();
initLayout();
launchMain();
}
@Override
public void onResume()
{
super.onResume();
cacheWord.reattach();
updateLocale();
if (informaCam.getCredentialManagerStatus() == org.witness.informacam.utils.Constants.Codes.Status.LOCKED)
{
informaCam.attemptLogout();
finish();
return;
}
informaCam.setEventListener(this);
informaCam.setListAdapterListener(this);
if(getIntent().hasExtra(Constants.Codes.Extras.CHANGE_LOCALE)) {
getIntent().removeExtra(Constants.Codes.Extras.CHANGE_LOCALE);
}
if (getIntent().hasExtra(Constants.Codes.Extras.GENERATING_KEY)) {
mFirstTime = true;
mainFragment.setIsGeneratingKey(getIntent().getBooleanExtra(Constants.Codes.Extras.GENERATING_KEY, false));
getIntent().removeExtra(Constants.Codes.Extras.GENERATING_KEY);
} else {
mainFragment.setIsGeneratingKey(false);
}
informaCam = (InformaCam) getApplication();
if (init.getData() != null)
{
final Uri ictdURI = init.getData();
mHandlerUI.post(new Runnable() {
@SuppressWarnings("unused")
@Override
public void run() {
IOrganization organization = informaCam.installICTD(ictdURI, mHandlerUI, HomeActivity.this);
if(organization != null) {
if (USE_USER_MANAGEMENT_FRAGMENT == 1)
viewPager.setCurrentItem(INDEX_USER_MANAGEMENT);
else
viewPager.setCurrentItem(INDEX_MAIN);
}
else
{
Toast.makeText(HomeActivity.this, getString(org.witness.informacam.R.string.could_not_import_ictd), Toast.LENGTH_LONG).show();
}
}
});
}
if (mFirstTime)
{
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which){
case DialogInterface.BUTTON_POSITIVE:
Intent intent = new Intent(HomeActivity.this,WebActivity.class);
startActivity(intent);
mFirstTime = false;
break;
case DialogInterface.BUTTON_NEGATIVE:
//No button clicked
break;
}
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage(R.string.welcome_to_camerav_would_you_like_to_read_the_user_guide_).setPositiveButton(android.R.string.yes, dialogClickListener)
.setNegativeButton(android.R.string.no, dialogClickListener).show();
}
}
private void updateLocale()
{
String localeCode = PreferenceManager.getDefaultSharedPreferences(this).getString("iw_language", "0");
int localeIdx = Integer.parseInt(localeCode);
String[] lang = getResources().getStringArray(org.witness.informacam.R.array.locales);
String[] localeString = lang[localeIdx].split("-");
Locale locale = null;
if (localeString.length == 1)
locale = new Locale(localeString[0]);
else
locale = new Locale(localeString[0],localeString[1]);
Locale.setDefault(locale);
Configuration config = getResources().getConfiguration();
if (Build.VERSION.SDK_INT >= 17)
config.setLocale(locale);
else
config.locale = locale;
getResources().updateConfiguration(config, getResources().getDisplayMetrics());
if (lastLocale != null && (!lastLocale.equals(localeCode)))
{
startActivity(new Intent(this,HomeActivity.class));
finish();
return;
}
lastLocale = localeCode;
}
private void initLayout()
{
pager = new TabPager(getSupportFragmentManager());
viewPager = (ViewPager) findViewById(R.id.view_pager_root);
viewPager.setAdapter(pager);
viewPager.setOnPageChangeListener(pager);
launchMain();
}
@Override
public void onSaveInstanceState(Bundle outState)
{
outState.putBoolean(Home.TAG, true);
super.onSaveInstanceState(outState);
}
@Override
public void onPause()
{
super.onPause();
cacheWord.detach();
}
@Override
public void onDestroy()
{
super.onDestroy();
cacheWord.disconnectFromService();
}
@SuppressWarnings("deprecation")
@Override
public int[] getDimensions()
{
Display display = getWindowManager().getDefaultDisplay();
return new int[] { display.getWidth(), display.getHeight() };
}
@Override
public void launchCamera() {
resetActionBar();
boolean externalCamera = PreferenceManager.getDefaultSharedPreferences(this).getBoolean("prefExternalCamera", false);
if (toCamera.hasExtra(org.witness.informacam.utils.Constants.Codes.Extras.CAMERA_TYPE))
toCamera.removeExtra(org.witness.informacam.utils.Constants.Codes.Extras.CAMERA_TYPE);
if (!externalCamera)
toCamera.putExtra(
org.witness.informacam.utils.Constants.Codes.Extras.CAMERA_TYPE,
org.witness.informacam.utils.Constants.App.Camera.Type.SECURE_CAMERA);
else
toCamera.putExtra(
org.witness.informacam.utils.Constants.Codes.Extras.CAMERA_TYPE,
org.witness.informacam.utils.Constants.App.Camera.Type.CAMERA);
route = toCamera;
startActivityForResult(toCamera, Routes.CAMERA);
}
@Override
public void launchEditor(IMedia media)
{
toEditor.putExtra(Codes.Extras.EDIT_MEDIA, media._id);
startActivityForResult(toEditor, Routes.EDITOR);
route = toEditor;
}
@Override
public void getContextualMenuFor(final INotification notification)
{
List<ContextMenuAction> actions = new Vector<ContextMenuAction>();
ContextMenuAction action = new ContextMenuAction();
action.label = getResources().getString(R.string.delete);
action.ocl = new OnClickListener()
{
@Override
public void onClick(View v)
{
mam.cancel();
informaCam.notificationsManifest.getById(notification._id).delete();
if (userManagementFragment != null)
((ListAdapterListener) userManagementFragment).updateAdapter(Codes.Adapters.NOTIFICATIONS);
}
};
actions.add(action);
if (notification.canRetry)
{
action = new ContextMenuAction();
action.label = getResources().getString(R.string.retry);
action.ocl = new OnClickListener()
{
@Override
public void onClick(View v)
{
mam.cancel();
try {
notification.retry();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
actions.add(action);
}
mam = new MediaActionMenu(this, actions);
mam.Show();
}
@Override
public void getContextualMenuFor(final IOrganization organization)
{
List<ContextMenuAction> actions = new Vector<ContextMenuAction>();
ContextMenuAction action = new ContextMenuAction();
action.label = getResources().getString(R.string.send_message);
action.ocl = new OnClickListener()
{
@Override
public void onClick(View v)
{
mam.cancel();
new TextareaPopup(HomeActivity.this, organization)
{
@Override
public void cancel()
{
// TODO: send a message...
super.cancel();
}
};
}
};
actions.add(action);
action = new ContextMenuAction();
action.label = getResources().getString(R.string.resend_credentials);
action.ocl = new OnClickListener()
{
@Override
public void onClick(View v)
{
mam.cancel();
informaCam.resendCredentials(organization);
Toast.makeText(HomeActivity.this, getResources().getString(R.string.you_have_resent_your_credentials_to_x, organization.organizationName),
Toast.LENGTH_LONG).show();
}
};
actions.add(action);
mam = new MediaActionMenu(this, actions);
mam.Show();
}
@SuppressWarnings("deprecation")
@Override
public void getContextualMenuFor(final IMedia media, View anchorView)
{
try
{
if (anchorView == null)
return; // Need an anchor view
LayoutInflater inflater = LayoutInflater.from(this);
ViewGroup anchorRoot = null;
anchorRoot = (ViewGroup) anchorView.getRootView();
View content = inflater.inflate(R.layout.popup_media_context_menu, anchorRoot, false);
content.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
PopupWindow mMenuPopup = new PopupWindow(content, content.getMeasuredWidth(), content.getMeasuredHeight(), true);
// Delete
//
View btnDelete = content.findViewById(R.id.btnDeleteMedia);
btnDelete.setOnClickListener(new PopupClickListener(mMenuPopup)
{
@Override
protected void onSelected()
{
if ((informaCam.mediaManifest.getById(media._id)).delete())
{
updateAdapter(0);
}
}
});
/**
// Share
//
View btnShare = content.findViewById(R.id.btnShareMedia);
btnShare.setOnClickListener(new PopupClickListener(mMenuPopup)
{
@Override
protected void onSelected()
{
new SharePopup(HomeActivity.this, informaCam.mediaManifest.getById(media._id), true, false);
}
}); */
mMenuPopup.setOutsideTouchable(true);
mMenuPopup.setBackgroundDrawable(new BitmapDrawable());
mMenuPopup.showAsDropDown(anchorView, anchorView.getWidth(), -anchorView.getHeight());
mMenuPopup.getContentView().setOnClickListener(new PopupClickListener(mMenuPopup));
}
catch (Exception e)
{
e.printStackTrace();
}
}
@Override
public void onBackPressed()
{
if (viewPager.getCurrentItem() != INDEX_MAIN)
{
viewPager.setCurrentItem(INDEX_MAIN);
}
else
{
setResult(Activity.RESULT_CANCELED);
finish();
}
}
@Override
public void logoutUser()
{
setResult(Activity.RESULT_CANCELED, getIntent().putExtra(Codes.Extras.LOGOUT_USER, true));
finish();
}
@Override
public void onActivityResult(int requestCode, int responseCode, Intent data) {
informaCam.setEventListener(this);
informaCam.setListAdapterListener(this);
if(responseCode == Activity.RESULT_OK) {
switch(requestCode) {
case Codes.Routes.CAMERA:
viewPager.setCurrentItem(INDEX_GALLERY);
informaCam.mediaManifest.sortBy(Models.IMediaManifest.Sort.DATE_DESC);
/*
* XXX: Other developers, take note:
*
* the returned media can be JSONified. It represents the media
* has been captured, but that may or may not have been
* processed.
*
* InformaCam will send a message whenever a new media item has
* been processed. The message contains the
* Codes.Extras.Messages.DCIM.ADD code, which is handled by
* "onUpdate()"
*/
//IDCIMSerializable returnedMedia = (IDCIMSerializable) data.getSerializableExtra(Codes.Extras.RETURNED_MEDIA);
//Logger.d(LOG, "new dcim:\n" + returnedMedia.asJson().toString());
//if(!returnedMedia.dcimList.isEmpty()) {
// setPending(returnedMedia.dcimList.size(), 0);
// }
// informaCam.stopInforma(); //camera activity handles this
route = null;
break;
case Codes.Routes.LOGOUT:
logoutUser();
break;
case Codes.Routes.EDITOR:
//informaCam.stopInforma();
route = null;
break;
case Codes.Routes.WIPE:
getIntent().putExtra(Codes.Extras.PERFORM_WIPE, true);
logoutUser();
break;
case Routes.WIZARD:
updateLocale();
break;
}
}
}
class TabPager extends FragmentStatePagerAdapter implements OnPageChangeListener
{
public TabPager(FragmentManager fragmentManager)
{
super(fragmentManager);
}
@Override
public void onPageScrollStateChanged(int state)
{
if (state == ViewPager.SCROLL_STATE_IDLE && viewPager.getCurrentItem() == INDEX_GALLERY)
{
// Landed in the gallery. Make sure data is initialized/loaded now!
galleryFragment.initData();
}
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2)
{
}
@Override
public void onPageSelected(int page)
{
// tabHost.setCurrentTab(page);
if (page == INDEX_CAMERA)
{
launchCamera();
} else {
//updateAdapter(0);
}
supportInvalidateOptionsMenu();
}
@Override
public Fragment getItem(int which)
{
return fragments.get(which);
}
@Override
public int getCount()
{
return fragments.size();
}
}
/*
private void routeUs()
{
if (informaCam.informaService != null)
doRouteUs();
else
informaCam.startInforma();
}
private void doRouteUs()
{
if (route != null)
{
if (route.equals(toEditor))
{
startActivityForResult(toEditor, Routes.EDITOR);
}
else if (route.equals(toCamera))
{
startActivityForResult(toCamera, Routes.CAMERA);
}
}
}*/
@Override
public void waiter(boolean show)
{
/*
* if(show) { waiter = new WaitPopup(this); } else { if(waiter != null)
* { waiter.cancel(); } }
*/
}
@Override
public void updateData(INotification notification, Message message)
{
}
@Override
public void updateData(IOrganization organization, Message message)
{
}
@Override
public void updateAdapter(int which)
{
if (informaCam.getCredentialManagerStatus() == org.witness.informacam.utils.Constants.Codes.Status.UNLOCKED)
{
for (Fragment f : fragments)
{
if (f instanceof ListAdapterListener)
{
((ListAdapterListener) f).updateAdapter(which);
}
}
}
}
@Override
public void setPending(int numPending, int numCompleted)
{
if (informaCam.getCredentialManagerStatus() == org.witness.informacam.utils.Constants.Codes.Status.UNLOCKED)
{
//Log.d(LOG, "Set pending: " + numPending + " and completed: " + numCompleted);
for (Fragment f : fragments)
{
if (f instanceof ListAdapterListener)
{
((ListAdapterListener) f).setPending(numPending, numCompleted);
}
}
}
}
@Override
public void setLocale(String newLocale)
{
lastLocale = newLocale;
}
@Override
public String getLocale()
{
return lastLocale;
}
@Override
public void onUpdate(final Message message)
{
int code = message.getData().getInt(Codes.Extras.MESSAGE_CODE);
switch (code)
{
case org.witness.informacam.utils.Constants.Codes.Messages.DCIM.ADD:
final Bundle data = message.getData();
mHandlerUI.sendEmptyMessage(0);
mHandlerUI.post(new Runnable()
{
@Override
public void run()
{
setPending(data.getInt(Codes.Extras.NUM_PROCESSING), data.getInt(Codes.Extras.NUM_COMPLETED));
}
});
break;
case org.witness.informacam.utils.Constants.Codes.Messages.Transport.GENERAL_FAILURE:
mHandlerUI.post(new Runnable()
{
@Override
public void run()
{
Toast.makeText(HomeActivity.this, message.getData().getString(Codes.Extras.GENERAL_FAILURE), Toast.LENGTH_LONG).show();
}
});
break;
case org.witness.informacam.utils.Constants.Codes.Messages.UI.REPLACE:
mainFragment.setIsGeneratingKey(false);
break;
case org.witness.informacam.utils.Constants.Codes.Messages.Transport.ORBOT_UNINSTALLED:
mHandlerUI.post(new Runnable() {
@Override
public void run() {
// OrbotHelper oh = new OrbotHelper(HomeActivity.this);
// oh.promptToInstall(HomeActivity.this);
}
});
break;
case org.witness.informacam.utils.Constants.Codes.Messages.Transport.ORBOT_NOT_RUNNING:
mHandlerUI.post(new Runnable() {
@Override
public void run() {
// OrbotHelper oh = new OrbotHelper(HomeActivity.this);
// oh.requestOrbotStart(HomeActivity.this);
}
});
break;
}
}
private final Handler mHandlerUI = new Handler()
{
@Override
public void handleMessage(Message msg)
{
super.handleMessage(msg);
updateAdapter(msg.what);
}
};
@Override
public void launchGallery()
{
//informaCam.stopInforma();
viewPager.setCurrentItem(INDEX_GALLERY);
}
@Override
public void launchVideo()
{
resetActionBar();
boolean externalCamera = PreferenceManager.getDefaultSharedPreferences(this).getBoolean("prefExternalCamera", false);
if (!externalCamera)
toCamera.putExtra(
org.witness.informacam.utils.Constants.Codes.Extras.CAMERA_TYPE,
org.witness.informacam.utils.Constants.App.Camera.Type.SECURE_CAMCORDER);
else
toCamera.putExtra(
org.witness.informacam.utils.Constants.Codes.Extras.CAMERA_TYPE,
org.witness.informacam.utils.Constants.App.Camera.Type.CAMCORDER);
route = toCamera;
startActivityForResult(toCamera, Routes.CAMERA);
}
@Override
public void launchMain()
{
viewPager.setCurrentItem(INDEX_MAIN);
resetActionBar();
mainFragment.initData();
//routeUs();
}
private void resetActionBar()
{
ActionBar actionBar = getActionBar();
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setTitle(R.string.app_name);
actionBar.setDisplayShowHomeEnabled(true);
actionBar.setDisplayHomeAsUpEnabled(false);
actionBar.setHomeButtonEnabled(true);
actionBar.setIcon(R.mipmap.ic_launcher);
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
}
@Override
public void onMediaRecorderStop()
{
}
@Override
public void onCacheWordLocked() {
logoutUser();
}
@Override
public void onCacheWordOpened() {
cacheWord.setTimeout(0);
}
@Override
public void onCacheWordUninitialized() {
finish();
}
}