├── .gitignore
├── AndroidManifest.xml
├── LICENSE.txt
├── README.markdown
├── assets
├── download.png
├── find.png
├── led.png
├── missed.png
├── phone.png
├── sms.png
└── test36.png
├── build.xml
├── libs
└── android-support-v4.jar
├── project.properties
├── res
├── drawable-hdpi
│ ├── inner_lv.png
│ └── olv_icon.png
├── layout
│ ├── entry_screen.xml
│ ├── test_activity.xml
│ ├── test_activity_left.xml
│ ├── test_activity_right.xml
│ └── user_main_screen.xml
└── values
│ ├── colors.xml
│ ├── dimensions.xml
│ ├── strings.xml
│ └── sytles.xml
└── src
└── com
└── pedronveloso
└── openliveview
├── Utils
├── CommandResult.java
├── Constants.java
├── StaticImages.java
└── Utils.java
├── activities
├── DevMainActivity.java
├── EntryActivity.java
└── UserMainActivity.java
├── protocol
├── AckMessage.java
├── DateTimeRequest.java
├── DateTimeResponse.java
├── GetAllMenuItemsRequest.java
├── GetMenuIconResponse.java
├── LEDRequest.java
├── LEDResponse.java
├── LiveViewRequest.java
├── MenuItemCountRequest.java
├── MenuItemCountResponse.java
├── Request.java
├── Response.java
├── SWVersionRequest.java
├── SWVersionResponse.java
├── ScreenPropertiesRequest.java
├── ScreenPropertiesResponse.java
├── StandByRequest.java
├── StandByResponse.java
├── UnknownResponse.java
├── VibrateRequest.java
└── VibrateResponse.java
├── server
├── BtServer.java
├── Menu.java
└── StateManager.java
└── services
└── CommService.java
/.gitignore:
--------------------------------------------------------------------------------
1 | /.idea/
2 | /liveview_output.txt
3 | /gen/
4 | /out/
5 | /bin/
6 | /ant.properties
7 | /OpenLiveView.iml
8 | /local.properties
9 | /proguard.cfg
10 | /.classpath
11 | /.metadata
12 | /.settings
13 | /default.properties
14 | /.project
15 |
--------------------------------------------------------------------------------
/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
9 |
11 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright 2012 OpenLiveView
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
--------------------------------------------------------------------------------
/README.markdown:
--------------------------------------------------------------------------------
1 | # About #
2 |
3 | This project's goal is to become a complete open source replacement of the LiveView official application, and even extend its original capabilities at some point.
4 |
5 | # WHAT WORKS #
6 |
7 | * Connecting to the LiveView device via Bluetooth
8 | * Basic protocol stack: Vibrate, Led, StandBy, Screen Properties, Date and Time, Protocol Version, Firmware Version
9 | * Basic stacking of commands
10 | * Send Menu Items to LiveView
11 |
12 | # WHAT REMAINS TO BE DONE #
13 |
14 | * Better connection handling
15 | * Handle menu input
16 | * LiveView official plugins support
17 | * Menu theming support
18 | * Integration with CyanogenMod ?
19 | * ...
20 |
21 | # CREDITS #
22 |
23 | This projects initial inspiration was this thread here on XDA: http://forum.xda-developers.com/showthread.php?t=1422106
24 |
25 | This project is maintained by:
26 |
27 | * Pedro Veloso (pedronveloso, aka pedrodh on XDA)
28 | * Florian Sundermann (boombuler)
29 |
30 | ## Special thanks to ##
31 |
32 | * archivator for initiate the project and reverse reverse engineering effort
33 | * AJ256 for firmware reserve engineering effort
34 | * x942
35 |
--------------------------------------------------------------------------------
/assets/download.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pedronveloso/OpenLiveView/62caeb43820a4464ffcc158c8ebd8b2716e7418c/assets/download.png
--------------------------------------------------------------------------------
/assets/find.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pedronveloso/OpenLiveView/62caeb43820a4464ffcc158c8ebd8b2716e7418c/assets/find.png
--------------------------------------------------------------------------------
/assets/led.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pedronveloso/OpenLiveView/62caeb43820a4464ffcc158c8ebd8b2716e7418c/assets/led.png
--------------------------------------------------------------------------------
/assets/missed.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pedronveloso/OpenLiveView/62caeb43820a4464ffcc158c8ebd8b2716e7418c/assets/missed.png
--------------------------------------------------------------------------------
/assets/phone.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pedronveloso/OpenLiveView/62caeb43820a4464ffcc158c8ebd8b2716e7418c/assets/phone.png
--------------------------------------------------------------------------------
/assets/sms.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pedronveloso/OpenLiveView/62caeb43820a4464ffcc158c8ebd8b2716e7418c/assets/sms.png
--------------------------------------------------------------------------------
/assets/test36.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pedronveloso/OpenLiveView/62caeb43820a4464ffcc158c8ebd8b2716e7418c/assets/test36.png
--------------------------------------------------------------------------------
/build.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
7 |
8 |
9 |
29 |
30 |
31 |
40 |
41 |
42 |
43 |
47 |
48 |
49 |
51 |
63 |
64 |
82 |
83 |
84 |
85 |
86 |
--------------------------------------------------------------------------------
/libs/android-support-v4.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pedronveloso/OpenLiveView/62caeb43820a4464ffcc158c8ebd8b2716e7418c/libs/android-support-v4.jar
--------------------------------------------------------------------------------
/project.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system use,
7 | # "ant.properties", and override values to adapt the script to your
8 | # project structure.
9 |
10 | # Project target.
11 | target=android-10
12 |
--------------------------------------------------------------------------------
/res/drawable-hdpi/inner_lv.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pedronveloso/OpenLiveView/62caeb43820a4464ffcc158c8ebd8b2716e7418c/res/drawable-hdpi/inner_lv.png
--------------------------------------------------------------------------------
/res/drawable-hdpi/olv_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pedronveloso/OpenLiveView/62caeb43820a4464ffcc158c8ebd8b2716e7418c/res/drawable-hdpi/olv_icon.png
--------------------------------------------------------------------------------
/res/layout/entry_screen.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
10 |
11 |
19 |
20 |
25 |
26 |
37 |
38 |
48 |
49 |
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/res/layout/test_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
16 |
17 |
22 |
23 |
--------------------------------------------------------------------------------
/res/layout/test_activity_left.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/res/layout/test_activity_right.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
11 |
12 |
16 |
17 |
20 |
21 |
24 |
25 |
28 |
29 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/res/layout/user_main_screen.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
12 |
13 |
--------------------------------------------------------------------------------
/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #ffffff
4 | #000000
5 |
--------------------------------------------------------------------------------
/res/values/dimensions.xml:
--------------------------------------------------------------------------------
1 |
2 | 10dip
3 |
--------------------------------------------------------------------------------
/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Open LiveView
4 |
5 |
6 | Swipe Left and Right for more options
7 | The actions below will become available once the connection with
8 | the device has been set, and the device is in \'Ready\' state
9 | Vibrate
10 | LED Red
11 | LED Blue
12 | LED Green
13 |
14 | Welcome to Open LiveView
15 | Open LiveView (for short OLV) is an OpenSource application
16 | with the purpose of providing a true OpenSource application stack for the interaction between a LiveView device
17 | and an Android device via Bluetooth and improve the communication and usability between the two.
18 | Open LiveView is made available under the Apache License, Version 2.0 . If you wish to learn more about the Apache
19 | license visit http://www.apache.org/licenses/LICENSE-2.0.html .\n This project is currently maintained by Pedro Veloso
20 | ( pedronveloso@androidpt.com ) and Boombuler but you too are free to contribute in any way you can, if you wish
21 | to do so visit https://github.com/pedronveloso/OpenLiveView for the project sources and related. You\'re also free
22 | to join the conversation over that XDA Forum on LiveView here: http://forum.xda-developers.com/showthread.php?t=1422106
23 |
24 | Proceed
25 | Proceed to Dev
26 |
27 |
28 |
--------------------------------------------------------------------------------
/res/values/sytles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
7 |
--------------------------------------------------------------------------------
/src/com/pedronveloso/openliveview/Utils/CommandResult.java:
--------------------------------------------------------------------------------
1 | package com.pedronveloso.openliveview.Utils;
2 |
3 | public class CommandResult {
4 |
5 | private int commandID;
6 | private int commandSuccessCode;
7 |
8 | public CommandResult(int commandSuccessCode, int commandID) {
9 | this.commandSuccessCode = commandSuccessCode;
10 | this.commandID = commandID;
11 | }
12 |
13 | public int getCommandID() {
14 | return commandID;
15 | }
16 |
17 | public int getCommandSuccessCode() {
18 | return commandSuccessCode;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/com/pedronveloso/openliveview/Utils/Constants.java:
--------------------------------------------------------------------------------
1 | package com.pedronveloso.openliveview.Utils;
2 |
3 | public interface Constants {
4 |
5 | public static String LOG_TAG = "OpenLV";
6 |
7 | public static String LIVEVIEW_UUID = "00001101-0000-1000-8000-00805F9B34FB";
8 |
9 | // make this false when we don't need verbose logcat output anymore
10 | public static boolean VERBOSE_LOGCAT = true;
11 |
12 | // Command Success Codes
13 | public static int SC_SUCCESS = 1;
14 | public static int SC_FAIL_IO = 2; //failed because of a regular IO Exception
15 | public static int SC_FAIL_IO_STREAM = 3; //failed because of IO Exception when declaring the Stream
16 | public static int SC_FAIL_UNRECOGNIZED_COMMAND = 4; //failed the identifier of the given command is unrecognized
17 |
18 |
19 |
20 | // For Information about the protocol see:
21 | // https://github.com/BurntBrunch/LivelierView/blob/master/protocol.txt
22 |
23 | public static final String STRING_ENCODING = "iso-8859-1";
24 | public static final byte[] PROTOCOL_VERSION = Utils.prepareString("0.0.6");
25 |
26 | public static final int MSG_OK = 0;
27 |
28 | public static final int SIZE_BYTE = 1;
29 | public static final int SIZE_SHORT = 2;
30 | public static final int SIZE_INT = 4;
31 |
32 | public static final int STATE_AWAKE = 2;
33 | public static final int STATE_CLOCK = 1;
34 | public static final int STATE_SLEEP = 0;
35 |
36 | public static final byte REQUEST_SCREEN_PROPERTIES = 1;
37 | public static final byte RESPONSE_SCREEN_PROPERTIES = 2;
38 | public static final byte REQUEST_STANDBY = 7;
39 | public static final byte RESPONSE_STANDBY = 8;
40 | public static final byte REQUEST_MENU_ITEM_COUNT = 23;
41 | public static final byte RESPONSE_MENU_ITEM_COUNT = 24;
42 | public static final byte RESPONSE_MENU_GET_ITEM = 26;
43 | public static final byte REQUEST_GET_ALL_MENU_ITEMS = 35;
44 | public static final byte REQUEST_DATE_TIME = 38;
45 | public static final byte RESPONSE_DATE_TIME = 39;
46 | public static final byte REQUEST_LED = 40;
47 | public static final byte RESPONSE_LED = 41;
48 | public static final byte REQUEST_VIBRATE = 42;
49 | public static final byte RESPONSE_VIBRATE = 43;
50 | public static final byte RESPONSE_ACK = 44;
51 | public static final byte REQUEST_SW_VERSION = 68;
52 | public static final byte RESPONSE_SW_VERSION = 69;
53 |
54 | // Intent EXTRAS
55 | public static final String EXTRA_START_SERVICE = "EXTRA_START_SERVICE";
56 | }
57 |
--------------------------------------------------------------------------------
/src/com/pedronveloso/openliveview/Utils/StaticImages.java:
--------------------------------------------------------------------------------
1 | package com.pedronveloso.openliveview.Utils;
2 |
3 | public class StaticImages {
4 |
5 | //TODO: replace with own icons instead of proprietary ones
6 |
7 | /**
8 | * This is the 'All Events' Icon
9 | */
10 | public static byte[] staticIconAllEvents;
11 | }
12 |
--------------------------------------------------------------------------------
/src/com/pedronveloso/openliveview/Utils/Utils.java:
--------------------------------------------------------------------------------
1 | package com.pedronveloso.openliveview.Utils;
2 |
3 | import android.graphics.Color;
4 | import android.util.Log;
5 |
6 | import java.io.UnsupportedEncodingException;
7 |
8 | public class Utils {
9 |
10 | public static final boolean enableLogging = true;
11 |
12 | public static void log(String msg) {
13 | if (enableLogging)
14 | Log.d(Constants.LOG_TAG, msg);
15 | }
16 |
17 | public static void logError(String msg) {
18 | //always log errors
19 | Log.e(Constants.LOG_TAG, msg);
20 | }
21 |
22 | public static String getString(byte[] bytes) {
23 | try {
24 | return new String(bytes, Constants.STRING_ENCODING);
25 | } catch (UnsupportedEncodingException e) {
26 | e.printStackTrace();
27 | return "";
28 | }
29 | }
30 |
31 | public static byte[] prepareString(String string) {
32 | try {
33 | return string.getBytes(Constants.STRING_ENCODING);
34 | } catch (UnsupportedEncodingException e) {
35 | e.printStackTrace();
36 | return new byte[0];
37 | }
38 | }
39 |
40 | public static short colorToRGB565(int color) {
41 | int r = Color.red(color) >> 3;
42 | int g = Color.green(color) >> 2;
43 | int b = Color.blue(color) >> 3;
44 | return (short)((r<<(5+6)) + (g << 5) + (b));
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/com/pedronveloso/openliveview/activities/DevMainActivity.java:
--------------------------------------------------------------------------------
1 | package com.pedronveloso.openliveview.activities;
2 |
3 | import android.app.Activity;
4 | import android.bluetooth.BluetoothAdapter;
5 | import android.bluetooth.BluetoothDevice;
6 | import android.content.Context;
7 | import android.graphics.Color;
8 | import android.os.Bundle;
9 | import android.support.v4.view.PagerAdapter;
10 | import android.support.v4.view.ViewPager;
11 | import android.util.Log;
12 | import android.view.LayoutInflater;
13 | import android.view.View;
14 | import android.view.View.OnClickListener;
15 | import android.widget.Button;
16 | import android.widget.TextView;
17 | import com.pedronveloso.openliveview.R;
18 | import com.pedronveloso.openliveview.Utils.Constants;
19 | import com.pedronveloso.openliveview.Utils.StaticImages;
20 | import com.pedronveloso.openliveview.Utils.Utils;
21 | import com.pedronveloso.openliveview.protocol.*;
22 | import com.pedronveloso.openliveview.server.BtServer;
23 | import com.pedronveloso.openliveview.server.Menu;
24 |
25 | import java.io.IOException;
26 | import java.io.InputStream;
27 | import java.nio.ByteOrder;
28 | import java.util.Set;
29 |
30 | public class DevMainActivity extends Activity
31 | implements BtServer.Callback, OnClickListener
32 |
33 | {
34 | BluetoothAdapter mBluetoothAdapter;
35 | TextView output;
36 | private Button btnVibrate;
37 | private Button btnLEDred;
38 | private Button btnLEDgreen;
39 | private Button btnLEDblue;
40 |
41 | public void addToOutput(final String line){
42 | Log.d(Constants.LOG_TAG, line);
43 | runOnUiThread(new Runnable() {
44 |
45 | public void run() {
46 | output.setText(output.getText()+"\n"+line);
47 | }
48 | });
49 | }
50 |
51 | /** Called when the activity is first created. */
52 | @Override
53 | public void onCreate(Bundle savedInstanceState)
54 | {
55 | super.onCreate(savedInstanceState);
56 |
57 | try {
58 | InputStream is = getAssets().open("test36.png");
59 | StaticImages.staticIconAllEvents = new byte[is.available()];
60 | is.read(StaticImages.staticIconAllEvents);
61 | is.close();
62 | } catch (IOException e) {
63 | e.printStackTrace();
64 | Utils.logError("Could NOT create icon from Assets");
65 | }
66 | Menu.instance().initDefaultItems();
67 |
68 | setContentView(R.layout.test_activity);
69 |
70 | TestActivityAdapter adapter = new TestActivityAdapter();
71 | ViewPager myPager = (ViewPager) findViewById(R.id.testactivitypager);
72 | myPager.setAdapter(adapter);
73 | myPager.setCurrentItem(0);
74 |
75 |
76 | }
77 |
78 | public void isReadyChanged(boolean isReady) {
79 | if (isReady)
80 | mBluetoothAdapter.cancelDiscovery();
81 | btnVibrate.setEnabled(isReady);
82 | btnLEDred.setEnabled(isReady);
83 | btnLEDgreen.setEnabled(isReady);
84 | btnLEDblue.setEnabled(isReady);
85 | addToOutput("IsReadyChanged: "+isReady);
86 | }
87 |
88 | public void handleResponse(Response aResponse) {
89 | if (aResponse instanceof ScreenPropertiesResponse) {
90 | addToOutput("Protocol Version: "+((ScreenPropertiesResponse)aResponse).getProtocolVersion());
91 | } else if (aResponse instanceof SWVersionResponse) {
92 | addToOutput("SW Version: "+((SWVersionResponse)aResponse).getVersion());
93 | } else if (aResponse instanceof UnknownResponse) {
94 | addToOutput("Unknown Response: "+(aResponse).getMsgId());
95 | } else
96 | addToOutput("handling: "+ aResponse.getClass().getSimpleName());
97 | }
98 |
99 | @Override
100 | protected void onDestroy() {
101 | BtServer.instance().removeCallback(this);
102 | BtServer.instance().stop();
103 | super.onDestroy();
104 | }
105 |
106 | public void onClick(View view) {
107 | switch (view.getId()){
108 | case R.id.btn_test_vibrate:
109 | BtServer.instance().write(new VibrateRequest((short)0, (short)500));
110 | break;
111 | case R.id.btn_test_led_red:
112 | BtServer.instance().write(new LEDRequest(Color.RED, (short)0, (short)500));
113 | break;
114 | case R.id.btn_test_led_green:
115 | BtServer.instance().write(new LEDRequest(Color.GREEN, (short)0, (short)500));
116 | break;
117 | case R.id.btn_test_led_blue:
118 | BtServer.instance().write(new LEDRequest(Color.BLUE, (short)0, (short)500));
119 | break;
120 | }
121 | }
122 |
123 | private class TestActivityAdapter extends PagerAdapter{
124 | @Override
125 | public boolean isViewFromObject(View arg0, Object arg1) {
126 | return arg0 == ((View) arg1);
127 | }
128 |
129 | public Object instantiateItem(View collection, int position) {
130 |
131 | LayoutInflater inflater = (LayoutInflater) collection.getContext()
132 | .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
133 |
134 | int resId = 0;
135 | switch (position) {
136 | case 0:
137 | resId = R.layout.test_activity_left;
138 | break;
139 | case 1:
140 | resId = R.layout.test_activity_right;
141 | break;
142 | }
143 |
144 | View view = inflater.inflate(resId, null);
145 |
146 | ((ViewPager) collection).addView(view, 0);
147 |
148 | // link to layout stuff
149 | if (position==0){
150 | output = (TextView) view.findViewById(R.id.tv_output);
151 | }
152 | if (position==1){
153 | btnVibrate = (Button) view.findViewById(R.id.btn_test_vibrate);
154 | btnVibrate.setOnClickListener(DevMainActivity.this);
155 | btnLEDred = (Button) view.findViewById(R.id.btn_test_led_red);
156 | btnLEDred.setOnClickListener(DevMainActivity.this);
157 | btnLEDgreen = (Button) view.findViewById(R.id.btn_test_led_green);
158 | btnLEDgreen.setOnClickListener(DevMainActivity.this);
159 | btnLEDblue = (Button) view.findViewById(R.id.btn_test_led_blue);
160 | btnLEDblue.setOnClickListener(DevMainActivity.this);
161 |
162 | //continue loading the app logic after UI has been instantiated
163 | continueLoading();
164 | }
165 |
166 | return view;
167 | }
168 |
169 | public int getCount() {
170 | return 2;
171 | }
172 |
173 |
174 | }
175 |
176 |
177 | /**
178 | * Continue app execution after UI elements have been instantiated
179 | */
180 | private void continueLoading(){
181 | if (ByteOrder.nativeOrder().equals(ByteOrder.BIG_ENDIAN))
182 | addToOutput("Current platform byte order is: BigEndian");
183 | else
184 | addToOutput("Current platform byte order is: LittleEndian");
185 |
186 | mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
187 | if (mBluetoothAdapter == null) {
188 | Log.e(Constants.LOG_TAG,"does not support bluetooth devices");
189 | finish();
190 | }
191 |
192 | if (!mBluetoothAdapter.isEnabled()) {
193 | Log.e(Constants.LOG_TAG, "bluetooth not enabled");
194 | finish();
195 | }
196 |
197 |
198 | Set pairedDevices = mBluetoothAdapter.getBondedDevices();
199 | BluetoothDevice liveView = null;
200 | // If there are paired devices
201 | if (pairedDevices.size() > 0) {
202 | // Loop through paired devices
203 | for (BluetoothDevice device : pairedDevices) {
204 | // Add the name and address to an array adapter to show in a ListView
205 | if ("LiveView".equals(device.getName())) {
206 | addToOutput(device.getName() + " : " + device.getAddress());
207 | liveView = device;
208 | }
209 | }
210 | }
211 |
212 | if (liveView != null) {
213 | BtServer.instance().setContext(this);
214 | BtServer.instance().addCallback(this);
215 | BtServer.instance().start(liveView);
216 | }else{
217 | addToOutput("Failed to obtain liveview device.");
218 | }
219 | }
220 |
221 | }
222 |
--------------------------------------------------------------------------------
/src/com/pedronveloso/openliveview/activities/EntryActivity.java:
--------------------------------------------------------------------------------
1 | package com.pedronveloso.openliveview.activities;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import android.view.View;
7 | import android.widget.Button;
8 | import com.pedronveloso.openliveview.R;
9 |
10 | /**
11 | * Author: Pedro Veloso
12 | */
13 | public class EntryActivity extends Activity implements View.OnClickListener {
14 |
15 | public void onCreate(Bundle savedInstanceState) {
16 | super.onCreate(savedInstanceState);
17 | setContentView(R.layout.entry_screen);
18 | Button btnProceed = (Button) findViewById(R.id.btn_next);
19 | btnProceed.setOnClickListener(this);
20 | btnProceed = (Button) findViewById(R.id.btn_next_dev);
21 | btnProceed.setOnClickListener(this);
22 | }
23 |
24 | public void onClick(View view) {
25 | switch (view.getId()){
26 | case R.id.btn_next:
27 | startActivity(new Intent(EntryActivity.this,UserMainActivity.class));
28 | break;
29 |
30 | case R.id.btn_next_dev:
31 | startActivity(new Intent(EntryActivity.this,DevMainActivity.class));
32 | break;
33 | }
34 | }
35 | }
--------------------------------------------------------------------------------
/src/com/pedronveloso/openliveview/activities/UserMainActivity.java:
--------------------------------------------------------------------------------
1 | package com.pedronveloso.openliveview.activities;
2 |
3 | import android.app.Activity;
4 | import android.content.Intent;
5 | import android.os.Bundle;
6 | import com.pedronveloso.openliveview.R;
7 | import com.pedronveloso.openliveview.Utils.Constants;
8 | import com.pedronveloso.openliveview.services.CommService;
9 |
10 | /**
11 | * User: Pedro Veloso
12 | */
13 | public class UserMainActivity extends Activity {
14 |
15 | public void onCreate(Bundle savedInstanceState) {
16 | super.onCreate(savedInstanceState);
17 | setContentView(R.layout.user_main_screen);
18 | Intent commService = new Intent(UserMainActivity.this, CommService.class);
19 | commService.putExtra(Constants.EXTRA_START_SERVICE,1);
20 | startService(commService);
21 | }
22 | }
--------------------------------------------------------------------------------
/src/com/pedronveloso/openliveview/protocol/AckMessage.java:
--------------------------------------------------------------------------------
1 | package com.pedronveloso.openliveview.protocol;
2 |
3 | import java.io.DataOutputStream;
4 | import java.io.IOException;
5 |
6 | import com.pedronveloso.openliveview.Utils.Constants;
7 |
8 | public class AckMessage extends Request {
9 |
10 | private byte mAckMessage;
11 |
12 | public AckMessage(byte ackMessage) {
13 | mAckMessage = ackMessage;
14 | }
15 |
16 | @Override
17 | protected byte getMessageId() {
18 | // TODO Auto-generated method stub
19 | return Constants.RESPONSE_ACK;
20 | }
21 |
22 | @Override
23 | protected int getPayloadSize() {
24 | return Constants.SIZE_BYTE;
25 | }
26 |
27 | @Override
28 | protected void WritePayload(DataOutputStream writer) throws IOException {
29 | writer.writeByte(mAckMessage);
30 |
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/src/com/pedronveloso/openliveview/protocol/DateTimeRequest.java:
--------------------------------------------------------------------------------
1 | package com.pedronveloso.openliveview.protocol;
2 |
3 | import java.io.DataInputStream;
4 | import java.io.IOException;
5 |
6 | public class DateTimeRequest extends LiveViewRequest {
7 |
8 | @Override
9 | public Request answer() {
10 | return new DateTimeResponse();
11 | }
12 |
13 | @Override
14 | protected void readPayload(DataInputStream input, int payloadLength)
15 | throws IOException {
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/com/pedronveloso/openliveview/protocol/DateTimeResponse.java:
--------------------------------------------------------------------------------
1 | package com.pedronveloso.openliveview.protocol;
2 |
3 | import android.text.format.DateFormat;
4 |
5 | import com.pedronveloso.openliveview.Utils.Constants;
6 | import com.pedronveloso.openliveview.server.BtServer;
7 |
8 | import java.io.DataOutputStream;
9 | import java.io.IOException;
10 | import java.util.Calendar;
11 | import java.util.Date;
12 |
13 |
14 | public class DateTimeResponse extends Request {
15 |
16 | @Override
17 | protected byte getMessageId() {
18 | return Constants.RESPONSE_DATE_TIME;
19 | }
20 |
21 | @Override
22 | protected int getPayloadSize() {
23 | return Constants.SIZE_INT + // Time
24 | Constants.SIZE_BYTE; // Display 24h format
25 | }
26 |
27 | @Override
28 | protected void WritePayload(DataOutputStream writer) throws IOException {
29 | Calendar rightNow = Calendar.getInstance();
30 | int time =(int)((rightNow.get(Calendar.ZONE_OFFSET) +
31 | rightNow.get(Calendar.DST_OFFSET) +
32 | new Date().getTime()) / 1000L);
33 | writer.writeInt(time);
34 | writer.writeByte(DateFormat.is24HourFormat(BtServer.instance().getContext()) ? 1 : 0);
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/src/com/pedronveloso/openliveview/protocol/GetAllMenuItemsRequest.java:
--------------------------------------------------------------------------------
1 | package com.pedronveloso.openliveview.protocol;
2 |
3 | import java.io.DataInputStream;
4 | import java.io.IOException;
5 |
6 | import com.pedronveloso.openliveview.Utils.Constants;
7 |
8 | public class GetAllMenuItemsRequest extends LiveViewRequest {
9 |
10 | private boolean mOk;
11 |
12 | @Override
13 | public Request answer() {
14 | return null; // Should be handled somewhere else
15 | // cause there will be more then one response
16 | }
17 |
18 | @Override
19 | protected void readPayload(DataInputStream input, int payloadLength)
20 | throws IOException {
21 | mOk = input.readByte() == Constants.MSG_OK;
22 | }
23 |
24 | public boolean getOk() {
25 | return mOk;
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/src/com/pedronveloso/openliveview/protocol/GetMenuIconResponse.java:
--------------------------------------------------------------------------------
1 | package com.pedronveloso.openliveview.protocol;
2 |
3 | import java.io.DataOutputStream;
4 | import java.io.IOException;
5 |
6 | import com.pedronveloso.openliveview.Utils.Constants;
7 | import com.pedronveloso.openliveview.Utils.Utils;
8 |
9 | public class GetMenuIconResponse extends Request {
10 |
11 | private boolean mAlertItem;
12 | private int mUnreadCount;
13 | private short mMenuItemId;
14 | private boolean mPlainText;
15 | private byte[] mTitle;
16 | private byte[] mBitmap;
17 |
18 | public GetMenuIconResponse(boolean alertItem, int unreadCount, short menuItemId, String title, byte[] bitmap)
19 | {
20 | mAlertItem = alertItem;
21 | mUnreadCount = unreadCount;
22 | mMenuItemId = (short)(menuItemId + 3);
23 | mTitle = Utils.prepareString(title);
24 | mBitmap = bitmap;
25 | mPlainText = true;
26 | }
27 |
28 | @Override
29 | protected byte getMessageId() {
30 | return Constants.RESPONSE_MENU_GET_ITEM;
31 | }
32 |
33 | @Override
34 | protected int getPayloadSize() {
35 |
36 | return Constants.SIZE_BYTE + // AlertItem (0) or OtherItem(1)
37 | Constants.SIZE_SHORT + // unknown
38 | Constants.SIZE_SHORT + // unread count
39 | Constants.SIZE_SHORT + // unknown
40 | Constants.SIZE_BYTE + // MenuItemId
41 | Constants.SIZE_BYTE + // Plaintext (0) or Bitmap (1)
42 | Constants.SIZE_INT + // unknown
43 | Constants.SIZE_SHORT + // Text length
44 | mTitle.length +
45 | mBitmap.length;
46 | }
47 |
48 | @Override
49 | protected void WritePayload(DataOutputStream writer) throws IOException {
50 | writer.writeByte(mAlertItem ? 0 : 1);
51 | writer.writeShort(0);
52 | writer.writeShort(mUnreadCount);
53 | writer.writeShort(0);
54 | writer.writeByte(mMenuItemId);
55 | writer.writeByte(mPlainText ? 0 : 1);
56 | writer.writeInt(0);
57 | writer.writeShort(mTitle.length);
58 | writer.write(mTitle);
59 | writer.write(mBitmap);
60 | }
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/src/com/pedronveloso/openliveview/protocol/LEDRequest.java:
--------------------------------------------------------------------------------
1 | package com.pedronveloso.openliveview.protocol;
2 |
3 | import com.pedronveloso.openliveview.Utils.Constants;
4 | import com.pedronveloso.openliveview.Utils.Utils;
5 |
6 | import java.io.DataOutputStream;
7 | import java.io.IOException;
8 |
9 | public class LEDRequest extends Request{
10 |
11 | private int mColor;
12 | private short mDelay;
13 | private short mDuration;
14 |
15 | public LEDRequest(int color, short delay, short duration) {
16 | mColor = color;
17 | mDelay = delay;
18 | mDuration = duration;
19 | }
20 |
21 | @Override
22 | protected byte getMessageId() {
23 | return Constants.REQUEST_LED;
24 | }
25 |
26 | @Override
27 | protected int getPayloadSize() {
28 | return Constants.SIZE_SHORT + // Color
29 | Constants.SIZE_SHORT + // Delay
30 | Constants.SIZE_SHORT; // Duration
31 | }
32 |
33 | @Override
34 | protected void WritePayload(DataOutputStream writer) throws IOException {
35 | writer.writeShort(Utils.colorToRGB565(mColor));
36 | writer.writeShort(mDelay);
37 | writer.writeShort(mDuration);
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/src/com/pedronveloso/openliveview/protocol/LEDResponse.java:
--------------------------------------------------------------------------------
1 | package com.pedronveloso.openliveview.protocol;
2 |
3 | import com.pedronveloso.openliveview.Utils.Constants;
4 |
5 | import java.io.DataInputStream;
6 | import java.io.IOException;
7 |
8 | public class LEDResponse extends Response {
9 |
10 | private boolean mOk = false;
11 |
12 | @Override
13 | protected void readPayload(DataInputStream input, int payloadLength) throws IOException {
14 | mOk = (payloadLength == Constants.SIZE_BYTE) && input.readByte() == Constants.MSG_OK;
15 | }
16 |
17 | public boolean getOk() {
18 | return mOk;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/com/pedronveloso/openliveview/protocol/LiveViewRequest.java:
--------------------------------------------------------------------------------
1 | package com.pedronveloso.openliveview.protocol;
2 |
3 | public abstract class LiveViewRequest extends Response {
4 |
5 | public abstract Request answer();
6 |
7 | }
8 |
--------------------------------------------------------------------------------
/src/com/pedronveloso/openliveview/protocol/MenuItemCountRequest.java:
--------------------------------------------------------------------------------
1 | package com.pedronveloso.openliveview.protocol;
2 |
3 | import java.io.DataOutputStream;
4 | import java.io.IOException;
5 |
6 | import com.pedronveloso.openliveview.Utils.Constants;
7 |
8 | public class MenuItemCountRequest extends Request {
9 |
10 | private int mItemCount;
11 |
12 | public MenuItemCountRequest(int itemCount) {
13 | mItemCount = itemCount;
14 | }
15 |
16 | @Override
17 | protected byte getMessageId() {
18 | return Constants.REQUEST_MENU_ITEM_COUNT;
19 | }
20 |
21 | @Override
22 | protected int getPayloadSize() {
23 | return Constants.SIZE_BYTE;
24 | }
25 |
26 | @Override
27 | protected void WritePayload(DataOutputStream writer) throws IOException {
28 | writer.write(mItemCount);
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/src/com/pedronveloso/openliveview/protocol/MenuItemCountResponse.java:
--------------------------------------------------------------------------------
1 | package com.pedronveloso.openliveview.protocol;
2 |
3 | import java.io.DataInputStream;
4 | import java.io.IOException;
5 |
6 | public class MenuItemCountResponse extends Response {
7 |
8 | @Override
9 | protected void readPayload(DataInputStream input, int payloadLength)
10 | throws IOException {
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/src/com/pedronveloso/openliveview/protocol/Request.java:
--------------------------------------------------------------------------------
1 | package com.pedronveloso.openliveview.protocol;
2 |
3 | import com.pedronveloso.openliveview.Utils.Constants;
4 |
5 | import java.io.DataOutputStream;
6 | import java.io.IOException;
7 |
8 | public abstract class Request {
9 |
10 | protected abstract byte getMessageId();
11 |
12 | protected abstract int getPayloadSize();
13 |
14 | protected abstract void WritePayload(DataOutputStream writer) throws IOException;
15 |
16 |
17 | public void Write(DataOutputStream stream) throws IOException {
18 | stream.writeByte(getMessageId());
19 | stream.writeByte(Constants.SIZE_INT);
20 | stream.writeInt(getPayloadSize());
21 | WritePayload(stream);
22 | stream.flush();
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/com/pedronveloso/openliveview/protocol/Response.java:
--------------------------------------------------------------------------------
1 | package com.pedronveloso.openliveview.protocol;
2 |
3 | import android.util.Log;
4 |
5 | import com.pedronveloso.openliveview.Utils.Constants;
6 |
7 | import java.io.DataInputStream;
8 | import java.io.IOException;
9 |
10 | public abstract class Response {
11 |
12 | private byte mMessageId;
13 |
14 | protected abstract void readPayload(DataInputStream input, int payloadLength) throws IOException;
15 |
16 | public static Response parse(byte msgId, DataInputStream input) throws IOException {
17 | Response result = null;
18 | Log.d(Constants.LOG_TAG, "Got message id:"+msgId);
19 | int lengthSize = (byte)input.readByte();
20 | int payloadlength = 0;
21 | switch(lengthSize) {
22 | case Constants.SIZE_BYTE:
23 | payloadlength = input.readByte(); break;
24 | case Constants.SIZE_SHORT:
25 | payloadlength = input.readShort(); break;
26 | case Constants.SIZE_INT:
27 | payloadlength = input.readInt(); break;
28 | case 0:
29 | payloadlength = 0; break;
30 | default: {
31 | Log.d(Constants.LOG_TAG, "unknown message length: "+lengthSize);
32 | return null; // Unknown Datatype!
33 | }
34 | }
35 |
36 | switch(msgId) {
37 | case Constants.RESPONSE_VIBRATE:
38 | result = new VibrateResponse(); break;
39 | case Constants.RESPONSE_LED:
40 | result = new LEDResponse(); break;
41 | case Constants.RESPONSE_SCREEN_PROPERTIES:
42 | result = new ScreenPropertiesResponse(); break;
43 | case Constants.REQUEST_STANDBY:
44 | result = new StandByRequest(); break;
45 | case Constants.REQUEST_DATE_TIME:
46 | result = new DateTimeRequest(); break;
47 | case Constants.RESPONSE_SW_VERSION:
48 | result = new SWVersionResponse(); break;
49 | case Constants.RESPONSE_MENU_ITEM_COUNT:
50 | result = new MenuItemCountResponse(); break;
51 | case Constants.REQUEST_GET_ALL_MENU_ITEMS:
52 | result = new GetAllMenuItemsRequest(); break;
53 | default:
54 | result = new UnknownResponse();
55 | }
56 |
57 | if (result != null) {
58 | result.mMessageId = msgId;
59 | if (payloadlength > 0) {
60 | result.readPayload(input, payloadlength);
61 | }
62 | }
63 | return result;
64 | }
65 |
66 | public byte getMsgId() {
67 | return mMessageId;
68 | }
69 |
70 | public boolean shouldSendAck() {
71 | return true;
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/com/pedronveloso/openliveview/protocol/SWVersionRequest.java:
--------------------------------------------------------------------------------
1 | package com.pedronveloso.openliveview.protocol;
2 |
3 | import com.pedronveloso.openliveview.Utils.Constants;
4 |
5 | import java.io.DataOutputStream;
6 | import java.io.IOException;
7 |
8 | public class SWVersionRequest extends Request{
9 |
10 | public SWVersionRequest() {
11 | }
12 |
13 | @Override
14 | protected byte getMessageId() {
15 | return Constants.REQUEST_SW_VERSION;
16 | }
17 |
18 | @Override
19 | protected int getPayloadSize() {
20 | return Constants.SIZE_BYTE; // MSG_OK
21 | }
22 |
23 | @Override
24 | protected void WritePayload(DataOutputStream writer) throws IOException {
25 | writer.writeByte(Constants.MSG_OK);
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/src/com/pedronveloso/openliveview/protocol/SWVersionResponse.java:
--------------------------------------------------------------------------------
1 | package com.pedronveloso.openliveview.protocol;
2 |
3 | import java.io.DataInputStream;
4 | import java.io.IOException;
5 |
6 | import com.pedronveloso.openliveview.Utils.Utils;
7 | import com.pedronveloso.openliveview.server.Menu;
8 |
9 | public class SWVersionResponse extends LiveViewRequest {
10 |
11 | private String mVersion;
12 |
13 | @Override
14 | protected void readPayload(DataInputStream input, int payloadLength) throws IOException {
15 | byte[] buffer = new byte[payloadLength];
16 | input.read(buffer);
17 | mVersion = Utils.getString(buffer);
18 | }
19 |
20 | public String getVersion() {
21 | return mVersion;
22 | }
23 |
24 | @Override
25 | public Request answer() {
26 | return new MenuItemCountRequest(Menu.instance().size());
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/com/pedronveloso/openliveview/protocol/ScreenPropertiesRequest.java:
--------------------------------------------------------------------------------
1 | package com.pedronveloso.openliveview.protocol;
2 |
3 | import com.pedronveloso.openliveview.Utils.Constants;
4 |
5 | import java.io.DataOutputStream;
6 | import java.io.IOException;
7 |
8 | public class ScreenPropertiesRequest extends Request {
9 |
10 | @Override
11 | protected byte getMessageId() {
12 | return Constants.REQUEST_SCREEN_PROPERTIES;
13 | }
14 |
15 | @Override
16 | protected int getPayloadSize() {
17 | return Constants.PROTOCOL_VERSION.length +
18 | Constants.SIZE_BYTE; // String Terminator
19 | }
20 |
21 | @Override
22 | protected void WritePayload(DataOutputStream writer) throws IOException {
23 | writer.write(Constants.PROTOCOL_VERSION);
24 | writer.writeByte(0); // String Terminator
25 | }
26 |
27 | }
28 |
--------------------------------------------------------------------------------
/src/com/pedronveloso/openliveview/protocol/ScreenPropertiesResponse.java:
--------------------------------------------------------------------------------
1 | package com.pedronveloso.openliveview.protocol;
2 |
3 | import com.pedronveloso.openliveview.Utils.Utils;
4 |
5 | import java.io.DataInputStream;
6 | import java.io.IOException;
7 |
8 | public class ScreenPropertiesResponse extends LiveViewRequest {
9 |
10 | private int mWidth;
11 | private int mHeight;
12 | private int mStatusBarWidth;
13 | private int mStatusBarHeight;
14 | private int mViewWidth;
15 | private int mViewHeight;
16 | private int mAnnounceWidth;
17 | private int mAnnounceHeight;
18 | private int mTextChunkSize;
19 | private int mIdleTimer;
20 | private String mProtocolVersion;
21 |
22 | public int getWidth() {
23 | return mWidth;
24 | }
25 |
26 | public int getHeight() {
27 | return mHeight;
28 | }
29 |
30 | public int getStatusBarWidth() {
31 | return mStatusBarWidth;
32 | }
33 |
34 | public int getStatusBarHeight() {
35 | return mStatusBarHeight;
36 | }
37 |
38 | public int getViewWidth() {
39 | return mViewWidth;
40 | }
41 |
42 | public int getViewHeight() {
43 | return mViewHeight;
44 | }
45 |
46 | public int getAnnounceWidth() {
47 | return mAnnounceWidth;
48 | }
49 |
50 | public int getAnnounceHeight() {
51 | return mAnnounceHeight;
52 | }
53 |
54 | public int getTextChunkSize() {
55 | return mTextChunkSize;
56 | }
57 |
58 | public int getIdleTimer() {
59 | return mIdleTimer;
60 | }
61 |
62 | public String getProtocolVersion() {
63 | return mProtocolVersion;
64 | }
65 |
66 | @Override
67 | protected void readPayload(DataInputStream input, int payloadLength)
68 | throws IOException {
69 | mWidth = input.readUnsignedByte();
70 | mHeight = input.readUnsignedByte();
71 | mStatusBarWidth = input.readUnsignedByte();
72 | mStatusBarHeight = input.readUnsignedByte();
73 | mViewWidth = input.readUnsignedByte();
74 | mViewHeight = input.readUnsignedByte();
75 | mAnnounceWidth = input.readUnsignedByte();
76 | mAnnounceHeight = input.readUnsignedByte();
77 | mTextChunkSize = input.readUnsignedByte();
78 | mIdleTimer = input.readUnsignedByte();
79 | int textLen = input.readUnsignedByte();
80 | byte[] buffer = new byte[textLen];
81 | input.read(buffer);
82 | mProtocolVersion = Utils.getString(buffer);
83 | }
84 |
85 | @Override
86 | public Request answer() {
87 | return new SWVersionRequest();
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/src/com/pedronveloso/openliveview/protocol/StandByRequest.java:
--------------------------------------------------------------------------------
1 | package com.pedronveloso.openliveview.protocol;
2 |
3 | import java.io.DataInputStream;
4 | import java.io.IOException;
5 |
6 | public class StandByRequest extends LiveViewRequest {
7 |
8 | private int mState;
9 |
10 | public int getState() {
11 | return mState;
12 | }
13 |
14 | @Override
15 | public Request answer() {
16 | return new StandByResponse();
17 | }
18 |
19 | @Override
20 | protected void readPayload(DataInputStream input, int payloadLength)
21 | throws IOException {
22 | mState = input.readUnsignedByte();
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/com/pedronveloso/openliveview/protocol/StandByResponse.java:
--------------------------------------------------------------------------------
1 | package com.pedronveloso.openliveview.protocol;
2 |
3 | import com.pedronveloso.openliveview.Utils.Constants;
4 |
5 | import java.io.DataOutputStream;
6 | import java.io.IOException;
7 |
8 | public class StandByResponse extends Request {
9 |
10 | @Override
11 | protected byte getMessageId() {
12 | return Constants.RESPONSE_STANDBY;
13 | }
14 |
15 | @Override
16 | protected int getPayloadSize() {
17 | return Constants.SIZE_BYTE;
18 | }
19 |
20 | @Override
21 | protected void WritePayload(DataOutputStream writer) throws IOException {
22 | writer.writeByte(Constants.MSG_OK);
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/src/com/pedronveloso/openliveview/protocol/UnknownResponse.java:
--------------------------------------------------------------------------------
1 | package com.pedronveloso.openliveview.protocol;
2 |
3 | import java.io.DataInputStream;
4 | import java.io.IOException;
5 |
6 | public class UnknownResponse extends Response {
7 |
8 | private byte[] mBuffer;
9 |
10 | @Override
11 | protected void readPayload(DataInputStream input, int payloadLength)
12 | throws IOException {
13 | mBuffer = new byte[payloadLength];
14 | input.read(mBuffer);
15 | }
16 |
17 | public byte[] getBuffer() {
18 | return mBuffer;
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/src/com/pedronveloso/openliveview/protocol/VibrateRequest.java:
--------------------------------------------------------------------------------
1 | package com.pedronveloso.openliveview.protocol;
2 |
3 | import com.pedronveloso.openliveview.Utils.Constants;
4 |
5 | import java.io.DataOutputStream;
6 | import java.io.IOException;
7 |
8 | public class VibrateRequest extends Request {
9 |
10 | private short mDelay;
11 | private short mDuration;
12 |
13 | public VibrateRequest(short delay, short duration) {
14 | super();
15 | mDelay = delay;
16 | mDuration = duration;
17 | }
18 |
19 | @Override
20 | protected byte getMessageId() {
21 | return Constants.REQUEST_VIBRATE;
22 | }
23 |
24 | @Override
25 | protected int getPayloadSize() {
26 | return Constants.SIZE_SHORT // Delay
27 | + Constants.SIZE_SHORT; // Duration
28 | }
29 |
30 | @Override
31 | protected void WritePayload(DataOutputStream writer) throws IOException {
32 | writer.writeShort(mDelay);
33 | writer.writeShort(mDuration);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/com/pedronveloso/openliveview/protocol/VibrateResponse.java:
--------------------------------------------------------------------------------
1 | package com.pedronveloso.openliveview.protocol;
2 |
3 | import com.pedronveloso.openliveview.Utils.Constants;
4 |
5 | import java.io.DataInputStream;
6 | import java.io.IOException;
7 |
8 | public class VibrateResponse extends Response {
9 |
10 | private boolean mOk = false;
11 |
12 | @Override
13 | protected void readPayload(DataInputStream input, int payloadLength) throws IOException {
14 | mOk = (payloadLength == Constants.SIZE_BYTE) && (input.readByte() == Constants.MSG_OK);
15 | }
16 |
17 | public boolean getOk() {
18 | return mOk;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/com/pedronveloso/openliveview/server/BtServer.java:
--------------------------------------------------------------------------------
1 | package com.pedronveloso.openliveview.server;
2 |
3 | import java.io.DataInputStream;
4 | import java.io.DataOutputStream;
5 | import java.io.IOException;
6 | import java.util.ArrayList;
7 | import java.util.List;
8 | import java.util.UUID;
9 |
10 | import com.pedronveloso.openliveview.Utils.Constants;
11 | import com.pedronveloso.openliveview.Utils.Utils;
12 | import com.pedronveloso.openliveview.protocol.*;
13 |
14 | import android.bluetooth.BluetoothDevice;
15 | import android.bluetooth.BluetoothSocket;
16 | import android.content.Context;
17 | import android.os.Handler;
18 |
19 | public class BtServer {
20 |
21 | public interface Callback {
22 | void handleResponse(Response aResponse);
23 | void isReadyChanged(boolean isReady);
24 | }
25 |
26 | private Handler mHandler = new Handler();
27 |
28 | private List mCallbacks = new ArrayList();
29 | private BluetoothSocket mSocket = null;
30 | private DataOutputStream mOutput = null;
31 | private ConnectedThread mThread = null;
32 | private Context mContext = null;
33 | private static BtServer sInstance = null;
34 |
35 | private BtServer() {
36 | }
37 |
38 | public static BtServer instance() {
39 | if (sInstance == null)
40 | sInstance = new BtServer();
41 | return sInstance;
42 | }
43 |
44 | public void start(BluetoothDevice liveView) {
45 | if (isReady())
46 | stop();
47 | ConnectThread ct = new ConnectThread(liveView);
48 | ct.start();
49 | }
50 |
51 | public void stop() {
52 | mThread = null;
53 | for (Callback c : mCallbacks)
54 | c.isReadyChanged(isReady());
55 | if (mSocket != null) {
56 | try {
57 | mSocket.close();
58 | } catch (IOException e) {
59 | e.printStackTrace();
60 | }
61 | }
62 | }
63 |
64 | public boolean isReady() {
65 | if (Constants.VERBOSE_LOGCAT){
66 | if (mSocket==null)
67 | Utils.log("isReady will fail because mSocket is NULL");
68 | if (mOutput==null)
69 | Utils.log("isReady will fail because mOutput is NULL");
70 | if (mThread==null)
71 | Utils.log("isReady will fail because mThread is NULL");
72 | }
73 | return mSocket != null && mOutput != null && mThread != null;
74 | }
75 |
76 | public void addCallback(Callback callback) {
77 | mCallbacks.add(callback);
78 | }
79 |
80 | public void removeCallback(Callback callback) {
81 | mCallbacks.remove(callback);
82 | }
83 |
84 | public void setContext(Context context) {
85 | mContext = context;
86 | }
87 |
88 | public Context getContext() {
89 | return mContext;
90 | }
91 |
92 | private void HandleResponse(Response response) {
93 | if (response != null) {
94 | for (Callback c : mCallbacks)
95 | c.handleResponse(response);
96 | }
97 | }
98 |
99 | public synchronized boolean write(Request aRequest) {
100 | if (!isReady())
101 | return false;
102 | try {
103 | aRequest.Write(mOutput);
104 | return true;
105 | } catch (IOException e) {
106 | e.printStackTrace();
107 | return false;
108 | }
109 | }
110 |
111 | /**
112 | * Running Thread that handles the I/O with a connected device
113 | */
114 | private class ConnectedThread extends Thread {
115 | private DataInputStream mInput;
116 |
117 | public ConnectedThread(DataInputStream stream) {
118 | mInput = stream;
119 | }
120 |
121 | @Override
122 | public void run() {
123 | write(new ScreenPropertiesRequest());
124 | mHandler.post(new Runnable() {
125 |
126 | public void run() {
127 | for (Callback c : mCallbacks)
128 | c.isReadyChanged(isReady());
129 | }
130 | });
131 |
132 | while(mThread == this) {
133 | try {
134 | int msgId = mInput.read();
135 | if (msgId != -1) {
136 | final Response resp = Response.parse((byte)msgId, mInput);
137 | if (resp == null)
138 | continue;
139 | if (resp.shouldSendAck()) {
140 | AckMessage ack = new AckMessage(resp.getMsgId());
141 | write(ack);
142 | }
143 |
144 | if (resp instanceof LiveViewRequest) {
145 | // LiveView asks us to answer something!
146 | Request request = ((LiveViewRequest)resp).answer();
147 | if (request != null)
148 | write(request);
149 | }
150 | mHandler.post(new Runnable() {
151 | public void run() {
152 | HandleResponse(resp);
153 | }
154 | });
155 | }
156 | } catch (IOException e) {
157 | mHandler.post(new Runnable() {
158 | public void run() {
159 | if (mThread == ConnectedThread.this)
160 | BtServer.this.stop();
161 | }
162 | });
163 | break;
164 | } catch (NullPointerException nullE){
165 | // ignore?
166 | Utils.log("Null exception when trying to read response: "+nullE.getMessage());
167 | nullE.printStackTrace();
168 | }
169 | }
170 | }
171 | }
172 |
173 | /**
174 | * Thread responsible for handling the effective connection to the device
175 | */
176 | private class ConnectThread extends Thread {
177 |
178 | public ConnectThread(BluetoothDevice device) {
179 | // Get a BluetoothSocket to connect with the given BluetoothDevice
180 | try {
181 | // MY_UUID is the app's UUID string, also used by the server code
182 | mSocket = device.createRfcommSocketToServiceRecord(UUID.fromString(Constants.LIVEVIEW_UUID));
183 | } catch (IOException e) {
184 | e.printStackTrace();
185 | }
186 | }
187 |
188 | public void run() {
189 | // Cancel discovery because it will slow down the connection
190 | try {
191 | // Make sure the state manager is registered.
192 | if (!mCallbacks.contains(StateManager.instance()))
193 | addCallback(StateManager.instance());
194 |
195 | // Connect the device through the socket. This will block
196 | // until it succeeds or throws an exception
197 | mSocket.connect();
198 | mOutput = new DataOutputStream(mSocket.getOutputStream());
199 | DataInputStream input = new DataInputStream(mSocket.getInputStream());
200 | mThread = new ConnectedThread(input);
201 | mThread.start();
202 |
203 | } catch (IOException connectException) {
204 | // Unable to connect; close the socket and get out
205 | try {
206 | mSocket.close();
207 | } catch (IOException ignored) { }
208 | }
209 | }
210 | }
211 | }
212 |
--------------------------------------------------------------------------------
/src/com/pedronveloso/openliveview/server/Menu.java:
--------------------------------------------------------------------------------
1 | package com.pedronveloso.openliveview.server;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import com.pedronveloso.openliveview.Utils.StaticImages;
7 | import com.pedronveloso.openliveview.protocol.GetAllMenuItemsRequest;
8 | import com.pedronveloso.openliveview.protocol.GetMenuIconResponse;
9 | import com.pedronveloso.openliveview.protocol.Response;
10 |
11 | public class Menu implements BtServer.Callback {
12 |
13 | public static class MenuItem {
14 |
15 | private short mId;
16 | private String mTitle;
17 | private byte[] mImage;
18 |
19 | public MenuItem(short id, String title, byte[] image) {
20 | mId = id;
21 | mTitle = title;
22 | mImage = image;
23 | }
24 |
25 | protected int getUnreadCount() {
26 | return 0; // Only Alert Items have unread messages
27 | }
28 |
29 | public GetMenuIconResponse toRequest() {
30 | return new GetMenuIconResponse(this instanceof AlertMenuItem,
31 | getUnreadCount(), mId, mTitle, mImage);
32 | }
33 | }
34 |
35 | public static class AlertMenuItem extends MenuItem {
36 |
37 | private int mUnread;
38 |
39 | public AlertMenuItem(short id, String title, byte[] image) {
40 | super(id, title, image);
41 | }
42 |
43 | public int getUnread() {
44 | return mUnread;
45 | }
46 |
47 | public void setUnread(int unread) {
48 | mUnread = unread;
49 | }
50 |
51 | @Override
52 | protected int getUnreadCount() {
53 | return getUnread();
54 | }
55 | }
56 |
57 | private static Menu sInstance;
58 |
59 | private List