summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Tsuk <robtsuk@google.com>2012-06-26 13:55:12 -0700
committerRob Tsuk <robtsuk@google.com>2012-06-26 14:22:37 -0700
commite4604930eb7f31d67afbf3eebb654485b5cfe6f1 (patch)
treefcd2ae890cc566d42518316c9ee6aa7b9a8edbbe
parent780257c6a6dc8a971731c1fc0f810c4348397aa6 (diff)
downloadadk2012-main.tar.gz
Import the app.HEADmastermain
Change-Id: I79d3421ecac1a5258ed4bfe7703479c225d2fc1e
-rw-r--r--.classpath8
-rw-r--r--.gitignore7
-rw-r--r--.project33
-rw-r--r--AndroidManifest.xml108
-rw-r--r--lint.xml4
-rw-r--r--proguard-project.txt20
-rw-r--r--project.properties14
-rw-r--r--res/drawable-hdpi/ic_launcher.pngbin0 -> 2343 bytes
-rw-r--r--res/drawable-hdpi/ic_launcher_adk.pngbin0 -> 6657 bytes
-rw-r--r--res/drawable-hdpi/scrubber_control_holo_dark.pngbin0 -> 1194 bytes
-rw-r--r--res/drawable-hdpi/scrubber_horizontal_blue_holo_dark.9.pngbin0 -> 238 bytes
-rw-r--r--res/drawable-hdpi/scrubber_horizontal_green_holo_dark.9.pngbin0 -> 250 bytes
-rw-r--r--res/drawable-hdpi/scrubber_horizontal_holo_dark.9.pngbin0 -> 487 bytes
-rw-r--r--res/drawable-hdpi/scrubber_horizontal_red_holo_dark.9.pngbin0 -> 242 bytes
-rw-r--r--res/drawable-hdpi/scrubber_vertical_blue_holo_dark.9.pngbin0 -> 274 bytes
-rw-r--r--res/drawable-hdpi/scrubber_vertical_green_holo_dark.9.pngbin0 -> 285 bytes
-rw-r--r--res/drawable-hdpi/scrubber_vertical_red_holo_dark.9.pngbin0 -> 280 bytes
-rw-r--r--res/drawable-ldpi/ic_launcher.pngbin0 -> 1733 bytes
-rw-r--r--res/drawable-mdpi/ic_launcher.pngbin0 -> 1953 bytes
-rw-r--r--res/drawable-mdpi/ic_launcher_adk.pngbin0 -> 3417 bytes
-rw-r--r--res/drawable-mdpi/scrubber_control_holo_dark.pngbin0 -> 866 bytes
-rw-r--r--res/drawable-mdpi/scrubber_horizontal_blue_holo_dark.9.pngbin0 -> 245 bytes
-rw-r--r--res/drawable-mdpi/scrubber_horizontal_green_holo_dark.9.pngbin0 -> 253 bytes
-rw-r--r--res/drawable-mdpi/scrubber_horizontal_holo_dark.9.pngbin0 -> 390 bytes
-rw-r--r--res/drawable-mdpi/scrubber_horizontal_red_holo_dark.9.pngbin0 -> 250 bytes
-rw-r--r--res/drawable-mdpi/scrubber_vertical_blue_holo_dark.9.pngbin0 -> 225 bytes
-rw-r--r--res/drawable-mdpi/scrubber_vertical_green_holo_dark.9.pngbin0 -> 239 bytes
-rw-r--r--res/drawable-mdpi/scrubber_vertical_red_holo_dark.9.pngbin0 -> 240 bytes
-rw-r--r--res/drawable-xhdpi/ab_rainbow_bg.9.pngbin0 -> 1461 bytes
-rw-r--r--res/drawable-xhdpi/adk_outline.pngbin0 -> 36361 bytes
-rw-r--r--res/drawable-xhdpi/ic_alarm.pngbin0 -> 7378 bytes
-rw-r--r--res/drawable-xhdpi/ic_brightness.pngbin0 -> 6195 bytes
-rw-r--r--res/drawable-xhdpi/ic_clock.pngbin0 -> 4989 bytes
-rw-r--r--res/drawable-xhdpi/ic_color.pngbin0 -> 5287 bytes
-rw-r--r--res/drawable-xhdpi/ic_display.pngbin0 -> 4341 bytes
-rw-r--r--res/drawable-xhdpi/ic_launcher.pngbin0 -> 2589 bytes
-rw-r--r--res/drawable-xhdpi/ic_launcher_adk.pngbin0 -> 10128 bytes
-rw-r--r--res/drawable-xhdpi/ic_lock.pngbin0 -> 3962 bytes
-rw-r--r--res/drawable-xhdpi/ic_presets.pngbin0 -> 3347 bytes
-rw-r--r--res/drawable-xhdpi/ic_unlock.pngbin0 -> 1647 bytes
-rw-r--r--res/drawable-xhdpi/ic_volume.pngbin0 -> 6621 bytes
-rw-r--r--res/drawable/home_button_bg.xml5
-rw-r--r--res/layout/alert_dialog.xml30
-rw-r--r--res/layout/color_camera.xml46
-rw-r--r--res/layout/color_combinations.xml77
-rw-r--r--res/layout/color_rgb.xml88
-rw-r--r--res/layout/color_sensor.xml43
-rw-r--r--res/layout/connect.xml63
-rw-r--r--res/layout/device_list.xml36
-rw-r--r--res/layout/device_name.xml21
-rw-r--r--res/layout/display.xml75
-rw-r--r--res/layout/home.xml164
-rw-r--r--res/layout/home_button.xml28
-rw-r--r--res/layout/licenses.xml14
-rw-r--r--res/layout/preset_name_dialog.xml44
-rw-r--r--res/layout/presets.xml21
-rw-r--r--res/layout/seekbar_preference.xml27
-rw-r--r--res/layout/time_dialog.xml14
-rw-r--r--res/menu/home_menu.xml16
-rw-r--r--res/menu/list_select_menu.xml16
-rw-r--r--res/menu/presets_menu.xml10
-rw-r--r--res/values/arrays.xml14
-rw-r--r--res/values/attrs.xml10
-rw-r--r--res/values/colors.xml12
-rw-r--r--res/values/strings.xml74
-rw-r--r--res/values/styles.xml11
-rw-r--r--res/xml/alarm_preferences.xml21
-rw-r--r--res/xml/brightness_preferences.xml9
-rw-r--r--res/xml/clock_preferences.xml11
-rw-r--r--res/xml/color_preferences.xml14
-rw-r--r--res/xml/display_preferences.xml15
-rw-r--r--res/xml/usb_accessory_filter.xml9
-rw-r--r--res/xml/volume_preferences.xml10
-rw-r--r--src/com/google/android/apps/adk2/ADK.java20
-rw-r--r--src/com/google/android/apps/adk2/BTConnection.java61
-rw-r--r--src/com/google/android/apps/adk2/Connection.java28
-rw-r--r--src/com/google/android/apps/adk2/Preferences.java45
-rw-r--r--src/com/google/android/apps/adk2/Presets.java129
-rw-r--r--src/com/google/android/apps/adk2/USBAccessoryActivity.java37
-rw-r--r--src/com/google/android/apps/adk2/UsbConnection.java95
-rw-r--r--src/com/google/android/apps/adk2/Utilities.java144
-rwxr-xr-xsrc/com/google/android/apps/adk2/activity/Adk2BaseActivity.java88
-rwxr-xr-xsrc/com/google/android/apps/adk2/activity/Adk2PreferenceActivity.java53
-rw-r--r--src/com/google/android/apps/adk2/activity/AlarmActivity.java95
-rwxr-xr-xsrc/com/google/android/apps/adk2/activity/BTDeviceListActivity.java90
-rw-r--r--src/com/google/android/apps/adk2/activity/BrightnessActivity.java54
-rw-r--r--src/com/google/android/apps/adk2/activity/ClockActivity.java83
-rw-r--r--src/com/google/android/apps/adk2/activity/ColorActivity.java41
-rw-r--r--src/com/google/android/apps/adk2/activity/ColorRGBActivity.java161
-rwxr-xr-xsrc/com/google/android/apps/adk2/activity/ColorSensorActivity.java107
-rwxr-xr-xsrc/com/google/android/apps/adk2/activity/ConnectActivity.java43
-rwxr-xr-xsrc/com/google/android/apps/adk2/activity/DisplayActivity.java63
-rwxr-xr-xsrc/com/google/android/apps/adk2/activity/HomeActivity.java968
-rw-r--r--src/com/google/android/apps/adk2/activity/LicenseActivity.java59
-rwxr-xr-xsrc/com/google/android/apps/adk2/activity/PresetsActivity.java260
-rw-r--r--src/com/google/android/apps/adk2/activity/VolumeActivity.java48
-rw-r--r--src/com/google/android/apps/adk2/views/ColorSensorView.java70
-rw-r--r--src/com/google/android/apps/adk2/views/Slider.java151
-rw-r--r--src/com/google/android/apps/adk2/widget/ActivityPreference.java57
-rw-r--r--src/com/google/android/apps/adk2/widget/SeekBarPreference.java102
-rw-r--r--src/com/google/android/apps/adk2/widget/TimeDialogPreference.java62
101 files changed, 4451 insertions, 5 deletions
diff --git a/.classpath b/.classpath
new file mode 100644
index 0000000..3f9691c
--- /dev/null
+++ b/.classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
+ <classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
+ <classpathentry kind="src" path="src"/>
+ <classpathentry kind="src" path="gen"/>
+ <classpathentry kind="output" path="bin/classes"/>
+</classpath>
diff --git a/.gitignore b/.gitignore
index 14e4dd1..1ec69fa 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,5 +1,2 @@
-*.swp
-*~
-TAGS
-tags
-cscope.out
+bin/
+gen/ \ No newline at end of file
diff --git a/.project b/.project
new file mode 100644
index 0000000..584b9d9
--- /dev/null
+++ b/.project
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>ADK 2012</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ <buildCommand>
+ <name>com.android.ide.eclipse.adt.ApkBuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>com.android.ide.eclipse.adt.AndroidNature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
new file mode 100644
index 0000000..f1a7d20
--- /dev/null
+++ b/AndroidManifest.xml
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.google.android.apps.adk2"
+ android:versionCode="1"
+ android:versionName="1.0" >
+
+ <uses-sdk
+ android:minSdkVersion="10"
+ android:targetSdkVersion="15" />
+
+ <uses-permission android:name="android.permission.BLUETOOTH" />
+ <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+ <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
+
+ <uses-feature
+ android:name="android.hardware.usb.accessory"
+ android:required="true" />
+
+ <application
+ android:hardwareAccelerated="true"
+ android:icon="@drawable/ic_launcher_adk"
+ android:label="@string/app_short_name"
+ android:theme="@style/Theme.ADK2" >
+ <uses-library android:name="com.android.future.usb.accessory" />
+
+ <activity
+ android:name=".activity.ConnectActivity"
+ android:label="@string/app_short_name"
+ android:screenOrientation="portrait" >
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+ <activity
+ android:name=".activity.BTDeviceListActivity"
+ android:label="@string/bluetooth"
+ android:screenOrientation="portrait" />
+ <activity
+ android:name=".activity.HomeActivity"
+ android:label="@string/app_short_name"
+ android:screenOrientation="portrait" >
+ </activity>
+ <activity
+ android:name=".activity.AlarmActivity"
+ android:label="@string/alarm"
+ android:screenOrientation="portrait" />
+ <activity
+ android:name=".activity.ClockActivity"
+ android:label="@string/clock"
+ android:screenOrientation="portrait" />
+ <activity
+ android:name=".activity.VolumeActivity"
+ android:label="@string/volume"
+ android:screenOrientation="portrait" />
+ <activity
+ android:name=".activity.ColorActivity"
+ android:label="@string/color"
+ android:screenOrientation="portrait" />
+ <activity
+ android:name=".activity.ColorRGBActivity"
+ android:label="@string/color"
+ android:screenOrientation="portrait" />
+ <activity
+ android:name=".activity.ColorCameraActivity"
+ android:label="@string/color"
+ android:screenOrientation="portrait" />
+ <activity
+ android:name=".activity.ColorSensorActivity"
+ android:label="@string/color_sensor"
+ android:screenOrientation="portrait" />
+ <activity
+ android:name=".activity.ColorCombinationsActivity"
+ android:label="@string/color_combinations"
+ android:screenOrientation="portrait" />
+ <activity
+ android:name=".activity.BrightnessActivity"
+ android:label="@string/brightness"
+ android:screenOrientation="portrait" />
+ <activity
+ android:name=".activity.DisplayActivity"
+ android:label="@string/display"
+ android:screenOrientation="portrait" />
+ <activity
+ android:name=".activity.PresetsActivity"
+ android:label="@string/presets"
+ android:screenOrientation="portrait" />
+ <activity
+ android:name=".activity.LicenseActivity"
+ android:label="@string/licenses"
+ android:screenOrientation="portrait" />
+ <activity
+ android:name="USBAccessoryActivity"
+ android:label="@string/app_long_name"
+ android:launchMode="singleInstance"
+ android:taskAffinity="" >
+ <intent-filter>
+ <action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
+ </intent-filter>
+
+ <meta-data
+ android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
+ android:resource="@xml/usb_accessory_filter" />
+ </activity>
+ </application>
+
+</manifest> \ No newline at end of file
diff --git a/lint.xml b/lint.xml
new file mode 100644
index 0000000..b0d4a8d
--- /dev/null
+++ b/lint.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<lint>
+ <issue id="Deprecated" severity="informational" />
+</lint> \ No newline at end of file
diff --git a/proguard-project.txt b/proguard-project.txt
new file mode 100644
index 0000000..f2fe155
--- /dev/null
+++ b/proguard-project.txt
@@ -0,0 +1,20 @@
+# To enable ProGuard in your project, edit project.properties
+# to define the proguard.config property as described in that file.
+#
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in ${sdk.dir}/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the ProGuard
+# include property in project.properties.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
diff --git a/project.properties b/project.properties
new file mode 100644
index 0000000..e0a848d
--- /dev/null
+++ b/project.properties
@@ -0,0 +1,14 @@
+# This file is automatically generated by Android Tools.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file must be checked in Version Control Systems.
+#
+# To customize properties used by the Ant build system edit
+# "ant.properties", and override values to adapt the script to your
+# project structure.
+#
+# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
+#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
+
+# Project target.
+target=Google Inc.:Google APIs:15
diff --git a/res/drawable-hdpi/ic_launcher.png b/res/drawable-hdpi/ic_launcher.png
new file mode 100644
index 0000000..99b9c53
--- /dev/null
+++ b/res/drawable-hdpi/ic_launcher.png
Binary files differ
diff --git a/res/drawable-hdpi/ic_launcher_adk.png b/res/drawable-hdpi/ic_launcher_adk.png
new file mode 100644
index 0000000..dcff319
--- /dev/null
+++ b/res/drawable-hdpi/ic_launcher_adk.png
Binary files differ
diff --git a/res/drawable-hdpi/scrubber_control_holo_dark.png b/res/drawable-hdpi/scrubber_control_holo_dark.png
new file mode 100644
index 0000000..5947ee1
--- /dev/null
+++ b/res/drawable-hdpi/scrubber_control_holo_dark.png
Binary files differ
diff --git a/res/drawable-hdpi/scrubber_horizontal_blue_holo_dark.9.png b/res/drawable-hdpi/scrubber_horizontal_blue_holo_dark.9.png
new file mode 100644
index 0000000..1dcd3b0
--- /dev/null
+++ b/res/drawable-hdpi/scrubber_horizontal_blue_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-hdpi/scrubber_horizontal_green_holo_dark.9.png b/res/drawable-hdpi/scrubber_horizontal_green_holo_dark.9.png
new file mode 100644
index 0000000..6221a0f
--- /dev/null
+++ b/res/drawable-hdpi/scrubber_horizontal_green_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-hdpi/scrubber_horizontal_holo_dark.9.png b/res/drawable-hdpi/scrubber_horizontal_holo_dark.9.png
new file mode 100644
index 0000000..6a162ed
--- /dev/null
+++ b/res/drawable-hdpi/scrubber_horizontal_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-hdpi/scrubber_horizontal_red_holo_dark.9.png b/res/drawable-hdpi/scrubber_horizontal_red_holo_dark.9.png
new file mode 100644
index 0000000..b785ebd
--- /dev/null
+++ b/res/drawable-hdpi/scrubber_horizontal_red_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-hdpi/scrubber_vertical_blue_holo_dark.9.png b/res/drawable-hdpi/scrubber_vertical_blue_holo_dark.9.png
new file mode 100644
index 0000000..5a22af5
--- /dev/null
+++ b/res/drawable-hdpi/scrubber_vertical_blue_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-hdpi/scrubber_vertical_green_holo_dark.9.png b/res/drawable-hdpi/scrubber_vertical_green_holo_dark.9.png
new file mode 100644
index 0000000..1ebd9f6
--- /dev/null
+++ b/res/drawable-hdpi/scrubber_vertical_green_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-hdpi/scrubber_vertical_red_holo_dark.9.png b/res/drawable-hdpi/scrubber_vertical_red_holo_dark.9.png
new file mode 100644
index 0000000..74800a4
--- /dev/null
+++ b/res/drawable-hdpi/scrubber_vertical_red_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-ldpi/ic_launcher.png b/res/drawable-ldpi/ic_launcher.png
new file mode 100644
index 0000000..bb4cf8e
--- /dev/null
+++ b/res/drawable-ldpi/ic_launcher.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_launcher.png b/res/drawable-mdpi/ic_launcher.png
new file mode 100644
index 0000000..831e794
--- /dev/null
+++ b/res/drawable-mdpi/ic_launcher.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_launcher_adk.png b/res/drawable-mdpi/ic_launcher_adk.png
new file mode 100644
index 0000000..3e7e712
--- /dev/null
+++ b/res/drawable-mdpi/ic_launcher_adk.png
Binary files differ
diff --git a/res/drawable-mdpi/scrubber_control_holo_dark.png b/res/drawable-mdpi/scrubber_control_holo_dark.png
new file mode 100644
index 0000000..90ece2a
--- /dev/null
+++ b/res/drawable-mdpi/scrubber_control_holo_dark.png
Binary files differ
diff --git a/res/drawable-mdpi/scrubber_horizontal_blue_holo_dark.9.png b/res/drawable-mdpi/scrubber_horizontal_blue_holo_dark.9.png
new file mode 100644
index 0000000..3a7665b
--- /dev/null
+++ b/res/drawable-mdpi/scrubber_horizontal_blue_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-mdpi/scrubber_horizontal_green_holo_dark.9.png b/res/drawable-mdpi/scrubber_horizontal_green_holo_dark.9.png
new file mode 100644
index 0000000..dac988a
--- /dev/null
+++ b/res/drawable-mdpi/scrubber_horizontal_green_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-mdpi/scrubber_horizontal_holo_dark.9.png b/res/drawable-mdpi/scrubber_horizontal_holo_dark.9.png
new file mode 100644
index 0000000..ce62fbe
--- /dev/null
+++ b/res/drawable-mdpi/scrubber_horizontal_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-mdpi/scrubber_horizontal_red_holo_dark.9.png b/res/drawable-mdpi/scrubber_horizontal_red_holo_dark.9.png
new file mode 100644
index 0000000..bd349fd
--- /dev/null
+++ b/res/drawable-mdpi/scrubber_horizontal_red_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-mdpi/scrubber_vertical_blue_holo_dark.9.png b/res/drawable-mdpi/scrubber_vertical_blue_holo_dark.9.png
new file mode 100644
index 0000000..fd9ca52
--- /dev/null
+++ b/res/drawable-mdpi/scrubber_vertical_blue_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-mdpi/scrubber_vertical_green_holo_dark.9.png b/res/drawable-mdpi/scrubber_vertical_green_holo_dark.9.png
new file mode 100644
index 0000000..f5cc83e
--- /dev/null
+++ b/res/drawable-mdpi/scrubber_vertical_green_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-mdpi/scrubber_vertical_red_holo_dark.9.png b/res/drawable-mdpi/scrubber_vertical_red_holo_dark.9.png
new file mode 100644
index 0000000..26eaa3d
--- /dev/null
+++ b/res/drawable-mdpi/scrubber_vertical_red_holo_dark.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/ab_rainbow_bg.9.png b/res/drawable-xhdpi/ab_rainbow_bg.9.png
new file mode 100644
index 0000000..7db3425
--- /dev/null
+++ b/res/drawable-xhdpi/ab_rainbow_bg.9.png
Binary files differ
diff --git a/res/drawable-xhdpi/adk_outline.png b/res/drawable-xhdpi/adk_outline.png
new file mode 100644
index 0000000..a270793
--- /dev/null
+++ b/res/drawable-xhdpi/adk_outline.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_alarm.png b/res/drawable-xhdpi/ic_alarm.png
new file mode 100644
index 0000000..bebd61e
--- /dev/null
+++ b/res/drawable-xhdpi/ic_alarm.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_brightness.png b/res/drawable-xhdpi/ic_brightness.png
new file mode 100644
index 0000000..d46da9f
--- /dev/null
+++ b/res/drawable-xhdpi/ic_brightness.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_clock.png b/res/drawable-xhdpi/ic_clock.png
new file mode 100644
index 0000000..524f073
--- /dev/null
+++ b/res/drawable-xhdpi/ic_clock.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_color.png b/res/drawable-xhdpi/ic_color.png
new file mode 100644
index 0000000..4de662c
--- /dev/null
+++ b/res/drawable-xhdpi/ic_color.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_display.png b/res/drawable-xhdpi/ic_display.png
new file mode 100644
index 0000000..867bfb3
--- /dev/null
+++ b/res/drawable-xhdpi/ic_display.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_launcher.png b/res/drawable-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..42b2269
--- /dev/null
+++ b/res/drawable-xhdpi/ic_launcher.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_launcher_adk.png b/res/drawable-xhdpi/ic_launcher_adk.png
new file mode 100644
index 0000000..c762de0
--- /dev/null
+++ b/res/drawable-xhdpi/ic_launcher_adk.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_lock.png b/res/drawable-xhdpi/ic_lock.png
new file mode 100644
index 0000000..bba0c72
--- /dev/null
+++ b/res/drawable-xhdpi/ic_lock.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_presets.png b/res/drawable-xhdpi/ic_presets.png
new file mode 100644
index 0000000..d8d6be8
--- /dev/null
+++ b/res/drawable-xhdpi/ic_presets.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_unlock.png b/res/drawable-xhdpi/ic_unlock.png
new file mode 100644
index 0000000..f8860a2
--- /dev/null
+++ b/res/drawable-xhdpi/ic_unlock.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_volume.png b/res/drawable-xhdpi/ic_volume.png
new file mode 100644
index 0000000..8e8784d
--- /dev/null
+++ b/res/drawable-xhdpi/ic_volume.png
Binary files differ
diff --git a/res/drawable/home_button_bg.xml b/res/drawable/home_button_bg.xml
new file mode 100644
index 0000000..2428828
--- /dev/null
+++ b/res/drawable/home_button_bg.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true" android:drawable="@color/home_button_pressed" />
+ <item android:drawable="@color/home_button_normal" />
+</selector> \ No newline at end of file
diff --git a/res/layout/alert_dialog.xml b/res/layout/alert_dialog.xml
new file mode 100644
index 0000000..f8c0aed
--- /dev/null
+++ b/res/layout/alert_dialog.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <TextView
+ android:id="@+id/username_view"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_marginLeft="20dip"
+ android:layout_marginRight="20dip"
+ android:text="@string/set_bt_name_title"
+ android:gravity="left"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ <EditText
+ android:id="@+id/btname_edit"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_marginLeft="20dip"
+ android:layout_marginRight="20dip"
+ android:scrollHorizontally="true"
+ android:autoText="false"
+ android:capitalize="none"
+ android:gravity="fill_horizontal"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+</LinearLayout> \ No newline at end of file
diff --git a/res/layout/color_camera.xml b/res/layout/color_camera.xml
new file mode 100644
index 0000000..87a9157
--- /dev/null
+++ b/res/layout/color_camera.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ >
+
+ <RelativeLayout
+ android:id="@+id/camera_frame"
+ android:layout_width="match_parent"
+ android:layout_height="300dip"
+ >
+
+ <SurfaceView
+ android:id="@+id/camera_surface"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_centerInParent="true"
+ />
+
+ <View tools:ignore="PxUsage"
+ android:layout_width="40px"
+ android:layout_height="40px"
+ android:layout_centerInParent="true"
+ android:background="#ff000000"
+ />
+
+ <View tools:ignore="PxUsage"
+ android:id="@+id/sample_preview"
+ android:layout_width="160px"
+ android:layout_height="160px"
+ android:layout_alignParentRight="true"
+ android:layout_alignParentTop="true"
+ android:visible="false"
+ />
+
+ </RelativeLayout>
+
+ <Button
+ android:id="@+id/color_sample_button"
+ android:layout_width="50dip"
+ android:layout_height="50dip"
+ android:layout_below="@+id/camera_frame"
+ android:layout_centerHorizontal="true"
+ />
+
+</RelativeLayout> \ No newline at end of file
diff --git a/res/layout/color_combinations.xml b/res/layout/color_combinations.xml
new file mode 100644
index 0000000..a29713f
--- /dev/null
+++ b/res/layout/color_combinations.xml
@@ -0,0 +1,77 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:padding="25dip" >
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="64dp" >
+
+ <View
+ android:id="@+id/color_combo1"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:background="@color/combination_color" />
+
+ <View
+ android:id="@+id/color_combo2"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:background="@color/combination_color" />
+
+ <View
+ android:id="@+id/color_combo3"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:background="@color/combination_color" />
+
+ <View
+ android:id="@+id/color_combo4"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:background="@color/combination_color" />
+
+ <View
+ android:id="@+id/color_combo5"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:background="@color/combination_color" />
+ </LinearLayout>
+
+ <RadioGroup
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/color_combination_group"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:padding="25dip" >
+
+ <RadioButton
+ android:id="@+id/radio_monochromatic"
+ style="@android:style/TextAppearance.DeviceDefault.Large"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/monochromatic" />
+
+ <RadioButton
+ android:id="@+id/radio_analogous"
+ style="@android:style/TextAppearance.DeviceDefault.Large"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/analogous" />
+
+ <RadioButton
+ android:id="@+id/radio_triad"
+ style="@android:style/TextAppearance.DeviceDefault.Large"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/triad" />
+ </RadioGroup>
+
+</LinearLayout> \ No newline at end of file
diff --git a/res/layout/color_rgb.xml b/res/layout/color_rgb.xml
new file mode 100644
index 0000000..6236391
--- /dev/null
+++ b/res/layout/color_rgb.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:padding="25dip"
+ tools:ignore="NestedWeights" >
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_margin="25dip"
+ android:orientation="horizontal" >
+
+ <View
+ android:id="@+id/original_color"
+ android:layout_width="0dip"
+ android:layout_height="50dip"
+ android:layout_weight="1"
+ android:background="#ff0000" />
+
+ <View
+ android:id="@+id/new_color"
+ android:layout_width="0dip"
+ android:layout_height="50dip"
+ android:layout_weight="1"
+ android:background="#ffff00" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_margin="25dip"
+ android:orientation="horizontal" >
+
+ <TextView
+ android:id="@+id/color_hex"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1.5"
+ android:gravity="center_horizontal"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ <TextView
+ android:id="@+id/color_r"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:gravity="center_horizontal"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ <TextView
+ android:id="@+id/color_g"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:gravity="center_horizontal"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ <TextView
+ android:id="@+id/color_b"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:gravity="center_horizontal"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+ </LinearLayout>
+
+ <com.google.android.apps.adk2.views.Slider
+ android:id="@+id/seek_bar_r"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_margin="25dip" />
+
+ <com.google.android.apps.adk2.views.Slider
+ android:id="@+id/seek_bar_g"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_margin="25dip" />
+
+ <com.google.android.apps.adk2.views.Slider
+ android:id="@+id/seek_bar_b"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_margin="25dip" />
+
+</LinearLayout> \ No newline at end of file
diff --git a/res/layout/color_sensor.xml b/res/layout/color_sensor.xml
new file mode 100644
index 0000000..dcff0ae
--- /dev/null
+++ b/res/layout/color_sensor.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+
+ <View
+ android:layout_width="0dip"
+ android:layout_height="0dip"
+ android:layout_weight="1"
+ android:gravity="center" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_margin="10dip"
+ android:gravity="center"
+ android:text="@string/capture_prompt"
+ android:textAppearance="?android:attr/textAppearanceMedium" />
+
+ <com.google.android.apps.adk2.views.ColorSensorView
+ android:id="@+id/color_sensor_view"
+ android:layout_width="200dip"
+ android:layout_height="200dip"
+ android:layout_gravity="center"
+ android:layout_margin="25dip"
+ android:gravity="center" />
+
+ <Button
+ android:id="@+id/color_sample_button"
+ android:layout_width="match_parent"
+ android:layout_height="80dip"
+ android:layout_margin="25dip"
+ android:gravity="center"
+ android:text="@string/capture" />
+
+ <View
+ android:layout_width="0dip"
+ android:layout_height="0dip"
+ android:layout_weight="1"
+ android:gravity="center" />
+
+</LinearLayout> \ No newline at end of file
diff --git a/res/layout/connect.xml b/res/layout/connect.xml
new file mode 100644
index 0000000..2aefb0f
--- /dev/null
+++ b/res/layout/connect.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:padding="5dp" >
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1" />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:text="@string/connect_please"
+ android:textAppearance="?android:attr/textAppearanceLarge" />
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1" />
+
+ <ImageView
+ android:id="@+id/imageView1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:contentDescription="@string/adk_description"
+ android:src="@drawable/adk_outline" />
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1" />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:text="@string/plug_in_or_use_bluetooth"
+ android:textAppearance="?android:attr/textAppearanceLarge" />
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1" />
+
+ <Button
+ android:id="@+id/connect_bluetooth_button"
+ android:layout_width="match_parent"
+ android:layout_height="80dip"
+ android:layout_margin="25dip"
+ android:gravity="center"
+ android:text="@string/bluetooth" />
+
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1" />
+
+</LinearLayout> \ No newline at end of file
diff --git a/res/layout/device_list.xml b/res/layout/device_list.xml
new file mode 100644
index 0000000..866d36e
--- /dev/null
+++ b/res/layout/device_list.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2009 The Android Open Source Project
+
+ 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.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+
+ <TextView
+ android:id="@+id/title_paired_devices"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/title_paired_devices"
+ android:textAppearance="?android:attr/textAppearanceLarge"
+ android:visibility="gone" />
+
+ <ListView
+ android:id="@+id/paired_devices"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1" />
+
+</LinearLayout> \ No newline at end of file
diff --git a/res/layout/device_name.xml b/res/layout/device_name.xml
new file mode 100644
index 0000000..8fa358c
--- /dev/null
+++ b/res/layout/device_name.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2009 The Android Open Source Project
+
+ 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.
+-->
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textSize="18sp"
+ android:padding="5dp"
+/> \ No newline at end of file
diff --git a/res/layout/display.xml b/res/layout/display.xml
new file mode 100644
index 0000000..d30ad23
--- /dev/null
+++ b/res/layout/display.xml
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RadioGroup xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/display_group"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:padding="25dip" >
+
+ <!--
+ AdkShowAnimation,
+ AdkShowAccel,
+ AdkShowMag,
+ AdkShowTemp,
+ AdkShowHygro,
+ AdkShowBaro,
+ AdkShowProx,
+ AdkShowColor,
+ -->
+
+ <RadioButton
+ android:id="@+id/radio_animation"
+ style="@android:style/TextAppearance.DeviceDefault.Large"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/leds_animation" />
+
+ <RadioButton
+ android:id="@+id/radio_accell"
+ style="@android:style/TextAppearance.DeviceDefault.Large"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/accel" />
+
+ <RadioButton
+ android:id="@+id/radio_mag"
+ style="@android:style/TextAppearance.DeviceDefault.Large"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/mag" />
+
+ <RadioButton
+ android:id="@+id/radio_temperature"
+ style="@android:style/TextAppearance.DeviceDefault.Large"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/temperature" />
+
+ <RadioButton
+ android:id="@+id/radio_hygro"
+ style="@android:style/TextAppearance.DeviceDefault.Large"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/hygro" />
+
+ <RadioButton
+ android:id="@+id/radio_baro"
+ style="@android:style/TextAppearance.DeviceDefault.Large"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/baro" />
+
+ <RadioButton
+ android:id="@+id/radio_prox"
+ style="@android:style/TextAppearance.DeviceDefault.Large"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/prox" />
+
+ <RadioButton
+ android:id="@+id/radio_color"
+ style="@android:style/TextAppearance.DeviceDefault.Large"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/color" />
+
+</RadioGroup> \ No newline at end of file
diff --git a/res/layout/home.xml b/res/layout/home.xml
new file mode 100644
index 0000000..b0c5133
--- /dev/null
+++ b/res/layout/home.xml
@@ -0,0 +1,164 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ >
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="0dip"
+ android:layout_weight="1"
+ android:orientation="horizontal"
+ >
+
+ <include
+ tools:ignore="NestedWeights"
+ layout="@layout/home_button"
+ android:id="@+id/clock_button"
+ android:layout_width="0dip"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ />
+
+ <View tools:ignore="PxUsage"
+ android:layout_width="1px"
+ android:layout_height="match_parent"
+ android:background="@color/home_activity_divider"
+ />
+
+ <include layout="@layout/home_button"
+ android:id="@+id/alarm_button"
+ android:layout_width="0dip"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ />
+
+ </LinearLayout>
+
+ <View tools:ignore="PxUsage"
+ android:layout_width="match_parent"
+ android:layout_height="1px"
+ android:background="@color/home_activity_divider"
+ />
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="0dip"
+ android:layout_weight="1"
+ android:orientation="horizontal"
+ >
+
+ <include
+ tools:ignore="NestedWeights"
+ layout="@layout/home_button"
+ android:id="@+id/volume_button"
+ android:layout_width="0dip"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ />
+
+ <View
+ tools:ignore="PxUsage"
+ android:layout_width="1px"
+ android:layout_height="match_parent"
+ android:background="@color/home_activity_divider"
+ />
+
+ <include
+ layout="@layout/home_button"
+ android:id="@+id/color_button"
+ android:layout_width="0dip"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ />
+
+ </LinearLayout>
+
+ <View
+ tools:ignore="PxUsage"
+ android:layout_width="match_parent"
+ android:layout_height="1px"
+ android:background="@color/home_activity_divider"
+ />
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="0dip"
+ android:layout_weight="1"
+ android:orientation="horizontal"
+ >
+
+ <include
+ tools:ignore="NestedWeights"
+ layout="@layout/home_button"
+ android:id="@+id/brightness_button"
+ android:layout_width="0dip"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ />
+
+ <View tools:ignore="PxUsage"
+ android:layout_width="1px"
+ android:layout_height="match_parent"
+ android:background="@color/home_activity_divider"
+ />
+
+ <include
+ layout="@layout/home_button"
+ android:id="@+id/display_button"
+ android:layout_width="0dip"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ />
+
+ </LinearLayout>
+
+ <View
+ tools:ignore="PxUsage"
+ android:layout_width="match_parent"
+ android:layout_height="1px"
+ android:background="@color/home_activity_divider"
+ />
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="0dip"
+ android:layout_weight="1"
+ android:orientation="horizontal"
+ >
+
+ <include
+ tools:ignore="NestedWeights"
+ layout="@layout/home_button"
+ android:id="@+id/presets_button"
+ android:layout_width="0dip"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ />
+
+ <View
+ tools:ignore="PxUsage"
+ android:layout_width="1px"
+ android:layout_height="match_parent"
+ android:background="@color/home_activity_divider"
+ />
+
+ <include
+ layout="@layout/home_button"
+ android:id="@+id/lock_button"
+ android:layout_width="0dip"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ />
+
+ </LinearLayout>
+
+ <View
+ tools:ignore="PxUsage"
+ android:layout_width="match_parent"
+ android:layout_height="1px"
+ android:background="@color/home_activity_divider"
+ />
+
+</LinearLayout> \ No newline at end of file
diff --git a/res/layout/home_button.xml b/res/layout/home_button.xml
new file mode 100644
index 0000000..1854d55
--- /dev/null
+++ b/res/layout/home_button.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:background="@drawable/home_button_bg"
+ android:clickable="true"
+ >
+
+ <ImageView tools:ignore="ContentDescription"
+ android:id="@+id/icon"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_marginBottom="14dip"
+ android:scaleType="center"
+ />
+
+ <TextView
+ android:id="@+id/label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_centerHorizontal="true"
+ android:layout_alignParentBottom="true"
+ android:layout_marginBottom="14dip"
+ android:textColor="@color/home_button_label"
+ />
+
+</RelativeLayout>
diff --git a/res/layout/licenses.xml b/res/layout/licenses.xml
new file mode 100644
index 0000000..7bd39d6
--- /dev/null
+++ b/res/layout/licenses.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/license_scroll"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" >
+
+ <TextView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/license_text"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+ </TextView>
+
+</ScrollView> \ No newline at end of file
diff --git a/res/layout/preset_name_dialog.xml b/res/layout/preset_name_dialog.xml
new file mode 100644
index 0000000..339bb73
--- /dev/null
+++ b/res/layout/preset_name_dialog.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/preset_name_root_view"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical"
+ android:padding="10dp" >
+
+ <TextView
+ android:id="@+id/preset_name_label"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/name"
+ android:textAppearance="?android:attr/textAppearanceLarge" />
+
+ <EditText
+ android:id="@+id/preset_name_edit"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:inputType="text" >
+
+ <requestFocus />
+ </EditText>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+
+ <Button
+ android:id="@+id/preset_edit_cancel"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:text="@android:string/cancel" />
+
+ <Button
+ android:id="@+id/preset_edit_rename"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:text="@string/rename" />
+ </LinearLayout>
+
+</LinearLayout> \ No newline at end of file
diff --git a/res/layout/presets.xml b/res/layout/presets.xml
new file mode 100644
index 0000000..0a7d73a
--- /dev/null
+++ b/res/layout/presets.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+
+ <ListView
+ android:id="@android:id/list"
+ android:layout_width="match_parent"
+ android:layout_height="0dip"
+ android:layout_weight="1"
+ android:drawSelectorOnTop="false"
+ android:choiceMode="multipleChoiceModal" />
+
+ <TextView
+ android:id="@android:id/empty"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:text="@string/no_presets" />
+
+</LinearLayout> \ No newline at end of file
diff --git a/res/layout/seekbar_preference.xml b/res/layout/seekbar_preference.xml
new file mode 100644
index 0000000..2fc3a29
--- /dev/null
+++ b/res/layout/seekbar_preference.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="10dip"
+ android:paddingLeft="8dip"
+ android:paddingBottom="14dip"
+ android:paddingRight="?android:attr/scrollbarSize"
+ >
+
+ <TextView android:id="@+android:id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:singleLine="true"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:ellipsize="marquee"
+ android:fadingEdge="horizontal"
+ />
+
+ <SeekBar android:id="@+id/seekbar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="12dip"
+ android:layout_below="@android:id/title"
+ android:layout_alignLeft="@android:id/title"
+ />
+</RelativeLayout>
diff --git a/res/layout/time_dialog.xml b/res/layout/time_dialog.xml
new file mode 100644
index 0000000..3ef9dd2
--- /dev/null
+++ b/res/layout/time_dialog.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ >
+
+ <TimePicker android:id="@+id/time_picker"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ />
+
+</LinearLayout> \ No newline at end of file
diff --git a/res/menu/home_menu.xml b/res/menu/home_menu.xml
new file mode 100644
index 0000000..ca6d261
--- /dev/null
+++ b/res/menu/home_menu.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <item
+ android:id="@+id/disconnect_menu"
+ android:showAsAction="never"
+ android:title="@string/disconnect">
+ </item>
+ <item android:id="@+id/change_bt_name" android:title="@string/change_bt_name"></item><item
+ android:id="@+id/license_menu"
+ android:showAsAction="always"
+ android:title="@string/licenses">
+ </item>
+
+
+</menu> \ No newline at end of file
diff --git a/res/menu/list_select_menu.xml b/res/menu/list_select_menu.xml
new file mode 100644
index 0000000..8017a78
--- /dev/null
+++ b/res/menu/list_select_menu.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <item
+ android:id="@+id/delete_preset"
+ android:icon="@android:drawable/ic_menu_delete"
+ android:showAsAction="ifRoom"
+ android:title="@string/delete"/>
+
+ <item
+ android:id="@+id/edit_preset"
+ android:icon="@android:drawable/ic_menu_edit"
+ android:showAsAction="always"
+ android:title="@string/edit"/>
+
+</menu> \ No newline at end of file
diff --git a/res/menu/presets_menu.xml b/res/menu/presets_menu.xml
new file mode 100644
index 0000000..56082b2
--- /dev/null
+++ b/res/menu/presets_menu.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<menu xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <item
+ android:id="@+id/new_preset"
+ android:showAsAction="always"
+ android:title="@string/new_preset">
+ </item>
+
+</menu> \ No newline at end of file
diff --git a/res/values/arrays.xml b/res/values/arrays.xml
new file mode 100644
index 0000000..88cb3d3
--- /dev/null
+++ b/res/values/arrays.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+ <string-array name="alarm_sounds">
+ <item>Silent</item>
+ <item>Cesium</item>
+ <item>Fermium</item>
+ <item>Hassium</item>
+ <item>Neptunium</item>
+ <item>Nobelium</item>
+ <item>Plutonium</item>
+ </string-array>
+
+</resources> \ No newline at end of file
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
new file mode 100644
index 0000000..3d5dbaf
--- /dev/null
+++ b/res/values/attrs.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<resources>
+ <declare-styleable name = "ActivityPreference">
+ <attr name="classname" format = "string"/>
+ </declare-styleable>
+
+ <declare-styleable name = "SeekBarPreference">
+ <attr name="max" format = "integer"/>
+ </declare-styleable>
+</resources> \ No newline at end of file
diff --git a/res/values/colors.xml b/res/values/colors.xml
new file mode 100644
index 0000000..cb03548
--- /dev/null
+++ b/res/values/colors.xml
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <color name="window_background">#000000</color>
+
+ <color name="home_button_normal">#000000</color>
+ <color name="home_button_pressed">#257391</color>
+
+ <color name="home_activity_divider">#666666</color>
+ <color name="home_button_label">#eeeeee</color>
+
+ <color name="combination_color">#eeeeee</color>
+</resources> \ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
new file mode 100644
index 0000000..6e94c2b
--- /dev/null
+++ b/res/values/strings.xml
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+ <string name="app_short_name">ADK 2012</string>
+ <string name="app_long_name">ADK DemoKit 2012</string>
+ <string name="clock">Clock</string>
+ <string name="capture">Capture</string>
+ <string name="adk_description">A picture of the 2012 ADK.</string>
+ <string name="capture_prompt">When ready press the capture button below.</string>
+ <string name="alarm">Alarm</string>
+ <string name="volume">Volume</string>
+ <string name="color">Color</string>
+ <string name="color_sensor">Color sensor</string>
+ <string name="color_combinations">Color combinations</string>
+ <string name="brightness">Brightness</string>
+ <string name="bluetooth">Use Bluetooth</string>
+ <string name="display">Display</string>
+ <string name="presets">Presets</string>
+ <string name="locked">Locked</string>
+ <string name="unlocked">Unlocked</string>
+ <string name="time">Time</string>
+ <string name="accel">Acceleration</string>
+ <string name="temperature">Temperature</string>
+ <string name="hygro">Hygro</string>
+ <string name="leds_animation">LEDs animation</string>
+ <string name="baro">Pressure</string>
+ <string name="mag">Magnetic</string>
+ <string name="prox">Proximity</string>
+ <string name="no_presets">No presets</string>
+ <string name="new_preset">New preset</string>
+ <string name="name">Name</string>
+ <string name="delete">Delete</string>
+ <string name="edit">Edit</string>
+ <string name="rename">Rename</string>
+ <string name="cancel">Cancel</string>
+ <string name="create">Create</string>
+ <string name="disconnect">Disconnect</string>
+ <string name="title_paired_devices">Paired devices</string>
+ <string name="set">Set</string>
+ <string name="licenses">Licenses</string>
+ <string name="monochromatic">Monochromatic</string>
+ <string name="analogous">Analogous</string>
+ <string name="triad">Triad</string>
+ <string name="complementary">Complementary</string>
+ <string name="shade">Shade</string>
+ <string name="connect_please">Your ADK is not connected.</string>
+ <string name="plug_in_or_use_bluetooth">Please plug in the USB cable or use Bluetooth to connect to the ADK.</string>
+ <string name="fake_it">Fake it</string>
+ <string name="none_paired">None paired</string>
+ <string name="select_device">Select device</string>
+ <string name="pref_alarm_on_title">Turn ADK alarm on</string>
+ <string name="pref_alarm_vibrate_title">Vibrate</string>
+ <string name="pref_alarm_time_title">Time</string>
+ <string name="pref_alarm_sound_title">ADK alarm sound</string>
+ <string name="pref_clock_set_time_title">Set time</string>
+ <string name="pref_volume_title">Volume</string>
+ <string name="pref_color_base">Base</string>
+ <string name="pref_color_camera">Capture with phone camera</string>
+ <string name="pref_color_colorimeter">Capture with ADK color sensor</string>
+ <string name="pref_color_combinations">Combinations</string>
+ <string name="sync_width_adk_clock">Sync with ADK clock</string>
+ <string name="tbd">{tbd}</string>
+
+ <plurals name="number_of_presets_deleted">
+ <item quantity="one">Deleted one preset.</item>
+ <item quantity="two">Deleted two presets.</item>
+ <item quantity="other">Deleted %d presets.</item>
+ </plurals>
+ <string name="change_bt_name">Change Bluetooth Name</string>
+ <string name="set_bt_name_title">Set Bluetooth Name</string>
+ <string name="set_bt_name_ok">OK</string>
+ <string name="set_bt_name_cancel">Cancel</string>
+
+</resources> \ No newline at end of file
diff --git a/res/values/styles.xml b/res/values/styles.xml
new file mode 100644
index 0000000..e0f48b1
--- /dev/null
+++ b/res/values/styles.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+ <style name="Theme.ADK2" parent="android:style/Theme.Holo">
+ <item name="android:actionBarStyle">@style/Theme.ADK2_ActionBar</item>
+ <item name="android:windowBackground">@color/window_background</item>
+ </style>
+
+ <style name="Theme.ADK2_ActionBar" parent="@android:style/Widget.Holo.ActionBar">
+ <item name="android:background">@drawable/ab_rainbow_bg</item>
+ </style>
+</resources> \ No newline at end of file
diff --git a/res/xml/alarm_preferences.xml b/res/xml/alarm_preferences.xml
new file mode 100644
index 0000000..db0e01a
--- /dev/null
+++ b/res/xml/alarm_preferences.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <CheckBoxPreference
+ android:defaultValue="true"
+ android:key="alarm_on"
+ android:title="@string/pref_alarm_on_title" />
+
+ <com.google.android.apps.adk2.widget.TimeDialogPreference
+ android:dialogLayout="@layout/time_dialog"
+ android:key="alarm_time"
+ android:negativeButtonText="@string/cancel"
+ android:positiveButtonText="@string/set"
+ android:title="@string/pref_alarm_time_title" />
+ />
+ <ListPreference
+ android:key="alarm_sound"
+ android:summary="{tbd}"
+ android:title="@string/pref_alarm_sound_title" />
+
+</PreferenceScreen> \ No newline at end of file
diff --git a/res/xml/brightness_preferences.xml b/res/xml/brightness_preferences.xml
new file mode 100644
index 0000000..5e09845
--- /dev/null
+++ b/res/xml/brightness_preferences.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:adk2012="http://schemas.android.com/apk/res/com.google.android.apps.adk2" >
+
+ <com.google.android.apps.adk2.widget.SeekBarPreference
+ adk2012:max="255"
+ android:key="brightness" />
+
+</PreferenceScreen> \ No newline at end of file
diff --git a/res/xml/clock_preferences.xml b/res/xml/clock_preferences.xml
new file mode 100644
index 0000000..76b45cb
--- /dev/null
+++ b/res/xml/clock_preferences.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <com.google.android.apps.adk2.widget.TimeDialogPreference
+ android:dialogLayout="@layout/time_dialog"
+ android:key="time"
+ android:negativeButtonText="@string/cancel"
+ android:positiveButtonText="@string/set"
+ android:title="@string/pref_clock_set_time_title" />
+
+</PreferenceScreen> \ No newline at end of file
diff --git a/res/xml/color_preferences.xml b/res/xml/color_preferences.xml
new file mode 100644
index 0000000..84be4e3
--- /dev/null
+++ b/res/xml/color_preferences.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="utf-8"?>
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:adk2012="http://schemas.android.com/apk/res/com.google.android.apps.adk2" >
+
+ <com.google.android.apps.adk2.widget.ActivityPreference
+ adk2012:classname="com.google.android.apps.adk2.activity.ColorRGBActivity"
+ android:key="color"
+ android:title="@string/pref_color_base" />
+ <com.google.android.apps.adk2.widget.ActivityPreference
+ adk2012:classname="com.google.android.apps.adk2.activity.ColorSensorActivity"
+ android:key="color"
+ android:title="@string/pref_color_colorimeter" />
+
+</PreferenceScreen> \ No newline at end of file
diff --git a/res/xml/display_preferences.xml b/res/xml/display_preferences.xml
new file mode 100644
index 0000000..98407a5
--- /dev/null
+++ b/res/xml/display_preferences.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <PreferenceCategory>
+ <CheckBoxPreference
+ android:defaultValue="true"
+ android:key="checkboxPref"
+ android:title="Use PIN" />
+ <CheckBoxPreference
+ android:defaultValue="false"
+ android:key="checkboxPref2"
+ android:title="Don&apos;t use PIN" />
+ </PreferenceCategory>
+
+</PreferenceScreen> \ No newline at end of file
diff --git a/res/xml/usb_accessory_filter.xml b/res/xml/usb_accessory_filter.xml
new file mode 100644
index 0000000..1ecc060
--- /dev/null
+++ b/res/xml/usb_accessory_filter.xml
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+
+ <usb-accessory
+ manufacturer="Google, Inc."
+ model="DemoKit"
+ version="2.0" />
+
+</resources> \ No newline at end of file
diff --git a/res/xml/volume_preferences.xml b/res/xml/volume_preferences.xml
new file mode 100644
index 0000000..73e8616
--- /dev/null
+++ b/res/xml/volume_preferences.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:adk2012="http://schemas.android.com/apk/res/com.google.android.apps.adk2" >
+
+ <com.google.android.apps.adk2.widget.SeekBarPreference
+ adk2012:max="255"
+ android:key="volume"
+ android:title="@string/pref_volume_title" />
+
+</PreferenceScreen> \ No newline at end of file
diff --git a/src/com/google/android/apps/adk2/ADK.java b/src/com/google/android/apps/adk2/ADK.java
new file mode 100644
index 0000000..d6a1f41
--- /dev/null
+++ b/src/com/google/android/apps/adk2/ADK.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+package com.google.android.apps.adk2;
+
+public final class ADK {
+ public static final String TAG = "ADK_2012";
+}
diff --git a/src/com/google/android/apps/adk2/BTConnection.java b/src/com/google/android/apps/adk2/BTConnection.java
new file mode 100644
index 0000000..d9568b0
--- /dev/null
+++ b/src/com/google/android/apps/adk2/BTConnection.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+package com.google.android.apps.adk2;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.UUID;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothSocket;
+
+public class BTConnection extends Connection {
+
+ private final BluetoothAdapter mAdapter;
+ private BluetoothSocket mSocket;
+
+ private static final UUID MY_UUID_INSECURE = UUID
+ .fromString("1dd35050-a437-11e1-b3dd-0800200c9a66");
+
+ public BTConnection(String address) {
+ mAdapter = BluetoothAdapter.getDefaultAdapter();
+ BluetoothDevice device = mAdapter.getRemoteDevice(address);
+ try {
+ mSocket = device
+ .createInsecureRfcommSocketToServiceRecord(MY_UUID_INSECURE);
+ mSocket.connect();
+ } catch (IOException e) {
+ }
+ }
+
+ @Override
+ public InputStream getInputStream() throws IOException {
+ return mSocket.getInputStream();
+ }
+
+ @Override
+ public OutputStream getOutputStream() throws IOException {
+ return mSocket.getOutputStream();
+ }
+
+ @Override
+ public void close() throws IOException {
+ mSocket.close();
+ }
+
+}
diff --git a/src/com/google/android/apps/adk2/Connection.java b/src/com/google/android/apps/adk2/Connection.java
new file mode 100644
index 0000000..ab889c1
--- /dev/null
+++ b/src/com/google/android/apps/adk2/Connection.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+package com.google.android.apps.adk2;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+public abstract class Connection {
+ public abstract InputStream getInputStream() throws IOException;
+
+ public abstract OutputStream getOutputStream() throws IOException;
+
+ public abstract void close() throws IOException;
+}
diff --git a/src/com/google/android/apps/adk2/Preferences.java b/src/com/google/android/apps/adk2/Preferences.java
new file mode 100644
index 0000000..ec88249
--- /dev/null
+++ b/src/com/google/android/apps/adk2/Preferences.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+package com.google.android.apps.adk2;
+
+import android.graphics.Color;
+
+public final class Preferences {
+
+ // Preference Keys
+ public static final String PREF_ALARM_ON = "alarm_on";
+ public static final String PREF_ALARM_TIME = "alarm_time";
+ public static final String PREF_ALARM_SOUND = "alarm_sound";
+ public static final String PREF_COLOR = "color";
+ public static final String PREF_DISPLAY = "display";
+ public static final String PREF_BRIGHTNESS = "brightness";
+ public static final String PREF_VOLUME = "volume";
+
+ public static final String PREF_TIME = "time";
+
+ public static final String PREF_COLOR_SENSOR = "color_sensor";
+ public static final String PREF_LOCKED = "locked";
+
+ public static final String PREF_LICENSE_TEXT = "license_text";
+
+ public static final String[] SETTINGS_PREFERENCES = { PREF_ALARM_ON,
+ PREF_ALARM_TIME, PREF_COLOR, PREF_BRIGHTNESS, PREF_VOLUME };
+
+ // Defaults
+ public static final int PREF_DEFAULT_COLOR = Color.argb(255, 128, 64, 32);
+ public static final int DEFAULT_ALARM_TIME = 390; // 390 = 6:30am
+
+}
diff --git a/src/com/google/android/apps/adk2/Presets.java b/src/com/google/android/apps/adk2/Presets.java
new file mode 100644
index 0000000..4eb03ee
--- /dev/null
+++ b/src/com/google/android/apps/adk2/Presets.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+package com.google.android.apps.adk2;
+
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.util.ArrayList;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+
+public class Presets {
+ private ArrayList<Preset> mPresets;
+ private final static String kFileName = "foo.dat";
+
+ public static class Preset implements Serializable {
+ private static final long serialVersionUID = 8075462052014816810L;
+ private String mName;
+ private Boolean mAlarmOn;
+ private int mAlarmTime;
+ private String mAlarmSound;
+ private int mVolume;
+ private int mColor;
+ private int mBrightness;
+ private int mDisplay;
+
+ Preset(String name) {
+ mName = name;
+ }
+
+ public String getName() {
+ return mName;
+ }
+
+ public void setName(String name) {
+ mName = name;
+ }
+
+ public String toString() {
+ return mName;
+ }
+
+ public void applyToPreferences(SharedPreferences thePrefs) {
+ SharedPreferences.Editor editor = thePrefs.edit();
+
+ editor.putBoolean(Preferences.PREF_ALARM_ON, mAlarmOn);
+ editor.putInt(Preferences.PREF_ALARM_TIME, mAlarmTime);
+ editor.putString(Preferences.PREF_ALARM_SOUND, mAlarmSound);
+
+ editor.putInt(Preferences.PREF_VOLUME, mVolume);
+
+ editor.putInt(Preferences.PREF_COLOR, mColor);
+
+ editor.putInt(Preferences.PREF_BRIGHTNESS, mBrightness);
+
+ editor.putInt(Preferences.PREF_DISPLAY, mDisplay);
+
+ editor.commit();
+ }
+
+ void extractFromPreferences(SharedPreferences thePrefs) {
+ mAlarmOn = thePrefs.getBoolean(Preferences.PREF_ALARM_ON, false);
+ mAlarmTime = thePrefs.getInt(Preferences.PREF_ALARM_TIME,
+ Preferences.DEFAULT_ALARM_TIME);
+ mAlarmSound = thePrefs.getString(Preferences.PREF_ALARM_SOUND, "");
+
+ mVolume = thePrefs.getInt(Preferences.PREF_VOLUME, 0);
+
+ mColor = thePrefs.getInt(Preferences.PREF_COLOR, 0);
+
+ mBrightness = thePrefs.getInt(Preferences.PREF_BRIGHTNESS, 0);
+
+ mDisplay = thePrefs.getInt(Preferences.PREF_DISPLAY, 0);
+ }
+
+ }
+
+ public Presets() {
+ mPresets = new ArrayList<Preset>();
+ }
+
+ public void save(Context context) throws IOException {
+ FileOutputStream fos = context.openFileOutput(kFileName,
+ Context.MODE_PRIVATE);
+ ObjectOutputStream os = new ObjectOutputStream(fos);
+ os.writeObject(mPresets);
+ os.close();
+ }
+
+ @SuppressWarnings("unchecked")
+ public void load(Context context) throws IOException,
+ ClassNotFoundException {
+ FileInputStream fis = context.openFileInput(kFileName);
+ ObjectInputStream is = new ObjectInputStream(fis);
+ Object readObject = is.readObject();
+ if (readObject != null) {
+ mPresets = (ArrayList<Preset>) readObject;
+ }
+ }
+
+ public ArrayList<Preset> getPresets() {
+ return mPresets;
+ }
+
+ public Preset makeNewPreset(SharedPreferences thePrefs) {
+ Preset preset = new Preset("Untitled");
+ preset.extractFromPreferences(thePrefs);
+ mPresets.add(preset);
+ return preset;
+ }
+
+}
diff --git a/src/com/google/android/apps/adk2/USBAccessoryActivity.java b/src/com/google/android/apps/adk2/USBAccessoryActivity.java
new file mode 100644
index 0000000..9ca10b4
--- /dev/null
+++ b/src/com/google/android/apps/adk2/USBAccessoryActivity.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+package com.google.android.apps.adk2;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+
+import com.google.android.apps.adk2.activity.HomeActivity;
+
+// receive USB_DEVICE_ATTACHED events and launch the main activity
+public final class USBAccessoryActivity extends Activity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ Intent i = (new Intent(this, HomeActivity.class));
+ i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ startActivity(i);
+
+ finish();
+ }
+}
diff --git a/src/com/google/android/apps/adk2/UsbConnection.java b/src/com/google/android/apps/adk2/UsbConnection.java
new file mode 100644
index 0000000..ecd539a
--- /dev/null
+++ b/src/com/google/android/apps/adk2/UsbConnection.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+package com.google.android.apps.adk2;
+
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import android.app.Activity;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.ParcelFileDescriptor;
+import android.util.Log;
+
+import com.android.future.usb.UsbAccessory;
+import com.android.future.usb.UsbManager;
+import com.google.android.apps.adk2.activity.ConnectActivity;
+
+public class UsbConnection extends Connection {
+ Activity mActivity;
+ FileInputStream mInputStream;
+ FileOutputStream mOutputStream;
+ ParcelFileDescriptor mFileDescriptor;
+ UsbAccessory mAccessory;
+
+ private static final String ACTION_USB_PERMISSION = "com.google.android.DemoKit.action.USB_PERMISSION";
+
+ private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ String action = intent.getAction();
+ if (UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action)) {
+ UsbAccessory accessory = UsbManager.getAccessory(intent);
+ if (accessory != null && accessory.equals(mAccessory)) {
+ Log.i(ADK.TAG, "closing accessory");
+ Intent connectIntent = new Intent(mActivity,
+ ConnectActivity.class);
+ connectIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ mActivity.startActivity(connectIntent);
+ }
+ }
+ }
+ };
+
+ public UsbConnection(Activity activity, UsbManager usbManager,
+ UsbAccessory accessory) {
+ mActivity = activity;
+ mFileDescriptor = usbManager.openAccessory(accessory);
+ if (mFileDescriptor != null) {
+ mAccessory = accessory;
+ FileDescriptor fd = mFileDescriptor.getFileDescriptor();
+ mInputStream = new FileInputStream(fd);
+ mOutputStream = new FileOutputStream(fd);
+ }
+ IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
+ filter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED);
+ mActivity.registerReceiver(mUsbReceiver, filter);
+ }
+
+ @Override
+ public InputStream getInputStream() {
+ return mInputStream;
+ }
+
+ @Override
+ public OutputStream getOutputStream() {
+ return mOutputStream;
+ }
+
+ public void close() throws IOException {
+ if (mFileDescriptor != null) {
+ mFileDescriptor.close();
+ }
+ mActivity.unregisterReceiver(mUsbReceiver);
+ }
+
+}
diff --git a/src/com/google/android/apps/adk2/Utilities.java b/src/com/google/android/apps/adk2/Utilities.java
new file mode 100644
index 0000000..99e9fd4
--- /dev/null
+++ b/src/com/google/android/apps/adk2/Utilities.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+package com.google.android.apps.adk2;
+
+import java.util.Date;
+
+import android.content.Context;
+import android.graphics.drawable.Drawable;
+import android.preference.Preference;
+import android.preference.PreferenceManager;
+
+public class Utilities {
+ public static void centerAround(int x, int y, Drawable d) {
+ int w = d.getIntrinsicWidth();
+ int h = d.getIntrinsicHeight();
+ int left = x - w / 2;
+ int top = y - h / 2;
+ int right = left + w;
+ int bottom = top + h;
+ d.setBounds(left, top, right, bottom);
+ }
+
+ public static int indexOf(int searchArray[], int itemToFind) {
+ for (int i = 0; i < searchArray.length; ++i) {
+ if (itemToFind == searchArray[i]) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ public static int indexOf(String searchArray[], String itemToFind) {
+ for (int i = 0; i < searchArray.length; ++i) {
+ if (itemToFind.equals(searchArray[i])) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ public static int stringToFourCC(String stringCode) {
+ int theCode = 0;
+ int count = Math.max(stringCode.length(), 4);
+ for (int i = 0; i < count; ++i) {
+ char c = stringCode.charAt(i);
+ theCode <<= 8;
+ theCode |= c;
+ }
+ return theCode;
+ }
+
+ public static String fourCCToString(int fourCC) {
+ StringBuilder sb = new StringBuilder();
+ sb.append('\'');
+ sb.append((fourCC & 0xFF000000) >> 24);
+ sb.append((fourCC & 0x00FF0000) >> 16);
+ sb.append((fourCC & 0x0000FF00) >> 8);
+ sb.append((fourCC & 0x000000FF));
+ sb.append('\'');
+ return sb.toString();
+ }
+
+ public static void enablePreference(PreferenceManager preferenceMgr,
+ String prefKey, Boolean isEnabled) {
+ Preference pref = preferenceMgr.findPreference(prefKey);
+ if (pref != null) {
+ preferenceMgr.findPreference(prefKey).setEnabled(isEnabled);
+ }
+ }
+
+ public static String formatTime(Context context, Date dateToFormat) {
+ java.text.DateFormat df = android.text.format.DateFormat
+ .getTimeFormat(context);
+ return df.format(dateToFormat);
+ }
+
+ public static String formatTime(Context context, int timeValue) {
+ Date date = new Date();
+ date.setHours(timeValue / 60);
+ date.setMinutes(timeValue % 60);
+ return formatTime(context, date);
+ }
+
+ public static int dateToTimeValue(int hours, int minutes) {
+ return hours * 60 + minutes;
+ }
+
+ public static int dateToTimeValue(Date date) {
+ return dateToTimeValue(date.getHours(), date.getMinutes());
+ }
+
+ private static final byte[] HEX_CHAR = new byte[] { '0', '1', '2', '3',
+ '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+
+ /**
+ * Helper function that dump an array of bytes in hex form
+ *
+ * @param buffer
+ * The bytes array to dump
+ * @return A string representation of the array of bytes
+ */
+ public static final String dumpBytes(byte[] buffer, int amountToDump) {
+ if (buffer == null) {
+ return "";
+ }
+
+ StringBuffer sb = new StringBuffer();
+
+ amountToDump = Math.min(amountToDump, buffer.length);
+
+ for (int i = 0; i < amountToDump; i++) {
+ sb.append("0x")
+ .append((char) (HEX_CHAR[(buffer[i] & 0x00F0) >> 4]))
+ .append((char) (HEX_CHAR[buffer[i] & 0x000F])).append(" ");
+ }
+
+ return sb.toString();
+ }
+
+ public static int unsignedByte(byte b) {
+ return b & 0xff;
+ }
+
+ public static int[] byteArrayToIntArray(byte[] byteArray) {
+ int[] intArray = new int[byteArray.length];
+ for (int i = 0; i < intArray.length; ++i) {
+ intArray[i] = byteArray[i] & 0xff;
+ }
+ return intArray;
+ }
+}
diff --git a/src/com/google/android/apps/adk2/activity/Adk2BaseActivity.java b/src/com/google/android/apps/adk2/activity/Adk2BaseActivity.java
new file mode 100755
index 0000000..310f56b
--- /dev/null
+++ b/src/com/google/android/apps/adk2/activity/Adk2BaseActivity.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+package com.google.android.apps.adk2.activity;
+
+import android.app.Activity;
+import android.content.SharedPreferences;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Message;
+import android.view.MenuItem;
+import android.view.View;
+
+public class Adk2BaseActivity extends Activity {
+
+ private boolean mWasPolling = false;
+
+ static void maybeDisplayHomeAsUp(Activity activity) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
+ activity.getActionBar().setDisplayHomeAsUpEnabled(true);
+ }
+
+ static boolean maybeHandleHomeMenuItem(MenuItem item, Activity activity) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ activity.finish();
+ return true;
+
+ default:
+ return false;
+ }
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ Adk2BaseActivity.maybeDisplayHomeAsUp(this);
+
+ HomeActivity h = HomeActivity.get();
+ if (h != null) {
+ mWasPolling = h.startPollingSettings();
+ }
+
+ }
+
+ @Override
+ public void onDestroy() {
+ HomeActivity h = HomeActivity.get();
+ if (h != null && !mWasPolling) {
+ h.stopPollingSettings();
+ }
+ super.onDestroy();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ return Adk2BaseActivity.maybeHandleHomeMenuItem(item, this);
+ }
+
+ public void onClick(View v) {
+ // TODO Auto-generated method stub
+
+ }
+
+ public boolean handleMessage(Message msg) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
+ String key) {
+ // TODO Auto-generated method stub
+
+ }
+}
diff --git a/src/com/google/android/apps/adk2/activity/Adk2PreferenceActivity.java b/src/com/google/android/apps/adk2/activity/Adk2PreferenceActivity.java
new file mode 100755
index 0000000..ff8f57e
--- /dev/null
+++ b/src/com/google/android/apps/adk2/activity/Adk2PreferenceActivity.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+package com.google.android.apps.adk2.activity;
+
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.os.Bundle;
+import android.preference.PreferenceActivity;
+import android.preference.PreferenceManager;
+import android.view.MenuItem;
+
+public abstract class Adk2PreferenceActivity extends PreferenceActivity
+ implements OnSharedPreferenceChangeListener {
+
+ protected PreferenceManager mPreferenceManager;
+ protected SharedPreferences mPreferences;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ Adk2BaseActivity.maybeDisplayHomeAsUp(this);
+
+ mPreferenceManager = getPreferenceManager();
+ mPreferences = PreferenceManager.getDefaultSharedPreferences(this);
+ mPreferences.registerOnSharedPreferenceChangeListener(this);
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ return Adk2BaseActivity.maybeHandleHomeMenuItem(item, this);
+ }
+
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
+ String key) {
+ // TODO Auto-generated method stub
+
+ }
+
+} \ No newline at end of file
diff --git a/src/com/google/android/apps/adk2/activity/AlarmActivity.java b/src/com/google/android/apps/adk2/activity/AlarmActivity.java
new file mode 100644
index 0000000..04bdf17
--- /dev/null
+++ b/src/com/google/android/apps/adk2/activity/AlarmActivity.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+package com.google.android.apps.adk2.activity;
+
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.ListPreference;
+import android.preference.Preference;
+import android.util.Log;
+
+import com.google.android.apps.adk2.ADK;
+import com.google.android.apps.adk2.Preferences;
+import com.google.android.apps.adk2.R;
+import com.google.android.apps.adk2.Utilities;
+
+public class AlarmActivity extends Adk2PreferenceActivity {
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ addPreferencesFromResource(R.xml.alarm_preferences);
+
+ updatePreferencesDisplay();
+
+ HomeActivity h = HomeActivity.get();
+ if (h == null) {
+ Log.i(ADK.TAG, "Can't find home activity");
+ } else {
+ Log.i(ADK.TAG, "h = " + h.toString());
+ }
+ }
+
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
+ String key) {
+ if (Preferences.PREF_ALARM_ON.equals(key)
+ || Preferences.PREF_ALARM_TIME.equals(key)
+ || Preferences.PREF_ALARM_SOUND.equals(key))
+ updatePreferencesDisplay();
+ }
+
+ void updatePreferencesDisplay() {
+ boolean alarmOn = mPreferences.getBoolean(Preferences.PREF_ALARM_ON,
+ true);
+
+ Utilities.enablePreference(mPreferenceManager,
+ Preferences.PREF_ALARM_TIME, alarmOn);
+ Utilities.enablePreference(mPreferenceManager,
+ Preferences.PREF_ALARM_SOUND, alarmOn);
+
+ updateAlarmTime();
+ updateAlarmSoundList();
+ }
+
+ private void updateAlarmTime() {
+ int alarmTime = mPreferences.getInt(Preferences.PREF_ALARM_TIME,
+ Preferences.DEFAULT_ALARM_TIME);
+ String alarmTimeString = Utilities.formatTime(this, alarmTime);
+ Preference alarmTimePref = mPreferenceManager
+ .findPreference(Preferences.PREF_ALARM_TIME);
+ if (alarmTimePref != null) {
+ alarmTimePref.setSummary(alarmTimeString);
+ }
+ }
+
+ private void updateAlarmSoundList() {
+ ListPreference alarmSoundPref = (ListPreference) mPreferenceManager
+ .findPreference(Preferences.PREF_ALARM_SOUND);
+ if (alarmSoundPref != null) {
+ HomeActivity h = HomeActivity.get();
+ String[] alarmSoundsList = h.getAlarmSounds();
+ String defaultAlarmSound = "";
+ if (alarmSoundsList.length > 0) {
+ defaultAlarmSound = alarmSoundsList[0];
+ }
+ String alarmSoundString = mPreferences.getString(
+ Preferences.PREF_ALARM_SOUND, defaultAlarmSound);
+ alarmSoundPref.setEntries(alarmSoundsList);
+ alarmSoundPref.setEntryValues(alarmSoundsList);
+ alarmSoundPref.setSummary(alarmSoundString);
+ alarmSoundPref.setValue(alarmSoundString);
+ }
+ }
+}
diff --git a/src/com/google/android/apps/adk2/activity/BTDeviceListActivity.java b/src/com/google/android/apps/adk2/activity/BTDeviceListActivity.java
new file mode 100755
index 0000000..d9649af
--- /dev/null
+++ b/src/com/google/android/apps/adk2/activity/BTDeviceListActivity.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+package com.google.android.apps.adk2.activity;
+
+import java.util.Set;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import com.google.android.apps.adk2.R;
+
+public class BTDeviceListActivity extends Adk2BaseActivity implements
+ OnItemClickListener {
+ private BluetoothAdapter mBtAdapter;
+ private ArrayAdapter<String> mPairedDevicesArrayAdapter;
+
+ public static String EXTRA_DEVICE_ADDRESS = "device_address";
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.device_list);
+
+ mPairedDevicesArrayAdapter = new ArrayAdapter<String>(this,
+ R.layout.device_name);
+
+ // Find and set up the ListView for paired devices
+ ListView pairedListView = (ListView) findViewById(R.id.paired_devices);
+ pairedListView.setAdapter(mPairedDevicesArrayAdapter);
+ pairedListView.setOnItemClickListener(this);
+
+ // Get the local Bluetooth adapter
+ mBtAdapter = BluetoothAdapter.getDefaultAdapter();
+
+ // Get a set of currently paired devices
+ Set<BluetoothDevice> pairedDevices = mBtAdapter.getBondedDevices();
+
+ // If there are paired devices, add each one to the ArrayAdapter
+ if (pairedDevices.size() > 0) {
+ findViewById(R.id.title_paired_devices).setVisibility(View.VISIBLE);
+ for (BluetoothDevice device : pairedDevices) {
+ mPairedDevicesArrayAdapter.add(device.getName() + "\n"
+ + device.getAddress());
+ }
+ } else {
+ String noDevices = getResources().getText(R.string.none_paired)
+ .toString();
+ mPairedDevicesArrayAdapter.add(noDevices);
+ }
+ }
+
+ public void onItemClick(AdapterView<?> arg0, View v, int arg2, long arg3) {
+ mBtAdapter.cancelDiscovery();
+
+ // Get the device MAC address, which is the last 17 chars in the View
+ String info = ((TextView) v).getText().toString();
+
+ if (info.equals(getResources().getText(R.string.none_paired).toString()))
+ return; // do not proceed if we clicked the "there are no devices"
+ // message
+
+ String address = info.substring(info.length() - 17);
+ Intent connectIntent = new Intent(this, HomeActivity.class);
+ connectIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ connectIntent.putExtra(EXTRA_DEVICE_ADDRESS, address);
+ startActivity(connectIntent);
+ }
+
+}
diff --git a/src/com/google/android/apps/adk2/activity/BrightnessActivity.java b/src/com/google/android/apps/adk2/activity/BrightnessActivity.java
new file mode 100644
index 0000000..b19e1fa
--- /dev/null
+++ b/src/com/google/android/apps/adk2/activity/BrightnessActivity.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+package com.google.android.apps.adk2.activity;
+
+import android.content.SharedPreferences;
+import android.os.Bundle;
+
+import com.google.android.apps.adk2.Preferences;
+import com.google.android.apps.adk2.R;
+import com.google.android.apps.adk2.widget.SeekBarPreference;
+
+public class BrightnessActivity extends Adk2PreferenceActivity {
+
+ public static final int MAX_BRIGHTNESS = 255;
+
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ addPreferencesFromResource(R.xml.brightness_preferences);
+ updatePreferencesDisplay();
+ }
+
+ private void updatePreferencesDisplay() {
+ SeekBarPreference brightness = (SeekBarPreference) mPreferenceManager
+ .findPreference(Preferences.PREF_BRIGHTNESS);
+
+ if (brightness != null) {
+ brightness.setValue(mPreferences.getInt(
+ Preferences.PREF_BRIGHTNESS, MAX_BRIGHTNESS));
+ brightness.setEnabled(true);
+ }
+ }
+
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
+ String key) {
+ if (Preferences.PREF_BRIGHTNESS.equals(key))
+ updatePreferencesDisplay();
+
+ }
+
+}
diff --git a/src/com/google/android/apps/adk2/activity/ClockActivity.java b/src/com/google/android/apps/adk2/activity/ClockActivity.java
new file mode 100644
index 0000000..fe75277
--- /dev/null
+++ b/src/com/google/android/apps/adk2/activity/ClockActivity.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+package com.google.android.apps.adk2.activity;
+
+import java.util.Date;
+
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.os.Handler;
+import android.preference.Preference;
+
+import com.google.android.apps.adk2.Preferences;
+import com.google.android.apps.adk2.R;
+import com.google.android.apps.adk2.Utilities;
+
+public class ClockActivity extends Adk2PreferenceActivity {
+
+ private Handler mHandler = new Handler();
+
+ private Runnable mUpdateTimeTask;
+
+ final static int kUpdateTime = 500;
+ int mHours = -1;
+ int mMinutes = -1;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ addPreferencesFromResource(R.xml.clock_preferences);
+
+ updatePreferencesDisplay();
+
+ mUpdateTimeTask = new Runnable() {
+ public void run() {
+ updatePreferencesDisplay();
+ mHandler.postDelayed(mUpdateTimeTask, kUpdateTime);
+ }
+ };
+ mHandler.postDelayed(mUpdateTimeTask, kUpdateTime);
+ }
+
+ @Override
+ protected void onPause() {
+ mHandler.removeCallbacks(mUpdateTimeTask);
+ super.onPause();
+ }
+
+ @Override
+ protected void onResume() {
+ mHandler.postDelayed(mUpdateTimeTask, kUpdateTime);
+ super.onResume();
+ }
+
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
+ String key) {
+ }
+
+ private void updatePreferencesDisplay() {
+ Preference clockTimePref = mPreferenceManager
+ .findPreference(Preferences.PREF_TIME);
+ if (clockTimePref != null) {
+ Date d = new Date();
+ if (d.getHours() != mHours || d.getMinutes() != mMinutes) {
+ mHours = d.getHours();
+ mMinutes = d.getMinutes();
+ clockTimePref.setSummary(Utilities.formatTime(this, d));
+ }
+ }
+ }
+}
diff --git a/src/com/google/android/apps/adk2/activity/ColorActivity.java b/src/com/google/android/apps/adk2/activity/ColorActivity.java
new file mode 100644
index 0000000..b9dc753
--- /dev/null
+++ b/src/com/google/android/apps/adk2/activity/ColorActivity.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+package com.google.android.apps.adk2.activity;
+
+import android.content.SharedPreferences;
+import android.os.Bundle;
+
+import com.google.android.apps.adk2.Preferences;
+import com.google.android.apps.adk2.R;
+
+public class ColorActivity extends Adk2PreferenceActivity {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ addPreferencesFromResource(R.xml.color_preferences);
+ }
+
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
+ String key) {
+ if (Preferences.PREF_COLOR.equals(key))
+ updatePreferencesDisplay();
+ }
+
+ private void updatePreferencesDisplay() {
+ }
+}
diff --git a/src/com/google/android/apps/adk2/activity/ColorRGBActivity.java b/src/com/google/android/apps/adk2/activity/ColorRGBActivity.java
new file mode 100644
index 0000000..9516cea
--- /dev/null
+++ b/src/com/google/android/apps/adk2/activity/ColorRGBActivity.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+package com.google.android.apps.adk2.activity;
+
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.view.View;
+import android.widget.SeekBar;
+import android.widget.TextView;
+
+import com.google.android.apps.adk2.Preferences;
+import com.google.android.apps.adk2.R;
+import com.google.android.apps.adk2.views.Slider;
+
+public class ColorRGBActivity extends Adk2BaseActivity implements
+ Slider.SliderPositionListener, OnSharedPreferenceChangeListener {
+ private View mOriginalColorView;
+ private View mNewColorView;
+ private TextView mTextHex;
+ private TextView mTextR;
+ private TextView mTextG;
+ private TextView mTextB;
+ private Slider mSeekBarR;
+ private Slider mSeekBarG;
+ private Slider mSeekBarB;
+ private Drawable mGreen;
+ private Drawable mRed;
+ private Drawable mBlue;
+
+ private int mOriginalColor;
+ private int mNewColor;
+
+ private final int kColorRange = 255;
+
+ private Slider setupSeekBar(int seekBarId, Drawable color) {
+ Slider theBar = (Slider) findViewById(seekBarId);
+ theBar.setPositionListener(this);
+ theBar.setSliderBackground(color);
+ return theBar;
+ }
+
+ private TextView setupTextField(int textFieldId) {
+ TextView theText = (TextView) findViewById(textFieldId);
+ return theText;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.color_rgb);
+
+ Resources res = getResources();
+ mRed = res.getDrawable(R.drawable.scrubber_horizontal_red_holo_dark);
+ mGreen = res
+ .getDrawable(R.drawable.scrubber_horizontal_green_holo_dark);
+ mBlue = res.getDrawable(R.drawable.scrubber_horizontal_blue_holo_dark);
+
+ mOriginalColorView = findViewById(R.id.original_color);
+ mNewColorView = findViewById(R.id.new_color);
+ mTextHex = setupTextField(R.id.color_hex);
+ mTextR = setupTextField(R.id.color_r);
+ mTextG = setupTextField(R.id.color_g);
+ mTextB = setupTextField(R.id.color_b);
+ mSeekBarR = setupSeekBar(R.id.seek_bar_r, mRed);
+ mSeekBarG = setupSeekBar(R.id.seek_bar_g, mGreen);
+ mSeekBarB = setupSeekBar(R.id.seek_bar_b, mBlue);
+
+ mOriginalColor = PreferenceManager.getDefaultSharedPreferences(this)
+ .getInt(Preferences.PREF_COLOR, Preferences.PREF_DEFAULT_COLOR);
+ mNewColor = mOriginalColor;
+
+ SharedPreferences preferences = PreferenceManager
+ .getDefaultSharedPreferences(this);
+ preferences.registerOnSharedPreferenceChangeListener(this);
+
+ updateDisplay();
+ }
+
+ public void onPositionChange(Slider slider, double value) {
+ switch (slider.getId()) {
+ case R.id.seek_bar_r:
+ mNewColor = (mNewColor & 0xff00ffff)
+ | ((int) (value * kColorRange) << 16);
+ break;
+
+ case R.id.seek_bar_g:
+ mNewColor = (mNewColor & 0xffff00ff)
+ | ((int) (value * kColorRange) << 8);
+ break;
+
+ case R.id.seek_bar_b:
+ mNewColor = (mNewColor & 0xffffff00) | (int) (value * kColorRange);
+ break;
+ }
+
+ persistPreferences();
+ updateDisplay();
+ }
+
+ public void onStartTrackingTouch(SeekBar seekBar) {
+ }
+
+ public void onStopTrackingTouch(SeekBar seekBar) {
+ }
+
+ private void persistPreferences() {
+ SharedPreferences.Editor editor = PreferenceManager
+ .getDefaultSharedPreferences(this).edit();
+ editor.putInt(Preferences.PREF_COLOR, mNewColor);
+ editor.apply();
+ }
+
+ private void updateDisplay() {
+ mOriginalColorView.setBackgroundColor(mOriginalColor | 0xff000000);
+ mNewColorView.setBackgroundColor(mNewColor | 0xff000000);
+
+ int r, g, b;
+ r = (mNewColor >> 16) & 0xff;
+ g = (mNewColor >> 8) & 0xff;
+ b = mNewColor & 0xff;
+
+ mTextHex.setText(String.format("%06X", mNewColor & 0xffffff));
+ mTextR.setText(String.format("%d", r));
+ mTextG.setText(Integer.toString(g));
+ mTextB.setText(Integer.toString(b));
+
+ mSeekBarR.setPosition((double) r / (double) kColorRange);
+ mSeekBarG.setPosition((double) g / (double) kColorRange);
+ mSeekBarB.setPosition((double) b / (double) kColorRange);
+ }
+
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
+ String key) {
+ if (Preferences.PREF_COLOR.equals(key)) {
+ mOriginalColor = sharedPreferences.getInt(Preferences.PREF_COLOR,
+ Preferences.PREF_DEFAULT_COLOR);
+ mNewColor = mOriginalColor;
+ updateDisplay();
+ }
+
+ }
+
+}
diff --git a/src/com/google/android/apps/adk2/activity/ColorSensorActivity.java b/src/com/google/android/apps/adk2/activity/ColorSensorActivity.java
new file mode 100755
index 0000000..ddf079f
--- /dev/null
+++ b/src/com/google/android/apps/adk2/activity/ColorSensorActivity.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+package com.google.android.apps.adk2.activity;
+
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Handler.Callback;
+import android.os.Message;
+import android.preference.PreferenceManager;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+
+import com.google.android.apps.adk2.Preferences;
+import com.google.android.apps.adk2.R;
+import com.google.android.apps.adk2.views.ColorSensorView;
+
+public class ColorSensorActivity extends Adk2BaseActivity implements
+ OnSharedPreferenceChangeListener, OnClickListener, Callback {
+
+ private Handler mColorPollingHandler;
+ private ColorSensorView mColorSensorView;
+ private Button mCaptureButton;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ SharedPreferences preferences = PreferenceManager
+ .getDefaultSharedPreferences(this);
+ preferences.registerOnSharedPreferenceChangeListener(this);
+
+ setContentView(R.layout.color_sensor);
+ mColorSensorView = (ColorSensorView) findViewById(R.id.color_sensor_view);
+ mCaptureButton = (Button) findViewById(R.id.color_sample_button);
+ mCaptureButton.setOnClickListener(this);
+
+ mColorPollingHandler = new Handler(this);
+ getColorFromSensor();
+ Message msg = mColorPollingHandler.obtainMessage();
+ mColorPollingHandler.sendMessageDelayed(msg, 500);
+ }
+
+ @Override
+ public void onDestroy() {
+ mColorPollingHandler = null;
+ super.onDestroy();
+ }
+
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
+ String key) {
+ if (Preferences.PREF_COLOR_SENSOR.equals(key))
+ updatePreferencesDisplay(sharedPreferences);
+ }
+
+ private void updatePreferencesDisplay(SharedPreferences sharedPreferences) {
+ mColorSensorView.setSensedColor(sharedPreferences.getInt(
+ Preferences.PREF_COLOR_SENSOR, 0) | 0xff000000);
+ getColorFromSensor();
+
+ }
+
+ private void getColorFromSensor() {
+ HomeActivity h = HomeActivity.get();
+ if (h != null) {
+ h.getSensors();
+ }
+ }
+
+ @Override
+ public void onClick(View v) {
+ SharedPreferences preferences = PreferenceManager
+ .getDefaultSharedPreferences(this);
+ SharedPreferences.Editor editor = preferences.edit();
+ int newColor = preferences.getInt(Preferences.PREF_COLOR_SENSOR,
+ 0xFFFFFF);
+ editor.putInt(Preferences.PREF_COLOR, newColor);
+ editor.commit();
+ finish();
+ }
+
+
+ public boolean handleMessage(Message msg) {
+ getColorFromSensor();
+ if (mColorPollingHandler != null) {
+ Message newMsg = mColorPollingHandler.obtainMessage();
+ mColorPollingHandler.sendMessageDelayed(newMsg, 500);
+ }
+ return true;
+ }
+
+}
diff --git a/src/com/google/android/apps/adk2/activity/ConnectActivity.java b/src/com/google/android/apps/adk2/activity/ConnectActivity.java
new file mode 100755
index 0000000..acfe7c3
--- /dev/null
+++ b/src/com/google/android/apps/adk2/activity/ConnectActivity.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+package com.google.android.apps.adk2.activity;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+
+import com.google.android.apps.adk2.R;
+
+public class ConnectActivity extends Activity implements OnClickListener {
+ private Button mBluetoothButton;
+
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.connect);
+ mBluetoothButton = (Button) findViewById(R.id.connect_bluetooth_button);
+ mBluetoothButton.setOnClickListener(this);
+ }
+
+ public void onClick(View v) {
+ if (v.getId() == R.id.connect_bluetooth_button) {
+ startActivity(new Intent(this, BTDeviceListActivity.class));
+ }
+ }
+
+}
diff --git a/src/com/google/android/apps/adk2/activity/DisplayActivity.java b/src/com/google/android/apps/adk2/activity/DisplayActivity.java
new file mode 100755
index 0000000..98ba3b6
--- /dev/null
+++ b/src/com/google/android/apps/adk2/activity/DisplayActivity.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+package com.google.android.apps.adk2.activity;
+
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.widget.RadioGroup;
+import android.widget.RadioGroup.OnCheckedChangeListener;
+
+import com.google.android.apps.adk2.Preferences;
+import com.google.android.apps.adk2.R;
+import com.google.android.apps.adk2.Utilities;
+
+public class DisplayActivity extends Adk2BaseActivity implements
+ OnCheckedChangeListener {
+
+ RadioGroup mDisplayGroup;
+
+ int mDisplayOption;
+
+ final int kDisplayButtons[] = { R.id.radio_animation, R.id.radio_accell,
+ R.id.radio_mag, R.id.radio_temperature, R.id.radio_hygro,
+ R.id.radio_baro, R.id.radio_prox, R.id.radio_color };
+
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.display);
+
+ mDisplayGroup = (RadioGroup) findViewById(R.id.display_group);
+ mDisplayGroup.setOnCheckedChangeListener(this);
+
+ mDisplayOption = PreferenceManager.getDefaultSharedPreferences(this)
+ .getInt(Preferences.PREF_DISPLAY, 0);
+ updateDisplay();
+ }
+
+ public void onCheckedChanged(RadioGroup group, int checkedId) {
+ mDisplayOption = Utilities.indexOf(kDisplayButtons, checkedId);
+ SharedPreferences.Editor editor = PreferenceManager
+ .getDefaultSharedPreferences(this).edit();
+ editor.putInt(Preferences.PREF_DISPLAY, mDisplayOption);
+ editor.apply();
+ }
+
+ void updateDisplay() {
+ mDisplayGroup.check(kDisplayButtons[mDisplayOption]);
+ }
+
+}
diff --git a/src/com/google/android/apps/adk2/activity/HomeActivity.java b/src/com/google/android/apps/adk2/activity/HomeActivity.java
new file mode 100755
index 0000000..dedad20
--- /dev/null
+++ b/src/com/google/android/apps/adk2/activity/HomeActivity.java
@@ -0,0 +1,968 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+package com.google.android.apps.adk2.activity;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.zip.GZIPInputStream;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Handler.Callback;
+import android.os.Message;
+import android.preference.PreferenceManager;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.EditText;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import com.android.future.usb.UsbAccessory;
+import com.android.future.usb.UsbManager;
+import com.google.android.apps.adk2.ADK;
+import com.google.android.apps.adk2.BTConnection;
+import com.google.android.apps.adk2.Connection;
+import com.google.android.apps.adk2.Preferences;
+import com.google.android.apps.adk2.R;
+import com.google.android.apps.adk2.UsbConnection;
+import com.google.android.apps.adk2.Utilities;
+
+public class HomeActivity extends Activity implements OnClickListener,
+ Callback, OnSharedPreferenceChangeListener, Runnable {
+
+ private Handler mDeviceHandler;
+ private Handler mSettingsPollingHandler;
+
+ private UsbManager mUSBManager;
+ private SharedPreferences mPreferences;
+
+ private ByteArrayOutputStream mLicenseTextStream;
+
+ private byte[] mSettingsBuffer = null;
+ private byte[] mSettingsPayload = new byte[8];
+ private byte[] mQueryBuffer = new byte[4];
+ private byte[] mEmptyPayload = new byte[0];
+
+ Connection mConnection;
+
+ UsbAccessory mAccessory;
+
+ private boolean mIgnorePrefChanges = false;
+ private boolean mPollSettings = false;
+
+ private long mIgnoreUpdatesUntil = System.currentTimeMillis();
+
+ private String mLicenseText = "";
+ private ArrayList<String> mSoundFiles;
+
+ static final String TUNES_FOLDER = "/Tunes";
+
+ static final byte CMD_GET_PROTO_VERSION = 1; // () -> (u8 protocolVersion)
+ static final byte CMD_GET_SENSORS = 2; // () -> (sensors:
+ // i32,i32,i32,i32,u16,u16,u16,u16,u16,u16,u16,i16,i16,i16,i16,i16,i16)
+ static final byte CMD_FILE_LIST = 3; // FIRST: (char name[]) -> (fileinfo or
+ // single zero byte) OR NONLATER: ()
+ // -> (fileinfo or empty or single
+ // zero byte)
+ static final byte CMD_FILE_DELETE = 4; // (char name[0-255)) -> (char
+ // success)
+ static final byte CMD_FILE_OPEN = 5; // (char name[0-255]) -> (char success)
+ static final byte CMD_FILE_WRITE = 6; // (u8 data[]) -> (char success)
+ static final byte CMD_FILE_CLOSE = 7; // () -> (char success)
+ static final byte CMD_GET_UNIQ_ID = 8; // () -> (u8 uniq[16])
+ static final byte CMD_BT_NAME = 9; // (char name[]) -> () OR () -> (char
+ // name[])
+ static final byte CMD_BT_PIN = 10; // (char PIN[]) -> () OR () -> (char
+ // PIN[])
+ static final byte CMD_TIME = 11; // (timespec) -> (char success)) OR () >
+ // (timespec)
+ static final byte CMD_SETTINGS = 12; // () ->
+ // (alarm:u8,u8,u8,brightness:u8,color:u8,u8,u8:volume:u8)
+ // or
+ // (alarm:u8,u8,u8,brightness:u8,color:u8,u8,u8:volume:u8)
+ // > (char success)
+ static final byte CMD_ALARM_FILE = 13; // () -> (char file[0-255]) OR (char
+ // file[0-255]) > (char success)
+ static final byte CMD_GET_LICENSE = 14; // () -> (u8 licensechunk[]) OR ()
+ // if last sent
+ static final byte CMD_DISPLAY_MODE = 15; // () -> (u8) OR (u8) -> ()
+ static final byte CMD_LOCK = 16; // () -> (u8) OR (u8) -> ()
+
+ private static final boolean gLogPackets = false;
+
+ static final int DIALOG_NO_PRESETS_ID = 0;
+
+ private static HomeActivity sHomeActivity = null;
+
+ private static String curBtName = "<UNKNOWN>";
+
+ public static HomeActivity get() {
+ return sHomeActivity;
+ }
+
+ public boolean startPollingSettings() {
+ boolean wasPolling = mPollSettings;
+ mPollSettings = true;
+ if (!wasPolling) {
+ pollSettings();
+ }
+ return wasPolling;
+ }
+
+ public void stopPollingSettings() {
+ mPollSettings = false;
+ }
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.home);
+
+ mDeviceHandler = new Handler(this);
+ mSettingsPollingHandler = new Handler(this);
+
+ mPreferences = PreferenceManager.getDefaultSharedPreferences(this);
+ mPreferences.registerOnSharedPreferenceChangeListener(this);
+
+ mUSBManager = UsbManager.getInstance(this);
+
+ mSoundFiles = new ArrayList<String>();
+
+ setUpButton(R.id.clock_button, R.drawable.ic_clock, R.string.clock);
+ setUpButton(R.id.alarm_button, R.drawable.ic_alarm, R.string.alarm);
+ setUpButton(R.id.volume_button, R.drawable.ic_volume, R.string.volume);
+ setUpButton(R.id.color_button, R.drawable.ic_color, R.string.color);
+ setUpButton(R.id.brightness_button, R.drawable.ic_brightness,
+ R.string.brightness);
+ setUpButton(R.id.display_button, R.drawable.ic_display,
+ R.string.display);
+ setUpButton(R.id.presets_button, R.drawable.ic_presets,
+ R.string.presets);
+ updateLockDisplay();
+
+ connectToAccessory();
+
+ startLicenseUpload();
+ sHomeActivity = this;
+
+ startPollingSettings();
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ MenuInflater inflater = getMenuInflater();
+ inflater.inflate(R.menu.home_menu, menu);
+ return true;
+ }
+
+ @Override
+ protected Dialog onCreateDialog(int id) {
+ Dialog dialog = null;
+ if (id == DIALOG_NO_PRESETS_ID) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(this);
+ builder.setMessage("Unsupported feature.");
+ dialog = builder.create();
+ }
+ return dialog;
+ }
+
+ private void changeBtName() {
+
+ // This example shows how to add a custom layout to an AlertDialog
+ LayoutInflater factory = LayoutInflater.from(this);
+ final View textEntryView = factory.inflate(R.layout.alert_dialog, null);
+ final EditText e = (EditText) textEntryView
+ .findViewById(R.id.btname_edit);
+
+ AlertDialog ad = new AlertDialog.Builder(this)
+ .setIconAttribute(android.R.attr.alertDialogIcon)
+ .setTitle("Set ADK Bluetooth Name")
+ .setView(textEntryView)
+ .setPositiveButton(R.string.set_bt_name_ok,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog,
+ int whichButton) {
+
+ curBtName = e.getText().toString();
+ if (curBtName.equals(""))
+ curBtName = "ADK 2012";
+
+ byte b[] = null;
+ try {
+ b = curBtName.getBytes("UTF-8");
+ } catch (UnsupportedEncodingException e1) {
+ // well aren't you SOL....
+ e1.printStackTrace();
+ }
+ byte b2[] = new byte[b.length + 1];
+ for (int i = 0; i < b.length; i++)
+ b2[i] = b[i];
+ b2[b.length] = 0;
+
+ sendCommand(CMD_BT_NAME, CMD_BT_NAME, b2);
+ }
+ })
+ .setNegativeButton(R.string.set_bt_name_cancel,
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog,
+ int whichButton) {
+
+ // user cancels
+ }
+ }).create();
+
+ e.setText(curBtName);
+ ad.show();
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.license_menu:
+ showLicenses();
+ return true;
+
+ case R.id.disconnect_menu:
+ disconnect();
+ return true;
+
+ case R.id.change_bt_name:
+ changeBtName();
+ return true;
+
+ default:
+ return false;
+ }
+ }
+
+ private void disconnect() {
+ finish();
+ }
+
+ private void showLicenses() {
+ Intent showLicenseIntent = new Intent(this, LicenseActivity.class);
+ startActivity(showLicenseIntent);
+ }
+
+ private void startLicenseUpload() {
+ Log.i(ADK.TAG, "startLicenseUpload");
+ mLicenseTextStream = new ByteArrayOutputStream();
+ sendCommand(CMD_GET_LICENSE, 33);
+ }
+
+ private void pollSettings() {
+ if (mPollSettings) {
+ sendCommand(CMD_SETTINGS, CMD_SETTINGS);
+ sendCommand(CMD_DISPLAY_MODE, CMD_DISPLAY_MODE);
+ sendCommand(CMD_LOCK, CMD_LOCK);
+ Message msg = mSettingsPollingHandler.obtainMessage(99);
+ if (!mSettingsPollingHandler.sendMessageDelayed(msg, 500)) {
+ Log.e(ADK.TAG, "faled to queue settings message");
+ }
+ }
+ }
+
+ @Override
+ public void onPause() {
+ super.onPause();
+ }
+
+ @Override
+ public void onResume() {
+ super.onResume();
+ pollSettings();
+ }
+
+ @Override
+ public void onDestroy() {
+ sHomeActivity = null;
+ if (mConnection != null) {
+ try {
+ mConnection.close();
+ } catch (IOException e) {
+ } finally {
+ mConnection = null;
+ }
+ }
+ super.onDestroy();
+ }
+
+ public void onClick(View v) {
+ switch (v.getId()) {
+ case R.id.clock_button:
+ startActivity(new Intent(this, ClockActivity.class));
+ break;
+
+ case R.id.alarm_button:
+ startActivity(new Intent(this, AlarmActivity.class));
+ break;
+
+ case R.id.volume_button:
+ startActivity(new Intent(this, VolumeActivity.class));
+ break;
+
+ case R.id.color_button:
+ startActivity(new Intent(this, ColorActivity.class));
+ break;
+
+ case R.id.brightness_button:
+ startActivity(new Intent(this, BrightnessActivity.class));
+ break;
+
+ case R.id.display_button:
+ startActivity(new Intent(this, DisplayActivity.class));
+ break;
+
+ case R.id.presets_button:
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
+ startActivity(new Intent(this, PresetsActivity.class));
+ else
+ showDialog(DIALOG_NO_PRESETS_ID);
+ break;
+
+ case R.id.lock_button:
+ toggleLock();
+ break;
+ }
+ }
+
+ private void toggleLock() {
+ boolean isLocked = mPreferences.getBoolean(Preferences.PREF_LOCKED,
+ false);
+ boolean newLocked = !isLocked;
+ SharedPreferences.Editor editor = mPreferences.edit();
+ editor.putBoolean(Preferences.PREF_LOCKED, newLocked);
+ editor.commit();
+ }
+
+ private void setUpButton(int buttonID, int iconID, int labelID) {
+ View button = findViewById(buttonID);
+ button.setOnClickListener(this);
+ ((ImageView) button.findViewById(R.id.icon)).setImageResource(iconID);
+ ((TextView) button.findViewById(R.id.label)).setText(labelID);
+ }
+
+ public void connectToAccessory() {
+ // bail out if we're already connected
+ if (mConnection != null)
+ return;
+
+ if (getIntent().hasExtra(BTDeviceListActivity.EXTRA_DEVICE_ADDRESS)) {
+ String address = getIntent().getStringExtra(
+ BTDeviceListActivity.EXTRA_DEVICE_ADDRESS);
+ Log.i(ADK.TAG, "want to connect to " + address);
+ mConnection = new BTConnection(address);
+ performPostConnectionTasks();
+ } else {
+ // assume only one accessory (currently safe assumption)
+ UsbAccessory[] accessories = mUSBManager.getAccessoryList();
+ UsbAccessory accessory = (accessories == null ? null
+ : accessories[0]);
+ if (accessory != null) {
+ if (mUSBManager.hasPermission(accessory)) {
+ openAccessory(accessory);
+ } else {
+ // synchronized (mUsbReceiver) {
+ // if (!mPermissionRequestPending) {
+ // mUsbManager.requestPermission(accessory,
+ // mPermissionIntent);
+ // mPermissionRequestPending = true;
+ // }
+ // }
+ }
+ } else {
+ // Log.d(TAG, "mAccessory is null");
+ }
+ }
+
+ }
+
+ public void disconnectFromAccessory() {
+ closeAccessory();
+ }
+
+ private void openAccessory(UsbAccessory accessory) {
+ mConnection = new UsbConnection(this, mUSBManager, accessory);
+ performPostConnectionTasks();
+ }
+
+ private void performPostConnectionTasks() {
+ sendCommand(CMD_GET_PROTO_VERSION, CMD_GET_PROTO_VERSION);
+ sendCommand(CMD_SETTINGS, CMD_SETTINGS);
+ sendCommand(CMD_BT_NAME, CMD_BT_NAME);
+ sendCommand(CMD_ALARM_FILE, CMD_ALARM_FILE);
+ listDirectory(TUNES_FOLDER);
+
+ Thread thread = new Thread(null, this, "ADK 2012");
+ thread.start();
+ }
+
+ public void closeAccessory() {
+ try {
+ mConnection.close();
+ } catch (IOException e) {
+ } finally {
+ mConnection = null;
+ }
+ }
+
+ public void run() {
+ int ret = 0;
+ byte[] buffer = new byte[16384];
+ int bufferUsed = 0;
+
+ while (ret >= 0) {
+ try {
+ ret = mConnection.getInputStream().read(buffer, bufferUsed,
+ buffer.length - bufferUsed);
+ bufferUsed += ret;
+ int remainder = process(buffer, bufferUsed);
+ if (remainder > 0) {
+ System.arraycopy(buffer, remainder, buffer, 0, bufferUsed
+ - remainder);
+ bufferUsed = remainder;
+ } else {
+ bufferUsed = 0;
+ }
+ } catch (IOException e) {
+ break;
+ }
+ }
+ Intent connectIntent = new Intent(this, ConnectActivity.class);
+ connectIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ startActivity(connectIntent);
+ }
+
+ public int process(byte[] buffer, int bufferUsed) {
+ if (gLogPackets) {
+ Log.i(ADK.TAG,
+ "read " + bufferUsed + " bytes: "
+ + Utilities.dumpBytes(buffer, bufferUsed));
+ }
+ ByteArrayInputStream inputStream = new ByteArrayInputStream(buffer, 0,
+ bufferUsed);
+ ProtocolHandler ph = new ProtocolHandler(mDeviceHandler, inputStream);
+ ph.process();
+ return inputStream.available();
+ }
+
+ public void listDirectory(String path) {
+ mSoundFiles.clear();
+ byte[] payload = new byte[path.length() + 1];
+ for (int i = 0; i < path.length(); ++i) {
+ payload[i] = (byte) path.charAt(i);
+ }
+ payload[path.length()] = 0;
+ sendCommand(CMD_FILE_LIST, CMD_FILE_LIST, payload);
+ }
+
+ public void getSensors() {
+ sendCommand(CMD_GET_SENSORS, CMD_GET_SENSORS);
+ }
+
+ public byte[] sendCommand(int command, int sequence, byte[] payload,
+ byte[] buffer) {
+ int bufferLength = payload.length + 4;
+ if (buffer == null || buffer.length < bufferLength) {
+ Log.i(ADK.TAG, "allocating new command buffer of length "
+ + bufferLength);
+ buffer = new byte[bufferLength];
+ }
+
+ buffer[0] = (byte) command;
+ buffer[1] = (byte) sequence;
+ buffer[2] = (byte) (payload.length & 0xff);
+ buffer[3] = (byte) ((payload.length & 0xff00) >> 8);
+ if (payload.length > 0) {
+ System.arraycopy(payload, 0, buffer, 4, payload.length);
+ }
+ if (mConnection != null && buffer[1] != -1) {
+ try {
+ if (gLogPackets) {
+ Log.i(ADK.TAG,
+ "sendCommand: "
+ + Utilities
+ .dumpBytes(buffer, buffer.length));
+ }
+ mConnection.getOutputStream().write(buffer);
+ } catch (IOException e) {
+ Log.e(ADK.TAG, "accessory write failed", e);
+ }
+ }
+ return buffer;
+ }
+
+ public void sendCommand(int command, int sequence, byte[] payload) {
+ sendCommand(command, sequence, payload, null);
+ }
+
+ private void sendCommand(int command, int sequence) {
+ sendCommand(command, sequence, mEmptyPayload, mQueryBuffer);
+ }
+
+ private void handleBtNameCommand(byte[] settingsBytes) {
+
+ if (settingsBytes.length > 1 || settingsBytes[0] == 0) { // it's a name
+ // reply
+
+ byte[] b = new byte[settingsBytes.length - 1];
+ for (int i = 0; i < settingsBytes.length - 1; i++)
+ b[i] = settingsBytes[i];
+
+ curBtName = new String(b);
+ }
+ }
+
+ private void handleSettingsCommand(byte[] settingsBytes) {
+
+ if (System.currentTimeMillis() < mIgnoreUpdatesUntil) {
+ return;
+ }
+
+ if (settingsBytes.length == 8) {
+ int settings[] = Utilities.byteArrayToIntArray(settingsBytes);
+ mIgnorePrefChanges = true;
+ SharedPreferences.Editor editor = PreferenceManager
+ .getDefaultSharedPreferences(this).edit();
+
+ // (alarm:u8,u8,u8,brightness:u8,color:u8,u8,u8:volume:u8)
+ int alarmTime = Utilities.dateToTimeValue(settings[0], settings[1]);
+ editor.putInt(Preferences.PREF_ALARM_TIME, alarmTime);
+ boolean alarmOn = (settings[2] != 0);
+ editor.putBoolean(Preferences.PREF_ALARM_ON, alarmOn);
+
+ editor.putInt(Preferences.PREF_BRIGHTNESS, settings[3]);
+
+ int color = settings[4] << 16 | settings[5] << 8 | settings[6];
+ editor.putInt(Preferences.PREF_COLOR, color);
+
+ int volume = settings[7];
+ editor.putInt(Preferences.PREF_VOLUME, volume);
+ editor.apply();
+
+ mIgnorePrefChanges = false;
+ }
+ }
+
+ private void handleLicenseTextCommand(byte[] licenseTextBytes) {
+ if (gLogPackets) {
+ Log.i(ADK.TAG, "License text chunk");
+ Log.i(ADK.TAG, Utilities.dumpBytes(licenseTextBytes,
+ licenseTextBytes.length));
+ }
+ if (licenseTextBytes.length > 1 && licenseTextBytes[0] != 0) {
+ mLicenseTextStream.write(licenseTextBytes, 1,
+ licenseTextBytes.length - 1);
+ sendCommand(CMD_GET_LICENSE, 33);
+ } else {
+
+ try {
+ mLicenseTextStream.close();
+ byte[] encodedArray = mLicenseTextStream.toByteArray();
+ GZIPInputStream gis = new GZIPInputStream(
+ new ByteArrayInputStream(encodedArray));
+ byte[] decodedBuffer = new byte[128 * 1024]; // TODO: make this
+ // buffer
+ // smaller
+ while (true) {
+ int length = gis.read(decodedBuffer);
+ if (length < 1) {
+ SharedPreferences.Editor editor = PreferenceManager
+ .getDefaultSharedPreferences(this).edit();
+ editor.putString(Preferences.PREF_LICENSE_TEXT,
+ mLicenseText);
+ editor.commit();
+ mLicenseText = "";
+ break;
+ }
+ mLicenseText = mLicenseText
+ + new String(decodedBuffer, 0, length, "utf-8");
+ }
+ } catch (IOException e) {
+ Log.i(ADK.TAG, "error = " + e.toString());
+ }
+ }
+ }
+
+ private void handleFileListCommand(byte[] fileListBytes) {
+ if (gLogPackets)
+ Log.i(ADK.TAG,
+ "handleFileListCommand: "
+ + Utilities.dumpBytes(fileListBytes,
+ fileListBytes.length));
+ if (fileListBytes.length == 1 && fileListBytes[0] == 0) {
+ return;
+ }
+ if (fileListBytes.length > 6) {
+ String fileName = new String(fileListBytes, 5,
+ fileListBytes.length - 6);
+ if (gLogPackets)
+ Log.i(ADK.TAG, "got file name '" + fileName + "'");
+ mSoundFiles.add(fileName);
+ }
+ sendCommand(CMD_FILE_LIST, CMD_FILE_LIST);
+
+ }
+
+ private void handleAlarmFileCommand(byte[] alarmFileNameBytes) {
+ if (alarmFileNameBytes.length > 1) {
+ mIgnorePrefChanges = true;
+ SharedPreferences.Editor editor = PreferenceManager
+ .getDefaultSharedPreferences(this).edit();
+ String alarmFileName = new String(alarmFileNameBytes, 0,
+ alarmFileNameBytes.length - 1);
+ alarmFileName = alarmFileName.replaceFirst("(?i)" + TUNES_FOLDER
+ + "/", "");
+ editor.putString(Preferences.PREF_ALARM_SOUND, alarmFileName);
+ editor.apply();
+ mIgnorePrefChanges = false;
+ }
+ }
+
+ private void handleGetSensorsCommand(byte[] sensorBytes) {
+ if (gLogPackets)
+ Log.i(ADK.TAG,
+ "handleGetSensorsCommand: "
+ + Utilities.dumpBytes(sensorBytes,
+ sensorBytes.length));
+ if (sensorBytes.length > 23) {
+ int sensorValues[] = Utilities.byteArrayToIntArray(sensorBytes);
+ int proxNormalized[] = {
+ sensorValues[20] | (sensorValues[21] << 8),
+ sensorValues[22] | (sensorValues[23] << 8),
+ sensorValues[24] | (sensorValues[25] << 8) };
+ proxNormalized[2] *= 3;
+ // find max
+ int proxMax = 0;
+ for (int i = 0; i < 3; i++)
+ if (proxMax < proxNormalized[i])
+ proxMax = proxNormalized[i];
+ proxMax++;
+ // normalize to 8-bits
+ for (int i = 0; i < 3; i++)
+ proxNormalized[i] = (proxNormalized[i] << 8) / proxMax;
+ final int exp[] = { 0, 19, 39, 59, 79, 100, 121, 143, 165, 187,
+ 209, 232, 255, 279, 303, 327, 352, 377, 402, 428, 454, 481,
+ 508, 536, 564, 592, 621, 650, 680, 710, 741, 772, 804, 836,
+ 869, 902, 936, 970, 1005, 1040, 1076, 1113, 1150, 1187,
+ 1226, 1264, 1304, 1344, 1385, 1426, 1468, 1511, 1554, 1598,
+ 1643, 1688, 1734, 1781, 1829, 1877, 1926, 1976, 2026, 2078,
+ 2130, 2183, 2237, 2292, 2348, 2404, 2461, 2520, 2579, 2639,
+ 2700, 2762, 2825, 2889, 2954, 3020, 3088, 3156, 3225, 3295,
+ 3367, 3439, 3513, 3588, 3664, 3741, 3819, 3899, 3980, 4062,
+ 4146, 4231, 4317, 4404, 4493, 4583, 4675, 4768, 4863, 4959,
+ 5057, 5156, 5257, 5359, 5463, 5568, 5676, 5785, 5895, 6008,
+ 6122, 6238, 6355, 6475, 6597, 6720, 6845, 6973, 7102, 7233,
+ 7367, 7502, 7640, 7780, 7922, 8066, 8213, 8362, 8513, 8666,
+ 8822, 8981, 9142, 9305, 9471, 9640, 9811, 9986, 10162,
+ 10342, 10524, 10710, 10898, 11089, 11283, 11480, 11681,
+ 11884, 12091, 12301, 12514, 12731, 12951, 13174, 13401,
+ 13632, 13866, 14104, 14345, 14591, 14840, 15093, 15351,
+ 15612, 15877, 16147, 16421, 16699, 16981, 17268, 17560,
+ 17856, 18156, 18462, 18772, 19087, 19407, 19733, 20063,
+ 20398, 20739, 21085, 21437, 21794, 22157, 22525, 22899,
+ 23279, 23666, 24058, 24456, 24861, 25272, 25689, 26113,
+ 26544, 26982, 27426, 27878, 28336, 28802, 29275, 29756,
+ 30244, 30740, 31243, 31755, 32274, 32802, 33338, 33883,
+ 34436, 34998, 35568, 36148, 36737, 37335, 37942, 38559,
+ 39186, 39823, 40469, 41126, 41793, 42471, 43159, 43859,
+ 44569, 45290, 46023, 46767, 47523, 48291, 49071, 49863,
+ 50668, 51486, 52316, 53159, 54016, 54886, 55770, 56668,
+ 57580, 58506, 59447, 60403, 61373, 62359, 63361, 64378,
+ 65412 };
+ for (int i = 0; i < 3; i++)
+ proxNormalized[i] = (exp[proxNormalized[i]] + 128) >> 8;
+
+ SharedPreferences.Editor editor = PreferenceManager
+ .getDefaultSharedPreferences(this).edit();
+ int color = (proxNormalized[0] << 16) | (proxNormalized[1] << 8)
+ | proxNormalized[2];
+ editor.putInt(Preferences.PREF_COLOR_SENSOR, color);
+ editor.commit();
+ }
+ }
+
+ private void handleLockCommand(byte[] lockedBytes) {
+ if (gLogPackets)
+ Log.i(ADK.TAG,
+ "lockBytes: "
+ + Utilities.dumpBytes(lockedBytes,
+ lockedBytes.length));
+ if (lockedBytes.length > 0 && lockedBytes[0] != 1) {
+ mIgnorePrefChanges = true;
+ SharedPreferences.Editor editor = PreferenceManager
+ .getDefaultSharedPreferences(this).edit();
+ editor.putBoolean(Preferences.PREF_LOCKED, lockedBytes[0] == 2);
+ editor.commit();
+ mIgnorePrefChanges = false;
+ }
+ }
+
+ public boolean handleMessage(Message msg) {
+ if (msg.getTarget() == mDeviceHandler) {
+ return handleDeviceMethod(msg);
+ } else {
+ pollSettings();
+ return true;
+ }
+ }
+
+ private boolean handleDeviceMethod(Message msg) {
+ switch (msg.what) {
+ case CMD_SETTINGS:
+ handleSettingsCommand((byte[]) msg.obj);
+ return true;
+ case CMD_BT_NAME:
+ handleBtNameCommand((byte[]) msg.obj);
+ case CMD_GET_LICENSE:
+ handleLicenseTextCommand((byte[]) msg.obj);
+ return true;
+ case CMD_FILE_LIST:
+ handleFileListCommand((byte[]) msg.obj);
+ return true;
+ case CMD_ALARM_FILE:
+ handleAlarmFileCommand((byte[]) msg.obj);
+ return true;
+ case CMD_GET_SENSORS:
+ handleGetSensorsCommand((byte[]) msg.obj);
+ return true;
+ case CMD_LOCK:
+ handleLockCommand((byte[]) msg.obj);
+ return true;
+ }
+ return false;
+ }
+
+ public Object getAccessory() {
+ return mAccessory;
+ }
+
+ private void updateLockDisplay() {
+ boolean isLocked = mPreferences.getBoolean(Preferences.PREF_LOCKED,
+ false);
+ setUpButton(R.id.lock_button, isLocked ? R.drawable.ic_lock
+ : R.drawable.ic_unlock, isLocked ? R.string.locked
+ : R.string.unlocked);
+ }
+
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
+ String key) {
+
+ if (Preferences.PREF_LOCKED.equals(key)) {
+ updateLockDisplay();
+ }
+
+ if (mIgnorePrefChanges) {
+ return;
+ }
+
+ if (gLogPackets)
+ Log.d(ADK.TAG, "changed: " + key);
+
+ if (Utilities.indexOf(Preferences.SETTINGS_PREFERENCES, key) != -1) {
+ if (gLogPackets)
+ Log.d(ADK.TAG, "updating settings");
+ updateSettings(sharedPreferences);
+ } else if (Preferences.PREF_TIME.equals(key)) {
+ updateTime(sharedPreferences);
+ } else if (Preferences.PREF_DISPLAY.equals(key)) {
+ updateDisplay(sharedPreferences);
+ } else if (Preferences.PREF_LOCKED.equals(key)) {
+ updateLocked(sharedPreferences);
+ } else if (Preferences.PREF_ALARM_SOUND.equals(key)) {
+ updateAlarmSound(sharedPreferences);
+ }
+ }
+
+ private void updateSettings(SharedPreferences sharedPreferences) {
+ mIgnoreUpdatesUntil = System.currentTimeMillis() + 1000;
+ int color = sharedPreferences.getInt(Preferences.PREF_COLOR,
+ Preferences.PREF_DEFAULT_COLOR);
+ byte[] payload = mSettingsPayload;
+ int alarmTimeValue = sharedPreferences.getInt(
+ Preferences.PREF_ALARM_TIME, Preferences.DEFAULT_ALARM_TIME);
+ payload[0] = (byte) (alarmTimeValue / 60);
+ payload[1] = (byte) (alarmTimeValue % 60);
+ boolean alarmOn = sharedPreferences.getBoolean(
+ Preferences.PREF_ALARM_ON, false);
+ payload[2] = (byte) (alarmOn ? 1 : 0);
+ int brightness = sharedPreferences.getInt(Preferences.PREF_BRIGHTNESS,
+ 255);
+ payload[3] = (byte) brightness;
+ payload[4] = (byte) (((color >> 16) & 0xff));
+ payload[5] = (byte) (((color >> 8) & 0xff));
+ payload[6] = (byte) ((color & 0xff));
+ int volume = sharedPreferences.getInt(Preferences.PREF_VOLUME, 128);
+ payload[7] = (byte) volume;
+ mSettingsBuffer = sendCommand(CMD_SETTINGS, CMD_SETTINGS, payload,
+ mSettingsBuffer);
+ }
+
+ private void updateTime(SharedPreferences sharedPreferences) {
+ int timeValue = sharedPreferences.getInt(Preferences.PREF_TIME, 0);
+ byte[] payload = new byte[7];
+ payload[0] = 0;
+ payload[1] = 0;
+ payload[2] = 0;
+ payload[3] = 0;
+ payload[4] = (byte) (timeValue / 60);
+ payload[5] = (byte) (timeValue % 60);
+ payload[6] = 0;
+ sendCommand(CMD_TIME, CMD_TIME, payload);
+ }
+
+ private void updateDisplay(SharedPreferences sharedPreferences) {
+ int displayValue = sharedPreferences
+ .getInt(Preferences.PREF_DISPLAY, 0);
+ byte[] payload = new byte[1];
+ payload[0] = (byte) displayValue;
+ sendCommand(CMD_DISPLAY_MODE, CMD_DISPLAY_MODE, payload);
+ }
+
+ private void updateLocked(SharedPreferences sharedPreferences) {
+ boolean isLocked = sharedPreferences.getBoolean(
+ Preferences.PREF_LOCKED, false);
+ Log.i(ADK.TAG, "updating locked " + isLocked);
+ byte[] payload = new byte[1];
+ payload[0] = (byte) (isLocked ? 2 : 0);
+ sendCommand(CMD_LOCK, CMD_LOCK, payload);
+ }
+
+ private void updateAlarmSound(SharedPreferences sharedPreferences) {
+ String alarmSound = TUNES_FOLDER + "/"
+ + sharedPreferences.getString(Preferences.PREF_ALARM_SOUND, "");
+ final int alarmSoundLength = alarmSound.length();
+ if (alarmSoundLength > 0) {
+ byte[] payload = new byte[alarmSoundLength + 1];
+ alarmSound.getBytes(0, alarmSoundLength, payload, 0);
+ payload[alarmSoundLength] = (byte) 0;
+ sendCommand(CMD_ALARM_FILE, CMD_ALARM_FILE, payload);
+ }
+ }
+
+ private static class ProtocolHandler {
+ InputStream mInputStream;
+ Handler mHandler;
+
+ public ProtocolHandler(Handler handler, InputStream inputStream) {
+ mHandler = handler;
+ mInputStream = inputStream;
+ }
+
+ int readByte() throws IOException {
+ int retVal = mInputStream.read();
+ if (retVal == -1) {
+ throw new RuntimeException("End of stream reached.");
+ }
+ return retVal;
+ }
+
+ int readInt16() throws IOException {
+ int low = readByte();
+ int high = readByte();
+ if (gLogPackets) {
+ Log.i(ADK.TAG, "readInt16 low=" + low + " high=" + high);
+ }
+ return low | (high << 8);
+ }
+
+ byte[] readBuffer(int bufferSize) throws IOException {
+ byte readBuffer[] = new byte[bufferSize];
+ int index = 0;
+ int bytesToRead = bufferSize;
+ while (bytesToRead > 0) {
+ int amountRead = mInputStream.read(readBuffer, index,
+ bytesToRead);
+ if (amountRead == -1) {
+ throw new RuntimeException("End of stream reached.");
+ }
+ bytesToRead -= amountRead;
+ index += amountRead;
+ }
+ return readBuffer;
+ }
+
+ public void process() {
+ mInputStream.mark(0);
+ try {
+ while (mInputStream.available() > 0) {
+ if (gLogPackets)
+ Log.i(ADK.TAG, "about to read opcode");
+ int opCode = readByte();
+ if (gLogPackets)
+ Log.i(ADK.TAG, "opCode = " + opCode);
+ if (isValidOpCode(opCode)) {
+ int sequence = readByte();
+ if (gLogPackets)
+ Log.i(ADK.TAG, "sequence = " + sequence);
+ int replySize = readInt16();
+ if (gLogPackets)
+ Log.i(ADK.TAG, "replySize = " + replySize);
+ byte[] replyBuffer = readBuffer(replySize);
+ if (gLogPackets) {
+ Log.i(ADK.TAG,
+ "replyBuffer: "
+ + Utilities.dumpBytes(replyBuffer,
+ replyBuffer.length));
+ }
+ processReply(opCode & 0x7f, sequence, replyBuffer);
+ mInputStream.mark(0);
+ }
+ }
+ mInputStream.reset();
+ } catch (IOException e) {
+ Log.i(ADK.TAG, "ProtocolHandler error " + e.toString());
+ }
+ }
+
+ boolean isValidOpCode(int opCodeWithReplyBitSet) {
+ if ((opCodeWithReplyBitSet & 0x80) != 0) {
+ int opCode = opCodeWithReplyBitSet & 0x7f;
+ return ((opCode >= CMD_GET_PROTO_VERSION) && (opCode <= CMD_LOCK));
+ }
+ return false;
+ }
+
+ private void processReply(int opCode, int sequence, byte[] replyBuffer) {
+ Message msg = mHandler.obtainMessage(opCode, sequence, 0,
+ replyBuffer);
+ mHandler.sendMessage(msg);
+ }
+ }
+
+ public String[] getAlarmSounds() {
+ String[] r = new String[mSoundFiles.size()];
+ return mSoundFiles.toArray(r);
+ }
+}
diff --git a/src/com/google/android/apps/adk2/activity/LicenseActivity.java b/src/com/google/android/apps/adk2/activity/LicenseActivity.java
new file mode 100644
index 0000000..f642f0e
--- /dev/null
+++ b/src/com/google/android/apps/adk2/activity/LicenseActivity.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+package com.google.android.apps.adk2.activity;
+
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.widget.TextView;
+
+import com.google.android.apps.adk2.Preferences;
+import com.google.android.apps.adk2.R;
+
+public class LicenseActivity extends Adk2BaseActivity implements
+ OnSharedPreferenceChangeListener {
+ private TextView mLicenseTextView;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.licenses);
+
+ mLicenseTextView = (TextView) findViewById(R.id.license_text);
+
+ SharedPreferences preferences = PreferenceManager
+ .getDefaultSharedPreferences(this);
+ preferences.registerOnSharedPreferenceChangeListener(this);
+ updateDisplay(preferences);
+ }
+
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
+ String key) {
+
+ if (Preferences.PREF_LICENSE_TEXT.equals(key)) {
+ updateDisplay(sharedPreferences);
+ }
+ }
+
+ private void updateDisplay(SharedPreferences sharedPreferences) {
+ String licenseText = sharedPreferences.getString(
+ Preferences.PREF_LICENSE_TEXT, "");
+ mLicenseTextView.setText(licenseText);
+ }
+}
diff --git a/src/com/google/android/apps/adk2/activity/PresetsActivity.java b/src/com/google/android/apps/adk2/activity/PresetsActivity.java
new file mode 100755
index 0000000..e5faaac
--- /dev/null
+++ b/src/com/google/android/apps/adk2/activity/PresetsActivity.java
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+package com.google.android.apps.adk2.activity;
+
+import java.io.IOException;
+import java.util.ArrayList;
+
+import android.app.Dialog;
+import android.app.ListActivity;
+import android.content.SharedPreferences;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.util.SparseBooleanArray;
+import android.view.ActionMode;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.ArrayAdapter;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.ListView;
+import android.widget.Toast;
+
+import com.google.android.apps.adk2.Presets;
+import com.google.android.apps.adk2.R;
+
+public class PresetsActivity extends ListActivity {
+
+ Presets mPresets;
+ boolean mWasPolling;
+ ArrayAdapter<Presets.Preset> mAdapter;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ mPresets = new Presets();
+ try {
+ mPresets.load(this);
+ } catch (IOException e) {
+ e.printStackTrace();
+ } catch (ClassNotFoundException e) {
+ e.printStackTrace();
+ }
+
+ Adk2BaseActivity.maybeDisplayHomeAsUp(this);
+
+ setContentView(R.layout.presets);
+
+ mAdapter = new ArrayAdapter<Presets.Preset>(this,
+ android.R.layout.simple_list_item_multiple_choice,
+ mPresets.getPresets());
+ setListAdapter(mAdapter);
+ getListView().setMultiChoiceModeListener(new ModeCallback());
+ getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
+
+ mWasPolling = HomeActivity.get().startPollingSettings();
+ }
+
+ protected void onDestroy() {
+ if (!mWasPolling) {
+ HomeActivity.get().stopPollingSettings();
+ }
+ super.onDestroy();
+ }
+
+ @Override
+ protected void onListItemClick(ListView l, View v, int position, long id) {
+ Presets.Preset p = mPresets.getPresets().get(position);
+ SharedPreferences sharedPreferences = PreferenceManager
+ .getDefaultSharedPreferences(this);
+ p.applyToPreferences(sharedPreferences);
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ MenuInflater inflater = getMenuInflater();
+ inflater.inflate(R.menu.presets_menu, menu);
+ return true;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ if (Adk2BaseActivity.maybeHandleHomeMenuItem(item, this)) {
+ return true;
+ }
+ switch (item.getItemId()) {
+ case R.id.new_preset:
+ makeNewPreset();
+ return true;
+
+ default:
+ return false;
+ }
+ }
+
+ private void makeNewPreset() {
+ SharedPreferences sharedPreferences = PreferenceManager
+ .getDefaultSharedPreferences(this);
+ Presets.Preset p = mPresets.makeNewPreset(sharedPreferences);
+ onContentChanged();
+ RenamePresetController rpc = new RenamePresetController(p, true);
+ rpc.start();
+ }
+
+ void deletePreset(Presets.Preset preset) {
+ mAdapter.remove(preset);
+ }
+
+ private void savePresets() {
+ try {
+ mPresets.save(this);
+ } catch (IOException e) {
+ // TODO Error message for save fail
+ e.printStackTrace();
+ }
+ }
+
+ void deleteSelectedItems() {
+ ListView lv = getListView();
+ SparseBooleanArray checkedPositions = lv.getCheckedItemPositions();
+ int count = checkedPositions.size();
+ Resources res = getResources();
+ String presetsDeleted = res.getQuantityString(
+ R.plurals.number_of_presets_deleted, count, count);
+ Toast.makeText(PresetsActivity.this, presetsDeleted, Toast.LENGTH_SHORT)
+ .show();
+ ArrayList<Presets.Preset> presets = mPresets.getPresets();
+ for (int i = count - 1; i >= 0; --i) {
+ int index = checkedPositions.keyAt(i);
+ if (index != -1) {
+ Presets.Preset p = presets.get(index);
+ deletePreset(p);
+ }
+ }
+ savePresets();
+ }
+
+ void editSelectedItems() {
+ ListView lv = getListView();
+ SparseBooleanArray checkedPositions = lv.getCheckedItemPositions();
+ int firstIndex = checkedPositions.keyAt(0);
+ if (firstIndex != -1) {
+ ArrayList<Presets.Preset> presets = mPresets.getPresets();
+ Presets.Preset p = presets.get(firstIndex);
+ RenamePresetController rpc = new RenamePresetController(p, false);
+ rpc.start();
+ }
+ }
+
+ private class RenamePresetController implements OnClickListener {
+ Dialog mDialog;
+ Presets.Preset mPreset;
+ EditText mNameEdit;
+ Boolean mDeleteOnCancel;
+
+ public RenamePresetController(Presets.Preset preset,
+ Boolean deleteOnCancel) {
+ mPreset = preset;
+ mDeleteOnCancel = deleteOnCancel;
+ }
+
+ public void start() {
+ mDialog = new Dialog(PresetsActivity.this);
+ mDialog.setContentView(R.layout.preset_name_dialog);
+ Button cancel = (Button) mDialog
+ .findViewById(R.id.preset_edit_cancel);
+ cancel.setOnClickListener(this);
+ Button rename = (Button) mDialog
+ .findViewById(R.id.preset_edit_rename);
+ if (mDeleteOnCancel) {
+ rename.setText(R.string.create);
+ }
+ rename.setOnClickListener(this);
+ mNameEdit = (EditText) mDialog.findViewById(R.id.preset_name_edit);
+ mNameEdit.setText(mPreset.getName());
+ mNameEdit.selectAll();
+ mDialog.setTitle("Preset Name");
+ mDialog.show();
+ }
+
+ public void onClick(View v) {
+ if (v.getId() == R.id.preset_edit_rename) {
+ mPreset.setName(mNameEdit.getText().toString());
+ onContentChanged();
+ savePresets();
+ } else {
+ if (mDeleteOnCancel) {
+ deletePreset(mPreset);
+ }
+ }
+ mDialog.dismiss();
+
+ }
+ }
+
+ private class ModeCallback implements ListView.MultiChoiceModeListener {
+
+ public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+ MenuInflater inflater = getMenuInflater();
+ inflater.inflate(R.menu.list_select_menu, menu);
+ mode.setTitle("Select Items");
+ return true;
+ }
+
+ public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+ return true;
+ }
+
+ public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.delete_preset:
+ deleteSelectedItems();
+ mode.finish();
+ break;
+ case R.id.edit_preset:
+ editSelectedItems();
+ mode.finish();
+ break;
+ }
+ return true;
+ }
+
+ public void onDestroyActionMode(ActionMode mode) {
+ }
+
+ public void onItemCheckedStateChanged(ActionMode mode, int position,
+ long id, boolean checked) {
+ final int checkedCount = getListView().getCheckedItemCount();
+ switch (checkedCount) {
+ case 0:
+ mode.setSubtitle(null);
+ break;
+ case 1:
+ mode.setSubtitle("One item selected");
+ break;
+ default:
+ mode.setSubtitle("" + checkedCount + " items selected");
+ break;
+ }
+ }
+
+ }
+}
diff --git a/src/com/google/android/apps/adk2/activity/VolumeActivity.java b/src/com/google/android/apps/adk2/activity/VolumeActivity.java
new file mode 100644
index 0000000..096e267
--- /dev/null
+++ b/src/com/google/android/apps/adk2/activity/VolumeActivity.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+package com.google.android.apps.adk2.activity;
+
+import android.content.SharedPreferences;
+import android.os.Bundle;
+
+import com.google.android.apps.adk2.Preferences;
+import com.google.android.apps.adk2.R;
+import com.google.android.apps.adk2.widget.SeekBarPreference;
+
+public class VolumeActivity extends Adk2PreferenceActivity {
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ addPreferencesFromResource(R.xml.volume_preferences);
+ updatePreferencesDisplay();
+ }
+
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
+ String key) {
+ if (Preferences.PREF_VOLUME.equals(key))
+ updatePreferencesDisplay();
+ }
+
+ private void updatePreferencesDisplay() {
+ SeekBarPreference vol = (SeekBarPreference) mPreferenceManager
+ .findPreference(Preferences.PREF_VOLUME);
+ if (vol != null) {
+ vol.setValue(mPreferences.getInt(Preferences.PREF_VOLUME, 0));
+ }
+ }
+} \ No newline at end of file
diff --git a/src/com/google/android/apps/adk2/views/ColorSensorView.java b/src/com/google/android/apps/adk2/views/ColorSensorView.java
new file mode 100644
index 0000000..c278cfa
--- /dev/null
+++ b/src/com/google/android/apps/adk2/views/ColorSensorView.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+package com.google.android.apps.adk2.views;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Paint.Style;
+import android.util.AttributeSet;
+import android.view.View;
+
+public class ColorSensorView extends View {
+ Paint mCircle;
+ Paint mBorder;
+
+ private final int kSize = 200;
+
+ public ColorSensorView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ initColorSensorView(context);
+ }
+
+ public ColorSensorView(Context context) {
+ super(context);
+ initColorSensorView(context);
+ }
+
+ public ColorSensorView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ initColorSensorView(context);
+ }
+
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ setMeasuredDimension(kSize, kSize);
+ }
+
+ private void initColorSensorView(Context context) {
+ mCircle = new Paint();
+ mCircle.setARGB(255, 255, 0, 0);
+ mCircle.setStyle(Style.FILL);
+
+ mBorder = new Paint();
+ mBorder.setARGB(255, 255, 255, 255);
+ mBorder.setStyle(Style.STROKE);
+ }
+
+ public void setSensedColor(int color) {
+ mCircle.setColor(color);
+ invalidate();
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ canvas.drawRect(0, 0, kSize - 1, kSize - 1, mBorder);
+ canvas.drawCircle(kSize / 2, kSize / 2, kSize / 8, mCircle);
+ }
+}
diff --git a/src/com/google/android/apps/adk2/views/Slider.java b/src/com/google/android/apps/adk2/views/Slider.java
new file mode 100644
index 0000000..0a9ae98
--- /dev/null
+++ b/src/com/google/android/apps/adk2/views/Slider.java
@@ -0,0 +1,151 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+package com.google.android.apps.adk2.views;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+
+import com.google.android.apps.adk2.R;
+import com.google.android.apps.adk2.Utilities;
+
+public class Slider extends View {
+
+ public interface SliderPositionListener {
+ void onPositionChange(Slider slider, double value);
+ }
+
+ private Drawable mIndicator;
+ private Drawable mBackground;
+ private double mPosition;
+ private SliderPositionListener mListener;
+ private boolean mVertical;
+
+ public Slider(Context context) {
+ super(context);
+ initSliderView(context, false);
+ }
+
+ public Slider(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ initSliderView(context, false);
+ }
+
+ public void setSliderBackground(Drawable background) {
+ mBackground = background;
+ invalidate();
+ }
+
+ public void setPositionListener(SliderPositionListener listener) {
+ mListener = listener;
+ }
+
+ public void setPosition(double position) {
+ if (mPosition != position) {
+ invalidate();
+ mPosition = position;
+ if (mListener != null) {
+ mListener.onPositionChange(this, mPosition);
+ }
+ }
+ }
+
+ private OnTouchListener mClickListener = new OnTouchListener() {
+ public boolean onTouch(View v, MotionEvent m) {
+ Rect r = new Rect();
+ getDrawingRect(r);
+
+ double position;
+ if (mVertical) {
+ double y = m.getY();
+ position = Math.max(0, (r.bottom - y) / r.height());
+ } else {
+ double x = m.getX();
+ position = Math.max(0, (x - r.left) / r.width());
+ }
+ position = Math.min(1, position);
+ setPosition(position);
+ return true;
+ }
+ };
+
+ protected void initSliderView(Context context, boolean vertical) {
+ mPosition = 0;
+ mVertical = vertical;
+ Resources res = context.getResources();
+ if (mVertical) {
+ mBackground = res
+ .getDrawable(R.drawable.scrubber_vertical_blue_holo_dark);
+ } else {
+ mBackground = res
+ .getDrawable(R.drawable.scrubber_horizontal_holo_dark);
+ }
+ mIndicator = res.getDrawable(R.drawable.scrubber_control_holo_dark);
+ this.setOnTouchListener(mClickListener);
+ }
+
+ protected void onDraw(Canvas canvas) {
+ Rect r = new Rect();
+ getDrawingRect(r);
+ if (mVertical) {
+ int lineX = r.centerX();
+ int bgW = mBackground.getIntrinsicWidth() / 2;
+ if (bgW == 0) {
+ bgW = 5;
+ }
+ mBackground.setBounds(lineX - bgW, r.top + 10, lineX + bgW,
+ r.bottom - 10);
+ mBackground.draw(canvas);
+ final int kMargin = 48;
+ int indicatorY = (int) (r.bottom - (r.height() - kMargin)
+ * mPosition)
+ - kMargin / 2;
+ Utilities.centerAround(lineX, indicatorY, mIndicator);
+ mIndicator.draw(canvas);
+ } else {
+ int lineY = r.centerY();
+ int bgH = mBackground.getIntrinsicHeight() / 2;
+ if (bgH == 0) {
+ bgH = 5;
+ }
+ mBackground.setBounds(r.left + 10, lineY - bgH, r.right - 10, lineY
+ + bgH);
+ mBackground.draw(canvas);
+ final int kMargin = 48;
+ int indicatorX = (int) ((r.width() - kMargin) * mPosition) + r.left
+ + kMargin / 2;
+ Utilities.centerAround(indicatorX, lineY, mIndicator);
+ mIndicator.draw(canvas);
+ }
+ }
+
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ if (mVertical) {
+ setMeasuredDimension(mIndicator.getIntrinsicWidth(),
+ getMeasuredHeight());
+ } else {
+ setMeasuredDimension(getMeasuredWidth(),
+ mIndicator.getIntrinsicHeight());
+ }
+ }
+
+}
diff --git a/src/com/google/android/apps/adk2/widget/ActivityPreference.java b/src/com/google/android/apps/adk2/widget/ActivityPreference.java
new file mode 100644
index 0000000..5eb5fe4
--- /dev/null
+++ b/src/com/google/android/apps/adk2/widget/ActivityPreference.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+package com.google.android.apps.adk2.widget;
+
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.TypedArray;
+import android.preference.Preference;
+import android.util.AttributeSet;
+import android.util.Log;
+
+import com.google.android.apps.adk2.ADK;
+import com.google.android.apps.adk2.R;
+
+public class ActivityPreference extends Preference {
+ String mActivityClassName;
+
+ public ActivityPreference(Context context) {
+ this(context, null);
+ }
+
+ public ActivityPreference(Context context, AttributeSet attrs) {
+ this(context, attrs, android.R.attr.preferenceStyle);
+ }
+
+ public ActivityPreference(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+
+ TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.ActivityPreference, defStyle, 0);
+ mActivityClassName = a.getString(R.styleable.ActivityPreference_classname);
+ a.recycle();
+ }
+
+ @Override
+ protected void onClick() {
+ try {
+ Class<?> activityClass = Class.forName(mActivityClassName);
+ Intent openNewIntent = new Intent(getContext(), activityClass);
+ getContext().startActivity(openNewIntent);
+ } catch (ClassNotFoundException e) {
+ Log.e(ADK.TAG, "class not found in ActivityPreference", e);
+ }
+ }
+}
diff --git a/src/com/google/android/apps/adk2/widget/SeekBarPreference.java b/src/com/google/android/apps/adk2/widget/SeekBarPreference.java
new file mode 100644
index 0000000..b4c9c02
--- /dev/null
+++ b/src/com/google/android/apps/adk2/widget/SeekBarPreference.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+package com.google.android.apps.adk2.widget;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.preference.Preference;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.SeekBar;
+import android.widget.SeekBar.OnSeekBarChangeListener;
+
+import com.google.android.apps.adk2.R;
+
+public class SeekBarPreference extends Preference implements OnSeekBarChangeListener {
+ private int mMax;
+ private int mValue;
+ private boolean mTrackingTouch;
+
+ public SeekBarPreference(Context context) {
+ this(context, null);
+ }
+
+ public SeekBarPreference(Context context, AttributeSet attrs) {
+ this(context, attrs, android.R.attr.preferenceStyle);
+ }
+
+ public SeekBarPreference(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+
+ TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SeekBarPreference, defStyle, 0);
+ mMax = a.getInteger(R.styleable.SeekBarPreference_max, 0);
+ a.recycle();
+
+ setLayoutResource(R.layout.seekbar_preference);
+ }
+
+ @Override
+ protected void onBindView(View view) {
+ super.onBindView(view);
+
+ SeekBar seekBar = (SeekBar)view.findViewById(R.id.seekbar);
+ seekBar.setMax(mMax);
+ seekBar.setProgress(mValue);
+ seekBar.setEnabled(isEnabled());
+
+ seekBar.setOnSeekBarChangeListener(this);
+ }
+
+ @Override
+ protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
+ setValue(restoreValue ? getPersistedInt(0) : (Integer)defaultValue);
+ }
+
+ @Override
+ protected Object onGetDefaultValue(TypedArray a, int index) {
+ return a.getInt(index, 0);
+ }
+
+ public void setValue(int value) {
+ if (value > mMax) value = mMax;
+ if (value < 0) value = 0;
+
+ if (value != mValue) {
+ mValue = value;
+ persistInt(value);
+ if (!mTrackingTouch)
+ notifyChanged();
+ }
+ }
+
+ public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+ if (progress != mValue) {
+ if (callChangeListener(progress)) {
+ setValue(progress);
+ } else {
+ seekBar.setProgress(progress);
+ }
+ }
+ }
+
+ public void onStartTrackingTouch(SeekBar seekBar) {
+ mTrackingTouch = true;
+ }
+
+ public void onStopTrackingTouch(SeekBar seekBar) {
+ mTrackingTouch = false;
+ }
+}
diff --git a/src/com/google/android/apps/adk2/widget/TimeDialogPreference.java b/src/com/google/android/apps/adk2/widget/TimeDialogPreference.java
new file mode 100644
index 0000000..bc87c39
--- /dev/null
+++ b/src/com/google/android/apps/adk2/widget/TimeDialogPreference.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * 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.
+ */
+package com.google.android.apps.adk2.widget;
+
+import java.util.Date;
+
+import android.content.Context;
+import android.preference.DialogPreference;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.TimePicker;
+
+import com.google.android.apps.adk2.Preferences;
+import com.google.android.apps.adk2.R;
+import com.google.android.apps.adk2.Utilities;
+
+public class TimeDialogPreference extends DialogPreference {
+ private TimePicker mTimePicker;
+
+ public TimeDialogPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ @Override
+ protected void onBindDialogView(View view) {
+ super.onBindDialogView(view);
+ mTimePicker = (TimePicker) view.findViewById(R.id.time_picker);
+
+ int time = 0;
+ if (getKey().equals(Preferences.PREF_ALARM_TIME)) {
+ time = getPersistedInt(Preferences.DEFAULT_ALARM_TIME);
+ } else {
+ Date d = new Date();
+ time = Utilities.dateToTimeValue(d);
+ }
+ mTimePicker.setCurrentHour(time / 60);
+ mTimePicker.setCurrentMinute(time % 60);
+ }
+
+ @Override
+ protected void onDialogClosed(boolean positiveResult) {
+ super.onDialogClosed(positiveResult);
+
+ if (positiveResult) {
+ persistInt(Utilities.dateToTimeValue(mTimePicker.getCurrentHour(),
+ mTimePicker.getCurrentMinute()));
+ }
+ }
+}