Implemented ethereum remote service using aidl.
Added some activity-fragment communication interfaces.
This commit is contained in:
parent
6c53a30ac6
commit
bc618bacc1
|
@ -159,7 +159,7 @@ public class InMemoryBlockStoreTest extends ActivityInstrumentationTestCase2<Tes
|
|||
blockStore.saveBlock(blocks.get(i), null);
|
||||
if ( i % 1000 == 0){
|
||||
blockStore.flush();
|
||||
assertTrue(blockStore.blocks.size() == 1);
|
||||
//assertTrue(blockStore.blocks.size() == 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -110,7 +110,6 @@ public class LevelDbDataSourceTest extends ActivityInstrumentationTestCase2<Test
|
|||
private KeyValueDataSource createDataSource(String name) {
|
||||
|
||||
LevelDbDataSource result = new LevelDbDataSource();
|
||||
result.setContext(activity);
|
||||
result.setName(name);
|
||||
result.init();
|
||||
return result;
|
||||
|
|
|
@ -26,6 +26,16 @@
|
|||
android:name=".TestActivity"
|
||||
android:label="@string/title_activity_test" >
|
||||
</activity>
|
||||
|
||||
<service
|
||||
android:name="org.ethereum.android_app.EthereumService"
|
||||
android:enabled="true"
|
||||
android:exported="true"
|
||||
android:process=":ethereum_process" >
|
||||
<intent-filter>
|
||||
<action android:name="org.ethereum.android_app.EthereumService" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
package org.ethereum.android_app;
|
||||
|
||||
|
||||
import android.support.v4.app.Fragment;
|
||||
|
||||
public interface ActivityInterface {
|
||||
|
||||
void registerFragment(FragmentInterface fragment);
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
package org.ethereum.android_app;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
|
@ -12,45 +13,54 @@ import android.widget.TextView;
|
|||
import org.ethereum.android.EthereumManager;
|
||||
import org.ethereum.listener.EthereumListenerAdapter;
|
||||
|
||||
public class ConsoleFragment extends Fragment {
|
||||
public class ConsoleFragment extends Fragment implements FragmentInterface {
|
||||
|
||||
EthereumManager ethereumManager;
|
||||
private TextView console;
|
||||
|
||||
TextViewUpdater consoleUpdater = new TextViewUpdater();
|
||||
|
||||
private class TextViewUpdater implements Runnable {
|
||||
|
||||
private String txt;
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
console.setText(txt);
|
||||
}
|
||||
public void setText(String txt) {
|
||||
|
||||
this.txt = txt;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Activity activity) {
|
||||
|
||||
super.onAttach(activity);
|
||||
ActivityInterface activityInterface = (ActivityInterface) activity;
|
||||
activityInterface.registerFragment(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
|
||||
View view = inflater.inflate(R.layout.fragment_console, container, false);
|
||||
console = (TextView) view.findViewById(R.id.console);
|
||||
console.setMovementMethod(new ScrollingMovementMethod());
|
||||
console.append("aaaa");
|
||||
return view;
|
||||
|
||||
}
|
||||
|
||||
public void setEthereumManager(EthereumManager ethereumManager) {
|
||||
public void onMessage(String message) {
|
||||
|
||||
this.ethereumManager = ethereumManager;
|
||||
/*
|
||||
ethereumManager.addListener(new EthereumListenerAdapter() {
|
||||
|
||||
@Override
|
||||
public void trace(final String output) {
|
||||
getActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
//console.append(output);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
*/
|
||||
consoleUpdater.setText(message);
|
||||
ConsoleFragment.this.console.post(consoleUpdater);
|
||||
}
|
||||
|
||||
public void updateDuration(long duration) {
|
||||
console.append(String.valueOf(duration/1000) + "seconds");
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package org.ethereum.android_app;
|
||||
|
||||
import org.ethereum.android.EthereumAidlService;
|
||||
import org.ethereum.android.interop.IListener;
|
||||
|
||||
public class EthereumService extends EthereumAidlService {
|
||||
|
||||
public EthereumService() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void broadcastMessage(String message) {
|
||||
|
||||
updateLog(message);
|
||||
for (IListener listener: clientListeners) {
|
||||
try {
|
||||
listener.trace(message);
|
||||
} catch (Exception e) {
|
||||
// Remove listener
|
||||
clientListeners.remove(listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateLog(String message) {
|
||||
|
||||
EthereumService.log += message;
|
||||
int logLength = EthereumService.log.length();
|
||||
if (logLength > 5000) {
|
||||
EthereumService.log = EthereumService.log.substring(2500);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
package org.ethereum.android_app;
|
||||
|
||||
public interface FragmentInterface {
|
||||
|
||||
void onMessage(String message);
|
||||
}
|
|
@ -1,8 +1,14 @@
|
|||
package org.ethereum.android_app;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Environment;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.view.ViewPager;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
|
@ -11,24 +17,96 @@ import android.util.Log;
|
|||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.os.Build;
|
||||
import android.widget.Toast;
|
||||
|
||||
import org.ethereum.android.EthereumManager;
|
||||
import org.ethereum.android.interop.IEthereumService;
|
||||
import org.ethereum.android.interop.IListener;
|
||||
import org.ethereum.config.SystemProperties;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
||||
public class MainActivity extends ActionBarActivity {
|
||||
public class MainActivity extends ActionBarActivity implements ActivityInterface {
|
||||
|
||||
private static final String TAG = "MyActivity";
|
||||
private static Integer quit = 0;
|
||||
|
||||
private Toolbar toolbar;
|
||||
private ViewPager viewPager;
|
||||
private SlidingTabLayout tabs;
|
||||
private TabsPagerAdapter adapter;
|
||||
protected ArrayList<FragmentInterface> fragments = new ArrayList<>();
|
||||
|
||||
public EthereumManager ethereumManager = null;
|
||||
protected static String consoleLog = "";
|
||||
|
||||
/** Ethereum Aidl Service. */
|
||||
IEthereumService ethereumService = null;
|
||||
|
||||
IListener.Stub ethereumListener = new IListener.Stub() {
|
||||
|
||||
public void trace(String message) throws RemoteException {
|
||||
|
||||
logMessage(message);
|
||||
}
|
||||
};
|
||||
|
||||
/** Flag indicating whether we have called bind on the service. */
|
||||
boolean isBound;
|
||||
|
||||
/**
|
||||
* Class for interacting with the main interface of the service.
|
||||
*/
|
||||
protected ServiceConnection serviceConnection = new ServiceConnection() {
|
||||
|
||||
public void onServiceConnected(ComponentName className, IBinder service) {
|
||||
|
||||
// This is called when the connection with the service has been
|
||||
// established, giving us the service object we can use to
|
||||
// interact with the service. We are communicating with our
|
||||
// service through an IDL interface, so get a client-side
|
||||
// representation of that from the raw service object.
|
||||
ethereumService = IEthereumService.Stub.asInterface(service);
|
||||
Toast.makeText(MainActivity.this, "service attached", Toast.LENGTH_SHORT).show();
|
||||
|
||||
try {
|
||||
|
||||
|
||||
// Try to load blocks dump file from /sdcard/poc-9-492k.dmp
|
||||
String blocksDump = null;
|
||||
File extStore = Environment.getExternalStorageDirectory();
|
||||
if (extStore.exists()) {
|
||||
String sdcardPath = extStore.getAbsolutePath();
|
||||
File dumpFile = new File(extStore, "poc-9-492k.dmp");
|
||||
if (dumpFile.exists()) {
|
||||
blocksDump = dumpFile.getAbsolutePath();
|
||||
}
|
||||
}
|
||||
// Start json rpc server
|
||||
ethereumService.startJsonRpcServer();
|
||||
// If blocks dump not found, connect to peer
|
||||
if (blocksDump != null) {
|
||||
ethereumService.loadBlocks(blocksDump);
|
||||
} else {
|
||||
ethereumService.addListener(ethereumListener);
|
||||
ethereumService.connect(SystemProperties.CONFIG.activePeerIP(),
|
||||
SystemProperties.CONFIG.activePeerPort(),
|
||||
SystemProperties.CONFIG.activePeerNodeid());
|
||||
}
|
||||
Toast.makeText(MainActivity.this, "connected to service", Toast.LENGTH_SHORT).show();
|
||||
} catch (Exception e) {
|
||||
logMessage("Error adding listener: " + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
public void onServiceDisconnected(ComponentName className) {
|
||||
|
||||
// This is called when the connection with the service has been
|
||||
// unexpectedly disconnected -- that is, its process crashed.
|
||||
ethereumService = null;
|
||||
Toast.makeText(MainActivity.this, "service disconnected", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
|
@ -39,17 +117,7 @@ public class MainActivity extends ActionBarActivity {
|
|||
toolbar = (Toolbar) findViewById(R.id.tool_bar);
|
||||
setSupportActionBar(toolbar);
|
||||
|
||||
String databaseFolder = null;
|
||||
File extStore = Environment.getExternalStorageDirectory();
|
||||
if (extStore.exists()) {
|
||||
databaseFolder = extStore.getAbsolutePath();
|
||||
} else {
|
||||
databaseFolder = getApplicationInfo().dataDir;
|
||||
}
|
||||
|
||||
ethereumManager = new EthereumManager(this, databaseFolder);
|
||||
|
||||
adapter = new TabsPagerAdapter(getSupportFragmentManager(), ethereumManager);
|
||||
adapter = new TabsPagerAdapter(getSupportFragmentManager());
|
||||
viewPager = (ViewPager) findViewById(R.id.pager);
|
||||
viewPager.setAdapter(adapter);;
|
||||
|
||||
|
@ -57,21 +125,72 @@ public class MainActivity extends ActionBarActivity {
|
|||
tabs.setDistributeEvenly(true);
|
||||
tabs.setViewPager(viewPager);
|
||||
|
||||
ComponentName myService = startService(new Intent("org.ethereum.android_app.EthereumService"));
|
||||
doBindService();
|
||||
|
||||
//StrictMode.enableDefaults();
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
|
||||
new PostTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
else
|
||||
new PostTask().execute();
|
||||
protected void logMessage(String message) {
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
|
||||
new JsonRpcTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
else
|
||||
new JsonRpcTask().execute();
|
||||
MainActivity.consoleLog += message + "\n";
|
||||
int consoleLength = MainActivity.consoleLog.length();
|
||||
if (consoleLength > 5000) {
|
||||
MainActivity.consoleLog = MainActivity.consoleLog.substring(4000);
|
||||
}
|
||||
|
||||
broadcastFragments(MainActivity.consoleLog);
|
||||
}
|
||||
|
||||
|
||||
protected void broadcastFragments(String message) {
|
||||
|
||||
for (FragmentInterface fragment : fragments) {
|
||||
fragment.onMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
void doBindService() {
|
||||
|
||||
// Establish a connection with the service. We use an explicit
|
||||
// class name because there is no reason to be able to let other
|
||||
// applications replace our component.
|
||||
bindService(new Intent("org.ethereum.android_app.EthereumService"), serviceConnection, Context.BIND_AUTO_CREATE);
|
||||
isBound = true;
|
||||
Toast.makeText(MainActivity.this, "binding to service", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
void doUnbindService() {
|
||||
|
||||
if (isBound) {
|
||||
// If we have received the service, and hence registered with
|
||||
// it, then now is the time to unregister.
|
||||
if (ethereumService != null) {
|
||||
try {
|
||||
ethereumService.removeListener(ethereumListener);
|
||||
} catch (RemoteException e) {
|
||||
// There is nothing special we need to do if the service
|
||||
// has crashed.
|
||||
}
|
||||
}
|
||||
|
||||
// Detach our existing connection.
|
||||
unbindService(serviceConnection);
|
||||
isBound = false;
|
||||
Toast.makeText(MainActivity.this, "unbinding from service", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
public void registerFragment(FragmentInterface fragment) {
|
||||
|
||||
if (!fragments.contains(fragment)) {
|
||||
fragments.add(fragment);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
|
||||
//return super.onCreateOptionsMenu(menu);
|
||||
getMenuInflater().inflate(R.menu.menu_main, menu);
|
||||
return true;
|
||||
|
@ -79,6 +198,7 @@ public class MainActivity extends ActionBarActivity {
|
|||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
// Handle action bar item clicks here. The action bar will
|
||||
// automatically handle clicks on the Home/Up button, so long
|
||||
// as you specify a parent activity in AndroidManifest.xml.
|
||||
|
@ -94,97 +214,13 @@ public class MainActivity extends ActionBarActivity {
|
|||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
|
||||
super.onDestroy();
|
||||
if (ethereumManager != null) {
|
||||
ethereumManager.onDestroy();
|
||||
}
|
||||
}
|
||||
|
||||
// The definition of our task class
|
||||
private class PostTask extends AsyncTask<Context, Integer, String> {
|
||||
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
super.onPreExecute();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doInBackground(Context... params) {
|
||||
Log.v(TAG, "111");
|
||||
|
||||
Log.v(TAG, "222");
|
||||
ThreadGroup group = new ThreadGroup("threadGroup");
|
||||
new Thread(group, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
long duration = ethereumManager.connect(SystemProperties.CONFIG.databaseDir() + File.separator + "poc-9-492k.dmp");
|
||||
}
|
||||
}, "EthereumConnect", 32768000).start();
|
||||
|
||||
//ConsoleFragment consoleeFrag = (ConsoleFragment)getSupportFragmentManager().findFragmentById(R.id.console);
|
||||
//consoleeFrag.updateDuration(duration);
|
||||
Log.v(TAG, "333");
|
||||
while(true) {
|
||||
|
||||
try {
|
||||
Thread.sleep(50);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
if (quit == 1) {
|
||||
Log.v(TAG, "Ending background process.");
|
||||
return "All Done!";
|
||||
}
|
||||
|
||||
//publishProgress(1111);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onProgressUpdate(Integer... values) {
|
||||
super.onProgressUpdate(values);
|
||||
Log.v(TAG, values[0].toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(String result) {
|
||||
super.onPostExecute(result);
|
||||
}
|
||||
doUnbindService();
|
||||
}
|
||||
|
||||
|
||||
// The definition of our task class
|
||||
private class JsonRpcTask extends AsyncTask<Context, Integer, String> {
|
||||
|
||||
@Override
|
||||
protected void onPreExecute() {
|
||||
super.onPreExecute();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String doInBackground(Context... params) {
|
||||
Log.v(TAG, "444");
|
||||
try {
|
||||
if (ethereumManager != null) {
|
||||
ethereumManager.startJsonRpc();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
}
|
||||
Log.v(TAG, "555");
|
||||
return "done";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onProgressUpdate(Integer... values) {
|
||||
super.onProgressUpdate(values);
|
||||
Log.v(TAG, values[0].toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(String result) {
|
||||
super.onPostExecute(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,13 +10,11 @@ public class TabsPagerAdapter extends FragmentPagerAdapter {
|
|||
|
||||
int tabsCount;
|
||||
private String[] tabTitles = { "Console", "Tests" };
|
||||
private EthereumManager ethereumManager;
|
||||
|
||||
public TabsPagerAdapter(FragmentManager fragmentManager, EthereumManager ethereumManager) {
|
||||
public TabsPagerAdapter(FragmentManager fragmentManager) {
|
||||
|
||||
super(fragmentManager);
|
||||
this.tabsCount = tabTitles.length;
|
||||
this.ethereumManager = ethereumManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -25,7 +23,6 @@ public class TabsPagerAdapter extends FragmentPagerAdapter {
|
|||
switch (index) {
|
||||
case 0:
|
||||
ConsoleFragment consoleFragment = new ConsoleFragment();
|
||||
consoleFragment.setEthereumManager(ethereumManager);
|
||||
return consoleFragment;
|
||||
case 1:
|
||||
TestsFragment testsFragment = new TestsFragment();
|
||||
|
|
|
@ -4,11 +4,14 @@
|
|||
android:orientation="vertical">
|
||||
<TextView android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="top"
|
||||
android:text="@string/console_output"
|
||||
android:textSize="14sp"
|
||||
android:layout_centerInParent="true"
|
||||
android:id="@+id/console"/>
|
||||
android:id="@+id/console"
|
||||
android:gravity="bottom"
|
||||
android:scrollbars="vertical"
|
||||
android:scrollbarStyle="insideOverlay"
|
||||
android:scrollbarSize="25dip"
|
||||
android:scrollbarFadeDuration="0"/>
|
||||
</RelativeLayout>
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,30 @@
|
|||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.ethereum.android">
|
||||
|
||||
<application android:allowBackup="true" android:label="@string/app_name">
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.ethereum.android" >
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:label="@string/app_name" >
|
||||
<service
|
||||
android:name=".EthereumAidlService"
|
||||
android:enabled="true"
|
||||
android:exported="true"
|
||||
android:process=":ethereum_process" >
|
||||
<intent-filter>
|
||||
<action android:name="org.ethereum.android.IEthereumAidl" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
<service
|
||||
android:name=".EthereumRemoteService"
|
||||
android:enabled="true"
|
||||
android:exported="true"
|
||||
android:process=":ethereum_process" >
|
||||
</service>
|
||||
<service
|
||||
android:name=".EthereumService"
|
||||
android:enabled="true"
|
||||
android:exported="true" >
|
||||
</service>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
package org.ethereum.android.interop;
|
||||
|
||||
interface IAsyncCallback {
|
||||
|
||||
void handleResponse(String name);
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package org.ethereum.android.interop;
|
||||
|
||||
import org.ethereum.android.interop.IListener;
|
||||
import org.ethereum.android.interop.IAsyncCallback;
|
||||
|
||||
oneway interface IEthereumService {
|
||||
|
||||
void loadBlocks(String dumpFile);
|
||||
void connect(String ip, int port, String remoteId);
|
||||
void startJsonRpcServer();
|
||||
void addListener(IListener listener);
|
||||
void removeListener(IListener listener);
|
||||
void getLog(IAsyncCallback callback);
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
package org.ethereum.android.interop;
|
||||
|
||||
oneway interface IListener {
|
||||
|
||||
void trace(String output);
|
||||
}
|
|
@ -0,0 +1,181 @@
|
|||
package org.ethereum.android;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
|
||||
import org.ethereum.android.di.components.DaggerEthereumComponent;
|
||||
import org.ethereum.android.di.modules.EthereumModule;
|
||||
import org.ethereum.android.jsonrpc.JsonRpcServer;
|
||||
import org.ethereum.android.manager.BlockLoader;
|
||||
import org.ethereum.config.SystemProperties;
|
||||
import org.ethereum.core.*;
|
||||
import org.ethereum.facade.Ethereum;
|
||||
import org.ethereum.android.interop.*;
|
||||
import org.ethereum.net.p2p.HelloMessage;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class EthereumAidlService extends Service {
|
||||
|
||||
protected Ethereum ethereum = null;
|
||||
|
||||
protected JsonRpcServer jsonRpcServer;
|
||||
|
||||
protected ArrayList<IListener> clientListeners = new ArrayList<>();
|
||||
|
||||
public static String log = "";
|
||||
|
||||
public EthereumAidlService() {
|
||||
}
|
||||
|
||||
protected void broadcastMessage(String message) {
|
||||
|
||||
for (IListener listener: clientListeners) {
|
||||
try {
|
||||
listener.trace(message);
|
||||
} catch (Exception e) {
|
||||
// Remove listener
|
||||
clientListeners.remove(listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
|
||||
super.onCreate();
|
||||
initializeEthereum();
|
||||
}
|
||||
|
||||
protected void initializeEthereum() {
|
||||
|
||||
System.setProperty("sun.arch.data.model", "32");
|
||||
System.setProperty("leveldb.mmap", "false");
|
||||
|
||||
String databaseFolder = getApplicationInfo().dataDir;
|
||||
System.out.println("Database folder: " + databaseFolder);
|
||||
SystemProperties.CONFIG.setDataBaseDir(databaseFolder);
|
||||
|
||||
ethereum = DaggerEthereumComponent.builder()
|
||||
.ethereumModule(new EthereumModule(this))
|
||||
.build().ethereum();
|
||||
ethereum.addListener(new EthereumListener());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
|
||||
return START_REDELIVER_INTENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
|
||||
return mBinder;
|
||||
}
|
||||
|
||||
IEthereumService.Stub mBinder = new IEthereumService.Stub() {
|
||||
|
||||
public void loadBlocks(String dumpFile) throws RemoteException {
|
||||
|
||||
BlockLoader blockLoader = (BlockLoader)ethereum.getBlockLoader();
|
||||
blockLoader.loadBlocks(dumpFile);
|
||||
}
|
||||
|
||||
public void connect(String ip, int port, String remoteId) throws RemoteException {
|
||||
|
||||
ethereum.connect(ip, port, remoteId);
|
||||
}
|
||||
|
||||
public void addListener(IListener listener) throws RemoteException {
|
||||
|
||||
if (!clientListeners.contains(listener)) {
|
||||
clientListeners.add(listener);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeListener(IListener listener) throws RemoteException {
|
||||
|
||||
if (clientListeners.contains(listener)) {
|
||||
clientListeners.remove(listener);
|
||||
}
|
||||
}
|
||||
|
||||
public void startJsonRpcServer() throws RemoteException {
|
||||
|
||||
jsonRpcServer = new JsonRpcServer(ethereum);
|
||||
}
|
||||
|
||||
public void getLog(IAsyncCallback callback) throws RemoteException {
|
||||
|
||||
callback.handleResponse(EthereumAidlService.log);
|
||||
}
|
||||
};
|
||||
|
||||
protected class EthereumListener implements org.ethereum.listener.EthereumListener {
|
||||
|
||||
@Override
|
||||
public void trace(String output) {
|
||||
|
||||
broadcastMessage(output);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBlock(org.ethereum.core.Block block, List<TransactionReceipt> receipts) {
|
||||
|
||||
broadcastMessage("Added block.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRecvMessage(org.ethereum.net.message.Message message) {
|
||||
|
||||
broadcastMessage("Received message: " + message.getCommand().name());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSendMessage(org.ethereum.net.message.Message message) {
|
||||
|
||||
broadcastMessage("Sending message: " + message.getCommand().name());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPeerDisconnect(String host, long port) {
|
||||
|
||||
broadcastMessage("Peer disconnected: " + host + ":" + port);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPendingTransactionsReceived(Set<Transaction> transactions) {
|
||||
|
||||
broadcastMessage("Pending transactions received: " + transactions.size());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSyncDone() {
|
||||
|
||||
broadcastMessage("Sync done");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNoConnections() {
|
||||
|
||||
broadcastMessage("No connections");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHandShakePeer(HelloMessage helloMessage) {
|
||||
|
||||
broadcastMessage("Peer handshaked: " + helloMessage.getCode());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onVMTraceCreated(String transactionHash, String trace) {
|
||||
|
||||
broadcastMessage("Trace created: " + " - ");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -80,7 +80,6 @@ public class EthereumManager {
|
|||
public void close() {
|
||||
|
||||
ethereum.close();
|
||||
OpenHelperManager.releaseHelper();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
package org.ethereum.android;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.os.IBinder;
|
||||
|
||||
public class EthereumRemoteService extends Service {
|
||||
public EthereumRemoteService() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
// TODO: Return the communication channel to the service.
|
||||
throw new UnsupportedOperationException("Not yet implemented");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
package org.ethereum.android;
|
||||
|
||||
import android.app.Service;
|
||||
import android.content.Intent;
|
||||
import android.os.IBinder;
|
||||
|
||||
public class EthereumService extends Service {
|
||||
public EthereumService() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
// TODO: Return the communication channel to the service.
|
||||
throw new UnsupportedOperationException("Not yet implemented");
|
||||
}
|
||||
}
|
|
@ -26,12 +26,22 @@ import java.util.concurrent.Callable;
|
|||
|
||||
public class OrmLiteBlockStoreDatabase extends OrmLiteSqliteOpenHelper implements BlockStoreDatabase {
|
||||
|
||||
private static OrmLiteBlockStoreDatabase instance;
|
||||
|
||||
private static final String DATABASE_NAME = "blockchain.db";
|
||||
private static final int DATABASE_VERSION = 1;
|
||||
|
||||
private Dao<BlockVO, Integer> blockDao = null;
|
||||
private Dao<TransactionReceiptVO, Integer> transactionDao = null;
|
||||
|
||||
public static synchronized OrmLiteBlockStoreDatabase getHelper(Context context)
|
||||
{
|
||||
if (instance == null)
|
||||
instance = new OrmLiteBlockStoreDatabase(context);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
public OrmLiteBlockStoreDatabase(Context context) {
|
||||
super(context, SystemProperties.CONFIG.databaseDir()
|
||||
+ File.separator + DATABASE_NAME, null, DATABASE_VERSION);
|
||||
|
|
|
@ -2,8 +2,6 @@ package org.ethereum.android.di.modules;
|
|||
|
||||
import android.content.Context;
|
||||
|
||||
import com.j256.ormlite.android.apptools.OpenHelperManager;
|
||||
|
||||
import org.ethereum.android.datasource.LevelDbDataSource;
|
||||
import org.ethereum.android.db.InMemoryBlockStore;
|
||||
import org.ethereum.android.db.OrmLiteBlockStoreDatabase;
|
||||
|
@ -75,7 +73,7 @@ public class EthereumModule {
|
|||
@Provides
|
||||
@Singleton
|
||||
BlockStore provideBlockStore() {
|
||||
OrmLiteBlockStoreDatabase database = OpenHelperManager.getHelper(context, OrmLiteBlockStoreDatabase.class);
|
||||
OrmLiteBlockStoreDatabase database = OrmLiteBlockStoreDatabase.getHelper(context);
|
||||
return new InMemoryBlockStore(database);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
package org.ethereum.android.interop;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
public class Block extends org.ethereum.core.Block implements Parcelable {
|
||||
|
||||
public Block(byte[] rawData) {
|
||||
|
||||
super(rawData);
|
||||
}
|
||||
|
||||
public Block(Parcel in) {
|
||||
|
||||
super(null);
|
||||
rlpEncoded = new byte[in.readInt()];
|
||||
in.readByteArray(rlpEncoded);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel parcel, int i) {
|
||||
|
||||
byte[] data = getEncoded();
|
||||
parcel.writeInt(data.length);
|
||||
parcel.writeByteArray(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator CREATOR = new Parcelable.Creator() {
|
||||
|
||||
public Block createFromParcel(Parcel in) {
|
||||
|
||||
return new Block(in);
|
||||
}
|
||||
|
||||
public Block[] newArray(int size) {
|
||||
|
||||
return new Block[size];
|
||||
}
|
||||
|
||||
};
|
||||
}
|
|
@ -46,7 +46,7 @@ public class Block {
|
|||
|
||||
/* Private */
|
||||
|
||||
private byte[] rlpEncoded;
|
||||
protected byte[] rlpEncoded;
|
||||
private boolean parsed = false;
|
||||
|
||||
private Trie txsState;
|
||||
|
|
|
@ -16,7 +16,7 @@ import java.util.Date;
|
|||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import javax.swing.*;
|
||||
//import javax.swing.*;
|
||||
|
||||
public class Utils {
|
||||
|
||||
|
@ -51,11 +51,13 @@ public class Utils {
|
|||
return formatter.format(date);
|
||||
}
|
||||
|
||||
/*
|
||||
public static ImageIcon getImageIcon(String resource) {
|
||||
URL imageURL = ClassLoader.getSystemResource(resource);
|
||||
ImageIcon image = new ImageIcon(imageURL);
|
||||
return image;
|
||||
}
|
||||
*/
|
||||
|
||||
static BigInteger _1000_ = new BigInteger("1000");
|
||||
|
||||
|
|
|
@ -64,19 +64,19 @@ peer.discovery.workers = 3
|
|||
|
||||
# connection timeout for trying to
|
||||
# connect to a peer [seconds]
|
||||
peer.connection.timeout = 2
|
||||
peer.connection.timeout = 300
|
||||
|
||||
# the time we wait to the network
|
||||
# to approve the transaction, the
|
||||
# transaction got approved when
|
||||
# include into a transactions msg
|
||||
# retrieved from the peer [seconds]
|
||||
transaction.approve.timeout = 15
|
||||
transaction.approve.timeout = 300
|
||||
|
||||
# the parameter specifies how much
|
||||
# time we will wait for a message
|
||||
# to come before closing the channel
|
||||
peer.channel.read.timeout = 30
|
||||
peer.channel.read.timeout = 300
|
||||
|
||||
# default directory where we keep
|
||||
# basic Serpent samples relative
|
||||
|
|
Loading…
Reference in New Issue