Added rotation of presentation view.

Change-Id: Iea68b7740c5e7cf9380c91b8b85ff02fd9c11b8e
This commit is contained in:
Andrzej J.R. Hunt
2012-08-14 12:59:22 +02:00
parent e1fb965edb
commit e02468f6e8
18 changed files with 339 additions and 190 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 222 B

After

Width:  |  Height:  |  Size: 203 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 B

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/handle_vertical_light" android:state_activated="true"/>
<item android:drawable="@drawable/handle_vertical_light" android:state_pressed="true"/>
<item android:drawable="@drawable/handle_vertical_light" android:state_focused="true"/>
<item android:drawable="@drawable/handle_vertical_default"/>
</selector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 202 B

View File

@@ -0,0 +1,54 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/presentation_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:orientation="vertical" >
<pl.polidea.coverflow.CoverFlow
xmlns:coverflow="http://schemas.android.com/apk/res/org.libreoffice.impressremote"
android:id="@+id/presentation_coverflow"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="5dip"
coverflow:imageHeight="150dip"
coverflow:imageWidth="180dip"
coverflow:withReflection="false" />
<TextView
android:id="@+id/presentation_slidenumber"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="" />
</LinearLayout>
<ImageView
android:id="@+id/presentation_handle"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginLeft="6dp"
android:layout_marginRight="6dp"
android:contentDescription="@string/presentation_ui_resizehandle"
android:paddingBottom="5dp"
android:paddingTop="5dp"
android:scaleType="fitXY"
android:src="@drawable/handle" />
<ScrollView
android:id="@+id/presentation_scrollview"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<WebView
android:id="@+id/presentation_notes"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</ScrollView>
</LinearLayout>

View File

@@ -5,24 +5,29 @@
android:orientation="vertical" > android:orientation="vertical" >
<TextView <TextView
android:id="@+id/textView1" android:id="@+id/pairing_instruction1"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:layout_margin="10dip"
android:gravity="center"
android:text="@string/pairing_instructions_1" /> android:text="@string/pairing_instructions_1" />
<TextView <TextView
android:id="@+id/textView2" android:id="@+id/pairing_instruction2_deviceName"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:text="@string/pairing_instructions_2" /> android:layout_margin="10dip"
android:gravity="center"
android:text="@string/pairing_instructions_2_deviceName" />
<TextView <TextView
android:id="@+id/textView3" android:id="@+id/pairing_instruction3"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:layout_margin="10dip"
android:text="@string/pairing_instructions_3" /> android:text="@string/pairing_instructions_3" />
<TextView <TextView
@@ -30,7 +35,9 @@
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" android:layout_gravity="center_horizontal"
android:layout_margin="10dip"
android:text="" android:text=""
android:textAppearance="?android:attr/textAppearanceLarge" /> android:textAppearance="?android:attr/textAppearanceLarge"
android:textSize="75dip" />
</LinearLayout> </LinearLayout>

View File

@@ -24,7 +24,7 @@
<string name="wifi">WI-FI</string> <string name="wifi">WI-FI</string>
<string name="selector_noservers">Searching for computers…</string> <string name="selector_noservers">Searching for computers…</string>
<string name="pairing_instructions_1">In Impress, click on the "Slideshow" menu and select "Impress Remote".</string> <string name="pairing_instructions_1">In Impress, click on the "Slideshow" menu and select "Impress Remote".</string>
<string name="pairing_instructions_2">Choose "{1}" as your device.</string> <string name="pairing_instructions_2_deviceName">Choose "{1}" as your device.</string>
<string name="pairing_instructions_3">Then input this PIN:</string> <string name="pairing_instructions_3">Then input this PIN:</string>
</resources> </resources>

View File

@@ -8,26 +8,36 @@
*/ */
package org.libreoffice.impressremote; package org.libreoffice.impressremote;
import java.text.MessageFormat;
import org.libreoffice.impressremote.communication.CommunicationService; import org.libreoffice.impressremote.communication.CommunicationService;
import org.libreoffice.impressremote.communication.CommunicationService.State;
import android.app.Activity; import android.app.Activity;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Bundle; import android.os.Bundle;
import android.os.IBinder;
import android.support.v4.content.LocalBroadcastManager; import android.support.v4.content.LocalBroadcastManager;
import android.widget.TextView; import android.widget.TextView;
public class PairingActivity extends Activity { public class PairingActivity extends Activity {
private CommunicationService mCommunicationService;
private boolean mIsBound = false;
private TextView mPinText; private TextView mPinText;
/** Called when the activity is first created. */ /** Called when the activity is first created. */
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pairing);
bindService(new Intent(this, CommunicationService.class), mConnection,
Context.BIND_IMPORTANT);
mIsBound = true;
mPinText = (TextView) findViewById(R.id.pairing_pin); mPinText = (TextView) findViewById(R.id.pairing_pin);
@@ -46,6 +56,33 @@ public class PairingActivity extends Activity {
// refreshLists(); // refreshLists();
} }
private ServiceConnection mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName aClassName,
IBinder aService) {
setContentView(R.layout.activity_pairing);
((TextView) findViewById(R.id.pairing_instruction2_deviceName))
.setText(MessageFormat
.format(getResources()
.getString(R.string.pairing_instructions_2_deviceName),
mCommunicationService
.getDeviceName()));
mCommunicationService = ((CommunicationService.CBinder) aService)
.getService();
if (mCommunicationService.getState() == State.CONNECTING) {
mPinText.setText(mCommunicationService.getPairingPin());
}
}
@Override
public void onServiceDisconnected(ComponentName aClassName) {
mCommunicationService = null;
}
};
private BroadcastReceiver mListener = new BroadcastReceiver() { private BroadcastReceiver mListener = new BroadcastReceiver() {
@Override @Override

View File

@@ -7,6 +7,7 @@ import pl.polidea.coverflow.AbstractCoverFlowImageAdapter;
import pl.polidea.coverflow.CoverFlow; import pl.polidea.coverflow.CoverFlow;
import android.app.Fragment; import android.app.Fragment;
import android.content.Context; import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Color; import android.graphics.Color;
@@ -28,224 +29,236 @@ import android.widget.TextView;
public class PresentationFragment extends Fragment { public class PresentationFragment extends Fragment {
private CoverFlow mTopView; private CoverFlow mTopView;
private ImageView mHandle; private ImageView mHandle;
private View mLayout; private View mLayout;
private WebView mNotes; private WebView mNotes;
private Context mContext; private Context mContext;
private TextView mNumberText; private TextView mNumberText;
private CommunicationService mCommunicationService; private CommunicationService mCommunicationService;
private SlideShow mSlideShow; private SlideShow mSlideShow;
private float mOriginalCoverflowWidth; private float mOriginalCoverflowWidth;
private float mOriginalCoverflowHeight; private float mOriginalCoverflowHeight;
private float mNewCoverflowWidth = 0; private float mNewCoverflowWidth = 0;
private float mNewCoverflowHeight = 0; private float mNewCoverflowHeight = 0;
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) { Bundle savedInstanceState) {
mContext = container.getContext(); mContext = container.getContext();
View v = inflater.inflate(R.layout.fragment_presentation, container, View v = inflater.inflate(R.layout.fragment_presentation, container,
false); false);
mNotes = (WebView) v.findViewById(R.id.presentation_notes); mNotes = (WebView) v.findViewById(R.id.presentation_notes);
String summary = "<html><body>This is just a test<br/><ul><li>And item</li><li>And again</li></ul>More text<br/>Blabla<br/>Blabla<br/>blabla<br/>Blabla</body></html>"; String summary = "<html><body>This is just a test<br/><ul><li>And item</li><li>And again</li></ul>More text<br/>Blabla<br/>Blabla<br/>blabla<br/>Blabla</body></html>";
mNotes.loadData(summary, "text/html", null); mNotes.loadData(summary, "text/html", null);
mNotes.setBackgroundColor(Color.TRANSPARENT); mNotes.setBackgroundColor(Color.TRANSPARENT);
// TextView aText = new TextView(); mTopView = (CoverFlow) v.findViewById(R.id.presentation_coverflow);
// aText.setText
mTopView = (CoverFlow) v.findViewById(R.id.presentation_coverflow); mLayout = v.findViewById(R.id.presentation_layout);
mLayout = v.findViewById(R.id.presentation_layout); mNumberText = (TextView) v.findViewById(R.id.presentation_slidenumber);
mNumberText = (TextView) v.findViewById(R.id.presentation_slidenumber); mHandle = (ImageView) v.findViewById(R.id.presentation_handle);
mHandle.setOnTouchListener(new SizeListener());
mHandle = (ImageView) v.findViewById(R.id.presentation_handle); // Call again to set things up if necessary.
mHandle.setOnTouchListener(new SizeListener()); setCommunicationService(mCommunicationService);
// Call again to set things up if necessary. // Save the height/width for future reference
setCommunicationService(mCommunicationService); mOriginalCoverflowHeight = mTopView.getImageHeight();
mOriginalCoverflowWidth = mTopView.getImageWidth();
// Save the height/width for future reference if (mNewCoverflowHeight != 0) {
mOriginalCoverflowHeight = mTopView.getImageHeight(); ThumbnailAdapter aAdapter = (ThumbnailAdapter) mTopView
mOriginalCoverflowWidth = mTopView.getImageWidth(); .getAdapter();
aAdapter.setHeight(mNewCoverflowHeight);
mTopView.setImageHeight(mNewCoverflowHeight);
aAdapter.setWidth(mNewCoverflowWidth);
mTopView.setImageWidth(mNewCoverflowWidth);
if (mNewCoverflowHeight != 0) { // We need to update the view now
ThumbnailAdapter aAdapter = (ThumbnailAdapter) mTopView aAdapter.notifyDataSetChanged();
.getAdapter(); }
aAdapter.setHeight(mNewCoverflowHeight); return v;
mTopView.setImageHeight(mNewCoverflowHeight); }
aAdapter.setWidth(mNewCoverflowWidth);
mTopView.setImageWidth(mNewCoverflowWidth);
// We need to update the view now private void updateSlideNumberDisplay() {
aAdapter.notifyDataSetChanged(); int aSlide = mSlideShow.getCurrentSlide();
} mNumberText.setText((aSlide + 1) + "/" + mSlideShow.getSize());
return v; mNotes.loadData(mSlideShow.getNotes(aSlide), "text/html", null);
} }
private void updateSlideNumberDisplay() { // -------------------------------------------------- RESIZING LISTENER ----
int aSlide = mSlideShow.getCurrentSlide(); private class SizeListener implements OnTouchListener {
mNumberText.setText((aSlide + 1) + "/" + mSlideShow.getSize());
mNotes.loadData(mSlideShow.getNotes(aSlide), "text/html", null);
}
// -------------------------------------------------- RESIZING LISTENER ---- @Override
private class SizeListener implements OnTouchListener { public boolean onTouch(View aView, MotionEvent aEvent) {
@Override switch (aEvent.getAction()) {
public boolean onTouch(View aView, MotionEvent aEvent) { case MotionEvent.ACTION_DOWN:
mHandle.setImageResource(R.drawable.handle_light);
break;
case MotionEvent.ACTION_UP:
mHandle.setImageResource(R.drawable.handle_default);
break;
case MotionEvent.ACTION_MOVE:
LayoutParams aParams = mTopView.getLayoutParams();
switch (aEvent.getAction()) { final int DRAG_MARGIN = 120;
case MotionEvent.ACTION_DOWN:
mHandle.setImageResource(R.drawable.handle_light);
break;
case MotionEvent.ACTION_UP:
mHandle.setImageResource(R.drawable.handle_default);
break;
case MotionEvent.ACTION_MOVE:
LayoutParams aParams = mTopView.getLayoutParams();
int aHeight = mTopView.getHeight();
int aViewSize = mLayout.getHeight();
final int DRAG_MARGIN = 120; boolean aPortrait = (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT);
// Calculate height change, taking limits into account int aFlowSize = mTopView.getHeight();
int aDiff = (int) (aEvent.getY()); int aViewSize = mLayout.getHeight();
if (aDiff + aHeight < DRAG_MARGIN) {
aDiff = DRAG_MARGIN - aHeight;
} else if ((aHeight + aDiff) > (aViewSize - DRAG_MARGIN)) {
aDiff = (aViewSize - DRAG_MARGIN) - aHeight;
}
// Now deal with the internal height // Calculate height change, taking limits into account
AbstractCoverFlowImageAdapter aAdapter = (AbstractCoverFlowImageAdapter) mTopView int aDiff = (int) (aPortrait ? aEvent.getY() : aEvent.getX());
.getAdapter(); if (aDiff + aFlowSize < DRAG_MARGIN) {
aDiff = DRAG_MARGIN - aFlowSize;
} else if ((aFlowSize + aDiff) > (aViewSize - DRAG_MARGIN)) {
aDiff = (aViewSize - DRAG_MARGIN) - aFlowSize;
}
double aRatio = mOriginalCoverflowWidth // Now deal with the internal height
/ mOriginalCoverflowHeight; AbstractCoverFlowImageAdapter aAdapter = (AbstractCoverFlowImageAdapter) mTopView
float aHeightNew = mTopView.getImageHeight() + aDiff; .getAdapter();
float aWidthNew = (float) (aRatio * aHeightNew);
// Too wide -- so scale down double aRatio = mOriginalCoverflowWidth
if (aWidthNew > mLayout.getWidth() - 50) { / mOriginalCoverflowHeight;
aWidthNew = mLayout.getWidth() - 50; float aHeightNew;
aHeightNew = (float) (aWidthNew / aRatio); float aWidthNew;
aDiff = (int) (aHeightNew - mTopView.getImageHeight()); if (aPortrait) {
} aHeightNew = mTopView.getImageHeight() + aDiff;
aWidthNew = (float) (aRatio * aHeightNew);
// Too wide -- so scale down
if (aWidthNew > mLayout.getWidth() - 50) {
aWidthNew = mLayout.getWidth() - 50;
aHeightNew = (float) (aWidthNew / aRatio);
aDiff = (int) (aHeightNew - mTopView.getImageHeight());
}
} else {
aWidthNew = mTopView.getImageWidth();
aHeightNew = (float) (aWidthNew / aRatio);
// Too High -- so scale down
if (aHeightNew > mLayout.getHeight() - 50) {
aHeightNew = mLayout.getHeight() - 50;
aWidthNew = (float) (aHeightNew / aRatio);
aDiff = (int) (aWidthNew - mTopView.getImageWidth());
}
}
mNewCoverflowHeight = aHeightNew; mNewCoverflowHeight = aHeightNew;
mNewCoverflowWidth = aWidthNew; mNewCoverflowWidth = aWidthNew;
aAdapter.setHeight(aHeightNew); aAdapter.setHeight(aHeightNew);
mTopView.setImageHeight(aHeightNew); mTopView.setImageHeight(aHeightNew);
aAdapter.setWidth(aWidthNew); aAdapter.setWidth(aWidthNew);
mTopView.setImageWidth(aWidthNew); mTopView.setImageWidth(aWidthNew);
// Force an update of the view // Force an update of the view
aAdapter.notifyDataSetChanged(); aAdapter.notifyDataSetChanged();
break; break;
} }
// TODO Auto-generated method stub // TODO Auto-generated method stub
return true; return true;
} }
} }
// ----------------------------------------------------- CLICK LISTENER ---- // ----------------------------------------------------- CLICK LISTENER ----
protected class ClickListener implements OnItemSelectedListener { protected class ClickListener implements OnItemSelectedListener {
@Override @Override
public void onItemSelected(AdapterView<?> arg0, View arg1, public void onItemSelected(AdapterView<?> arg0, View arg1,
int aPosition, long arg3) { int aPosition, long arg3) {
if (mCommunicationService != null) if (mCommunicationService != null)
mCommunicationService.getTransmitter().gotoSlide(aPosition); mCommunicationService.getTransmitter().gotoSlide(aPosition);
} }
@Override @Override
public void onNothingSelected(AdapterView<?> arg0) { public void onNothingSelected(AdapterView<?> arg0) {
} }
} }
// ---------------------------------------------------- MESSAGE HANDLER ---- // ---------------------------------------------------- MESSAGE HANDLER ----
public void setCommunicationService( public void setCommunicationService(
CommunicationService aCommunicationService) { CommunicationService aCommunicationService) {
mCommunicationService = aCommunicationService; mCommunicationService = aCommunicationService;
if (mCommunicationService == null) if (mCommunicationService == null)
return; return;
mSlideShow = mCommunicationService.getSlideShow(); mSlideShow = mCommunicationService.getSlideShow();
if (mTopView != null && mSlideShow != null) { if (mTopView != null && mSlideShow != null) {
mTopView.setAdapter(new ThumbnailAdapter(mContext, mSlideShow)); mTopView.setAdapter(new ThumbnailAdapter(mContext, mSlideShow));
mTopView.setSelection(mSlideShow.getCurrentSlide(), true); mTopView.setSelection(mSlideShow.getCurrentSlide(), true);
mTopView.setOnItemSelectedListener(new ClickListener()); mTopView.setOnItemSelectedListener(new ClickListener());
} }
updateSlideNumberDisplay(); updateSlideNumberDisplay();
} }
public void handleMessage(Message aMessage) { public void handleMessage(Message aMessage) {
Bundle aData = aMessage.getData(); Bundle aData = aMessage.getData();
switch (aMessage.what) { switch (aMessage.what) {
case CommunicationService.MSG_SLIDE_CHANGED: case CommunicationService.MSG_SLIDE_CHANGED:
int aSlide = aData.getInt("slide_number"); int aSlide = aData.getInt("slide_number");
mTopView.setSelection(aSlide, true); mTopView.setSelection(aSlide, true);
updateSlideNumberDisplay(); updateSlideNumberDisplay();
break; break;
case CommunicationService.MSG_SLIDE_PREVIEW: case CommunicationService.MSG_SLIDE_PREVIEW:
int aNSlide = aData.getInt("slide_number"); int aNSlide = aData.getInt("slide_number");
if (mTopView.getSelectedItemPosition() == aNSlide) { if (mTopView.getSelectedItemPosition() == aNSlide) {
// mTopView. // TODO: update the current item // mTopView. // TODO: update the current item
} }
break; break;
} }
} }
// ------------------------------------------------- THUMBNAIL ADAPTER ---- // ------------------------------------------------- THUMBNAIL ADAPTER ----
protected class ThumbnailAdapter extends AbstractCoverFlowImageAdapter { protected class ThumbnailAdapter extends AbstractCoverFlowImageAdapter {
private Context mContext; private Context mContext;
private SlideShow mSlideShow; private SlideShow mSlideShow;
public ThumbnailAdapter(Context aContext, SlideShow aSlideShow) { public ThumbnailAdapter(Context aContext, SlideShow aSlideShow) {
mContext = aContext; mContext = aContext;
mSlideShow = aSlideShow; mSlideShow = aSlideShow;
} }
@Override @Override
public int getCount() { public int getCount() {
return mSlideShow.getSize(); return mSlideShow.getSize();
} }
@Override @Override
protected Bitmap createBitmap(int position) { protected Bitmap createBitmap(int position) {
Bitmap aBitmap = mSlideShow.getImage(position); Bitmap aBitmap = mSlideShow.getImage(position);
final int borderWidth = 8; final int borderWidth = 8;
Paint p = new Paint(Paint.ANTI_ALIAS_FLAG); Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
p.setShadowLayer(borderWidth, 0, 0, Color.BLACK); p.setShadowLayer(borderWidth, 0, 0, Color.BLACK);
RectF aRect = new RectF(borderWidth, borderWidth, borderWidth RectF aRect = new RectF(borderWidth, borderWidth, borderWidth
+ aBitmap.getWidth(), borderWidth + aBitmap.getWidth(), borderWidth
+ aBitmap.getHeight()); + aBitmap.getHeight());
Bitmap aOut = Bitmap.createBitmap(aBitmap.getWidth() + 2 Bitmap aOut = Bitmap.createBitmap(aBitmap.getWidth() + 2
* borderWidth, aBitmap.getHeight() + 2 * borderWidth, aBitmap.getHeight() + 2
* borderWidth, aBitmap.getConfig()); * borderWidth, aBitmap.getConfig());
Canvas canvas = new Canvas(aOut); Canvas canvas = new Canvas(aOut);
canvas.drawColor(Color.TRANSPARENT); canvas.drawColor(Color.TRANSPARENT);
canvas.drawRect(aRect, p); canvas.drawRect(aRect, p);
canvas.drawBitmap(aBitmap, null, aRect, null); canvas.drawBitmap(aBitmap, null, aRect, null);
return aOut; return aOut;
} }
} }
} }

View File

@@ -158,9 +158,9 @@ public class SelectorActivity extends Activity {
aLayout); aLayout);
TextView aText = (TextView) aView TextView aText = (TextView) aView
.findViewById(R.id.selector_sub_label); .findViewById(R.id.selector_sub_label);
aView.setOnClickListener(mClickListener); aText.setOnClickListener(mClickListener);
aText.setText(aServer.getName()); aText.setText(aServer.getName());
aMap.put(aServer, aView); aMap.put(aServer, aText);
} }
} }
@@ -182,7 +182,6 @@ public class SelectorActivity extends Activity {
@Override @Override
public void onClick(View aView) { public void onClick(View aView) {
// TODO Auto-generated method stub
mCommunicationService.stopFindingServers(); mCommunicationService.stopFindingServers();
Server aDesiredServer = null; Server aDesiredServer = null;

View File

@@ -32,6 +32,7 @@ public abstract class Client {
protected InputStream mInputStream; protected InputStream mInputStream;
protected BufferedReader mReader; protected BufferedReader mReader;
protected OutputStream mOutputStream; protected OutputStream mOutputStream;
protected String mPin = "";
public abstract void closeConnection(); public abstract void closeConnection();
@@ -79,6 +80,10 @@ public abstract class Client {
} }
public String getPin() {
return mPin;
}
/** /**
* Send a valid JSON string to the server. * Send a valid JSON string to the server.
* *

View File

@@ -27,6 +27,22 @@ public class CommunicationService extends Service implements Runnable {
private State mState = State.DISCONNECTED; private State mState = State.DISCONNECTED;
public State getState() {
return mState;
}
public String getPairingPin() {
if (mClient != null)
return mClient.getPin();
else
return "";
}
public String getDeviceName() {
return "Bob";
// FIXME: get the device name somehow.
}
private State mStateDesired = State.DISCONNECTED; private State mStateDesired = State.DISCONNECTED;
private Server mServerDesired = null; private Server mServerDesired = null;

View File

@@ -17,7 +17,6 @@ import java.util.Random;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.StrictMode;
import android.support.v4.content.LocalBroadcastManager; import android.support.v4.content.LocalBroadcastManager;
/** /**
@@ -33,10 +32,6 @@ public class NetworkClient extends Client {
public NetworkClient(String ipAddress, Context aContext) { public NetworkClient(String ipAddress, Context aContext) {
super(aContext); super(aContext);
// FIXME: eventually networking will be fully threaded.
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
.permitAll().build();
StrictMode.setThreadPolicy(policy);
try { try {
mSocket = new Socket(ipAddress, PORT); mSocket = new Socket(ipAddress, PORT);
mInputStream = mSocket.getInputStream(); mInputStream = mSocket.getInputStream();
@@ -45,10 +40,14 @@ public class NetworkClient extends Client {
mOutputStream = mSocket.getOutputStream(); mOutputStream = mSocket.getOutputStream();
// Pairing. // Pairing.
Random aRandom = new Random(); Random aRandom = new Random();
String aPin = "" + aRandom.nextInt(10000); String aPin = "" + (aRandom.nextInt(9000) + 1000);
while (aPin.length() < 4) {
aPin = "0" + aPin; // Add leading zeros if necessary
}
Intent aIntent = new Intent( Intent aIntent = new Intent(
CommunicationService.MSG_PAIRING_STARTED); CommunicationService.MSG_PAIRING_STARTED);
aIntent.putExtra("PIN", aPin); aIntent.putExtra("PIN", aPin);
mPin = aPin;
LocalBroadcastManager.getInstance(mContext).sendBroadcast(aIntent); LocalBroadcastManager.getInstance(mContext).sendBroadcast(aIntent);
// Send out // Send out
String aName = "Bob"; // TODO: get the proper name String aName = "Bob"; // TODO: get the proper name

View File

@@ -8,6 +8,8 @@ import java.net.InetAddress;
import java.net.SocketException; import java.net.SocketException;
import java.util.HashMap; import java.util.HashMap;
import org.libreoffice.impressremote.communication.Server.Protocol;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.support.v4.content.LocalBroadcastManager; import android.support.v4.content.LocalBroadcastManager;
@@ -93,6 +95,14 @@ public class ServerFinder {
mFinishRequested = false; mFinishRequested = false;
// TODO: Remove for production
mServerList.put("10.0.2.2",
new Server(Protocol.NETWORK, "10.0.2.2",
"Android Emulator Localhost", System
.currentTimeMillis()));
Intent aIntent = new Intent(CommunicationService.MSG_SERVERLIST_CHANGED);
LocalBroadcastManager.getInstance(mContext).sendBroadcast(aIntent);
if (mListenerThread == null) { if (mListenerThread == null) {
mListenerThread = new Thread() { mListenerThread = new Thread() {
@Override @Override