diff --git a/MyTracks/res/values-de/strings.xml b/MyTracks/res/values-de/strings.xml index af2c04ed5..9514ddec3 100644 --- a/MyTracks/res/values-de/strings.xml +++ b/MyTracks/res/values-de/strings.xml @@ -184,9 +184,6 @@ limitations under the License. Beim teilen mit Freunden wird nur die Karten URL gesendet. Beim teilen mit Freunden wird der GPS Track selbst gesendet. - Empfangsstärke Aufzeichnungsfrequenz - Dauer zwischen zwei Aufzeichnungen der Telefonempfangsstärke. - Zerteilungs Frequenz Längste Dauer oder Entfernung nach der automatisch ein Marker eingefügt wird. Tempo diff --git a/MyTracks/res/values-es/strings.xml b/MyTracks/res/values-es/strings.xml index 5e6a29f8b..7a58e15e8 100644 --- a/MyTracks/res/values-es/strings.xml +++ b/MyTracks/res/values-es/strings.xml @@ -187,9 +187,6 @@ limitations under the License. Sólo el URL del mapa será enviado al compartir Los contenidos de la pista también serán incluídos al compartir - Frecuencia de medición de señal - Tiempo entre grabaciones de la intensidad de la señal del teléfono - Dividir frecuencia Tiempo o distancia máxima para insertar una nueva marca de división Paso diff --git a/MyTracks/res/values-fr/strings.xml b/MyTracks/res/values-fr/strings.xml index a67f90749..bbe44c007 100644 --- a/MyTracks/res/values-fr/strings.xml +++ b/MyTracks/res/values-fr/strings.xml @@ -187,9 +187,6 @@ limitations under the License. Seule l\'adresse URL de la carte sera envoyée lors du partage Le contenu du parcours sera également inclus lors du partage - Échantillonnage du signal - Intervalle de temps entre deux enregistrements de la force du signal - Fréquence de séparation Temps ou distance minimum avant l\'insertion d\'un marqueur de séparation Rythme diff --git a/MyTracks/res/values-it/strings.xml b/MyTracks/res/values-it/strings.xml index 2f9024552..2fe4ff4ba 100644 --- a/MyTracks/res/values-it/strings.xml +++ b/MyTracks/res/values-it/strings.xml @@ -193,9 +193,6 @@ limitations under the License. Solo l\'URL della mappa sarà inviata quando condividi un percorso Anche il contenuto del percorso sarà inviato quando condividi un persorso - Frequenza di campionamento - Tempo fra due registrazioni della qualità del segnale cellulare - Frequenza di divisione Tempo o distanza massima dopo di cui il percorso verrà diviso Andatura diff --git a/MyTracks/res/values-ja/strings.xml b/MyTracks/res/values-ja/strings.xml index b88304819..6a5745f77 100644 --- a/MyTracks/res/values-ja/strings.xml +++ b/MyTracks/res/values-ja/strings.xml @@ -194,9 +194,6 @@ limitations under the License. 共有時にマップのURLのみ送信します 共有時にトラックのコンテントが含まれます - 信号サンプリング周波数 - 端末の信号強度記録の時間間隔 - 分割頻度 分割マーカを挿入する時間または距離の間隔 ペース @@ -384,12 +381,4 @@ limitations under the License. 計測単位についてのご注意 デフォルトの単位はメートルです.設定を変更しますか? - - - 誤り率: %1$d - S/N比: %1$d - Ec/Io比: %1$.1f dB - GSM 強度: %1$d - CDMA 強度: %1$d dBm - EVDO 強度: %1$d dBm diff --git a/MyTracks/res/values-pl/strings.xml b/MyTracks/res/values-pl/strings.xml index 049209c7d..2d597a9e2 100644 --- a/MyTracks/res/values-pl/strings.xml +++ b/MyTracks/res/values-pl/strings.xml @@ -195,9 +195,6 @@ limitations under the License. Tylko odnośnik do mapy będzie wysyłany podczas dzielenia się Zawartość trasy będzie również przesyłana - Częstotliowść próbkowania sygnału - Czas między dwoma zapisami siły sygnału telefonu - Częstotliwość rozdzielania Maksymalny czas lub odległość po którym wstawiony zostanie znacznik rozdzielenia @@ -416,12 +413,4 @@ limitations under the License. Jednostki miary Domyślnie używane są jednostki metryczne. Chcesz to zmienić? - - - Poziom błędów: %1$d - Stosunek sygnału do szumu: %1$d - Ec/lo: %1$.1f dB - Siła GSM: %1$d - Siła CDMA: %1$d dBm - Siła EVDO: %1$d dBm diff --git a/MyTracks/res/values-sv/strings.xml b/MyTracks/res/values-sv/strings.xml index fa43e18e7..3b18a5f95 100644 --- a/MyTracks/res/values-sv/strings.xml +++ b/MyTracks/res/values-sv/strings.xml @@ -195,9 +195,6 @@ limitations under the License. Bara länken till kartan kommer att skickas vid delning Innehållet i spåret kommer också att inkluderas vid delning - Signalprovsfrekvens - Tid mellan två inspelningar av telefonens signalstyrka - Delningsfrekvens Maximala tiden eller distansen varefter en ny delningsmarkör kommer infogas Tempo @@ -383,12 +380,4 @@ limitations under the License. Mätenheter Som standard är enheterna metriska. Vill du ändra den inställningen? - - - Felfrekvens: %1$d - Signal / brus-förhållande: %1$d - Ec/lo: %1$.1f dB - GSM-styrka: %1$d - CDMA-styrka: %1$d dBm - EVDO-styrka: %1$d dBm diff --git a/MyTracks/res/values-zh-rCN/strings.xml b/MyTracks/res/values-zh-rCN/strings.xml index 648550a39..cacf8422c 100644 --- a/MyTracks/res/values-zh-rCN/strings.xml +++ b/MyTracks/res/values-zh-rCN/strings.xml @@ -201,9 +201,6 @@ limitations under the License. 在分享时只发送地图的 URL 在分享时也包括轨迹的内容 - 信号采样频率 - 记录电话信号强度的时间间隔 - 切割频度 插入新切割标记所需要达到的最大时间或距离 @@ -451,14 +448,6 @@ limitations under the License. 测量单位提示 默认单位均为公制. 你想要修改此设置吗? - - 错误率: %1$d - 信噪比: %1$d - Ec/lo: %1$.1f dB - GSM 强度 %1$d - CDMA 强度 %1$d dBm - EVDO 强度 %1$d dBm - 蓝牙 蓝牙设置 @@ -467,12 +456,6 @@ limitations under the License. 感应器选项 - - - - - - 连接到 %s 蓝牙感应器连接中 ... diff --git a/MyTracks/res/values/keys.xml b/MyTracks/res/values/keys.xml index 43a843ebc..a4ec6dc48 100644 --- a/MyTracks/res/values/keys.xml +++ b/MyTracks/res/values/keys.xml @@ -36,7 +36,6 @@ limitations under the License. sensorId sensorType shareUrlOnly - signalSamplingFrequency splitFrequency timestampTrackName diff --git a/MyTracks/res/values/strings.xml b/MyTracks/res/values/strings.xml index 59354f03b..e52af7809 100644 --- a/MyTracks/res/values/strings.xml +++ b/MyTracks/res/values/strings.xml @@ -201,9 +201,6 @@ limitations under the License. Only the URL of the map will be sent when sharing The contents of the track will also be included when sharing - Signal sampling frequency - Time between two recordings of the phone\'s signal strength - Split frequency Maximum time or distance after which a new split marker will be inserted @@ -447,14 +444,6 @@ limitations under the License. Units of Measure Notice By default units are metric. Would you like to change that setting? - - Error Rate: %1$d - Signal to Noise Ratio: %1$d - Ec/lo: %1$.1f dB - GSM Strength: %1$d - CDMA Strength: %1$d dBm - EVDO Strength: %1$d dBm - Bluetooth Bluetooth options diff --git a/MyTracks/res/xml/preferences.xml b/MyTracks/res/xml/preferences.xml index 848bab5a2..98d34845a 100644 --- a/MyTracks/res/xml/preferences.xml +++ b/MyTracks/res/xml/preferences.xml @@ -84,14 +84,6 @@ limitations under the License. android:entryValues="@array/min_required_accuracy_values" android:defaultValue="200" /> - - 0) { + waypoint.stats = source.readParcelable(classLoader); + } byte hasLocation = source.readByte(); if (hasLocation > 0) { waypoint.location = source.readParcelable(classLoader); @@ -100,7 +103,10 @@ public final class Waypoint implements Parcelable { dest.writeInt(type); dest.writeLong(startId); dest.writeLong(stopId); - dest.writeParcelable(stats, 0); + dest.writeByte(stats == null ? (byte) 0 : (byte) 1); + if (stats != null) { + dest.writeParcelable(stats, 0); + } dest.writeByte(location == null ? (byte) 0 : (byte) 1); if (location != null) { dest.writeParcelable(location, 0); diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/PreferenceManager.java b/MyTracks/src/com/google/android/apps/mytracks/services/PreferenceManager.java index 413ddb364..fee208d54 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/services/PreferenceManager.java +++ b/MyTracks/src/com/google/android/apps/mytracks/services/PreferenceManager.java @@ -40,7 +40,6 @@ public class PreferenceManager implements OnSharedPreferenceChangeListener { private final String minRecordingIntervalKey; private final String minRequiredAccuracyKey; private final String recordingTrackKey; - private final String signalSamplingFrequencyKey; private final String splitFrequencyKey; public PreferenceManager(TrackRecordingService service) { @@ -72,8 +71,6 @@ public class PreferenceManager implements OnSharedPreferenceChangeListener { service.getString(R.string.min_required_accuracy_key); recordingTrackKey = service.getString(R.string.recording_track_key); - signalSamplingFrequencyKey = - service.getString(R.string.signal_sampling_frequency_key); splitFrequencyKey = service.getString(R.string.split_frequency_key); @@ -163,10 +160,6 @@ public class PreferenceManager implements OnSharedPreferenceChangeListener { service.getSplitManager().setSplitFrequency( sharedPreferences.getInt(splitFrequencyKey, 0)); } - if (key == null || key.equals(signalSamplingFrequencyKey)) { - service.getSignalManager().setFrequency( - sharedPreferences.getInt(signalSamplingFrequencyKey, -1), service); - } if (key == null || key.equals(metricUnitsKey)) { service.getSplitManager().setMetricUnits( sharedPreferences.getBoolean(metricUnitsKey, true)); diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/SignalStrengthTaskFactory.java b/MyTracks/src/com/google/android/apps/mytracks/services/SignalStrengthTaskFactory.java deleted file mode 100644 index 844b48b95..000000000 --- a/MyTracks/src/com/google/android/apps/mytracks/services/SignalStrengthTaskFactory.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2010 Google Inc. - * - * 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.mytracks.services; - -import com.google.android.apps.mytracks.MyTracksConstants; -import com.google.android.apps.mytracks.util.ApiFeatures; - -import android.content.Context; -import android.util.Log; - -/** - * Factory for producing a proper {@link SignalStrengthTask} according to the - * current API level. - * - * @author Rodrigo Damazio - */ -public class SignalStrengthTaskFactory { - private final boolean hasModernSignalStrength; - - SignalStrengthTaskFactory(ApiFeatures apiFeatures) { - this.hasModernSignalStrength = apiFeatures.hasModernSignalStrength(); - } - - public PeriodicTask create(Context context) { - if (hasModernSignalStrength) { - Log.d(MyTracksConstants.TAG, - "TrackRecordingService using modern signal strength api."); - return new SignalStrengthTaskModern(context); - } else { - Log.w(MyTracksConstants.TAG, - "TrackRecordingService using legacy signal strength api."); - return new SignalStrengthTask(context); - } - } -} diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java b/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java index c0c18a048..0e279ac1a 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java +++ b/MyTracks/src/com/google/android/apps/mytracks/services/TrackRecordingService.java @@ -123,7 +123,6 @@ public class TrackRecordingService extends Service implements LocationListener { * Status announcer executer. */ private PeriodicTaskExecuter announcementExecuter; - private TaskExecuterManager signalManager; private SplitManager splitManager; private PreferenceManager prefManager; @@ -425,7 +424,6 @@ public class TrackRecordingService extends Service implements LocationListener { statsBuilder = new TripStatisticsBuilder(stats.getStartTime()); setUpAnnouncer(); - signalManager.restore(); splitManager.restore(); length = 0; lastValidLocation = null; @@ -643,11 +641,6 @@ public class TrackRecordingService extends Service implements LocationListener { locationManager = (LocationManager) getSystemService(LOCATION_SERVICE); splitManager = new SplitManager(this); - SignalStrengthTaskFactory strengthTaskFactory = - new SignalStrengthTaskFactory(ApiFeatures.getInstance()); - signalManager = - new TaskExecuterManager(-1, strengthTaskFactory.create(this), this); - prefManager = new PreferenceManager(this); registerLocationListener(); /** @@ -730,8 +723,6 @@ public class TrackRecordingService extends Service implements LocationListener { timer.purge(); unregisterLocationListener(); shutdownAnnouncer(); - signalManager.shutdown(); - signalManager = null; splitManager.shutdown(); splitManager = null; @@ -863,15 +854,25 @@ public class TrackRecordingService extends Service implements LocationListener { throw new IllegalStateException( "Unable to insert waypoint marker while not recording!"); } - - if (waypoint.getLocation() != null) { - waypoint.setLength(length); - waypoint.setDuration(waypoint.getLocation().getTime() - - statsBuilder.getStatistics().getStartTime()); - Uri uri = providerUtils.insertWaypoint(waypoint); - return Long.parseLong(uri.getLastPathSegment()); + + if (waypoint.getLocation() == null) { + if (lastValidLocation == null) { + Log.w(MyTracksConstants.TAG, "Cannot insert waypoint with no location"); + return -1; + } + + waypoint.setLocation(lastValidLocation); } - return -1; + + if (waypoint.getTrackId() < 0) { + waypoint.setTrackId(recordingTrackId); + } + + waypoint.setLength(length); + waypoint.setDuration(waypoint.getLocation().getTime() + - statsBuilder.getStatistics().getStartTime()); + Uri uri = providerUtils.insertWaypoint(waypoint); + return Long.parseLong(uri.getLastPathSegment()); } /** @@ -1041,7 +1042,6 @@ public class TrackRecordingService extends Service implements LocationListener { showNotification(); registerLocationListener(); splitManager.restore(); - signalManager.restore(); // Reset the number of auto-resume retries. setAutoResumeTrackRetries( @@ -1168,8 +1168,4 @@ public class TrackRecordingService extends Service implements LocationListener { public SplitManager getSplitManager() { return splitManager; } - - public TaskExecuterManager getSignalManager() { - return signalManager; - } } diff --git a/MyTracks/src/com/google/android/apps/mytracks/util/ApiFeatures.java b/MyTracks/src/com/google/android/apps/mytracks/util/ApiFeatures.java index 7979e12b5..06727cd2d 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/util/ApiFeatures.java +++ b/MyTracks/src/com/google/android/apps/mytracks/util/ApiFeatures.java @@ -107,10 +107,6 @@ public class ApiFeatures { return true; } - - public boolean hasModernSignalStrength() { - return getApiLevel() >= 7; - } // Visible for testing. protected int getApiLevel() { diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/services/SignalStrengthTaskFactoryTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/services/SignalStrengthTaskFactoryTest.java deleted file mode 100644 index e37684f64..000000000 --- a/MyTracksTest/src/com/google/android/apps/mytracks/services/SignalStrengthTaskFactoryTest.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2010 Google Inc. - * - * 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.mytracks.services; - -import com.google.android.apps.mytracks.util.ApiFeatures; - -import android.test.AndroidTestCase; - -/** - * Tests for {@link SignalStrengthTaskFactoryTest}. - * These tests require Eclair+ (API level 7) to run. - * - * @author Rodrigo Damazio - */ -public class SignalStrengthTaskFactoryTest extends AndroidTestCase { - /** - * Mock version of the {@link ApiFeatures} class. - */ - private static class MockApiFeatures extends ApiFeatures { - private boolean hasModernStrength; - - public void setHasModernSignalStrength(boolean hasModernStrength) { - this.hasModernStrength = hasModernStrength; - } - - @Override - public boolean hasModernSignalStrength() { - return hasModernStrength; - } - } - - private MockApiFeatures apiFeatures; - - @Override - protected void setUp() throws Exception { - super.setUp(); - - apiFeatures = new MockApiFeatures(); - } - - public void testCreate() { - apiFeatures.setHasModernSignalStrength(true); - SignalStrengthTaskFactory factory = - new SignalStrengthTaskFactory(apiFeatures); - - PeriodicTask task = factory.create(getContext()); - assertTrue(task.getClass().getName(), - task instanceof SignalStrengthTaskModern); - } - - public void testCreate_legacy() { - apiFeatures.setHasModernSignalStrength(false); - SignalStrengthTaskFactory factory = - new SignalStrengthTaskFactory(apiFeatures); - - PeriodicTask task = factory.create(getContext()); - assertTrue(task.getClass().getName(), task instanceof SignalStrengthTask); - } -} diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/services/TrackRecordingServiceTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/services/TrackRecordingServiceTest.java index 8b8e06669..b42b2c732 100644 --- a/MyTracksTest/src/com/google/android/apps/mytracks/services/TrackRecordingServiceTest.java +++ b/MyTracksTest/src/com/google/android/apps/mytracks/services/TrackRecordingServiceTest.java @@ -561,16 +561,6 @@ public class TrackRecordingServiceTest functionalTest(R.string.min_recording_distance_key, 2); } - @MediumTest - public void testWithProperties_noSignalSamplingFreq() throws Exception { - functionalTest(R.string.signal_sampling_frequency_key, (Object) null); - } - - @MediumTest - public void testWithProperties_defaultSignalSamplingFreq() throws Exception { - functionalTest(R.string.signal_sampling_frequency_key, 1); - } - @MediumTest public void testWithProperties_noSplitFreq() throws Exception { functionalTest(R.string.split_frequency_key, (Object) null); diff --git a/MyTracksTest/src/com/google/android/apps/mytracks/util/ApiFeaturesTest.java b/MyTracksTest/src/com/google/android/apps/mytracks/util/ApiFeaturesTest.java index f47ab6dbb..a0db9b8da 100644 --- a/MyTracksTest/src/com/google/android/apps/mytracks/util/ApiFeaturesTest.java +++ b/MyTracksTest/src/com/google/android/apps/mytracks/util/ApiFeaturesTest.java @@ -65,17 +65,6 @@ public class ApiFeaturesTest extends TestCase { } } - public void testHasModernSignalStrength() { - for (int i = 3; i <= 6; i++) { - features.setApiLevel(i); - assertFalse(features.hasModernSignalStrength()); - } - features.setApiLevel(7); - assertTrue(features.hasModernSignalStrength()); - features.setApiLevel(8); - assertTrue(features.hasModernSignalStrength()); - } - public void testGetApiPlatformAdapter() { assertNotNull(features.getApiPlatformAdapter()); } diff --git a/SignalStrengthSampler/.classpath b/SignalStrengthSampler/.classpath new file mode 100644 index 000000000..609aa00eb --- /dev/null +++ b/SignalStrengthSampler/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/SignalStrengthSampler/.project b/SignalStrengthSampler/.project new file mode 100644 index 000000000..cb1013e1b --- /dev/null +++ b/SignalStrengthSampler/.project @@ -0,0 +1,33 @@ + + + SignalStrengthSampler + + + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + diff --git a/SignalStrengthSampler/.settings/org.eclipse.jdt.core.prefs b/SignalStrengthSampler/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..77576ec3e --- /dev/null +++ b/SignalStrengthSampler/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,12 @@ +#Tue Nov 23 23:09:24 PST 2010 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/SignalStrengthSampler/AndroidManifest.xml b/SignalStrengthSampler/AndroidManifest.xml new file mode 100644 index 000000000..03d216a34 --- /dev/null +++ b/SignalStrengthSampler/AndroidManifest.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SignalStrengthSampler/default.properties b/SignalStrengthSampler/default.properties new file mode 100644 index 000000000..420db56e3 --- /dev/null +++ b/SignalStrengthSampler/default.properties @@ -0,0 +1,11 @@ +# 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 use, +# "build.properties", and override values to adapt the script to your +# project structure. + +# Project target. +target=Google Inc.:Google APIs:8 diff --git a/SignalStrengthSampler/proguard.cfg b/SignalStrengthSampler/proguard.cfg new file mode 100644 index 000000000..8ad7d3352 --- /dev/null +++ b/SignalStrengthSampler/proguard.cfg @@ -0,0 +1,34 @@ +-optimizationpasses 5 +-dontusemixedcaseclassnames +-dontskipnonpubliclibraryclasses +-dontpreverify +-verbose +-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* + +-keep public class * extends android.app.Activity +-keep public class * extends android.app.Application +-keep public class * extends android.app.Service +-keep public class * extends android.content.BroadcastReceiver +-keep public class * extends android.content.ContentProvider +-keep public class com.android.vending.licensing.ILicensingService + +-keepclasseswithmembernames class * { + native ; +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet); +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet, int); +} + +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} + +-keep class * implements android.os.Parcelable { + public static final android.os.Parcelable$Creator *; +} diff --git a/SignalStrengthSampler/res/drawable/icon.png b/SignalStrengthSampler/res/drawable/icon.png new file mode 100644 index 000000000..a07c69fa5 Binary files /dev/null and b/SignalStrengthSampler/res/drawable/icon.png differ diff --git a/SignalStrengthSampler/res/values/arrays.xml b/SignalStrengthSampler/res/values/arrays.xml new file mode 100644 index 000000000..a37bc949d --- /dev/null +++ b/SignalStrengthSampler/res/values/arrays.xml @@ -0,0 +1,41 @@ + + + + + + As often as possible + 1 min + 2 min + 5 min + 10 min + 15 min + 30 min + 60 min + + + + + -1 + 1 + 2 + 5 + 10 + 15 + 30 + 60 + + diff --git a/SignalStrengthSampler/res/values/strings.xml b/SignalStrengthSampler/res/values/strings.xml new file mode 100644 index 000000000..187f169ed --- /dev/null +++ b/SignalStrengthSampler/res/values/strings.xml @@ -0,0 +1,50 @@ + + + + Signal strength sampler for My Tracks + + Sampling settings + Automatic start + Automatically start inserting signal strength waypoints whenever My Tracks starts recording a track. + You will need to manually start signal sampling using the controls below. + Min. sampling period + Minimum time between two recordings of the phone\'s signal strength + + Sampling control + Start sampling + Starts sampling signal strength immediately, if My Tracks is recording. Sampling will stop once My Tracks stops recording. + Stop sampling + Stops sampling signal strength if sampling is currently active. + + Started sampling cell signal strength. + Stopped sampling cell signal strength. + - + + + Error Rate: %1$d + Signal to Noise Ratio: %1$d + Ec/lo: %1$.1f dB + GSM Strength: %1$d + CDMA Strength: %1$d dBm + EVDO Strength: %1$d dBm + + + autoStartSampling + signalSamplingFrequency + startSamplingControl + stopSamplingControl + diff --git a/SignalStrengthSampler/res/xml/preferences.xml b/SignalStrengthSampler/res/xml/preferences.xml new file mode 100644 index 000000000..7277d0ba0 --- /dev/null +++ b/SignalStrengthSampler/res/xml/preferences.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + diff --git a/SignalStrengthSampler/src/com/google/android/apps/mytracks/content/Waypoint.aidl b/SignalStrengthSampler/src/com/google/android/apps/mytracks/content/Waypoint.aidl new file mode 100644 index 000000000..fece6fd44 --- /dev/null +++ b/SignalStrengthSampler/src/com/google/android/apps/mytracks/content/Waypoint.aidl @@ -0,0 +1,2 @@ +package com.google.android.apps.mytracks.content; +parcelable Waypoint; \ No newline at end of file diff --git a/SignalStrengthSampler/src/com/google/android/apps/mytracks/content/Waypoint.java b/SignalStrengthSampler/src/com/google/android/apps/mytracks/content/Waypoint.java new file mode 100644 index 000000000..93cdc0e4b --- /dev/null +++ b/SignalStrengthSampler/src/com/google/android/apps/mytracks/content/Waypoint.java @@ -0,0 +1,189 @@ +/* + * Copyright 2009 Google Inc. + * + * 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.mytracks.content; + +import android.location.Location; +import android.os.Parcel; +import android.os.Parcelable; + +/** + * A way point. It has a location, meta data such as name, description, + * category, and icon, plus it can store track statistics for a "sub-track". + * + * TODO: hashCode and equals + * + * @author Leif Hendrik Wilden + * @author Rodrigo Damazio + */ +public final class Waypoint implements Parcelable { + + /** + * Creator for a Waypoint object + */ + public static class Creator implements Parcelable.Creator { + + public Waypoint createFromParcel(Parcel source) { + ClassLoader classLoader = getClass().getClassLoader(); + Waypoint waypoint = new Waypoint(); + waypoint.id = source.readLong(); + waypoint.name = source.readString(); + waypoint.description = source.readString(); + waypoint.category = source.readString(); + waypoint.icon = source.readString(); + waypoint.trackId = source.readLong(); + waypoint.type = source.readInt(); + waypoint.startId = source.readLong(); + waypoint.stopId = source.readLong(); + if (source.readByte() > 0) { + throw new UnsupportedOperationException( + "No support for reading waypoints with stats"); + } + byte hasLocation = source.readByte(); + if (hasLocation > 0) { + waypoint.location = source.readParcelable(classLoader); + } + return waypoint; + } + + public Waypoint[] newArray(int size) { + return new Waypoint[size]; + } + } + + public static final Creator CREATOR = new Creator(); + + public static final int TYPE_WAYPOINT = 0; + public static final int TYPE_STATISTICS = 1; + + private long id = -1; + private String name = ""; + private String description = ""; + private String category = ""; + private String icon = ""; + private long trackId = -1; + private int type = 0; + + private Location location; + + /** Start track point id */ + private long startId = -1; + /** Stop track point id */ + private long stopId = -1; + + public void writeToParcel(Parcel dest, int flags) { + dest.writeLong(id); + dest.writeString(name); + dest.writeString(description); + dest.writeString(category); + dest.writeString(icon); + dest.writeLong(trackId); + dest.writeInt(type); + dest.writeLong(startId); + dest.writeLong(stopId); + dest.writeByte((byte) 0); // No stats + dest.writeByte(location == null ? (byte) 0 : (byte) 1); + if (location != null) { + dest.writeParcelable(location, 0); + } + } + + // Getters and setters: + //--------------------- + + public String getIcon() { + return icon; + } + + public void setIcon(String icon) { + this.icon = icon; + } + + public Location getLocation() { + return location; + } + + public void setTrackId(long trackId) { + this.trackId = trackId; + } + + public int describeContents() { + return 0; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public long getTrackId() { + return trackId; + } + + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + public long getStartId() { + return startId; + } + + public void setStartId(long startId) { + this.startId = startId; + } + + public long getStopId() { + return stopId; + } + + public void setStopId(long stopId) { + this.stopId = stopId; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getCategory() { + return category; + } + + public void setCategory(String category) { + this.category = category; + } + + public void setLocation(Location location) { + this.location = location; + } +} diff --git a/SignalStrengthSampler/src/com/google/android/apps/mytracks/services/ITrackRecordingService.aidl b/SignalStrengthSampler/src/com/google/android/apps/mytracks/services/ITrackRecordingService.aidl new file mode 100644 index 000000000..d0e492563 --- /dev/null +++ b/SignalStrengthSampler/src/com/google/android/apps/mytracks/services/ITrackRecordingService.aidl @@ -0,0 +1,87 @@ +/* + * Copyright 2008 Google Inc. + * + * 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.mytracks.services; + +import com.google.android.apps.mytracks.content.Waypoint; + +/** + * MyTracks service. + * This service is the process that actually records and manages tracks. + */ +interface ITrackRecordingService { + + /** + * Starts recording a new track. + * + * @return the track ID of the new track + */ + long startNewTrack(); + + /** + * Checks and returns whether we're currently recording a track. + */ + boolean isRecording(); + + /** + * Returns the track ID of the track currently being recorded, or -1 if none + * is being recorded. This ID can then be used to read track data from the + * content source. + */ + long getRecordingTrackId(); + + /** + * Inserts a waypoint marker in the track being recorded. + * + * @param waypoint the waypoint to insert + * @return the unique ID of the inserted marker + */ + long insertWaypointMarker(in Waypoint waypoint); + + /** + * Inserts a statistics marker in the track being recorded. + * + * @param location the location at which to insert the marker + * @return the unique ID of the inserted marker + */ + long insertStatisticsMarker(in Location location); + + /** + * Inserts a location in the track being recorded. + * + * When recording, locations detected by the GPS are already automatically + * added to the track, so this should be used only for adding special points + * or for testing. + * + * @param loc the location to insert + */ + void recordLocation(in Location loc); + + /** + * Stops recording the current track. + */ + void endCurrentTrack(); + + /** + * Returns whether at least one track has been or is being recorded (and was + * not deleted). + */ + boolean hasRecorded(); + + /** + * Deletes all the stored tracks. + */ + void deleteAllTracks(); +} diff --git a/SignalStrengthSampler/src/com/google/android/apps/mytracks/signalstrength/RecordingStateReceiver.java b/SignalStrengthSampler/src/com/google/android/apps/mytracks/signalstrength/RecordingStateReceiver.java new file mode 100644 index 000000000..8ac6351f1 --- /dev/null +++ b/SignalStrengthSampler/src/com/google/android/apps/mytracks/signalstrength/RecordingStateReceiver.java @@ -0,0 +1,61 @@ +/* + * Copyright 2010 Google Inc. + * + * 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.mytracks.signalstrength; + +import static com.google.android.apps.mytracks.signalstrength.SignalStrengthConstants.*; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; +import android.util.Log; + +/** + * Broadcast listener which gets notified when we start or stop recording a track. + * + * @author Rodrigo Damazio + */ +public class RecordingStateReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context ctx, Intent intent) { + SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(ctx); + boolean autoStart = preferences.getBoolean( + ctx.getString(R.string.settings_auto_start_key), false); + if (!autoStart) { + Log.d(TAG, "Not auto-starting signal sampling"); + return; + } + + String action = intent.getAction(); + if (START_TRACK_ACTION.equals(action) || RESUME_TRACK_ACTION.equals(action)) { + startService(ctx); + } else if (STOP_TRACK_ACTION.equals(action) || PAUSE_TRACK_ACTION.equals(action)) { + stopService(ctx); + } else { + Log.e(TAG, "Unknown action received: " + action); + } + } + + // @VisibleForTesting + protected void stopService(Context ctx) { + SignalStrengthService.stopService(ctx); + } + + // @VisibleForTesting + protected void startService(Context ctx) { + SignalStrengthService.startService(ctx); + } +} diff --git a/SignalStrengthSampler/src/com/google/android/apps/mytracks/signalstrength/SignalStrengthConstants.java b/SignalStrengthSampler/src/com/google/android/apps/mytracks/signalstrength/SignalStrengthConstants.java new file mode 100644 index 000000000..f4bd6a7ff --- /dev/null +++ b/SignalStrengthSampler/src/com/google/android/apps/mytracks/signalstrength/SignalStrengthConstants.java @@ -0,0 +1,56 @@ +/* + * Copyright 2010 Google Inc. + * + * 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.mytracks.signalstrength; + +import android.content.ComponentName; +import android.os.Build; + +/** + * Constants for the signal sampler. + * + * @author Rodrigo Damazio + */ +public class SignalStrengthConstants { + // TODO: Many of these could be moved into a common library for third-party apps + public static final String START_TRACK_ACTION = + "com.google.android.apps.mytracks.TRACK_STARTED"; + public static final String PAUSE_TRACK_ACTION = + "com.google.android.apps.mytracks.TRACK_PAUSED"; + public static final String RESUME_TRACK_ACTION = + "com.google.android.apps.mytracks.TRACK_RESUMED"; + public static final String STOP_TRACK_ACTION = + "com.google.android.apps.mytracks.TRACK_STOPPED"; + public static final String TRACK_ID_EXTRA = + "com.google.android.apps.mytracks.TRACK_ID"; + public static final String MYTRACKS_SERVICE = + "com.google.android.apps.mytracks.services.TrackRecordingService"; + public static final String MYTRACKS_SERVICE_PACKAGE = + "com.google.android.maps.mytracks"; + public static final ComponentName MYTRACKS_SERVICE_COMPONENT = + new ComponentName(MYTRACKS_SERVICE_PACKAGE, MYTRACKS_SERVICE); + + public static final String START_SAMPLING = + "com.google.android.apps.mytracks.signalstrength.START"; + public static final String STOP_SAMPLING = + "com.google.android.apps.mytracks.signalstrength.STOP"; + + public static final int ANDROID_API_LEVEL = Integer.parseInt( + Build.VERSION.SDK); + + public static final String TAG = "SignalStrengthSampler"; + + private SignalStrengthConstants() {} +} diff --git a/SignalStrengthSampler/src/com/google/android/apps/mytracks/signalstrength/SignalStrengthListener.java b/SignalStrengthSampler/src/com/google/android/apps/mytracks/signalstrength/SignalStrengthListener.java new file mode 100644 index 000000000..e65da532d --- /dev/null +++ b/SignalStrengthSampler/src/com/google/android/apps/mytracks/signalstrength/SignalStrengthListener.java @@ -0,0 +1,42 @@ +/* + * Copyright 2010 Google Inc. + * + * 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.mytracks.signalstrength; + +/** + * Interface for the service that reads signal strength. + * + * @author Rodrigo Damazio + */ +public interface SignalStrengthListener { + /** + * Interface for getting notified about a new sampled signal strength. + */ + public interface SignalStrengthCallback { + void onSignalStrengthSampled( + String description, + String icon); + } + + /** + * Starts listening to signal strength. + */ + void register(); + + /** + * Stops listening to signal strength. + */ + void unregister(); +} diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/SignalStrengthTask.java b/SignalStrengthSampler/src/com/google/android/apps/mytracks/signalstrength/SignalStrengthListenerCupcake.java similarity index 68% rename from MyTracks/src/com/google/android/apps/mytracks/services/SignalStrengthTask.java rename to SignalStrengthSampler/src/com/google/android/apps/mytracks/signalstrength/SignalStrengthListenerCupcake.java index 3d6017f74..4fdb68a80 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/services/SignalStrengthTask.java +++ b/SignalStrengthSampler/src/com/google/android/apps/mytracks/signalstrength/SignalStrengthListenerCupcake.java @@ -13,14 +13,11 @@ * License for the specific language governing permissions and limitations under * the License. */ +package com.google.android.apps.mytracks.signalstrength; -package com.google.android.apps.mytracks.services; - -import com.google.android.apps.mytracks.MyTracksConstants; -import com.google.android.apps.mytracks.content.Waypoint; +import static com.google.android.apps.mytracks.signalstrength.SignalStrengthConstants.*; import android.content.Context; -import android.location.Location; import android.telephony.CellLocation; import android.telephony.NeighboringCellInfo; import android.telephony.PhoneStateListener; @@ -31,67 +28,49 @@ import java.util.List; /** * A class to monitor the network signal strength. + * + * TODO: i18n * * @author Sandor Dornbush */ -public class SignalStrengthTask extends PhoneStateListener - implements PeriodicTask { - +public class SignalStrengthListenerCupcake extends PhoneStateListener + implements SignalStrengthListener { private final Context context; + private final SignalStrengthCallback callback; + private TelephonyManager manager; private int signalStrength = -1; - public SignalStrengthTask(Context c) { - context = c; + public SignalStrengthListenerCupcake(Context context, SignalStrengthCallback callback) { + this.context = context; + this.callback = callback; } @Override - public void start() { - manager = - (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); + public void register() { + manager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); if (manager == null) { - Log.e(MyTracksConstants.TAG, "Cannot get telephony manager."); + Log.e(TAG, "Cannot get telephony manager."); } else { manager.listen(this, getListenEvents()); } } protected int getListenEvents() { - return PhoneStateListener.LISTEN_SIGNAL_STRENGTHS; + return PhoneStateListener.LISTEN_SIGNAL_STRENGTH; } @Override - public void onSignalStrengthChanged(int asu) { - this.signalStrength = asu; - Log.d(MyTracksConstants.TAG, "Signal Strength: " + signalStrength); + public void onSignalStrengthChanged(int signalStrength) { + Log.d(TAG, "Signal Strength: " + signalStrength); + this.signalStrength = signalStrength; + + notifySignalSampled(); } - @Override - public void run(TrackRecordingService service) { - Log.d(MyTracksConstants.TAG, "Adding signal marker"); - Location location = service.getLastLocation(); - if (manager == null) { - Log.d(MyTracksConstants.TAG, "Adding signal marker: marker null"); - return; - } - if (location == null) { - Log.d(MyTracksConstants.TAG, "Adding signal marker: location null"); - return; - } - Waypoint wpt = new Waypoint(); - wpt.setName("Signal Strength"); - wpt.setType(Waypoint.TYPE_WAYPOINT); - wpt.setTrackId(service.getRecordingTrackId()); + protected void notifySignalSampled() { int networkType = manager.getNetworkType(); - wpt.setIcon(getIcon(networkType)); - wpt.setLocation(location); - wpt.setDescription(getDescription()); - long waypointId = service.insertWaypointMarker(wpt); - if (waypointId >= 0) { - Log.d(MyTracksConstants.TAG, "Added signal marker"); - } else { - Log.e(MyTracksConstants.TAG, "Cannot insert waypoint marker?"); - } + callback.onSignalStrengthSampled(getDescription(), getIcon(networkType)); } /** @@ -138,7 +117,7 @@ public class SignalStrengthTask extends PhoneStateListener sb.append('\n'); List infos = manager.getNeighboringCellInfo(); - Log.i(MyTracksConstants.TAG, "Found " + infos.size() + " cells."); + Log.i(TAG, "Found " + infos.size() + " cells."); if (infos.size() > 0) { sb.append("Neighbors: "); for (NeighboringCellInfo info : infos) { @@ -178,7 +157,7 @@ public class SignalStrengthTask extends PhoneStateListener } @Override - public void shutdown() { + public void unregister() { if (manager != null) { manager.listen(this, PhoneStateListener.LISTEN_NONE); manager = null; @@ -192,4 +171,8 @@ public class SignalStrengthTask extends PhoneStateListener protected Context getContext() { return context; } + + public SignalStrengthCallback getSignalStrengthCallback() { + return callback; + } } diff --git a/MyTracks/src/com/google/android/apps/mytracks/services/SignalStrengthTaskModern.java b/SignalStrengthSampler/src/com/google/android/apps/mytracks/signalstrength/SignalStrengthListenerEclair.java similarity index 91% rename from MyTracks/src/com/google/android/apps/mytracks/services/SignalStrengthTaskModern.java rename to SignalStrengthSampler/src/com/google/android/apps/mytracks/signalstrength/SignalStrengthListenerEclair.java index 12c6f74ee..f5f0e2d00 100644 --- a/MyTracks/src/com/google/android/apps/mytracks/services/SignalStrengthTaskModern.java +++ b/SignalStrengthSampler/src/com/google/android/apps/mytracks/signalstrength/SignalStrengthListenerEclair.java @@ -14,10 +14,9 @@ * the License. */ -package com.google.android.apps.mytracks.services; +package com.google.android.apps.mytracks.signalstrength; -import com.google.android.apps.mytracks.MyTracksConstants; -import com.google.android.maps.mytracks.R; +import static com.google.android.apps.mytracks.signalstrength.SignalStrengthConstants.*; import android.content.Context; import android.telephony.PhoneStateListener; @@ -27,15 +26,17 @@ import android.util.Log; /** * A class to monitor the network signal strength. + * + * TODO: i18n * * @author Sandor Dornbush */ -public class SignalStrengthTaskModern extends SignalStrengthTask { +public class SignalStrengthListenerEclair extends SignalStrengthListenerCupcake { private SignalStrength signalStrength = null; - public SignalStrengthTaskModern(Context c) { - super(c); + public SignalStrengthListenerEclair(Context ctx, SignalStrengthCallback callback) { + super(ctx, callback); } @Override @@ -43,6 +44,13 @@ public class SignalStrengthTaskModern extends SignalStrengthTask { return PhoneStateListener.LISTEN_SIGNAL_STRENGTHS; } + @Override + public void onSignalStrengthsChanged(SignalStrength signalStrength) { + Log.d(TAG, "Signal Strength Modern: " + signalStrength); + this.signalStrength = signalStrength; + notifySignalSampled(); + } + /** * Gets a human readable description for the network type. * @@ -146,10 +154,4 @@ public class SignalStrengthTaskModern extends SignalStrengthTask { sb.append(getContext().getString(signalFormat, signal)); sb.append("\n"); } - - @Override - public void onSignalStrengthsChanged(SignalStrength signalStrength) { - Log.d(MyTracksConstants.TAG, "Signal Strength Modern: " + signalStrength); - this.signalStrength = signalStrength; - } } diff --git a/SignalStrengthSampler/src/com/google/android/apps/mytracks/signalstrength/SignalStrengthListenerFactory.java b/SignalStrengthSampler/src/com/google/android/apps/mytracks/signalstrength/SignalStrengthListenerFactory.java new file mode 100644 index 000000000..1272b321a --- /dev/null +++ b/SignalStrengthSampler/src/com/google/android/apps/mytracks/signalstrength/SignalStrengthListenerFactory.java @@ -0,0 +1,47 @@ +/* + * Copyright 2010 Google Inc. + * + * 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.mytracks.signalstrength; + +import static com.google.android.apps.mytracks.signalstrength.SignalStrengthConstants.*; + +import com.google.android.apps.mytracks.signalstrength.SignalStrengthListener.SignalStrengthCallback; + +import android.content.Context; +import android.util.Log; + +/** + * Factory for producing a proper {@link SignalStrengthListenerCupcake} according to the + * current API level. + * + * @author Rodrigo Damazio + */ +public class SignalStrengthListenerFactory { + + public SignalStrengthListener create(Context context, SignalStrengthCallback callback) { + if (hasModernSignalStrength()) { + Log.d(TAG, "TrackRecordingService using modern signal strength api."); + return new SignalStrengthListenerEclair(context, callback); + } else { + Log.w(TAG, "TrackRecordingService using legacy signal strength api."); + return new SignalStrengthListenerCupcake(context, callback); + } + } + + // @VisibleForTesting + protected boolean hasModernSignalStrength() { + return ANDROID_API_LEVEL >= 7; + } +} diff --git a/SignalStrengthSampler/src/com/google/android/apps/mytracks/signalstrength/SignalStrengthPreferences.java b/SignalStrengthSampler/src/com/google/android/apps/mytracks/signalstrength/SignalStrengthPreferences.java new file mode 100644 index 000000000..0096ee4a0 --- /dev/null +++ b/SignalStrengthSampler/src/com/google/android/apps/mytracks/signalstrength/SignalStrengthPreferences.java @@ -0,0 +1,53 @@ +/* + * Copyright 2010 Google Inc. + * + * 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.mytracks.signalstrength; + +import android.os.Bundle; +import android.preference.Preference; +import android.preference.Preference.OnPreferenceClickListener; +import android.preference.PreferenceActivity; + +/** + * Main signal strength sampler activity, which displays preferences. + * + * @author Rodrigo Damazio + */ +public class SignalStrengthPreferences extends PreferenceActivity { + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + addPreferencesFromResource(R.xml.preferences); + + // Attach service control funciontality + findPreference(getString(R.string.settings_control_start_key)) + .setOnPreferenceClickListener(new OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + SignalStrengthService.startService(SignalStrengthPreferences.this); + return true; + } + }); + findPreference(getString(R.string.settings_control_stop_key)) + .setOnPreferenceClickListener(new OnPreferenceClickListener() { + @Override + public boolean onPreferenceClick(Preference preference) { + SignalStrengthService.stopService(SignalStrengthPreferences.this); + return true; + } + }); + } +} \ No newline at end of file diff --git a/SignalStrengthSampler/src/com/google/android/apps/mytracks/signalstrength/SignalStrengthService.java b/SignalStrengthSampler/src/com/google/android/apps/mytracks/signalstrength/SignalStrengthService.java new file mode 100644 index 000000000..1be7182aa --- /dev/null +++ b/SignalStrengthSampler/src/com/google/android/apps/mytracks/signalstrength/SignalStrengthService.java @@ -0,0 +1,248 @@ +/* + * Copyright 2010 Google Inc. + * + * 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.mytracks.signalstrength; + +import static com.google.android.apps.mytracks.signalstrength.SignalStrengthConstants.*; + +import com.google.android.apps.mytracks.content.Waypoint; +import com.google.android.apps.mytracks.services.ITrackRecordingService; +import com.google.android.apps.mytracks.signalstrength.SignalStrengthListener.SignalStrengthCallback; + +import android.app.ActivityManager; +import android.app.ActivityManager.RunningServiceInfo; +import android.app.Service; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.ServiceConnection; +import android.content.SharedPreferences; +import android.content.SharedPreferences.OnSharedPreferenceChangeListener; +import android.os.IBinder; +import android.os.RemoteException; +import android.preference.PreferenceManager; +import android.util.Log; +import android.widget.Toast; + +import java.util.List; + +/** + * Serivce which actually reads signal strength and sends it to My Tracks. + * + * @author Rodrigo Damazio + */ +public class SignalStrengthService extends Service + implements ServiceConnection, SignalStrengthCallback, OnSharedPreferenceChangeListener { + + private SignalStrengthListener signalListener; + private ITrackRecordingService mytracksService; + private long lastSamplingTime; + private long samplingPeriod; + + @Override + public void onStart(Intent intent, int startId) { + handleCommand(intent, startId); + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + handleCommand(intent, startId); + return START_STICKY; + } + + private void handleCommand(Intent intent, int startId) { + String action = intent.getAction(); + if (START_SAMPLING.equals(action)) { + startSampling(); + } else { + stopSampling(); + } + } + + private void startSampling() { + // TODO: Start foreground + + if (!isMytracksRunning()) { + Log.w(TAG, "My Tracks not running!"); + return; + } + + Log.d(TAG, "Starting sampling"); + Intent intent = new Intent(); + intent.setComponent(MYTRACKS_SERVICE_COMPONENT); + if (!bindService(intent, SignalStrengthService.this, 0)) { + Log.e(TAG, "Couldn't bind to service."); + return; + } + } + + private boolean isMytracksRunning() { + ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE); + List services = activityManager.getRunningServices(Integer.MAX_VALUE); + for (RunningServiceInfo serviceInfo : services) { + if (serviceInfo.pid != 0 && + serviceInfo.service.equals(MYTRACKS_SERVICE_COMPONENT)) { + return true; + } + } + return false; + } + + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + synchronized (this) { + mytracksService = ITrackRecordingService.Stub.asInterface(service); + + Log.d(TAG, "Bound to My Tracks"); + + boolean recording = false; + try { + recording = mytracksService.isRecording(); + } catch (RemoteException e) { + Log.e(TAG, "Failed to talk to my tracks", e); + } + if (!recording) { + Log.w(TAG, "My Tracks is not recording, bailing"); + stopSampling(); + return; + } + + // We're ready to send waypoints, so register for signal sampling + SignalStrengthListenerFactory factory = new SignalStrengthListenerFactory(); + signalListener = factory.create(this, this); + signalListener.register(); + + // Register for preference changes + SharedPreferences preferences = + PreferenceManager.getDefaultSharedPreferences(this); + samplingPeriod = Long.parseLong(preferences.getString( + getString(R.string.settings_min_signal_sampling_period_key), "-1")); + preferences.registerOnSharedPreferenceChangeListener(this); + + // Tell the user we've started. + Toast.makeText(this, R.string.started_sampling, Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onSignalStrengthSampled(String description, String icon) { + long now = System.currentTimeMillis(); + if (now - lastSamplingTime < samplingPeriod * 60 * 1000) { + return; + } + + // We don't set location or track id - My Tracks can fill those + Waypoint wpt = new Waypoint(); + wpt.setName("Signal Strength"); + wpt.setType(Waypoint.TYPE_WAYPOINT); + wpt.setIcon(icon); + wpt.setDescription(description); + + try { + long waypointId; + synchronized (this) { + if (mytracksService == null) { + Log.d(TAG, "No my tracks service to send to"); + return; + } + + waypointId = mytracksService.insertWaypointMarker(wpt); + } + + if (waypointId >= 0) { + Log.d(TAG, "Added signal marker"); + lastSamplingTime = now; + } else { + Log.e(TAG, "Cannot insert waypoint marker?"); + } + } catch (RemoteException e) { + Log.e(TAG, "Cannot talk to my tracks service", e); + } + } + + private void stopSampling() { + Log.d(TAG, "Stopping sampling"); + + synchronized (this) { + // Unregister from preference change updates + SharedPreferences preferences = + PreferenceManager.getDefaultSharedPreferences(this); + preferences.unregisterOnSharedPreferenceChangeListener(this); + + // Unregister from receiving signal updates + if (signalListener != null) { + signalListener.unregister(); + signalListener = null; + } + + // Unbind from My Tracks + if (mytracksService != null) { + unbindService(this); + mytracksService = null; + } + + // Reset the last sampling time + lastSamplingTime = 0; + + // Tell the user we've stopped + Toast.makeText(this, R.string.stopped_sampling, Toast.LENGTH_SHORT).show(); + + // Stop + stopSelf(); + } + } + + @Override + public void onServiceDisconnected(ComponentName name) { + Log.i(TAG, "Disconnected from My Tracks"); + synchronized (this) { + mytracksService = null; + } + } + + @Override + public void onDestroy() { + stopSampling(); + + super.onDestroy(); + } + + @Override + public IBinder onBind(Intent intent) { + return null; + } + + public static void startService(Context context) { + Intent intent = new Intent(); + intent.setClass(context, SignalStrengthService.class); + intent.setAction(START_SAMPLING); + context.startService(intent); + } + + public static void stopService(Context context) { + Intent intent = new Intent(); + intent.setClass(context, SignalStrengthService.class); + intent.setAction(STOP_SAMPLING); + context.startService(intent); + } + + @Override + public void onSharedPreferenceChanged( + SharedPreferences sharedPreferences, String key) { + if (getString(R.string.settings_min_signal_sampling_period_key).equals(key)) { + samplingPeriod = Long.parseLong(sharedPreferences.getString(key, "-1")); + } + } +} diff --git a/SignalStrengthSamplerTest/.classpath b/SignalStrengthSamplerTest/.classpath new file mode 100644 index 000000000..bee7810d7 --- /dev/null +++ b/SignalStrengthSamplerTest/.classpath @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/SignalStrengthSamplerTest/.project b/SignalStrengthSamplerTest/.project new file mode 100644 index 000000000..2b5c9679d --- /dev/null +++ b/SignalStrengthSamplerTest/.project @@ -0,0 +1,34 @@ + + + SignalStrengthSamplerTest + + + SignalStrengthSampler + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + diff --git a/SignalStrengthSamplerTest/.settings/org.eclipse.jdt.core.prefs b/SignalStrengthSamplerTest/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..db1e1ea37 --- /dev/null +++ b/SignalStrengthSamplerTest/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,5 @@ +#Fri Nov 26 22:23:21 PST 2010 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.source=1.5 diff --git a/SignalStrengthSamplerTest/AndroidManifest.xml b/SignalStrengthSamplerTest/AndroidManifest.xml new file mode 100644 index 000000000..81a878083 --- /dev/null +++ b/SignalStrengthSamplerTest/AndroidManifest.xml @@ -0,0 +1,12 @@ + + + + + + + + \ No newline at end of file diff --git a/SignalStrengthSamplerTest/default.properties b/SignalStrengthSamplerTest/default.properties new file mode 100644 index 000000000..420db56e3 --- /dev/null +++ b/SignalStrengthSamplerTest/default.properties @@ -0,0 +1,11 @@ +# 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 use, +# "build.properties", and override values to adapt the script to your +# project structure. + +# Project target. +target=Google Inc.:Google APIs:8 diff --git a/SignalStrengthSamplerTest/libs/AndroidMockRuntime.jar b/SignalStrengthSamplerTest/libs/AndroidMockRuntime.jar new file mode 100644 index 000000000..40fa9e173 Binary files /dev/null and b/SignalStrengthSamplerTest/libs/AndroidMockRuntime.jar differ diff --git a/SignalStrengthSamplerTest/proguard.cfg b/SignalStrengthSamplerTest/proguard.cfg new file mode 100644 index 000000000..8ad7d3352 --- /dev/null +++ b/SignalStrengthSamplerTest/proguard.cfg @@ -0,0 +1,34 @@ +-optimizationpasses 5 +-dontusemixedcaseclassnames +-dontskipnonpubliclibraryclasses +-dontpreverify +-verbose +-optimizations !code/simplification/arithmetic,!field/*,!class/merging/* + +-keep public class * extends android.app.Activity +-keep public class * extends android.app.Application +-keep public class * extends android.app.Service +-keep public class * extends android.content.BroadcastReceiver +-keep public class * extends android.content.ContentProvider +-keep public class com.android.vending.licensing.ILicensingService + +-keepclasseswithmembernames class * { + native ; +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet); +} + +-keepclasseswithmembernames class * { + public (android.content.Context, android.util.AttributeSet, int); +} + +-keepclassmembers enum * { + public static **[] values(); + public static ** valueOf(java.lang.String); +} + +-keep class * implements android.os.Parcelable { + public static final android.os.Parcelable$Creator *; +} diff --git a/SignalStrengthSamplerTest/res/values/strings.xml b/SignalStrengthSamplerTest/res/values/strings.xml new file mode 100644 index 000000000..1d9464eb2 --- /dev/null +++ b/SignalStrengthSamplerTest/res/values/strings.xml @@ -0,0 +1,19 @@ + + + + Hello World! + diff --git a/SignalStrengthSamplerTest/src/com/google/android/apps/mytracks/signalstrength/test/SignalStrengthListenerFactoryTest.java b/SignalStrengthSamplerTest/src/com/google/android/apps/mytracks/signalstrength/test/SignalStrengthListenerFactoryTest.java new file mode 100644 index 000000000..2e26be26a --- /dev/null +++ b/SignalStrengthSamplerTest/src/com/google/android/apps/mytracks/signalstrength/test/SignalStrengthListenerFactoryTest.java @@ -0,0 +1,68 @@ +/* + * Copyright 2010 Google Inc. + * + * 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.mytracks.signalstrength.test; + +import com.google.android.apps.mytracks.signalstrength.SignalStrengthListener; +import com.google.android.apps.mytracks.signalstrength.SignalStrengthListener.SignalStrengthCallback; +import com.google.android.apps.mytracks.signalstrength.SignalStrengthListenerCupcake; +import com.google.android.apps.mytracks.signalstrength.SignalStrengthListenerEclair; +import com.google.android.apps.mytracks.signalstrength.SignalStrengthListenerFactory; +import com.google.android.testing.mocking.AndroidMock; + +import android.test.AndroidTestCase; + +/** + * Tests for {@link SignalStrengthListenerFactory}. + * These tests require Eclair+ (API level 7) to run. + * + * @author Rodrigo Damazio + */ +public class SignalStrengthListenerFactoryTest extends AndroidTestCase { + private boolean hasModernSignalStrength; + private TestableSignalStrengthListenerFactory factory; + private SignalStrengthCallback callback; + + private class TestableSignalStrengthListenerFactory extends SignalStrengthListenerFactory { + @Override + protected boolean hasModernSignalStrength() { + return hasModernSignalStrength; + } + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + + factory = new TestableSignalStrengthListenerFactory(); + callback = AndroidMock.createMock(SignalStrengthCallback.class); + } + + public void testCreate_eclair() { + hasModernSignalStrength = true; + + SignalStrengthListener listener = factory.create(getContext(), callback); + assertTrue(listener.getClass().getName(), + listener instanceof SignalStrengthListenerEclair); + } + + public void testCreate_legacy() { + hasModernSignalStrength = false; + + SignalStrengthListener listener = factory.create(getContext(), callback); + assertTrue(listener.getClass().getName(), + listener instanceof SignalStrengthListenerCupcake); + } +}