package com.ghostsq.commander;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import com.ghostsq.commander.adapters.CommanderAdapter;
import com.ghostsq.commander.adapters.Engine;
import com.ghostsq.commander.adapters.FSAdapter;
import com.ghostsq.commander.adapters.FindAdapter;
import com.ghostsq.commander.root.MountAdapter;
import com.ghostsq.commander.root.RootAdapter;
import com.ghostsq.commander.utils.Credentials;
import com.ghostsq.commander.utils.Utils;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.Dialog;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Message;
import android.os.Parcelable;
import android.preference.PreferenceManager;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.content.res.Configuration;
import android.view.ContextMenu;
import android.view.Display;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MenuInflater;
import android.view.KeyEvent;
import android.view.Window;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.inputmethod.InputMethodManager;
import android.util.Log;
import android.widget.AdapterView;
import android.widget.RemoteViews;
import android.widget.Toast;
public class FileCommander extends Activity implements Commander, ServiceConnection, View.OnClickListener {
private final static String TAG = "GhostCommanderActivity";
public final static int REQUEST_CODE_PREFERENCES = 1, REQUEST_CODE_SRV_FORM = 2;
public final static int FIND_ACT = 1017, DBOX_APP = 3592, SMB_ACT = 2751, FTP_ACT = 4501, SFTP_ACT = 2450;
private ArrayList<Dialogs> dialogs;
private ProgressDialog waitPopup;
public Panels panels;
private boolean on = false, exit = false, dont_restore = false,
sxs_auto = true, show_confirm = true, back_exits = false, ab = false;
private String lang = ""; // just need to issue a warning on change
private int file_exist_resolution = Commander.UNKNOWN;
private IBackgroundWork background_work;
private NotificationManager notMan = null;
private ArrayList<NotificationId> bg_ids = new ArrayList<NotificationId>();
private final static String PARCEL = "parcel", TASK_ID = "task_id";
private class NotificationId {
public long id;
public long started, last;
public NotificationId( long id_ ) {
id = id_;
started = System.currentTimeMillis();
last = started;
}
public final boolean is( long fid ) {
return id == fid;
}
}
public final void showMemory( String s ) {
final ActivityManager sys = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);
ActivityManager.MemoryInfo mem = new ActivityManager.MemoryInfo();
sys.getMemoryInfo(mem);
showMessage(s + "\n Memory: " + mem.availMem + ( mem.lowMemory ? " !!!" : "" ));
}
public final void showMessage( String s ) {
Toast.makeText(this, s, Toast.LENGTH_LONG).show();
}
public int getWidth() {
return panels.getWidth();
}
public boolean isActionBar() {
return ab;
}
protected final Dialogs getDialogsInstance( int id ) {
for( int i = 0; i < dialogs.size(); i++ )
if( dialogs.get(i).getId() == id )
return dialogs.get(i);
return null;
}
protected final Dialogs obtainDialogsInstance( int id ) {
Dialogs dh = getDialogsInstance( id );
if( dh == null ) {
dh = new Dialogs( this, id );
dialogs.add( dh );
}
return dh;
}
protected final void addDialogsInstance( Dialogs dh ) {
dialogs.add(dh);
}
/** Called when the activity is first created. */
@Override
public void onCreate( Bundle savedInstanceState ) {
super.onCreate( savedInstanceState );
if( android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB ) {
if( ( getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK )
>= Configuration.SCREENLAYOUT_SIZE_LARGE )
/*
Display display = getWindowManager().getDefaultDisplay();
DisplayMetrics displayMetrics = new DisplayMetrics();
display.getMetrics(displayMetrics);
if( displayMetrics.heightPixels / displayMetrics.densityDpi > 1000 )
*/
ab = getWindow().requestFeature(Window.FEATURE_ACTION_BAR);
}
if( !ab ) requestWindowFeature( Window.FEATURE_NO_TITLE );
// TODO: show progress when there is no title
// requestWindowFeature( Window.FEATURE_INDETERMINATE_PROGRESS );
dialogs = new ArrayList<Dialogs>( Dialogs.numDialogTypes );
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
back_exits = sharedPref.getBoolean( "exit_on_back", false );
lang = sharedPref.getString( "language", "" );
Utils.changeLanguage( this );
String panels_mode = sharedPref.getString( "panels_sxs_mode", "a" );
sxs_auto = panels_mode.equals( "a" );
boolean sxs = sxs_auto ? getRotMode() : panels_mode.equals( "y" );
panels = new Panels( this, sxs );
setConfirmMode( sharedPref );
notMan = (NotificationManager)getSystemService( Context.NOTIFICATION_SERVICE );
bindService( new Intent( this /*?*/, BackgroundWork.class ), this, Context.BIND_AUTO_CREATE );
}
@Override
protected void onStart() {
//Log.v( TAG, "Starting\n" );
super.onStart();
on = true;
if( dont_restore )
dont_restore = false;
else {
Utils.changeLanguage( this );
Intent intent = getIntent();
SharedPreferences prefs = getPreferences( MODE_PRIVATE );
Panels.State s = panels.new State();
s.restore( prefs );
String action = intent.getAction();
Log.i( TAG, "Action: " + action );
if( Intent.ACTION_VIEW.equals( action ) ) {
Log.d( TAG, "Not restoring " + s.getCurrent() );
panels.setState( s, s.getCurrent() );
Log.d( TAG, "VIEW opens in " + panels.getCurrent() );
onNewIntent( intent );
return;
}
panels.setState( s, -1 );
final String FT = "first_time";
if( prefs.getBoolean( FT, true ) ) {
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean( FT, false );
editor.commit();
showInfo( getString( R.string.keys_text) );
}
//panels.setPanelCurrent( use_panel );
if( Intent.ACTION_SEARCH_LONG_PRESS.equals( action ) ) {
showSearchDialog();
return;
}
}
}
@Override
protected void onPause() {
Log.v( TAG, "Pausing\n");
super.onPause();
on = false;
SharedPreferences.Editor editor = getPreferences( MODE_PRIVATE ).edit();
Panels.State s = panels.getState();
s.store( editor );
editor.commit();
}
@Override
protected void onResume() {
Log.v( TAG, "Resuming\n");
super.onResume();
on = true;
}
@Override
protected void onStop() {
Log.v( TAG, "Stopping\n");
super.onStop();
on = false;
}
@Override
protected void onDestroy() {
Log.v( TAG, "Destroying\n");
on = false;
super.onDestroy();
if( notMan != null ) notMan.cancelAll();
panels.Destroy();
unbindService( this );
if( isFinishing() && exit ) {
Log.i( TAG, "Good bye cruel world...");
System.exit( 0 );
}
}
@Override
protected void onSaveInstanceState( Bundle outState ) {
Log.i( TAG, "Saving Instance State");
Panels.State s = panels.getState();
s.store( outState );
super.onSaveInstanceState( outState );
}
@Override
protected void onRestoreInstanceState( Bundle savedInstanceState ) {
Log.i( TAG, "Restoring Instance State");
if( savedInstanceState != null ) {
Panels.State s = panels.new State();
s.restore( savedInstanceState );
panels.setState( s, -1 );
}
super.onRestoreInstanceState( savedInstanceState );
}
@Override
public void onConfigurationChanged( Configuration newConfig ) {
Utils.changeLanguage( this );
super.onConfigurationChanged( newConfig );
panels.setLayoutMode( sxs_auto ? newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE : panels.getLayoutMode() );
/*
// Checks whether a hardware keyboard is available
if (newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO) {
Toast.makeText(this, "keyboard visible", Toast.LENGTH_SHORT).show();
} else if (newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_YES) {
Toast.makeText(this, "keyboard hidden", Toast.LENGTH_SHORT).show();
}
*/
}
@Override
public void onCreateContextMenu( ContextMenu menu, View v, ContextMenuInfo menuInfo ) {
try {
Utils.changeLanguage( this );
AdapterView.AdapterContextMenuInfo acmi = (AdapterView.AdapterContextMenuInfo)menuInfo;
menu.setHeaderTitle( getString( R.string.operation ) );
CommanderAdapter ca = panels.getListAdapter( true );
ca.populateContextMenu( menu, acmi, panels.getNumItemsChecked() );
}
catch( Exception e ) {
Log.e( TAG, "onCreateContextMenu()", e );
}
}
@Override
public boolean onContextItemSelected( MenuItem item ) {
try {
panels.resetQuickSearch();
AdapterView.AdapterContextMenuInfo info;
info = (AdapterView.AdapterContextMenuInfo)item.getMenuInfo();
if( info == null ) return false;
panels.setSelection( info.position );
int item_id = item.getItemId();
if( OPEN == item_id )
panels.openItem( info.position );
else
dispatchCommand( item_id );
return true;
} catch( Exception e ) {
Log.e(TAG, "onContextItemSelected()", e);
return false;
}
}
@Override
protected Dialog onCreateDialog( int id ) {
if( !on ) {
Log.e( TAG, "onCreateDialog() is called when the activity is down" );
}
Dialogs dh = obtainDialogsInstance( id );
Dialog d = dh.createDialog( id );
return d != null ? d : super.onCreateDialog( id );
}
@Override
protected void onPrepareDialog( int id, Dialog dialog ) {
Dialogs dh = getDialogsInstance( id );
if( dh != null )
dh.prepareDialog( id, dialog );
super.onPrepareDialog( id, dialog );
}
@Override
public boolean onCreateOptionsMenu( Menu menu ) {
try {
Utils.changeLanguage( this );
// Inflate the currently selected menu XML resource.
MenuInflater inflater = getMenuInflater();
if( ab ) {
inflater.inflate( R.menu.actions, menu );
inflater.inflate( R.menu.menu, menu );
MenuItem list_menu = menu.findItem( R.id.list );
if( list_menu != null )
list_menu.setVisible( false );
} else
inflater.inflate( R.menu.menu, menu );
return true;
} catch( Error e ) {
e.printStackTrace();
}
return false;
}
@Override
public boolean onMenuItemSelected( int featureId, MenuItem item ) {
panels.resetQuickSearch();
boolean processed = super.onMenuItemSelected( featureId, item );
if( !processed )
dispatchCommand( item.getItemId() );
return true;
}
@Override
public void issue( Intent in, int ret ) {
if( in == null ) return;
try {
if( ret == 0 )
startActivity( in );
else
startActivityForResult( in, ret );
} catch( Exception e ) {
Log.e( TAG, in.getDataString(), e );
}
}
@Override
protected void onActivityResult( int requestCode, int resultCode, Intent data ) {
super.onActivityResult( requestCode, resultCode, data );
Log.d( TAG, "onActivityResult()" );
switch( requestCode ) {
case REQUEST_CODE_PREFERENCES: {
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
back_exits = sharedPref.getBoolean( "exit_on_back", false );
String lang_ = sharedPref.getString( "language", "" );
if( !lang.equalsIgnoreCase( lang_ ) ) {
lang = lang_;
Utils.changeLanguage( this );
showMessage( getString( R.string.restart_to_apply_lang ) );
exit = true;
}
panels.applySettings( sharedPref, false );
String panels_mode = sharedPref.getString( "panels_sxs_mode", "a" );
sxs_auto = panels_mode.equals( "a" );
boolean sxs = sxs_auto ? getRotMode() : panels_mode.equals( "y" );
panels.setLayoutMode( sxs );
panels.showToolbar( sharedPref.getBoolean("show_toolbar", true ) );
setConfirmMode( sharedPref );
}
break;
case REQUEST_CODE_SRV_FORM: {
if( resultCode == RESULT_OK ) {
dont_restore = true;
Uri uri = data.getData();
if( uri != null ) {
Credentials crd = null;
try {
crd = (Credentials)data.getParcelableExtra( Credentials.KEY );
} catch( Exception e ) {
Log.e( TAG, "on taking credentials from parcel", e );
}
panels.Navigate( panels.getCurrent(), uri, crd, null );
}
}
}
break;
case R.id.create_shortcut:
if( data != null ) {
data.setAction( "com.android.launcher.action.INSTALL_SHORTCUT" );
sendBroadcast( data );
}
break;
case ACTIVITY_REQUEST_FOR_NOTIFY_RESULT:
if( data != null ) {
on = true;
Message msg = data.getParcelableExtra( MESSAGE_EXTRA );
if( msg != null )
notifyMe( msg );
else
panels.refreshLists( null );
}
break;
default: {
CommanderAdapter ca = panels.getListAdapter( true );
if( ca != null && ca.handleActivityResult( requestCode, resultCode, data ) )
return;
ca = panels.getListAdapter( false );
if( ca != null )
ca.handleActivityResult( requestCode, resultCode, data );
}
}
}
@Override
public boolean onKeyDown( int keyCode, KeyEvent event ) {
//Log.v( TAG, "global key:" + keyCode + ", number:" + event.getNumber() + ", uchar:" + event.getUnicodeChar() );
char c = (char)event.getUnicodeChar();
panels.resetQuickSearch();
switch( c ) {
case '=':
panels.makeOtherAsCurrent();
return true;
case '&':
openPrefs();
return true;
case '/':
showSearchDialog();
return true;
case '1':
showInfo(getString(R.string.keys_text));
return true;
case '9':
openPrefs();
return true;
case '0':
exit = true;
finish();
return true;
}
switch( keyCode ) {
case KeyEvent.KEYCODE_TAB:
panels.togglePanels( false );
return true;
case KeyEvent.KEYCODE_VOLUME_DOWN:
if( panels.volumeLegacy ) {
panels.togglePanels( false );
return true;
}
break;
case KeyEvent.KEYCODE_SEARCH:
showSearchDialog();
return false;
}
return super.onKeyDown( keyCode, event );
}
@Override
public boolean onKeyUp( int keyCode, KeyEvent event ) {
if( keyCode == KeyEvent.KEYCODE_VOLUME_UP || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN )
return true;
return super.onKeyUp(keyCode, event);
}
/*
* @see android.view.View.OnClickListener#onClick(android.view.View)
*/
// ?????????????????????????????????????????????????
// @Override
public void onClick( View button ) {
panels.resetQuickSearch();
if( button == null )
return;
dispatchCommand( button.getId() );
}
public final boolean backExit() {
if( back_exits ) {
finish();
return true;
}
return false;
}
public void dispatchCommand( int id ) {
try {
Utils.changeLanguage( this );
switch( id ) {
case R.id.keys:
case R.id.F1:
showInfo( getString( R.string.keys_text ) );
break;
case R.id.F3:
panels.openForView();
break;
case R.id.F4:
panels.openForEdit(null);
break;
case R.id.F2:
case R.id.new_zip:
case R.id.F5:
case R.id.F6:
case R.id.F8:
if( panels.getNumItemsSelectedOrChecked() > 0 )
showDialog( id );
else
showMessage( getString( R.string.no_items ) );
break;
case R.id.new_file:
case R.id.SF4:
case R.id.F7:
case R.id.about:
showDialog( id );
break;
case R.id.donate:
startViewURIActivity( R.string.donate_uri );
break;
case R.id.prefs:
case R.id.F9:
openPrefs();
break;
case R.id.exit:
case R.id.F10:
exit = true;
finish();
break;
case R.id.menu:
openOptionsMenu();
case R.id.oth_sh_this:
case R.id.eq:
panels.makeOtherAsCurrent();
break;
case R.id.toggle_panels_mode:
panels.togglePanelsMode();
break;
case R.id.tgl:
panels.togglePanels(true);
break;
case R.id.sz:
panels.showSizes();
break;
case R.id.action_back:
panels.goUp();
break;
case R.id.action_totop:
panels.goTop();
break;
case R.id.action_tobot:
panels.goBot();
break;
case R.id.home:
Navigate( Uri.parse( "home:" ), null, null );
break;
case R.id.favs:
Navigate( Uri.parse( "favs:" ), null, null );
break;
case R.id.sdcard:
Navigate( Uri.parse( Panels.DEFAULT_LOC ), null, null );
break;
case R.id.root: {
Uri cu = panels.getFolderUriWithAuth( true );
String shm = cu != null ? cu.getScheme() : null;
String to_go;
if( "root".equals( shm ) )
to_go = cu.getPath();
else
to_go = RootAdapter.DEFAULT_LOC + ( cu == null || Utils.str( shm ) ? "" : cu.getPath() );
Navigate( Uri.parse( to_go ), null, null );
}
break;
case R.id.mount:
Navigate( Uri.parse( MountAdapter.DEFAULT_LOC ), null, null );
break;
case FTP_ACT: {
Intent i = new Intent( this, ServerForm.class );
i.putExtra( "schema", "ftp" );
startActivityForResult( i, REQUEST_CODE_SRV_FORM );
}
break;
case SFTP_ACT: {
Intent i = new Intent( this, ServerForm.class );
i.putExtra( "schema", "sftp" );
startActivityForResult( i, REQUEST_CODE_SRV_FORM );
}
break;
case SMB_ACT: {
Intent i = new Intent( this, ServerForm.class );
i.putExtra( "schema", "smb" );
startActivityForResult( i, REQUEST_CODE_SRV_FORM );
}
break;
case R.id.search:
showSearchDialog();
break;
case R.id.enter:
panels.openGoPanel();
break;
case R.id.add_fav:
panels.addCurrentToFavorites();
break;
case R.id.by_name:
panels.changeSorting( CommanderAdapter.SORT_NAME );
break;
case R.id.by_ext:
panels.changeSorting( CommanderAdapter.SORT_EXT );
break;
case R.id.by_size:
panels.changeSorting( CommanderAdapter.SORT_SIZE );
break;
case R.id.by_date:
panels.changeSorting( CommanderAdapter.SORT_DATE );
break;
case R.id.refresh:
panels.refreshLists( null );
break;
case R.id.sel_all:
showDialog( Dialogs.SELECT_DIALOG );
break;
case R.id.uns_all:
showDialog( Dialogs.UNSELECT_DIALOG );
break;
case R.id.online: {
Intent intent = new Intent( Intent.ACTION_VIEW );
intent.setData( Uri.parse( getString( R.string.help_uri ) ) );
startActivity( intent );
}
break;
case SEND_TO:
panels.tryToSend();
break;
case OPEN_WITH:
panels.tryToOpen();
break;
case COPY_NAME:
panels.copyName();
break;
case SHRCT_CMD:
panels.createDesktopShortcut();
break;
case FAV_FLD:
panels.faveSelectedFolder();
break;
case R.id.softkbd:
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(0, 0);
break;
case R.id.hidden:
panels.toggleHidden();
break;
case R.id.rescan:
sendBroadcast( new Intent( Intent.ACTION_MEDIA_MOUNTED, Uri.parse( "file://" + Panels.DEFAULT_LOC ) ) );
break;
default:
CommanderAdapter ca = panels.getListAdapter( true );
if( ca != null )
ca.doIt( id, panels.getSelectedOrChecked() );
}
}
catch( Throwable e ) {
e.printStackTrace();
}
}
private final void openPrefs() {
try {
Intent launchPreferencesIntent = new Intent().setClass( this, Prefs.class );
startActivityForResult( launchPreferencesIntent, REQUEST_CODE_PREFERENCES );
} catch( Error e ) {
Log.e( TAG, "Preferences can't open", e );
}
}
private final void showSearchDialog() {
CommanderAdapter ca = panels.getListAdapter( true );
if( ca instanceof FSAdapter || ca instanceof FindAdapter ) {
String cur_s = ca.toString();
if( cur_s != null ) {
Uri cur_uri = Uri.parse( cur_s );
if( cur_uri != null ) {
String cur_path = cur_uri.getPath();
if( cur_path != null ) {
Dialogs dh = obtainDialogsInstance( FIND_ACT );
dh.setCookie( cur_path );
showDialog( FIND_ACT );
return;
}
}
}
showMessage( "Error" );
}
else
showError( getString( R.string.find_on_fs_only ) );
}
/*
* Commander interface implementation
*/
@Override
public void Navigate( Uri uri, Credentials crd, String posTo ) {
panels.Navigate( panels.getCurrent(), uri, crd, posTo );
}
@Override
public void Open( Uri uri, Credentials crd ) {
try {
if( uri == null ) return;
String scheme = uri.getScheme();
String path = uri.getPath();
String ext = Utils.getFileExt( "zip".equals( scheme ) ? uri.getFragment() : path );
String mime = Utils.getMimeByExt( ext );
if( !Utils.str( scheme ) ) {
if( ext != null && ext.compareToIgnoreCase( ".zip" ) == 0 ) {
Navigate( uri.buildUpon().scheme( "zip" ).build(), null, null );
return;
}
Intent i = new Intent( Intent.ACTION_VIEW );
Intent op_intent = getIntent();
if( op_intent != null ) {
String action = op_intent.getAction();
if( Intent.ACTION_PICK.equals( action ) ) {
i.setData( uri );
setResult( RESULT_OK, i );
finish();
return;
}
if( Intent.ACTION_GET_CONTENT.equals( action ) ) {
i.setData( Uri.parse( FileProvider.URI_PREFIX + path ) );
setResult( RESULT_OK, i );
finish();
return;
}
}
i.setDataAndType( uri.buildUpon().scheme( "file" ).authority( "" ).build(), mime );
i.setFlags( Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET );
// | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
startActivity( i );
}
else
if( mime != null && ( mime.startsWith( "audio" ) || mime.startsWith( "video" ) ) ) {
startService( new Intent( this, StreamServer.class ) );
Intent i = new Intent( Intent.ACTION_VIEW );
String http_url = "http://127.0.0.1:5322/" + Uri.encode( uri.toString() );
if( crd != null )
StreamServer.credentials = crd;
//Log.d( TAG, "Stream " + mime + " from: " + http_url );
i.setDataAndType( Uri.parse( http_url ), mime );
i.setFlags( Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET );
startActivity( i );
return;
}
} catch( ActivityNotFoundException e ) {
showMessage("Application for open '" + uri.toString() + "' is not available, ");
} catch( Exception e ) {
Log.e( TAG, uri.toString(), e );
}
}
@Override
public Context getContext() {
return this;
}
@Override
protected void onNewIntent( Intent intent ) {
on = true;
super.onNewIntent( intent );
try {
Bundle extras = intent.getExtras();
if( extras != null ) {
long task_id = extras.getLong( TASK_ID );
if( task_id > 0 ) {
// switch the current active task with the one which comes from the background
Dialogs dh = obtainDialogsInstance( Dialogs.PROGRESS_DIALOG );
if( dh != null ) {
long d_task_id = dh.getTaskId();
if( d_task_id != 0 )
bg_ids.add( new NotificationId( d_task_id ) );
dh.cancelDialog();
}
remBgNotifId( task_id );
dh.setTaskId( task_id );
dh.showDialog();
Parcelable pe = intent.getParcelableExtra( PARCEL );
if( pe != null && pe instanceof Message )
notifyMe( (Message)pe );
return;
}
}
String action = intent.getAction();
Uri uri = intent.getData();
if( uri != null && Intent.ACTION_VIEW.equals( action ) ) {
// || "org.openintents.action.VIEW_DIRECTORY".equals( action ) ) { // DiskUsage support
Log.v( TAG, "Intent URI: " + uri );
Credentials crd = null;
try {
crd = (Credentials)intent.getParcelableExtra( Credentials.KEY );
} catch( Throwable e ) {
Log.e( TAG, "on extracting credentials from an intent", e );
}
String file_name = null;
String type = intent.getType();
if( "application/x-zip-compressed".equals( type ) ||
"application/zip".equals( type ) )
uri = uri.buildUpon().scheme( "zip" ).build();
else if( ContentResolver.SCHEME_CONTENT.equals( uri.getScheme() ) ) {
// unknown content is being passed. Let's just save it
try {
InputStream is = getContentResolver().openInputStream( uri );
if( is != null ) {
File dwf = new File( Panels.DEFAULT_LOC, "download" );
if( !dwf.exists() )
dwf.mkdirs();
String fn = uri.getLastPathSegment();
File f = null;
for( int i = 0; i < 99; i++ ) {
file_name = i == 0 ? fn : fn + "_" + i;
f = new File( dwf, file_name );
if( f.exists() ) continue;
if( f.createNewFile() )
break;
f = null;
}
if( f!= null ) {
BufferedOutputStream bos = new BufferedOutputStream( new FileOutputStream( f ), 8192 );
byte[] buf = new byte[4096];
int n;
while( ( n = is.read( buf ) ) != -1 )
bos.write( buf, 0, n );
bos.close( );
is.close( );
uri = Uri.fromFile( dwf );
showMessage( getString( R.string.copied_f, f.toString() ) );
}
else
showError( getString( R.string.not_accs, fn ) );
}
} catch( Exception e ) {
showError( getString( R.string.not_accs, "" ) ); // TODO more verbose
}
}
panels.Navigate( panels.getCurrent(), uri, crd, file_name );
dont_restore = true;
}
} catch( Exception e ) {
Log.e( TAG, "Can't extract a parcel from intent", e );
}
}
@Override
public boolean startEngine( Engine e ) {
if( background_work != null ) {
background_work.start( e );
return true;
}
Log.e( TAG, "background work service is not available!" );
return false;
}
public boolean stopEngine( long task_id ) {
if( background_work == null )
return false;
return background_work.stopEngine( task_id );
}
@Override
public boolean notifyMe( Message progress ) {
final boolean TERMINATE = true, CONTINUE = false;
String string = null;
try {
if( progress.obj != null ) {
if( progress.obj instanceof Bundle )
string = ((Bundle)progress.obj).getString( MESSAGE_STRING );
else if( progress.obj instanceof String ) {
string = (String)progress.obj;
Log.w( TAG, "Old version message type!" );
}
}
Bundle b = progress.getData();
String cookie = b != null ? b.getString( NOTIFY_COOKIE ) : null;
if( progress.what == Commander.OPERATION_STARTED ) {
setProgressBarIndeterminateVisibility( true );
if( Utils.str( string ) )
showMessage( string );
return CONTINUE;
}
long task_id = b.getLong( Commander.NOTIFY_TASK );
//Log.v( TAG, "got message " + progress.what + " from task " + task_id + " " + string );
Dialogs dh = null;
if( progress.what == OPERATION_IN_PROGRESS ) {
if( progress.arg1 >= 0 ) {
boolean id_found = false;
if( on ) {
dh = obtainDialogsInstance( Dialogs.PROGRESS_DIALOG );
if( dh != null ) {
if( task_id == dh.getTaskId() ) {
dh.showDialog();
dh.setProgress( string, progress.arg1, progress.arg2, b != null ? b.getInt( NOTIFY_SPEED, -1 ) : 0 );
remBgNotifId( task_id );
return CONTINUE;
}
for( NotificationId bg_id : bg_ids ) {
if( bg_id.is( task_id ) ) {
id_found = true;
break;
}
}
if( !id_found ) {
Dialog dlg = dh.getDialog();
if( dlg == null || !dlg.isShowing() ) {
dh.setTaskId( task_id );
dh.showDialog();
dh.setProgress( string, progress.arg1, progress.arg2, b != null ? b.getInt( NOTIFY_SPEED, -1 ) : 0 );
return CONTINUE;
}
}
}
}
if( !id_found )
addBgNotifId( task_id );
setSystemOngoingNotification( (int)task_id, string, progress.arg2 > 0 ? progress.arg2 : progress.arg1 );
return CONTINUE;
} else {
if( waitPopup == null )
waitPopup = ProgressDialog.show( this, "", getString( R.string.wait ), true, true );
}
return CONTINUE;
}
dh = getDialogsInstance( Dialogs.PROGRESS_DIALOG );
if( dh != null && task_id == dh.getTaskId() ) {
Log.d( TAG, "Cancelling dialog " + task_id );
dh.cancelDialog();
} else {
//Log.d( TAG, "No opened dialog found " + task_id );
remBgNotifId( task_id );
}
if( notMan != null ) notMan.cancel( (int)task_id );
if( !on ) {
setSystemNotification( (int)task_id, progress );
return progress.what != OPERATION_SUSPENDED_FILE_EXIST;
}
if( waitPopup != null ) {
waitPopup.cancel();
waitPopup = null;
}
setProgressBarIndeterminateVisibility( false );
panels.operationFinished();
switch( progress.what ) {
case OPERATION_SUSPENDED_FILE_EXIST: {
dh = obtainDialogsInstance( Dialogs.FILE_EXIST_DIALOG );
dh.setMessageToBeShown( string, null );
dh.showDialog();
}
return CONTINUE;
case OPERATION_FAILED:
case OPERATION_FAILED_REFRESH_REQUIRED:
if( Utils.str( cookie ) ) {
int which_panel = cookie.charAt( 0 ) == '1' ? 1 : 0;
panels.setPanelTitle( getString( R.string.fail ), which_panel );
}
if( Utils.str( string ) )
showError( string );
if( progress.what == OPERATION_FAILED_REFRESH_REQUIRED ) {
String posto = b != null ? b.getString( NOTIFY_POSTO ) : null;
panels.refreshLists( posto );
} else
panels.redrawLists();
return TERMINATE;
case OPERATION_FAILED_LOGIN_REQUIRED:
if( string != null ) {
dh = obtainDialogsInstance( Dialogs.LOGIN_DIALOG );
if( b != null ) {
Parcelable crd_p = b.getParcelable( NOTIFY_CRD );
if( crd_p != null && crd_p instanceof Credentials )
dh.setCredentials( (Credentials)crd_p, Utils.str( cookie ) ? cookie.charAt( 0 ) == '1' ? 1 : 0 : -1 );
}
dh.setMessageToBeShown( string, cookie );
showDialog( Dialogs.LOGIN_DIALOG );
}
return TERMINATE;
case OPERATION_COMPLETED_REFRESH_REQUIRED:
String posto = b != null ? b.getString( NOTIFY_POSTO ) : null;
panels.refreshLists( posto );
break;
case OPERATION_COMPLETED:
if( Utils.str( cookie ) ) {
int which_panel = cookie.charAt( 0 ) == '1' ? 1 : 0;
String item_name = cookie.substring( 1 );
panels.recoverAfterRefresh( item_name, which_panel );
}
else
panels.recoverAfterRefresh( null, -1 );
break;
}
if( ( show_confirm || progress.arg1 == OPERATION_REPORT_IMPORTANT ) && Utils.str( string ) )
showInfo( string );
} catch( Exception e ) {
Log.e( TAG, string, e );
}
return TERMINATE;
}
public final void addBgNotifId( long id ) {
for( NotificationId bg_id : bg_ids ) {
if( bg_id.is( id ) )
return;
}
bg_ids.add( new NotificationId( id ) );
}
private final boolean remBgNotifId( long id ) {
for( NotificationId bg_id : bg_ids ) {
if( bg_id.is( id ) ) {
bg_ids.remove( bg_id );
notMan.cancel( (int)id );
return true;
}
}
return false;
}
private PendingIntent getPendingIntent( long task_id, Parcelable parcel ) {
Intent intent = new Intent( this, FileCommander.class );
intent.setFlags( Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP );
intent.setAction( Intent.ACTION_MAIN );
intent.putExtra( TASK_ID, task_id );
if( parcel != null )
intent.putExtra( PARCEL, parcel );
return PendingIntent.getActivity( this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT );
}
private void setSystemOngoingNotification( int id, String str, int p ) {
if( notMan == null || str == null ) return;
NotificationId n_id = null;
for( NotificationId bg_id : bg_ids ) {
if( bg_id.is( id ) )
n_id = bg_id;
}
if( n_id == null ) return;
long cur_time = System.currentTimeMillis();
if( n_id.last + 1000 > cur_time ) return;
n_id.last = cur_time;
Notification notification = new Notification( R.drawable.icon, getString( R.string.inprogress ), n_id.started );
notification.contentIntent = getPendingIntent( id, null );
notification.flags |= Notification.FLAG_ONGOING_EVENT;
RemoteViews not_view = new RemoteViews( getPackageName(), R.layout.progress );
not_view.setTextViewText( R.id.text, str.replace( "\n", " " ) );
not_view.setProgressBar( R.id.progress_bar, 100, p, false );
not_view.setTextViewText( R.id.percent, "" + p + "%" );
notification.contentView = not_view;
notMan.notify( id, notification );
}
private void setSystemNotification( int id, Message msg ) {
if( notMan == null || msg == null ) return;
String str = "Unknown Event";
try {
if( msg.obj instanceof Bundle )
str = ((Bundle)msg.obj).getString( MESSAGE_STRING );
} catch( Exception e ) {
Log.e( TAG, "", e );
}
Notification notification = new Notification( R.drawable.icon, str, System.currentTimeMillis() );
notification.setLatestEventInfo( this, getString( R.string.app_name ), str, getPendingIntent( id, msg ) );
notification.flags |= Notification.FLAG_ONLY_ALERT_ONCE | Notification.FLAG_AUTO_CANCEL;
if( msg.what == OPERATION_SUSPENDED_FILE_EXIST ) {
notification.flags |= Notification.FLAG_SHOW_LIGHTS;
notification.defaults |= Notification.DEFAULT_VIBRATE;
notification.ledARGB = 0xFFFF0000;
notification.ledOnMS = 300;
notification.ledOffMS = 1000;
}
notMan.notify( id, notification );
}
public void setResolution( int r ) {
synchronized( this ) {
file_exist_resolution = r;
notify();
}
}
@Override
public int getResolution() {
int r = file_exist_resolution;
file_exist_resolution = Commander.UNKNOWN;
return r;
}
@Override
public void showError( String errMsg ) {
try {
if( !on ) return;
Dialogs dh = obtainDialogsInstance( Dialogs.ALERT_DIALOG );
dh.setMessageToBeShown( errMsg, null );
dh.showDialog();
return;
} catch( Exception e ) {
e.printStackTrace();
}
showMessage( errMsg );
}
@Override
public void showInfo( String msg ) {
if( !on ) return;
if( msg.length() < 32 )
showMessage( msg );
else {
Dialogs dh = obtainDialogsInstance( Dialogs.INFO_DIALOG );
dh.setMessageToBeShown( msg, null );
dh.showDialog();
}
}
public final void startViewURIActivity( int res_id ) {
Intent i = new Intent( Intent.ACTION_VIEW );
i.setData( Uri.parse( getString( res_id ) ) );
startActivity( i );
}
private final boolean getRotMode() {
boolean sideXside = false;
try {
Display disp = getWindowManager().getDefaultDisplay();
sideXside = disp.getWidth() > disp.getHeight();
} catch( Exception e ) {
Log.e( TAG, "", e );
}
return sideXside;
}
private final void setConfirmMode( SharedPreferences sharedPref ) {
show_confirm = sharedPref.getBoolean("show_confirm", true );
}
// ServiceConnection implementation
@Override
public void onServiceConnected( ComponentName name, IBinder service ) {
background_work = ((IBackgroundWork.IBackgroundWorkBinder)service).init( this );
}
@Override
public void onServiceDisconnected( ComponentName name ) {
background_work = null;
}
}