import java.nio.ByteBuffer;
import java.nio.channels.SocketChannel;
import java.nio.charset.Charset;
+import java.util.Timer;
+import java.util.TimerTask;
+import java.util.concurrent.atomic.AtomicBoolean;
import org.tizen.sdblib.exception.SdbCommandRejectedException;
import org.tizen.sdblib.exception.TimeoutException;
* @param chan the opened socket to write to.
* @param data the buffer to send.
*
- * @throws TimeoutException in case of timeout on the connection.
- * @throws IOException in case of I/O error on the connection.
+ * @throws IOException if writing is failed
*/
- public static void write(SocketChannel chan, byte[] data) throws TimeoutException, IOException {
+ public static
+ void
+ write(
+ final SocketChannel chan,
+ final byte[] data
+ )
+ throws IOException
+ {
write(chan, data, -1, Preferences.getTimeOut());
}
/**
* write {@code data} untim time out
*
- * @param chan the opened socket to write to.
- * @param data the buffer to send.
- * @param length the length to write or -1 to send the whole buffer.
- * @param timeout The timeout value. A timeout of zero means "wait forever".
+ * @param chan {@link SocketChannel} to write.
+ * @param data data in byte[].
+ * @param length the length to write.
+ * @param timeout timeout to wait.
*
- * @throws TimeoutException in case of timeout on the connection.
- * @throws IOException in case of I/O error on the connection.
+ * @throws IOException if writing is failed
*/
- public static void write(
+ public static
+ void
+ write(
final SocketChannel chan,
final byte[] data,
final int length,
final int timeout
)
- throws TimeoutException, IOException
+ throws IOException
{
- ByteBuffer buf = ByteBuffer.wrap(data, 0, length < 0 ? data.length : length );
- int numWaits = 0;
-
- while (buf.position() != buf.limit()) {
- int count;
+ final ByteBuffer buf = ByteBuffer.wrap(data, 0, length < 0 ? data.length : length );
+ final AtomicBoolean running = new AtomicBoolean( true );
+ if ( 0 < timeout ) {
+ final Timer timer = new Timer();
+ timer.schedule( new TimerTask()
+ {
+ @Override
+ synchronized public void run()
+ {
+ running.set( false );
+ }
+ }, timeout );
+ }
- count = chan.write(buf);
- if (count < 0) {
+ while (buf.position() != buf.limit() && running.get() )
+ {
+ int count = chan.write( buf );
+ if ( count < 0 )
+ {
Log.d("sdb", "write: channel EOF");
throw new IOException("channel EOF");
- } else if (count == 0) {
- // TODO: need more accurate timeout?
- if ( 0 < timeout && numWaits * WAIT_TIME > timeout) {
- Log.d("sdb", "write: timeout");
- throw new TimeoutException();
- }
- // non-blocking spin
- try {
- Thread.sleep(WAIT_TIME);
- } catch (InterruptedException ie) {
- }
- numWaits++;
- } else {
- numWaits = 0;
}
+ else if ( 0 == count )
+ {
+ trySleep( WAIT_TIME );
+ }
+ }
+ if ( buf.position() == buf.limit() )
+ {
+ return ;
}
+ Log.d("sdb", "write: Timeout");
+ throw new TimeoutException();
}
/**
}
/**
- * Creates a new debug bridge from the location of the command line tool.
+ * Creates {@link SmartDevelopmentBridge} instance.
* <p/>
- * Any existing server will be disconnected, unless the location is the same and
- * <code>forceNewBridge</code> is set to false.
- * @param osLocation the location of the command line tool 'sdb'
- * @param forceNewBridge force creation of a new bridge even if one with the same location
- * already exists.
- * @return a connected bridge.
+ * @param location the location of 'sdb'
+ * @param bForce force to create new instance
+ *
+ * @return {@link SmartDevelopmentBridge} instance
*/
public static
SmartDevelopmentBridge
createBridge(
- final String osLocation,
- final boolean forceNewBridge
+ final String location,
+ final boolean bForce
)
{
init();
synchronized (sLock) {
if (instance != null) {
- if (instance.mSdbOsLocation != null && instance.mSdbOsLocation.equals(osLocation) &&
- forceNewBridge == false) {
+ if (instance.mSdbOsLocation != null && instance.mSdbOsLocation.equals(location) &&
+ bForce == false) {
return instance;
} else {
// stop the current server
}
}
- instance = new SmartDevelopmentBridge(osLocation);
+ instance = new SmartDevelopmentBridge(location);
instance.start();
-
- // because the listeners could remove themselves from the list while processing
- // their event callback, we make a copy of the list and iterate on it instead of
- // the main list.
- // This mostly happens when the application quits.
- IDebugBridgeChangeListener[] listenersCopy = sBridgeListeners.toArray(
- new IDebugBridgeChangeListener[sBridgeListeners.size()]);
-
- // notify the listeners of the change
- for (IDebugBridgeChangeListener listener : listenersCopy) {
- // we attempt to catch any exception so that a bad listener doesn't kill our
- // thread
- try {
- listener.bridgeChanged(instance);
- } catch (Exception e) {
- Log.e(TAG_SDBLIB, e);
+
+ for ( final IDebugBridgeChangeListener listener : sBridgeListeners.toArray( new IDebugBridgeChangeListener[0] ) ) {
+ try
+ {
+ listener.bridgeChanged( instance );
+ }
+ catch ( final Exception e )
+ {
+ Log.e( TAG_SDBLIB, e );
}
}
/**
* Starts the sdb host side server.
+ *
* @return true if success
*/
- synchronized boolean startSdb() {
- if (mSdbOsLocation == null) {
+ synchronized
+ boolean
+ startSdb()
+ {
+ if (mSdbOsLocation == null)
+ {
Log.e(TAG_SDB,
"Cannot start sdb when SmartDevelopmentBridge is created without the location of sdb."); //$NON-NLS-1$
return false;
return true;
} catch (IOException ioe) {
Log.d(TAG_SDBLIB, "unable to run 'sdb': " + ioe.getMessage()); //$NON-NLS-1$
- // we'll return false;
} catch (InterruptedException ie) {
Log.d(TAG_SDBLIB, "unable to run 'sdb': " + ie.getMessage()); //$NON-NLS-1$
- // we'll return false;
}
return false;
command[1] = "kill-server"; //$NON-NLS-1$
proc = Runtime.getRuntime().exec(command);
status = proc.waitFor();
+
+ if ( 0 == status )
+ {
+ Log.d(TAG_SDBLIB, "'sdb kill-server' succeeded"); //$NON-NLS-1$
+ setStarted(false);
+ return true;
+ }
}
catch (IOException ioe) {
// we'll return false;
// we'll return false;
}
- if (status != 0) {
- Log.w(TAG_SDBLIB,
- "'sdb kill-server' failed -- run manually if necessary"); //$NON-NLS-1$
- return false;
- }
+ Log.w(TAG_SDBLIB,
+ "'sdb kill-server' failed -- run manually if necessary"); //$NON-NLS-1$
+ return false;
- Log.d(TAG_SDBLIB, "'sdb kill-server' succeeded"); //$NON-NLS-1$
- setStarted(false);
- return true;
}
/**
- * Get the stderr outputs
+ * Get and return the stderr outputs
*
- * @param process The process to get the ouput from
+ * @param process The process to get the stderr from
*
* @return contents of error stream( stderr )
*
-/*\r
- * sdblib\r
- *\r
- * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
- *\r
- * Contact: \r
- * Kangho Kim <kh5325.kim@samsung.com>\r
- * BonYong Lee <bonyong.lee@samsung.com>\r
- * \r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- *\r
- * Contributors:\r
- * - S-Core Co., Ltd\r
- *\r
- */\r
-package org.tizen.sdblib;\r
-\r
-import static org.junit.Assert.assertArrayEquals;\r
-import static org.junit.Assert.assertEquals;\r
-import static org.junit.Assert.assertTrue;\r
-import static org.powermock.api.mockito.PowerMockito.mock;\r
-import static org.powermock.api.mockito.PowerMockito.when;\r
-import static org.tizen.sdblib.SdbHelper.check;\r
-import static org.tizen.sdblib.SdbHelper.read;\r
-import static org.tizen.sdblib.SdbHelper.readAsString;\r
-\r
-import java.nio.ByteBuffer;\r
-import java.nio.channels.SocketChannel;\r
-\r
-import org.junit.Test;\r
-import org.mockito.Matchers;\r
-import org.mockito.invocation.InvocationOnMock;\r
-import org.mockito.stubbing.Answer;\r
-\r
-/**\r
- * SdbHelperTest\r
- *\r
- * Testcase for {@link SdbHelper}\r
- * \r
- * @author BonYong Lee{@literal <bonyong.lee@samsung.com>} (S-Core)\r
- */\r
-public class\r
-SdbHelperTest\r
-{\r
-\r
- /**\r
- * test for {@link SdbHelper#check(byte[], int, byte[], int, int)}\r
- * \r
- * @throws Exception if test fails\r
- */\r
- @Test\r
- public\r
- void\r
- test_check()\r
- throws Exception\r
- {\r
- assertTrue( check( "HELLO".getBytes(), 0, "HEL123".getBytes(), 0, 3) );\r
- }\r
- \r
- @Test\r
- public\r
- void\r
- test_read()\r
- throws Exception\r
- {\r
- final SocketChannel channel = mock( SocketChannel.class );\r
- final byte[] buffer = new byte[4];\r
- when( channel.read( Matchers.<ByteBuffer>any() ) ).then( new Answer<Integer>()\r
- {\r
-\r
- @Override\r
- public\r
- Integer\r
- answer(\r
- final InvocationOnMock invocation\r
- )\r
- throws Throwable\r
- {\r
- final ByteBuffer buf = (ByteBuffer) invocation.getArguments()[0];\r
- buf.put( "HELO".getBytes() );\r
- return 4;\r
- }\r
- } );\r
- read( channel, buffer, -1, -1 );\r
- \r
- assertArrayEquals( "HELO".getBytes(), buffer );\r
- }\r
- \r
- @Test\r
- public\r
- void\r
- test_readAsString()\r
- throws Exception\r
- {\r
- final SocketChannel channel = mock( SocketChannel.class );\r
- final byte[] buffer = new byte[4];\r
- when( channel.read( Matchers.<ByteBuffer>any() ) ).then( new Answer<Integer>()\r
- {\r
-\r
- @Override\r
- public\r
- Integer\r
- answer(\r
- final InvocationOnMock invocation\r
- )\r
- throws Throwable\r
- {\r
- final ByteBuffer buf = (ByteBuffer) invocation.getArguments()[0];\r
- buf.put( "HELO".getBytes() );\r
- return 4;\r
- }\r
- } );\r
- assertEquals( "HELO", readAsString( channel, buffer ) );\r
- }\r
- \r
-\r
-}\r
+/*
+ * sdblib
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * Kangho Kim <kh5325.kim@samsung.com>
+ * BonYong Lee <bonyong.lee@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+package org.tizen.sdblib;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+import static org.mockito.Matchers.any;
+import static org.powermock.api.mockito.PowerMockito.mock;
+import static org.powermock.api.mockito.PowerMockito.when;
+import static org.tizen.sdblib.SdbHelper.check;
+import static org.tizen.sdblib.SdbHelper.read;
+import static org.tizen.sdblib.SdbHelper.readAsString;
+import static org.tizen.sdblib.SdbHelper.write;
+import static org.tizen.sdblib.util.ThreadUtil.trySleep;
+
+import java.io.ByteArrayOutputStream;
+import java.nio.ByteBuffer;
+import java.nio.channels.SocketChannel;
+
+import org.junit.Test;
+import org.mockito.Matchers;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+import org.tizen.sdblib.exception.TimeoutException;
+
+public class
+SdbHelperTest
+{
+
+ @Test
+ public
+ void
+ test_check()
+ throws Exception
+ {
+ assertTrue( check( "HELLO".getBytes(), 0, "HEL123".getBytes(), 0, 3) );
+ }
+
+ @Test
+ public
+ void
+ test_read()
+ throws Exception
+ {
+ final SocketChannel channel = mock( SocketChannel.class );
+ final byte[] buffer = new byte[4];
+ when( channel.read( Matchers.<ByteBuffer>any() ) ).then( new Answer<Integer>()
+ {
+
+ @Override
+ public
+ Integer
+ answer(
+ final InvocationOnMock invocation
+ )
+ throws Throwable
+ {
+ final ByteBuffer buf = (ByteBuffer) invocation.getArguments()[0];
+ buf.put( "HELO".getBytes() );
+ return 4;
+ }
+ } );
+ read( channel, buffer, -1, -1 );
+
+ assertArrayEquals( "HELO".getBytes(), buffer );
+ }
+
+ @Test
+ public
+ void
+ test_readAsString()
+ throws Exception
+ {
+ final SocketChannel channel = mock( SocketChannel.class );
+ final byte[] buffer = new byte[4];
+ when( channel.read( Matchers.<ByteBuffer>any() ) ).then( new Answer<Integer>()
+ {
+
+ @Override
+ public
+ Integer
+ answer(
+ final InvocationOnMock invocation
+ )
+ throws Throwable
+ {
+ final ByteBuffer buf = (ByteBuffer) invocation.getArguments()[0];
+ buf.put( "HELO".getBytes() );
+ return 4;
+ }
+ } );
+ assertEquals( "HELO", readAsString( channel, buffer ) );
+ }
+
+ @Test
+ public
+ void
+ test_write()
+ throws Exception
+ {
+ {
+ final SocketChannel channel = mock( SocketChannel.class );
+ final byte[] buffer = "Hello, world".getBytes();
+ final ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+ when( channel.write( any( ByteBuffer.class ) ) ).then( new Answer<Integer>()
+ {
+
+ @Override
+ public Integer answer(InvocationOnMock invocation) throws Throwable
+ {
+ final ByteBuffer b = (ByteBuffer) invocation.getArguments()[0];
+ int i = 0;
+ while( i<2 && 0 < b.remaining() ) {
+ byteOut.write( b.get() );
+ ++i;
+ }
+ return i;
+ }
+ } );
+ write( channel, buffer, -1, 1000 );
+
+ assertArrayEquals( "Hello, world".getBytes(), byteOut.toByteArray() );
+ }
+
+ {
+ final SocketChannel channel = mock( SocketChannel.class );
+ final byte[] buffer = "Hello, world".getBytes();
+ final ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
+ when( channel.write( any( ByteBuffer.class ) ) ).then( new Answer<Integer>()
+ {
+
+ @Override
+ public
+ Integer
+ answer( final InvocationOnMock invocation
+ ) throws Throwable
+ {
+ final ByteBuffer b = (ByteBuffer) invocation.getArguments()[0];
+ int i = 0;
+ while( i<2 && 0 < b.remaining() ) {
+ byteOut.write( b.get() );
+ ++i;
+ }
+ trySleep( 300 );
+ return i;
+ }
+ } );
+ try
+ {
+ write( channel, buffer, -1, 1000 );
+ fail();
+ }
+ catch ( final TimeoutException e )
+ {
+ }
+
+ }
+
+ }
+
+}
public void test_checkForVersion() throws Exception {
final String[] validedVersions = { "1.0.1", "1.0.111", "1.10.111", "35.35.123", "0.0.1", "0.1" };
for ( String version : validedVersions ) {
- assertTrue( ValidationUtil.checkForVersion( version ) );
+ assertTrue( "Failed for \"" + version + "\"", ValidationUtil.checkForVersion( version ) );
}
final String[] invalidedVersions = { "", "0.0.0", "111.111.111111", "1", "1.0.", "0" };
for ( String version : invalidedVersions ) {
- assertFalse( ValidationUtil.checkForVersion( version ) );
+ assertFalse( "Failed for \"" + version + "\"", ValidationUtil.checkForVersion( version ) );
}
}
public void test_checkForDynamicBoxId() throws Exception {
final String[] validedIDS = { "1wfV7ZwO6r.test.test", "1wfV7ZwO6r.test.111", "1wfV7ZwO6r.test.test2222" };
for ( String id : validedIDS ) {
- assertTrue( ValidationUtil.checkForDynamicBoxId( id ) );
+ assertTrue( "Failed for \"" + id + "\"", ValidationUtil.checkForDynamicBoxId( id ) );
}
final String[] invalidedIDS = { "", "1wfV7ZwO6r.test.-1", "1wfV7ZwO6r.test.!test", "1wfV7ZwO6r.test.test test", "1wfV7ZwO6r.test.test!#", "1wfV7ZwO6r." };
for ( String id : invalidedIDS ) {
- assertFalse( ValidationUtil.checkForDynamicBoxId( id ) );
+ assertFalse( "Failed for \"" + id + "\"", ValidationUtil.checkForDynamicBoxId( id ) );
}
}