From 27acc1255cfe6ebfa4b69f92bb35aa72c1d31e12 Mon Sep 17 00:00:00 2001 From: John David Taylor Date: Thu, 30 Dec 2021 13:45:17 -0500 Subject: [PATCH] More Kotlinization. (#450) * Make things more kotlin-ey in the Application Module. * Went a bit overboard with the Kotlinizing - return types need to be explicit for dagger in some places. * It mostly doesn't matter if analytics is null, so silently skip if that's the case. * More auto-Kotlin conversion. * More auto Kotlin conversion. * Minor clean up of some imports. Boy this code is unnecessarily complex. Why did I decide I wanted a factory here? * More auto-converted stuff. Search package this time. * More auto-kotlin conversions and some clean up. This time the touch code. * Kotlinizing more utils functions. * Restore the Java sensor smoother code for now to avoid a merge conflict. * Converting the AnalyticsInterface to Kotlin broke the build. Only the FDroid build, for reasons I don't understand. Revert for now. --- app/build.gradle | 4 +- .../android/stardroid/ApplicationModule.kt | 68 ++----- .../android/stardroid/StardroidApplication.kt | 54 +++--- .../activities/DynamicStarMapActivity.java | 9 +- .../activities/ImageDisplayActivity.java | 6 +- .../activities/ImageGalleryActivity.java | 4 +- .../MultipleSearchResultsDialogFragment.java | 2 +- .../gallery/{Gallery.java => Gallery.kt} | 11 +- ...{GalleryFactory.java => GalleryFactory.kt} | 22 +-- .../{GalleryImage.java => GalleryImage.kt} | 15 +- ...dcodedGallery.java => HardcodedGallery.kt} | 113 ++++++----- .../{HasComponent.java => HasComponent.kt} | 8 +- .../android/stardroid/inject/PerActivity.java | 10 - .../android/stardroid/inject/PerActivity.kt | 7 + .../android/stardroid/search/PrefixStore.java | 100 ---------- .../android/stardroid/search/PrefixStore.kt | 91 +++++++++ .../{SearchResult.java => SearchResult.kt} | 38 ++-- .../stardroid/search/SearchTermsProvider.java | 179 ----------------- .../stardroid/search/SearchTermsProvider.kt | 159 +++++++++++++++ .../stardroid/sensors/SensorModelAdaptor.java | 31 --- .../stardroid/sensors/SensorModelAdaptor.kt | 21 ++ ....java => DragRotateZoomGestureDetector.kt} | 183 ++++++++---------- .../android/stardroid/touch/Flinger.java | 76 -------- .../google/android/stardroid/touch/Flinger.kt | 71 +++++++ .../stardroid/touch/GestureInterpreter.java | 80 -------- .../stardroid/touch/GestureInterpreter.kt | 74 +++++++ .../android/stardroid/touch/MapMover.java | 70 ------- .../android/stardroid/touch/MapMover.kt | 64 ++++++ .../util/{FixedPoint.java => FixedPoint.kt} | 19 +- .../PreferenceChangeAnalyticsTracker.java | 95 --------- .../util/PreferenceChangeAnalyticsTracker.kt | 87 +++++++++ .../stardroid/util/SensorAccuracyMonitor.java | 110 ----------- .../stardroid/util/SensorAccuracyMonitor.kt | 106 ++++++++++ .../android/stardroid/util/Toaster.java | 28 --- .../google/android/stardroid/util/Toaster.kt | 20 ++ .../views/source/ViewSourceListener.java | 76 -------- 36 files changed, 942 insertions(+), 1169 deletions(-) rename app/src/main/java/com/google/android/stardroid/gallery/{Gallery.java => Gallery.kt} (82%) rename app/src/main/java/com/google/android/stardroid/gallery/{GalleryFactory.java => GalleryFactory.kt} (70%) rename app/src/main/java/com/google/android/stardroid/gallery/{GalleryImage.java => GalleryImage.kt} (68%) rename app/src/main/java/com/google/android/stardroid/gallery/{HardcodedGallery.java => HardcodedGallery.kt} (54%) rename app/src/main/java/com/google/android/stardroid/inject/{HasComponent.java => HasComponent.kt} (51%) delete mode 100644 app/src/main/java/com/google/android/stardroid/inject/PerActivity.java create mode 100644 app/src/main/java/com/google/android/stardroid/inject/PerActivity.kt delete mode 100644 app/src/main/java/com/google/android/stardroid/search/PrefixStore.java create mode 100644 app/src/main/java/com/google/android/stardroid/search/PrefixStore.kt rename app/src/main/java/com/google/android/stardroid/search/{SearchResult.java => SearchResult.kt} (54%) delete mode 100644 app/src/main/java/com/google/android/stardroid/search/SearchTermsProvider.java create mode 100644 app/src/main/java/com/google/android/stardroid/search/SearchTermsProvider.kt delete mode 100644 app/src/main/java/com/google/android/stardroid/sensors/SensorModelAdaptor.java create mode 100644 app/src/main/java/com/google/android/stardroid/sensors/SensorModelAdaptor.kt rename app/src/main/java/com/google/android/stardroid/touch/{DragRotateZoomGestureDetector.java => DragRotateZoomGestureDetector.kt} (51%) delete mode 100644 app/src/main/java/com/google/android/stardroid/touch/Flinger.java create mode 100644 app/src/main/java/com/google/android/stardroid/touch/Flinger.kt delete mode 100644 app/src/main/java/com/google/android/stardroid/touch/GestureInterpreter.java create mode 100644 app/src/main/java/com/google/android/stardroid/touch/GestureInterpreter.kt delete mode 100644 app/src/main/java/com/google/android/stardroid/touch/MapMover.java create mode 100644 app/src/main/java/com/google/android/stardroid/touch/MapMover.kt rename app/src/main/java/com/google/android/stardroid/util/{FixedPoint.java => FixedPoint.kt} (65%) delete mode 100644 app/src/main/java/com/google/android/stardroid/util/PreferenceChangeAnalyticsTracker.java create mode 100644 app/src/main/java/com/google/android/stardroid/util/PreferenceChangeAnalyticsTracker.kt delete mode 100644 app/src/main/java/com/google/android/stardroid/util/SensorAccuracyMonitor.java create mode 100644 app/src/main/java/com/google/android/stardroid/util/SensorAccuracyMonitor.kt delete mode 100644 app/src/main/java/com/google/android/stardroid/util/Toaster.java create mode 100644 app/src/main/java/com/google/android/stardroid/util/Toaster.kt delete mode 100644 app/src/main/java/com/google/android/stardroid/views/source/ViewSourceListener.java diff --git a/app/build.gradle b/app/build.gradle index a8a738acc..f5425d044 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -85,10 +85,12 @@ android { dependencies { implementation project(path: ':datamodel') + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" // Android support implementation 'androidx.appcompat:appcompat:1.4.0' implementation 'androidx.preference:preference:1.1.1' + implementation "androidx.core:core-ktx:1.7.0" // Third-party implementation 'com.google.guava:guava:30.1.1-jre' @@ -121,8 +123,6 @@ dependencies { androidTestImplementation 'org.hamcrest:hamcrest-library:1.3' // Optional -- UI testing with Espresso androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' - implementation "androidx.core:core-ktx:1.7.0" - implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" // Optional -- UI testing with UI Automator // androidTestImplementation 'androidx.test.uiautomator:uiautomator:2.2.0' } diff --git a/app/src/main/java/com/google/android/stardroid/ApplicationModule.kt b/app/src/main/java/com/google/android/stardroid/ApplicationModule.kt index 87d178c47..7730efe2e 100644 --- a/app/src/main/java/com/google/android/stardroid/ApplicationModule.kt +++ b/app/src/main/java/com/google/android/stardroid/ApplicationModule.kt @@ -9,7 +9,7 @@ import android.hardware.SensorManager import android.location.LocationManager import android.net.ConnectivityManager import android.util.Log -import androidx.core.content.ContextCompat +import androidx.core.content.getSystemService import androidx.preference.PreferenceManager import com.google.android.stardroid.control.* import com.google.android.stardroid.layers.* @@ -18,7 +18,6 @@ import com.google.android.stardroid.util.AnalyticsInterface import com.google.android.stardroid.util.MiscUtil.getTag import dagger.Module import dagger.Provides -import java.util.concurrent.ExecutorService import java.util.concurrent.ScheduledThreadPoolExecutor import javax.inject.Named import javax.inject.Singleton @@ -28,96 +27,66 @@ import javax.inject.Singleton * Created by johntaylor on 3/26/16. */ @Module -class ApplicationModule(app: StardroidApplication) { - private val app: StardroidApplication +class ApplicationModule(private val app: StardroidApplication) { @Provides @Singleton - fun provideApplication(): StardroidApplication { - return app - } + fun provideApplication() = app @Provides - fun provideContext(): Context { - return app - } + fun provideContext(): Context = app @Provides @Singleton - fun provideSharedPreferences(): SharedPreferences { - Log.d(TAG, "Providing shared preferences") - return PreferenceManager.getDefaultSharedPreferences(app) - } + fun provideSharedPreferences() = PreferenceManager.getDefaultSharedPreferences(app) @Provides @Singleton - fun provideLocationManager(): LocationManager? { - return ContextCompat.getSystemService(app, LocationManager::class.java) - } + fun provideLocationManager() = app.getSystemService() @Provides @Singleton fun provideAstronomerModel( @Named("zero") magneticDeclinationCalculator: MagneticDeclinationCalculator - ): AstronomerModel { - return AstronomerModelImpl(magneticDeclinationCalculator) - } + ): AstronomerModel = AstronomerModelImpl(magneticDeclinationCalculator) @Provides @Singleton @Named("zero") - fun provideDefaultMagneticDeclinationCalculator(): MagneticDeclinationCalculator { - return ZeroMagneticDeclinationCalculator() - } + fun provideDefaultMagneticDeclinationCalculator(): MagneticDeclinationCalculator = ZeroMagneticDeclinationCalculator() @Provides @Singleton @Named("real") - fun provideRealMagneticDeclinationCalculator(): MagneticDeclinationCalculator { - return RealMagneticDeclinationCalculator() - } + fun provideRealMagneticDeclinationCalculator(): MagneticDeclinationCalculator = RealMagneticDeclinationCalculator() @Provides @Singleton - fun provideAnalytics(analytics: Analytics): AnalyticsInterface { - return analytics - } + fun provideAnalytics(analytics: Analytics): AnalyticsInterface = analytics @Provides @Singleton - fun provideBackgroundExecutor(): ExecutorService { - return ScheduledThreadPoolExecutor(1) - } + fun provideBackgroundExecutor() = ScheduledThreadPoolExecutor(1) @Provides @Singleton - fun provideAssetManager(): AssetManager { - return app.assets - } + fun provideAssetManager() = app.assets @Provides @Singleton - fun provideResources(): Resources { - return app.resources - } + fun provideResources() = app.resources @Provides @Singleton - fun provideSensorManager(): SensorManager? { - return ContextCompat.getSystemService(app, SensorManager::class.java) - } + fun provideSensorManager() = app.getSystemService() @Provides @Singleton - fun provideConnectivityManager(): ConnectivityManager? { - return ContextCompat.getSystemService(app, ConnectivityManager::class.java) - } + fun provideConnectivityManager() = app.getSystemService() @Provides @Singleton - fun provideAccountManager(context: Context): AccountManager { - return AccountManager.get(context) - } + fun provideAccountManager(context: Context) = AccountManager.get(context) @Provides @Singleton @@ -145,9 +114,4 @@ class ApplicationModule(app: StardroidApplication) { companion object { private val TAG = getTag(ApplicationModule::class.java) } - - init { - Log.d(TAG, "Creating application module for $app") - this.app = app - } } \ No newline at end of file diff --git a/app/src/main/java/com/google/android/stardroid/StardroidApplication.kt b/app/src/main/java/com/google/android/stardroid/StardroidApplication.kt index b9b1680b2..f96a9ae30 100644 --- a/app/src/main/java/com/google/android/stardroid/StardroidApplication.kt +++ b/app/src/main/java/com/google/android/stardroid/StardroidApplication.kt @@ -27,7 +27,6 @@ import android.util.Log import androidx.core.content.pm.PackageInfoCompat import androidx.preference.PreferenceManager import com.google.android.stardroid.layers.LayerManager -import com.google.android.stardroid.util.Analytics import com.google.android.stardroid.util.AnalyticsInterface import com.google.android.stardroid.util.MiscUtil.getTag import com.google.android.stardroid.util.PreferenceChangeAnalyticsTracker @@ -89,11 +88,11 @@ class StardroidApplication : Application() { } private fun setUpAnalytics(versionName: String) { - analytics!!.setEnabled(preferences!!.getBoolean(Analytics.PREF_KEY, true)) + (analytics ?: return).setEnabled((preferences ?: return).getBoolean(AnalyticsInterface.PREF_KEY, true)) // Ugly hack since this isn't injectable PreferencesButton.setAnalytics(analytics) - var previousVersion = preferences!!.getString(PREVIOUS_APP_VERSION_PREF, NONE) + var previousVersion = preferences?.getString(PREVIOUS_APP_VERSION_PREF, NONE) var newUser = false if (previousVersion == NONE) { // It's possible a previous version exists, it's just that it wasn't a recent enough @@ -108,8 +107,8 @@ class StardroidApplication : Application() { newUser = true } } - analytics!!.setUserProperty(AnalyticsInterface.NEW_USER, java.lang.Boolean.toString(newUser)) - preferences!!.edit().putString(PREVIOUS_APP_VERSION_PREF, versionName).commit() + analytics?.setUserProperty(AnalyticsInterface.NEW_USER, java.lang.Boolean.toString(newUser)) + preferences!!.edit().putString(PREVIOUS_APP_VERSION_PREF, versionName).apply() if (previousVersion != versionName) { // It's either an upgrade or a new installation Log.d(TAG, "New installation: version $versionName") @@ -118,14 +117,14 @@ class StardroidApplication : Application() { // It will be interesting to see *when* people use Sky Map. val b = Bundle() - b.putInt(Analytics.START_EVENT_HOUR, Calendar.getInstance()[Calendar.HOUR_OF_DAY]) - analytics!!.trackEvent(Analytics.START_EVENT, b) + b.putInt(AnalyticsInterface.START_EVENT_HOUR, Calendar.getInstance()[Calendar.HOUR_OF_DAY]) + analytics?.trackEvent(AnalyticsInterface.START_EVENT, b) preferences!!.registerOnSharedPreferenceChangeListener(preferenceChangeAnalyticsTracker) } override fun onTerminate() { super.onTerminate() - analytics!!.setEnabled(false) + analytics?.setEnabled(false) }// TODO(jontayler): update to use the info created by gradle. /** @@ -166,27 +165,27 @@ class StardroidApplication : Application() { private fun performFeatureCheck() { if (sensorManager == null) { Log.e(TAG, "No sensor manager") - analytics!!.setUserProperty(Analytics.DEVICE_SENSORS, Analytics.DEVICE_SENSORS_NONE) + analytics?.setUserProperty(AnalyticsInterface.DEVICE_SENSORS, AnalyticsInterface.DEVICE_SENSORS_NONE) return } // Reported available sensors - val reportedSensors: MutableList = ArrayList() + val reportedSensors: MutableList = ArrayList() if (hasDefaultSensor(Sensor.TYPE_ACCELEROMETER)) { - reportedSensors.add(Analytics.DEVICE_SENSORS_ACCELEROMETER) + reportedSensors.add(AnalyticsInterface.DEVICE_SENSORS_ACCELEROMETER) } if (hasDefaultSensor(Sensor.TYPE_GYROSCOPE)) { - reportedSensors.add(Analytics.DEVICE_SENSORS_GYRO) + reportedSensors.add(AnalyticsInterface.DEVICE_SENSORS_GYRO) } if (hasDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD)) { - reportedSensors.add(Analytics.DEVICE_SENSORS_MAGNETIC) + reportedSensors.add(AnalyticsInterface.DEVICE_SENSORS_MAGNETIC) } if (hasDefaultSensor(Sensor.TYPE_ROTATION_VECTOR)) { - reportedSensors.add(Analytics.DEVICE_SENSORS_ROTATION) + reportedSensors.add(AnalyticsInterface.DEVICE_SENSORS_ROTATION) } // TODO: Change to String.join once we're at API > 26 - analytics!!.setUserProperty( - Analytics.DEVICE_SENSORS, TextUtils.join("|", reportedSensors) + analytics?.setUserProperty( + AnalyticsInterface.DEVICE_SENSORS, TextUtils.join("|", reportedSensors) ) // Check for a particularly strange combo - it would be weird to have a rotation sensor @@ -216,9 +215,9 @@ class StardroidApplication : Application() { // Lastly a dump of all the sensors. Log.d(TAG, "All sensors:") - val allSensors = sensorManager!!.getSensorList(Sensor.TYPE_ALL) + val allSensors = sensorManager?.getSensorList(Sensor.TYPE_ALL) val sensorTypes: MutableSet = HashSet() - for (sensor in allSensors) { + for (sensor in allSensors?: emptyList()) { Log.i(TAG, sensor.name) sensorTypes.add(getSafeNameForSensor(sensor)) } @@ -229,10 +228,7 @@ class StardroidApplication : Application() { } private fun hasDefaultSensor(sensorType: Int): Boolean { - if (sensorManager == null) { - return false - } - val sensor = sensorManager!!.getDefaultSensor(sensorType) ?: return false + val sensor = sensorManager?.getDefaultSensor(sensorType) ?: return false val dummy: SensorEventListener = object : SensorEventListener { override fun onSensorChanged(event: SensorEvent) { // Nothing @@ -242,13 +238,13 @@ class StardroidApplication : Application() { // Nothing } } - val success = sensorManager!!.registerListener( + val success = sensorManager?.registerListener( dummy, sensor, SensorManager.SENSOR_DELAY_UI - ) + ) ?: false if (!success) { - analytics!!.setUserProperty(Analytics.SENSOR_LIAR, "true") + analytics?.setUserProperty(AnalyticsInterface.SENSOR_LIAR, "true") } - sensorManager!!.unregisterListener(dummy) + sensorManager?.unregisterListener(dummy) return success } @@ -263,11 +259,7 @@ class StardroidApplication : Application() { * on the supported OS level along with some context. */ fun getSafeNameForSensor(sensor: Sensor): String { - return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) { - "Sensor type: " + sensor.stringType + ": " + sensor.type - } else { - "Sensor type: " + sensor.type - } + return "Sensor type: ${sensor.stringType}: ${sensor.type}" } } } \ No newline at end of file diff --git a/app/src/main/java/com/google/android/stardroid/activities/DynamicStarMapActivity.java b/app/src/main/java/com/google/android/stardroid/activities/DynamicStarMapActivity.java index 63fb0aea1..6d1edfded 100644 --- a/app/src/main/java/com/google/android/stardroid/activities/DynamicStarMapActivity.java +++ b/app/src/main/java/com/google/android/stardroid/activities/DynamicStarMapActivity.java @@ -73,6 +73,7 @@ import com.google.android.stardroid.touch.GestureInterpreter; import com.google.android.stardroid.touch.MapMover; import com.google.android.stardroid.util.Analytics; +import com.google.android.stardroid.util.AnalyticsInterface; import com.google.android.stardroid.util.MiscUtil; import com.google.android.stardroid.util.SensorAccuracyMonitor; import com.google.android.stardroid.views.ButtonLayerView; @@ -618,9 +619,9 @@ private void doSearchWithIntent(Intent searchIntent) { Log.d(TAG, "Query string " + queryString); List results = layerManager.searchByObjectName(queryString); Bundle b = new Bundle(); - b.putString(Analytics.SEARCH_TERM, queryString); - b.putBoolean(Analytics.SEARCH_SUCCESS, results.size() > 0); - analytics.trackEvent(Analytics.SEARCH_EVENT, b); + b.putString(AnalyticsInterface.SEARCH_TERM, queryString); + b.putBoolean(AnalyticsInterface.SEARCH_SUCCESS, results.size() > 0); + analytics.trackEvent(AnalyticsInterface.SEARCH_EVENT, b); if (results.isEmpty()) { Log.d(TAG, "No results returned"); noSearchResultsDialogFragment.show(fragmentManager, "No Search Results"); @@ -630,7 +631,7 @@ private void doSearchWithIntent(Intent searchIntent) { } else { Log.d(TAG, "One result returned."); final SearchResult result = results.get(0); - activateSearchTarget(result.coords(), result.capitalizedName); + activateSearchTarget(result.coords(), result.getCapitalizedName()); } } diff --git a/app/src/main/java/com/google/android/stardroid/activities/ImageDisplayActivity.java b/app/src/main/java/com/google/android/stardroid/activities/ImageDisplayActivity.java index 59b72c29a..59c2dbde0 100644 --- a/app/src/main/java/com/google/android/stardroid/activities/ImageDisplayActivity.java +++ b/app/src/main/java/com/google/android/stardroid/activities/ImageDisplayActivity.java @@ -72,9 +72,9 @@ protected void onCreate(Bundle icicle) { List galleryImages = GalleryFactory.getGallery(getResources()).getGalleryImages(); selectedImage = galleryImages.get(position); ImageView imageView = (ImageView) findViewById(R.id.gallery_image); - imageView.setImageResource(selectedImage.imageId); + imageView.setImageResource(selectedImage.getImageId()); TextView label = (TextView) findViewById(R.id.gallery_image_title); - label.setText(selectedImage.name); + label.setText(selectedImage.getName()); Button backButton = (Button) findViewById(R.id.gallery_image_back_btn); backButton.setOnClickListener(this::goBack); Button searchButton = (Button) findViewById(R.id.gallery_image_search_btn); @@ -117,7 +117,7 @@ public void doSearch(View source) { Intent queryIntent = new Intent(); queryIntent.setAction(Intent.ACTION_SEARCH); - queryIntent.putExtra(SearchManager.QUERY, selectedImage.searchTerm); + queryIntent.putExtra(SearchManager.QUERY, selectedImage.getSearchTerm()); queryIntent.setClass(ImageDisplayActivity.this, DynamicStarMapActivity.class); startActivity(queryIntent); } diff --git a/app/src/main/java/com/google/android/stardroid/activities/ImageGalleryActivity.java b/app/src/main/java/com/google/android/stardroid/activities/ImageGalleryActivity.java index a7e518e09..647a8ad5b 100644 --- a/app/src/main/java/com/google/android/stardroid/activities/ImageGalleryActivity.java +++ b/app/src/main/java/com/google/android/stardroid/activities/ImageGalleryActivity.java @@ -83,9 +83,9 @@ public View getView(int position, View convertView, ViewGroup parent) { } GalleryImage galleryImage = galleryImages.get(position); ImageView imageView = (ImageView) imagePanel.findViewById(R.id.image_gallery_image); - imageView.setImageResource(galleryImage.imageId); + imageView.setImageResource(galleryImage.getImageId()); TextView imageLabel = (TextView) imagePanel.findViewById(R.id.image_gallery_title); - imageLabel.setText(galleryImage.name); + imageLabel.setText(galleryImage.getName()); return imagePanel; } } diff --git a/app/src/main/java/com/google/android/stardroid/activities/dialogs/MultipleSearchResultsDialogFragment.java b/app/src/main/java/com/google/android/stardroid/activities/dialogs/MultipleSearchResultsDialogFragment.java index cbc5718fa..3ded3aedf 100644 --- a/app/src/main/java/com/google/android/stardroid/activities/dialogs/MultipleSearchResultsDialogFragment.java +++ b/app/src/main/java/com/google/android/stardroid/activities/dialogs/MultipleSearchResultsDialogFragment.java @@ -48,7 +48,7 @@ public void onClick(DialogInterface dialog, int whichButton) { Log.d(TAG, "Many search results Dialog closed with cancel"); } else { final SearchResult item = multipleSearchResultsAdaptor.getItem(whichButton); - parentActivity.activateSearchTarget(item.coords(), item.capitalizedName); + parentActivity.activateSearchTarget(item.coords(), item.getCapitalizedName()); } dialog.dismiss(); } diff --git a/app/src/main/java/com/google/android/stardroid/gallery/Gallery.java b/app/src/main/java/com/google/android/stardroid/gallery/Gallery.kt similarity index 82% rename from app/src/main/java/com/google/android/stardroid/gallery/Gallery.java rename to app/src/main/java/com/google/android/stardroid/gallery/Gallery.kt index 85d679b10..281cba1d1 100644 --- a/app/src/main/java/com/google/android/stardroid/gallery/Gallery.java +++ b/app/src/main/java/com/google/android/stardroid/gallery/Gallery.kt @@ -11,16 +11,13 @@ // 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.stardroid.gallery; - -import java.util.List; +package com.google.android.stardroid.gallery /** * A Gallery contains a list of images. * * @author John Taylor */ -public interface Gallery { - List getGalleryImages(); -} +interface Gallery { + val galleryImages: List +} \ No newline at end of file diff --git a/app/src/main/java/com/google/android/stardroid/gallery/GalleryFactory.java b/app/src/main/java/com/google/android/stardroid/gallery/GalleryFactory.kt similarity index 70% rename from app/src/main/java/com/google/android/stardroid/gallery/GalleryFactory.java rename to app/src/main/java/com/google/android/stardroid/gallery/GalleryFactory.kt index d735c99cc..3ee2ffc39 100644 --- a/app/src/main/java/com/google/android/stardroid/gallery/GalleryFactory.java +++ b/app/src/main/java/com/google/android/stardroid/gallery/GalleryFactory.kt @@ -11,29 +11,27 @@ // 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.stardroid.gallery -package com.google.android.stardroid.gallery; - -import android.content.res.Resources; +import android.content.res.Resources /** * Constructs galleries. * * @author John Taylor */ -public class GalleryFactory { - private static Gallery gallery; - - private GalleryFactory() { - } +object GalleryFactory { + private var gallery: Gallery? = null /** * Returns the gallery. This will usually be a singleton. */ - public static synchronized Gallery getGallery(Resources resources) { + @JvmStatic + @Synchronized + fun getGallery(resources: Resources): Gallery? { if (gallery == null) { - gallery = new HardcodedGallery(resources); + gallery = HardcodedGallery(resources) } - return gallery; + return gallery } -} +} \ No newline at end of file diff --git a/app/src/main/java/com/google/android/stardroid/gallery/GalleryImage.java b/app/src/main/java/com/google/android/stardroid/gallery/GalleryImage.kt similarity index 68% rename from app/src/main/java/com/google/android/stardroid/gallery/GalleryImage.java rename to app/src/main/java/com/google/android/stardroid/gallery/GalleryImage.kt index f50987666..92b69f5ab 100644 --- a/app/src/main/java/com/google/android/stardroid/gallery/GalleryImage.java +++ b/app/src/main/java/com/google/android/stardroid/gallery/GalleryImage.kt @@ -11,22 +11,11 @@ // 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.stardroid.gallery; +package com.google.android.stardroid.gallery /** * Holds data about an image. * * @author John Taylor */ -public class GalleryImage { - public int imageId; - public String name; - public String searchTerm; - - public GalleryImage(int imageId, String name, String searchTerm) { - this.imageId = imageId; - this.name = name; - this.searchTerm = searchTerm; - } -} +data class GalleryImage(var imageId: Int, var name: String, var searchTerm: String) \ No newline at end of file diff --git a/app/src/main/java/com/google/android/stardroid/gallery/HardcodedGallery.java b/app/src/main/java/com/google/android/stardroid/gallery/HardcodedGallery.kt similarity index 54% rename from app/src/main/java/com/google/android/stardroid/gallery/HardcodedGallery.java rename to app/src/main/java/com/google/android/stardroid/gallery/HardcodedGallery.kt index 52e8070e8..9af40c788 100644 --- a/app/src/main/java/com/google/android/stardroid/gallery/HardcodedGallery.java +++ b/app/src/main/java/com/google/android/stardroid/gallery/HardcodedGallery.kt @@ -11,75 +11,84 @@ // 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.stardroid.gallery -package com.google.android.stardroid.gallery; - -import android.content.res.Resources; - -import com.google.android.stardroid.R; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; +import android.content.res.Resources +import com.google.android.stardroid.gallery.GalleryImage +import com.google.android.stardroid.gallery.GalleryFactory +import com.google.android.stardroid.gallery.HardcodedGallery +import com.google.android.stardroid.R +import java.util.* /** * A collection of gallery images. * * @author John Taylor */ -public class HardcodedGallery implements Gallery { - private List images; - private Resources resources; - - HardcodedGallery(Resources resources) { - this.resources = resources; - images = Collections.unmodifiableList(createImages()); - } - - public List getGalleryImages() { - return images; - } +class HardcodedGallery internal constructor(private val resources: Resources) : Gallery { + override val galleryImages: List /** * Adds an image to the gallery, but using an internationalized search term. * Note, that for this to work the internationalized name _must_ be in the * search index. */ - private final void add(ArrayList images, int imageId, - int nameId, int searchTermId) { - images.add(new GalleryImage(imageId, getString(nameId), getString(searchTermId))); + private fun add( + images: ArrayList, imageId: Int, + nameId: Int, searchTermId: Int + ) { + images.add(GalleryImage(imageId, getString(nameId), getString(searchTermId))) } - private ArrayList createImages() { - ArrayList galleryImages = new ArrayList(); + private fun createImages(): ArrayList { + val galleryImages = ArrayList() // Note the internationalized names in places. Be sure that if the // search term is internationalized in the search index then it is here too. - add(galleryImages, R.drawable.messenger_11_07_39, R.string.mercury, R.string.mercury); - add(galleryImages, R.drawable.hubble_venus_clouds_tops, R.string.venus, R.string.venus); - add(galleryImages, R.drawable.hubble_mars, R.string.mars, R.string.mars); - add(galleryImages, R.drawable.hubble_jupiter, R.string.jupiter, R.string.jupiter); - add(galleryImages, R.drawable.hubble_saturn, R.string.saturn, R.string.saturn); - add(galleryImages, R.drawable.hubble_uranus, R.string.uranus, R.string.uranus); - add(galleryImages, R.drawable.hubble_neptune, R.string.neptune, R.string.neptune); - add(galleryImages, R.drawable.nh_pluto_in_false_color, R.string.pluto, R.string.pluto); - add(galleryImages, R.drawable.hubble_m1, R.string.crab_nebula, R.string.crab_nebula); - add(galleryImages, R.drawable.hubble_m13, R.string.hercules_gc, R.string.hercules_gc); - add(galleryImages, R.drawable.hubble_m16, R.string.eagle_nebula, R.string.eagle_nebula); - add(galleryImages, R.drawable.kennett_m31, R.string.andromeda_galaxy, R.string.andromeda_galaxy); - add(galleryImages, R.drawable.hubble_m45, R.string.pleiades, R.string.pleiades); - add(galleryImages, R.drawable.hubble_m51a, R.string.whirlpool_galaxy, R.string.whirlpool_galaxy); - add(galleryImages, R.drawable.hubble_m57, R.string.ring_nebula, R.string.ring_nebula); - add(galleryImages, R.drawable.hubble_m101, R.string.pinwheel_galaxy, R.string.pinwheel_galaxy); - add(galleryImages, R.drawable.hubble_m104, R.string.sombrero_galaxy, R.string.sombrero_galaxy); - add(galleryImages, R.drawable.hubble_catseyenebula, R.string.cats_eye_nebula, R.string.cats_eye_nebula); - add(galleryImages, R.drawable.hubble_omegacentauri, R.string.omega_centauri, R.string.omega_centauri); - add(galleryImages, R.drawable.hubble_orion, R.string.orion_nebula, R.string.orion_nebula); - add(galleryImages, R.drawable.hubble_ultra_deep_field, R.string.hubble_deep_field, R.string.hubble_deep_field); - add(galleryImages, R.drawable.hubble_v838, R.string.v838_mon, R.string.v838_mon); - return galleryImages; + add(galleryImages, R.drawable.messenger_11_07_39, R.string.mercury, R.string.mercury) + add(galleryImages, R.drawable.hubble_venus_clouds_tops, R.string.venus, R.string.venus) + add(galleryImages, R.drawable.hubble_mars, R.string.mars, R.string.mars) + add(galleryImages, R.drawable.hubble_jupiter, R.string.jupiter, R.string.jupiter) + add(galleryImages, R.drawable.hubble_saturn, R.string.saturn, R.string.saturn) + add(galleryImages, R.drawable.hubble_uranus, R.string.uranus, R.string.uranus) + add(galleryImages, R.drawable.hubble_neptune, R.string.neptune, R.string.neptune) + add(galleryImages, R.drawable.nh_pluto_in_false_color, R.string.pluto, R.string.pluto) + add(galleryImages, R.drawable.hubble_m1, R.string.crab_nebula, R.string.crab_nebula) + add(galleryImages, R.drawable.hubble_m13, R.string.hercules_gc, R.string.hercules_gc) + add(galleryImages, R.drawable.hubble_m16, R.string.eagle_nebula, R.string.eagle_nebula) + add(galleryImages, R.drawable.kennett_m31, R.string.andromeda_galaxy, R.string.andromeda_galaxy) + add(galleryImages, R.drawable.hubble_m45, R.string.pleiades, R.string.pleiades) + add(galleryImages, R.drawable.hubble_m51a, R.string.whirlpool_galaxy, R.string.whirlpool_galaxy) + add(galleryImages, R.drawable.hubble_m57, R.string.ring_nebula, R.string.ring_nebula) + add(galleryImages, R.drawable.hubble_m101, R.string.pinwheel_galaxy, R.string.pinwheel_galaxy) + add(galleryImages, R.drawable.hubble_m104, R.string.sombrero_galaxy, R.string.sombrero_galaxy) + add( + galleryImages, + R.drawable.hubble_catseyenebula, + R.string.cats_eye_nebula, + R.string.cats_eye_nebula + ) + add( + galleryImages, + R.drawable.hubble_omegacentauri, + R.string.omega_centauri, + R.string.omega_centauri + ) + add(galleryImages, R.drawable.hubble_orion, R.string.orion_nebula, R.string.orion_nebula) + add( + galleryImages, + R.drawable.hubble_ultra_deep_field, + R.string.hubble_deep_field, + R.string.hubble_deep_field + ) + add(galleryImages, R.drawable.hubble_v838, R.string.v838_mon, R.string.v838_mon) + return galleryImages + } + + private fun getString(id: Int): String { + return resources.getString(id) } - private String getString(int id) { - return resources.getString(id); + init { + galleryImages = Collections.unmodifiableList(createImages()) } -} +} \ No newline at end of file diff --git a/app/src/main/java/com/google/android/stardroid/inject/HasComponent.java b/app/src/main/java/com/google/android/stardroid/inject/HasComponent.kt similarity index 51% rename from app/src/main/java/com/google/android/stardroid/inject/HasComponent.java rename to app/src/main/java/com/google/android/stardroid/inject/HasComponent.kt index 17fa43c80..1f0b5eefe 100644 --- a/app/src/main/java/com/google/android/stardroid/inject/HasComponent.java +++ b/app/src/main/java/com/google/android/stardroid/inject/HasComponent.kt @@ -1,9 +1,9 @@ -package com.google.android.stardroid.inject; +package com.google.android.stardroid.inject /** * Implemented by activities to access their dagger component. * Created by johntaylor on 4/9/16. */ -public interface HasComponent { - C getComponent(); -} +interface HasComponent { + val component: C +} \ No newline at end of file diff --git a/app/src/main/java/com/google/android/stardroid/inject/PerActivity.java b/app/src/main/java/com/google/android/stardroid/inject/PerActivity.java deleted file mode 100644 index cea566235..000000000 --- a/app/src/main/java/com/google/android/stardroid/inject/PerActivity.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.google.android.stardroid.inject; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -import javax.inject.Scope; - -@Scope -@Retention(RetentionPolicy.RUNTIME) -public @interface PerActivity {} \ No newline at end of file diff --git a/app/src/main/java/com/google/android/stardroid/inject/PerActivity.kt b/app/src/main/java/com/google/android/stardroid/inject/PerActivity.kt new file mode 100644 index 000000000..fd35a08c0 --- /dev/null +++ b/app/src/main/java/com/google/android/stardroid/inject/PerActivity.kt @@ -0,0 +1,7 @@ +package com.google.android.stardroid.inject + +import javax.inject.Scope + +@Scope +@Retention(AnnotationRetention.RUNTIME) +annotation class PerActivity \ No newline at end of file diff --git a/app/src/main/java/com/google/android/stardroid/search/PrefixStore.java b/app/src/main/java/com/google/android/stardroid/search/PrefixStore.java deleted file mode 100644 index 66548b222..000000000 --- a/app/src/main/java/com/google/android/stardroid/search/PrefixStore.java +++ /dev/null @@ -1,100 +0,0 @@ -// 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.stardroid.search; - -import java.util.Collection; -import java.util.Collections; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; - -/** - * Given a set of strings such as search terms, this class allows you to search - * for that string by prefix. - * @author John Taylor - * - */ -public class PrefixStore { - - static private class TrieNode { - Map children = new HashMap<>(); - - // we need to store the originals to support insensitive case searching - Set results = new HashSet<>(); - } - - private TrieNode root = new TrieNode(); - - private static final Set EMPTY_SET = Collections.unmodifiableSet(new HashSet()); - - public void clear() { - root = new TrieNode(); - } - /** - * Search for any queries matching this prefix. Note that the prefix is - * case-independent. - * - * TODO(@tcao) refactor this API. Search should return a relevance ranked list. - */ - public Set queryByPrefix(String prefix) { - prefix = prefix.toLowerCase(); - TrieNode n = root; - for (int i = 0; i < prefix.length(); i++) { - TrieNode c = n.children.get(prefix.charAt(i)); - if (c == null) { - return EMPTY_SET; - } - n = c; - } - Set coll = new HashSet(); - collect(n, coll); - return coll; - } - - private void collect(TrieNode n, Collection coll) { - coll.addAll(n.results); - for (TrieNode trieNode : n.children.values()) { - collect(trieNode, coll); - } - } - - /** - * Put a new string in the store. - */ - public void add(String string) { - TrieNode n = root; - String lower = string.toLowerCase(); - for (int i = 0; i < lower.length(); i++) { - TrieNode c = n.children.get(lower.charAt(i)); - if (c == null) { - c = new TrieNode(); - n.children.put(lower.charAt(i), c); - } - n = c; - } - n.results.add(string); - } - - /** - * Put a whole load of objects in the store at once. - * @param strings a collection of strings. - */ - public void addAll(Collection strings) { - for (String string : strings) { - add(string); - } - } -} diff --git a/app/src/main/java/com/google/android/stardroid/search/PrefixStore.kt b/app/src/main/java/com/google/android/stardroid/search/PrefixStore.kt new file mode 100644 index 000000000..4fab06f74 --- /dev/null +++ b/app/src/main/java/com/google/android/stardroid/search/PrefixStore.kt @@ -0,0 +1,91 @@ +// 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.stardroid.search + +import java.util.* + +/** + * Given a set of strings such as search terms, this class allows you to search + * for that string by prefix. + * @author John Taylor + */ +class PrefixStore { + private class TrieNode { + var children: MutableMap = HashMap() + + // we need to store the originals to support insensitive case searching + var results: MutableSet = HashSet() + } + + private var root = TrieNode() + fun clear() { + root = TrieNode() + } + + /** + * Search for any queries matching this prefix. Note that the prefix is + * case-independent. + * + * TODO(@tcao) refactor this API. Search should return a relevance ranked list. + */ + fun queryByPrefix(prefix: String): Set { + val prefixLower = prefix.lowercase() + var n = root + for (element in prefixLower) { + val c = n.children[element] ?: return EMPTY_SET + n = c + } + val coll: MutableSet = HashSet() + collect(n, coll) + return coll + } + + private fun collect(n: TrieNode, coll: MutableCollection) { + coll.addAll(n.results) + for (trieNode in n.children.values) { + collect(trieNode, coll) + } + } + + /** + * Put a new string in the store. + */ + fun add(string: String) { + var n = root + val lower = string.lowercase() + for (i in lower.indices) { + var c = n.children[lower[i]] + if (c == null) { + c = TrieNode() + n.children[lower[i]] = c + } + n = c + } + n.results.add(string) + } + + /** + * Put a whole load of objects in the store at once. + * @param strings a collection of strings. + */ + fun addAll(strings: Collection) { + for (string in strings) { + add(string) + } + } + + companion object { + private val EMPTY_SET = Collections.unmodifiableSet(HashSet()) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/google/android/stardroid/search/SearchResult.java b/app/src/main/java/com/google/android/stardroid/search/SearchResult.kt similarity index 54% rename from app/src/main/java/com/google/android/stardroid/search/SearchResult.java rename to app/src/main/java/com/google/android/stardroid/search/SearchResult.kt index 40045f54c..79675c468 100644 --- a/app/src/main/java/com/google/android/stardroid/search/SearchResult.java +++ b/app/src/main/java/com/google/android/stardroid/search/SearchResult.kt @@ -11,39 +11,31 @@ // 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.stardroid.search -package com.google.android.stardroid.search; - -import com.google.android.stardroid.math.Vector3; -import com.google.android.stardroid.renderables.AstronomicalRenderable; +import com.google.android.stardroid.math.Vector3 +import com.google.android.stardroid.renderables.AstronomicalRenderable /** * A single search result. * * @author John Taylor */ -public class SearchResult { - public AstronomicalRenderable renderable; +class SearchResult +/** + * @param capitalizedName The user-presentable name of the object, properly capitalized. + * @param renderable The searched for object.. + */( /** * The user-presentable name of the object, properly capitalized. */ - public String capitalizedName; - - /** - * @param capitalizedName The user-presentable name of the object, properly capitalized. - * @param renderable The searched for object.. - */ - public SearchResult(String capitalizedName, AstronomicalRenderable renderable) { - this.capitalizedName = capitalizedName; - this.renderable = renderable; - } - - public Vector3 coords() { - return renderable.getSearchLocation(); + var capitalizedName: String, var renderable: AstronomicalRenderable +) { + fun coords(): Vector3 { + return renderable.searchLocation } - @Override - public String toString() { - return capitalizedName; + override fun toString(): String { + return capitalizedName } -} +} \ No newline at end of file diff --git a/app/src/main/java/com/google/android/stardroid/search/SearchTermsProvider.java b/app/src/main/java/com/google/android/stardroid/search/SearchTermsProvider.java deleted file mode 100644 index 7ab627f0a..000000000 --- a/app/src/main/java/com/google/android/stardroid/search/SearchTermsProvider.java +++ /dev/null @@ -1,179 +0,0 @@ -// 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.stardroid.search; - -import android.app.SearchManager; -import android.content.ContentProvider; -import android.content.ContentValues; -import android.content.Context; -import android.content.UriMatcher; -import android.database.Cursor; -import android.database.MatrixCursor; -import android.net.Uri; -import android.text.TextUtils; -import android.util.Log; - -import com.google.android.stardroid.ApplicationComponent; -import com.google.android.stardroid.StardroidApplication; -import com.google.android.stardroid.layers.LayerManager; -import com.google.android.stardroid.util.MiscUtil; - -import java.util.Set; - -import javax.inject.Inject; - -/** - * Provides search suggestions for a list of words and their definitions. - */ -public class SearchTermsProvider extends ContentProvider { - public static class SearchTerm { - public String origin; - public String query; - - public SearchTerm(String query, String origin) { - this.query = query; - this.origin = origin; - } - } - - private static final String TAG = MiscUtil.getTag(SearchTermsProvider.class); - public static String AUTHORITY = "com.google.android.stardroid.searchterms"; - public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY); - private static final int SEARCH_SUGGEST = 0; - private static final UriMatcher uriMatcher = buildUriMatcher(); - @Inject LayerManager layerManager; - - /** - * The columns we'll include in our search suggestions. - */ - private static final String[] COLUMNS = {"_id", // must include this column - SearchManager.SUGGEST_COLUMN_QUERY, - SearchManager.SUGGEST_COLUMN_TEXT_1, - SearchManager.SUGGEST_COLUMN_TEXT_2}; - - /** - * Sets up a uri matcher for search suggestion and shortcut refresh queries. - */ - private static UriMatcher buildUriMatcher() { - UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH); - matcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY, SEARCH_SUGGEST); - matcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY + "/*", SEARCH_SUGGEST); - return matcher; - } - - @Override - public boolean onCreate() { - maybeInjectMe(); - return true; - } - - private boolean alreadyInjected; - - private boolean maybeInjectMe() { - // Ugh. Android's separation of content providers from their owning apps makes this - // almost impossible. TODO(jontayler): revisit and see if we can make this less - // nasty. - if (alreadyInjected) { - return true; - } - Context appContext = getContext().getApplicationContext(); - if (!(appContext instanceof StardroidApplication)) { - return false; - } - ApplicationComponent component = ((StardroidApplication) appContext).getApplicationComponent(); - if (component == null) { - return false; - } - component.inject(this); - alreadyInjected = true; - return true; - } - - @Override - public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, - String sortOrder) { - Log.d(TAG, "Got query for " + uri); - if (!maybeInjectMe()) { - return null; - } - if (!TextUtils.isEmpty(selection)) { - throw new IllegalArgumentException("selection not allowed for " + uri); - } - if (selectionArgs != null && selectionArgs.length != 0) { - throw new IllegalArgumentException("selectionArgs not allowed for " + uri); - } - if (!TextUtils.isEmpty(sortOrder)) { - throw new IllegalArgumentException("sortOrder not allowed for " + uri); - } - if (uriMatcher.match(uri) == SEARCH_SUGGEST) { - String query = null; - if (uri.getPathSegments().size() > 1) { - query = uri.getLastPathSegment(); - } - Log.d(TAG, "Got suggestions query for " + query); - return getSuggestions(query); - } - throw new IllegalArgumentException("Unknown URL " + uri); - } - - private Cursor getSuggestions(String query) { - MatrixCursor cursor = new MatrixCursor(COLUMNS); - if (query == null) { - return cursor; - } - Set results = layerManager.getObjectNamesMatchingPrefix(query); - Log.d("SearchTermsProvider", "Got results n=" + results.size()); - for (SearchTerm result : results) { - cursor.addRow(columnValuesOfSuggestion(result)); - } - return cursor; - } - - private static int s = 0; - - private Object[] columnValuesOfSuggestion(SearchTerm suggestion) { - return new String[] {Integer.toString(s++), // _id - suggestion.query, // query - suggestion.query, // text1 - suggestion.origin, // text2 - }; - } - - /** - * All queries for this provider are for the search suggestion mime type. - */ - @Override - public String getType(Uri uri) { - if (uriMatcher.match(uri) == SEARCH_SUGGEST) { - return SearchManager.SUGGEST_MIME_TYPE; - } - throw new IllegalArgumentException("Unknown URL " + uri); - } - - @Override - public Uri insert(Uri uri, ContentValues values) { - throw new UnsupportedOperationException(); - } - - @Override - public int delete(Uri uri, String selection, String[] selectionArgs) { - throw new UnsupportedOperationException(); - } - - @Override - public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { - throw new UnsupportedOperationException(); - } -} diff --git a/app/src/main/java/com/google/android/stardroid/search/SearchTermsProvider.kt b/app/src/main/java/com/google/android/stardroid/search/SearchTermsProvider.kt new file mode 100644 index 000000000..847e9935b --- /dev/null +++ b/app/src/main/java/com/google/android/stardroid/search/SearchTermsProvider.kt @@ -0,0 +1,159 @@ +// 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.stardroid.search + +import android.app.SearchManager +import android.content.ContentProvider +import android.content.ContentValues +import android.content.UriMatcher +import android.database.Cursor +import android.database.MatrixCursor +import android.net.Uri +import android.text.TextUtils +import android.util.Log +import com.google.android.stardroid.StardroidApplication +import com.google.android.stardroid.layers.LayerManager +import com.google.android.stardroid.util.MiscUtil.getTag +import javax.inject.Inject + +/** + * Provides search suggestions for a list of words and their definitions. + */ +class SearchTermsProvider : ContentProvider() { + data class SearchTerm(var query: String, var origin: String) + + @JvmField + @Inject + var layerManager: LayerManager? = null + override fun onCreate(): Boolean { + maybeInjectMe() + return true + } + + private var alreadyInjected = false + private fun maybeInjectMe(): Boolean { + // Ugh. Android's separation of content providers from their owning apps makes this + // almost impossible. TODO(jontayler): revisit and see if we can make this less + // nasty. + if (alreadyInjected) { + return true + } + val appContext = context?.applicationContext as? StardroidApplication ?: return false + val component = appContext.applicationComponent ?: return false + component.inject(this) + alreadyInjected = true + return true + } + + override fun query( + uri: Uri, projection: Array?, selection: String?, selectionArgs: Array?, + sortOrder: String? + ): Cursor? { + Log.d(TAG, "Got query for $uri") + if (!maybeInjectMe()) { + return null + } + require(TextUtils.isEmpty(selection)) { "selection not allowed for $uri" } + require(!(selectionArgs != null && selectionArgs.size != 0)) { "selectionArgs not allowed for $uri" } + require(TextUtils.isEmpty(sortOrder)) { "sortOrder not allowed for $uri" } + if (uriMatcher.match(uri) == SEARCH_SUGGEST) { + var query: String? = null + if (uri.pathSegments.size > 1) { + query = uri.lastPathSegment + } + Log.d(TAG, "Got suggestions query for $query") + return getSuggestions(query) + } + throw IllegalArgumentException("Unknown URL $uri") + } + + private fun getSuggestions(query: String?): Cursor { + val cursor = MatrixCursor(COLUMNS) + if (query == null) { + return cursor + } + val results = layerManager!!.getObjectNamesMatchingPrefix(query) + Log.d("SearchTermsProvider", "Got results n=" + results.size) + for (result in results) { + cursor.addRow(columnValuesOfSuggestion(result)) + } + return cursor + } + + private fun columnValuesOfSuggestion(suggestion: SearchTerm): Array { + return arrayOf( + Integer.toString(id++), // _id + suggestion.query, // query + suggestion.query, // text1 + suggestion.origin + ) + } + + /** + * All queries for this provider are for the search suggestion mime type. + */ + override fun getType(uri: Uri): String { + if (uriMatcher.match(uri) == SEARCH_SUGGEST) { + return SearchManager.SUGGEST_MIME_TYPE + } + throw IllegalArgumentException("Unknown URL $uri") + } + + override fun insert(uri: Uri, values: ContentValues?): Uri? { + throw UnsupportedOperationException() + } + + override fun delete(uri: Uri, selection: String?, selectionArgs: Array?): Int { + throw UnsupportedOperationException() + } + + override fun update( + uri: Uri, + values: ContentValues?, + selection: String?, + selectionArgs: Array? + ): Int { + throw UnsupportedOperationException() + } + + companion object { + private val TAG = getTag(SearchTermsProvider::class.java) + var AUTHORITY = "com.google.android.stardroid.searchterms" + val CONTENT_URI = Uri.parse("content://" + AUTHORITY) + private const val SEARCH_SUGGEST = 0 + private val uriMatcher = buildUriMatcher() + + /** + * The columns we'll include in our search suggestions. + */ + private val COLUMNS = arrayOf( + "_id", // must include this column + SearchManager.SUGGEST_COLUMN_QUERY, + SearchManager.SUGGEST_COLUMN_TEXT_1, + SearchManager.SUGGEST_COLUMN_TEXT_2 + ) + + /** + * Sets up a uri matcher for search suggestion and shortcut refresh queries. + */ + private fun buildUriMatcher(): UriMatcher { + val matcher = UriMatcher(UriMatcher.NO_MATCH) + matcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY, SEARCH_SUGGEST) + matcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY + "/*", SEARCH_SUGGEST) + return matcher + } + + private var id = 0 + } +} \ No newline at end of file diff --git a/app/src/main/java/com/google/android/stardroid/sensors/SensorModelAdaptor.java b/app/src/main/java/com/google/android/stardroid/sensors/SensorModelAdaptor.java deleted file mode 100644 index 91630cbba..000000000 --- a/app/src/main/java/com/google/android/stardroid/sensors/SensorModelAdaptor.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.google.android.stardroid.sensors; - -import android.hardware.Sensor; -import android.hardware.SensorEvent; -import android.hardware.SensorEventListener; - -import com.google.android.stardroid.control.AstronomerModel; - -import javax.inject.Inject; - -/** - * Connects the rotation vector to the model code. - */ -public class SensorModelAdaptor implements SensorEventListener { - private AstronomerModel model; - - @Inject - SensorModelAdaptor(AstronomerModel model) { - this.model = model; - } - - @Override - public void onSensorChanged(SensorEvent event) { - // do something with the model - } - - @Override - public void onAccuracyChanged(Sensor sensor, int accuracy) { - // Do nothing. - } -} diff --git a/app/src/main/java/com/google/android/stardroid/sensors/SensorModelAdaptor.kt b/app/src/main/java/com/google/android/stardroid/sensors/SensorModelAdaptor.kt new file mode 100644 index 000000000..9bb372d53 --- /dev/null +++ b/app/src/main/java/com/google/android/stardroid/sensors/SensorModelAdaptor.kt @@ -0,0 +1,21 @@ +package com.google.android.stardroid.sensors + +import android.hardware.Sensor +import android.hardware.SensorEvent +import android.hardware.SensorEventListener +import com.google.android.stardroid.control.AstronomerModel +import javax.inject.Inject + +/** + * Connects the rotation vector to the model code. + */ +class SensorModelAdaptor @Inject internal constructor(private val model: AstronomerModel) : + SensorEventListener { + override fun onSensorChanged(event: SensorEvent) { + // do something with the model + } + + override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) { + // Do nothing. + } +} \ No newline at end of file diff --git a/app/src/main/java/com/google/android/stardroid/touch/DragRotateZoomGestureDetector.java b/app/src/main/java/com/google/android/stardroid/touch/DragRotateZoomGestureDetector.kt similarity index 51% rename from app/src/main/java/com/google/android/stardroid/touch/DragRotateZoomGestureDetector.java rename to app/src/main/java/com/google/android/stardroid/touch/DragRotateZoomGestureDetector.kt index 8d5c49085..3b4f5d93d 100644 --- a/app/src/main/java/com/google/android/stardroid/touch/DragRotateZoomGestureDetector.java +++ b/app/src/main/java/com/google/android/stardroid/touch/DragRotateZoomGestureDetector.kt @@ -11,54 +11,42 @@ // 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.stardroid.touch -package com.google.android.stardroid.touch; - -//import android.util.Log; - -import static com.google.android.stardroid.math.MathUtilsKt.RADIANS_TO_DEGREES; - -import android.util.Log; -import android.view.MotionEvent; - -import com.google.android.stardroid.math.MathUtils; -import com.google.android.stardroid.util.MiscUtil; +import android.util.Log +import android.view.MotionEvent +import com.google.android.stardroid.math.MathUtils.atan2 +import com.google.android.stardroid.math.MathUtils.sqrt +import com.google.android.stardroid.math.RADIANS_TO_DEGREES +import com.google.android.stardroid.util.MiscUtil.getTag /** * Detects map drags, rotations and pinch zooms. * * @author John Taylor */ -public class DragRotateZoomGestureDetector { +class DragRotateZoomGestureDetector(private val listener: DragRotateZoomGestureDetectorListener) { /** - * Listens for the gestures detected by the {@link DragRotateZoomGestureDetector}. + * Listens for the gestures detected by the [DragRotateZoomGestureDetector]. * * @author John Taylor */ - public interface DragRotateZoomGestureDetectorListener { - boolean onDrag(float xPixels, float yPixels); - boolean onStretch(float ratio); - boolean onRotate(float radians); + interface DragRotateZoomGestureDetectorListener { + fun onDrag(xPixels: Float, yPixels: Float): Boolean + fun onStretch(ratio: Float): Boolean + fun onRotate(degrees: Float): Boolean } - private static final String TAG = MiscUtil.getTag(DragRotateZoomGestureDetector.class); - - private DragRotateZoomGestureDetectorListener listener; - - public DragRotateZoomGestureDetector(DragRotateZoomGestureDetectorListener listener) { - this.listener = listener; + private enum class State { + READY, DRAGGING, DRAGGING2 } - private enum State {READY, DRAGGING, DRAGGING2} - private State currentState = State.READY; - private float last1X; - private float last1Y; - - private float last2X; - private float last2Y; - - - public boolean onTouchEvent(MotionEvent ev) { + private var currentState = State.READY + private var last1X = 0f + private var last1Y = 0f + private var last2X = 0f + private var last2Y = 0f + fun onTouchEvent(ev: MotionEvent): Boolean { // The state changes are as follows. // READY -> DRAGGING -> DRAGGING2 -> READY // @@ -76,123 +64,122 @@ public boolean onTouchEvent(MotionEvent ev) { // ACTION_POINTER_DOWN: DRAGGING->DRAGGING2 // we're in multitouch mode // last position1 = current position1 - // last poisiton2 = current position2 + // last position2 = current position2 // // ACTION_MOVE: // calculate move // last position1 = current position1 // last position2 = current position2 - int actionCode = ev.getAction() & MotionEvent.ACTION_MASK; + val actionCode = ev.action and MotionEvent.ACTION_MASK // Log.d(TAG, "Action: " + actionCode + ", current state " + currentState); if (actionCode == MotionEvent.ACTION_DOWN || currentState == State.READY) { - currentState = State.DRAGGING; - last1X = ev.getX(); - last1Y = ev.getY(); + currentState = State.DRAGGING + last1X = ev.x + last1Y = ev.y // Log.d(TAG, "Down. Store last position " + last1X + ", " + last1Y); - return true; + return true } - if (actionCode == MotionEvent.ACTION_MOVE && currentState == State.DRAGGING) { // Log.d(TAG, "Move"); - float current1X = ev.getX(); - float current1Y = ev.getY(); + val current1X = ev.x + val current1Y = ev.y // Log.d(TAG, "Move. Last position " + last1X + ", " + last1Y + // "Current position " + current1X + ", " + current1Y); - listener.onDrag(current1X - last1X, current1Y - last1Y); - last1X = current1X; - last1Y = current1Y; - return true; + listener.onDrag(current1X - last1X, current1Y - last1Y) + last1X = current1X + last1Y = current1Y + return true } - if (actionCode == MotionEvent.ACTION_MOVE && currentState == State.DRAGGING2) { // Log.d(TAG, "Move with two fingers"); - int pointerCount = ev.getPointerCount(); + val pointerCount = ev.pointerCount if (pointerCount != 2) { - Log.w(TAG, "Expected exactly two pointers but got " + pointerCount); - return false; + Log.w(TAG, "Expected exactly two pointers but got $pointerCount") + return false } - float current1X = ev.getX(0); - float current1Y = ev.getY(0); - float current2X = ev.getX(1); - float current2Y = ev.getY(1); + val current1X = ev.getX(0) + val current1Y = ev.getY(0) + val current2X = ev.getX(1) + val current2Y = ev.getY(1) // Log.d(TAG, "Old Point 1: " + lastPointer1X + ", " + lastPointer1Y); // Log.d(TAG, "Old Point 2: " + lastPointer2X + ", " + lastPointer2Y); // Log.d(TAG, "New Point 1: " + current1X + ", " + current1Y); // Log.d(TAG, "New Point 2: " + current2X + ", " + current2Y); - - float distanceMovedX1 = current1X - last1X; - float distanceMovedY1 = current1Y - last1Y; - float distanceMovedX2 = current2X - last2X; - float distanceMovedY2 = current2Y - last2Y; + val distanceMovedX1 = current1X - last1X + val distanceMovedY1 = current1Y - last1Y + val distanceMovedX2 = current2X - last2X + val distanceMovedY2 = current2Y - last2Y // Log.d(TAG, "Point 1 moved by: " + distanceMovedX1 + ", " + distanceMovedY1); // Log.d(TAG, "Point 2 moved by: " + distanceMovedX2 + ", " + distanceMovedY2); // Dragging map by the mean of the points - listener.onDrag((distanceMovedX1 + distanceMovedX2) / 2, - (distanceMovedY1 + distanceMovedY2) / 2); + listener.onDrag( + (distanceMovedX1 + distanceMovedX2) / 2, + (distanceMovedY1 + distanceMovedY2) / 2 + ) // These are the vectors between the two points. - float vectorLastX = last1X - last2X; - float vectorLastY = last1Y - last2Y; - float vectorCurrentX = current1X - current2X; - float vectorCurrentY = current1Y - current2Y; + val vectorLastX = last1X - last2X + val vectorLastY = last1Y - last2Y + val vectorCurrentX = current1X - current2X + val vectorCurrentY = current1Y - current2Y // Log.d(TAG, "Previous vector: " + vectorBeforeX + ", " + vectorBeforeY); // Log.d(TAG, "Current vector: " + vectorCurrentX + ", " + vectorCurrentY); - - float lengthRatio = MathUtils.sqrt(normSquared(vectorCurrentX, vectorCurrentY) - / normSquared(vectorLastX, vectorLastY)); + val lengthRatio = sqrt( + normSquared(vectorCurrentX, vectorCurrentY) + / normSquared(vectorLastX, vectorLastY) + ) // Log.d(TAG, "Stretching map by ratio " + ratio); - listener.onStretch(lengthRatio); - float angleLast = MathUtils.atan2(vectorLastX, vectorLastY); - float angleCurrent = MathUtils.atan2(vectorCurrentX, vectorCurrentY); + listener.onStretch(lengthRatio) + val angleLast = atan2(vectorLastX, vectorLastY) + val angleCurrent = atan2(vectorCurrentX, vectorCurrentY) // Log.d(TAG, "Angle before " + angleBefore); // Log.d(TAG, "Angle after " + angleAfter); - float angleDelta = angleCurrent - angleLast; + val angleDelta = angleCurrent - angleLast // Log.d(TAG, "Rotating map by angle delta " + angleDelta); - listener.onRotate(angleDelta * RADIANS_TO_DEGREES); - - last1X = current1X; - last1Y = current1Y; - last2X = current2X; - last2Y = current2Y; - return true; + listener.onRotate(angleDelta * RADIANS_TO_DEGREES) + last1X = current1X + last1Y = current1Y + last2X = current2X + last2Y = current2Y + return true } - if (actionCode == MotionEvent.ACTION_UP && currentState != State.READY) { // Log.d(TAG, "Up"); - currentState = State.READY; - return true; + currentState = State.READY + return true } - if (actionCode == MotionEvent.ACTION_POINTER_DOWN && currentState == State.DRAGGING) { //Log.d(TAG, "Non primary pointer down " + pointer); - int pointerCount = ev.getPointerCount(); + val pointerCount = ev.pointerCount if (pointerCount != 2) { - Log.w(TAG, "Expected exactly two pointers but got " + pointerCount); - return false; + Log.w(TAG, "Expected exactly two pointers but got $pointerCount") + return false } - currentState = State.DRAGGING2; - last1X = ev.getX(0); - last1Y = ev.getY(0); - last2X = ev.getX(1); - last2Y = ev.getY(1); - return true; + currentState = State.DRAGGING2 + last1X = ev.getX(0) + last1Y = ev.getY(0) + last2X = ev.getX(1) + last2Y = ev.getY(1) + return true } - if (actionCode == MotionEvent.ACTION_POINTER_UP && currentState == State.DRAGGING2) { // Log.d(TAG, "Non primary pointer up " + pointer); // Let's just drop dragging for now - can worry about continuity with one finger // drag later. - currentState = State.READY; - return true; + currentState = State.READY + return true } // Log.d(TAG, "End state " + currentState); - return false; + return false } - private static float normSquared(float x, float y) { - return (x * x + y * y); + companion object { + private val TAG = getTag(DragRotateZoomGestureDetector::class.java) + private fun normSquared(x: Float, y: Float): Float { + return x * x + y * y + } } } \ No newline at end of file diff --git a/app/src/main/java/com/google/android/stardroid/touch/Flinger.java b/app/src/main/java/com/google/android/stardroid/touch/Flinger.java deleted file mode 100644 index 58021396d..000000000 --- a/app/src/main/java/com/google/android/stardroid/touch/Flinger.java +++ /dev/null @@ -1,76 +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.stardroid.touch; - -import com.google.android.stardroid.util.MiscUtil; - -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.ScheduledFuture; -import java.util.concurrent.TimeUnit; - -import android.util.Log; - -/** - * Given a flung motion event, this class pumps new Motion events out - * to simulate an underlying object with some inertia. - */ -public class Flinger { - private static final String TAG = MiscUtil.getTag(Flinger.class); - public interface FlingListener { - void fling(float distanceX, float distanceY); - } - private FlingListener listener; - private int updatesPerSecond = 20; - private int timeIntervalMillis = 1000/updatesPerSecond; - private ScheduledExecutorService executor; - private ScheduledFuture flingTask; - public Flinger(FlingListener listener) { - this.listener = listener; - executor = Executors.newScheduledThreadPool(1); - } - - public void fling(float velocityX, float velocityY) { - Log.d(TAG, "Doing the fling"); - class PositionUpdater implements Runnable { - private float myVelocityX, myVelocityY; - private float decelFactor = 1.1f; - private float TOL = 10; - public PositionUpdater(float velocityX, float velocityY) { - this.myVelocityX = velocityX; - this.myVelocityY = velocityY; - } - public void run() { - if (myVelocityX * myVelocityX + myVelocityY * myVelocityY < TOL) { - stop(); - } - listener.fling(myVelocityX / updatesPerSecond, - myVelocityY / updatesPerSecond); - myVelocityX /= decelFactor; - myVelocityY /= decelFactor; - } - } - flingTask = executor.scheduleAtFixedRate(new PositionUpdater(velocityX, velocityY), - 0, timeIntervalMillis, TimeUnit.MILLISECONDS); - } - - /** - * Brings the flinger to a dead stop. - */ - public void stop() { - if (flingTask != null) flingTask.cancel(true); - Log.d(TAG, "Fling stopped"); - } -} diff --git a/app/src/main/java/com/google/android/stardroid/touch/Flinger.kt b/app/src/main/java/com/google/android/stardroid/touch/Flinger.kt new file mode 100644 index 000000000..063a1fcc9 --- /dev/null +++ b/app/src/main/java/com/google/android/stardroid/touch/Flinger.kt @@ -0,0 +1,71 @@ +// 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.stardroid.touch + +import android.util.Log +import com.google.android.stardroid.util.MiscUtil.getTag +import java.util.concurrent.Executors +import java.util.concurrent.ScheduledExecutorService +import java.util.concurrent.ScheduledFuture +import java.util.concurrent.TimeUnit + +/** + * Given a flung motion event, this class pumps new Motion events out + * to simulate an underlying object with some inertia. + */ +class Flinger(private val listener: (Float, Float) -> Unit) { + private val updatesPerSecond = 20 + private val timeIntervalMillis = 1000 / updatesPerSecond + private val executor: ScheduledExecutorService + private var flingTask: ScheduledFuture<*>? = null + fun fling(velocityX: Float, velocityY: Float) { + Log.d(TAG, "Doing the fling") + class PositionUpdater(private var myVelocityX: Float, private var myVelocityY: Float) : + Runnable { + private val decelFactor = 1.1f + private val TOL = 10f + override fun run() { + if (myVelocityX * myVelocityX + myVelocityY * myVelocityY < TOL) { + stop() + } + listener( + myVelocityX / updatesPerSecond, + myVelocityY / updatesPerSecond + ) + myVelocityX /= decelFactor + myVelocityY /= decelFactor + } + } + flingTask = executor.scheduleAtFixedRate( + PositionUpdater(velocityX, velocityY), + 0, timeIntervalMillis.toLong(), TimeUnit.MILLISECONDS + ) + } + + /** + * Brings the flinger to a dead stop. + */ + fun stop() { + flingTask?.cancel(true) + Log.d(TAG, "Fling stopped") + } + + companion object { + private val TAG = getTag(Flinger::class.java) + } + + init { + executor = Executors.newScheduledThreadPool(1) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/google/android/stardroid/touch/GestureInterpreter.java b/app/src/main/java/com/google/android/stardroid/touch/GestureInterpreter.java deleted file mode 100644 index 3945382ad..000000000 --- a/app/src/main/java/com/google/android/stardroid/touch/GestureInterpreter.java +++ /dev/null @@ -1,80 +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.stardroid.touch; - -import android.util.Log; -import android.view.GestureDetector; -import android.view.MotionEvent; - -import com.google.android.stardroid.activities.util.FullscreenControlsManager; -import com.google.android.stardroid.touch.Flinger.FlingListener; -import com.google.android.stardroid.util.MiscUtil; - -/** - * Processes touch events and scrolls the screen in manual mode. - * - * @author John Taylor - */ -public class GestureInterpreter extends GestureDetector.SimpleOnGestureListener { - private static final String TAG = MiscUtil.getTag(GestureInterpreter.class); - private FullscreenControlsManager fullscreenControlsManager; - private MapMover mapMover; - - public GestureInterpreter( - FullscreenControlsManager fullscreenControlsManager, - MapMover mapMover) { - this.fullscreenControlsManager = fullscreenControlsManager; - this.mapMover = mapMover; - } - - private final Flinger flinger = new Flinger(new FlingListener() { - public void fling(float distanceX, float distanceY) { - mapMover.onDrag(distanceX, distanceY); - } - }); - - @Override - public boolean onDown(MotionEvent e) { - Log.d(TAG, "Tap down"); - flinger.stop(); - return true; - } - - @Override - public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { - Log.d(TAG, "Flinging " + velocityX + ", " + velocityY); - flinger.fling(velocityX, velocityY); - return true; - } - - @Override - public boolean onSingleTapUp(MotionEvent e) { - Log.d(TAG, "Tap up"); - fullscreenControlsManager.toggleControls(); - return true; - } - - @Override - public boolean onDoubleTap(MotionEvent e) { - Log.d(TAG, "Double tap"); - return false; - } - - @Override - public boolean onSingleTapConfirmed(MotionEvent e) { - Log.d(TAG, "Confirmed single tap"); - return false; - } -} diff --git a/app/src/main/java/com/google/android/stardroid/touch/GestureInterpreter.kt b/app/src/main/java/com/google/android/stardroid/touch/GestureInterpreter.kt new file mode 100644 index 000000000..8539e8850 --- /dev/null +++ b/app/src/main/java/com/google/android/stardroid/touch/GestureInterpreter.kt @@ -0,0 +1,74 @@ +// 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.stardroid.touch + +import android.util.Log +import android.view.GestureDetector.SimpleOnGestureListener +import android.view.MotionEvent +import com.google.android.stardroid.activities.util.FullscreenControlsManager +import com.google.android.stardroid.util.MiscUtil.getTag + +/** + * Processes touch events and scrolls the screen in manual mode. + * + * @author John Taylor + */ +class GestureInterpreter( + private val fullscreenControlsManager: FullscreenControlsManager, + private val mapMover: MapMover +) : SimpleOnGestureListener() { + private val flinger = Flinger { distanceX: Float, distanceY: Float -> + mapMover.onDrag( + distanceX, + distanceY + ) + } + + override fun onDown(e: MotionEvent): Boolean { + Log.d(TAG, "Tap down") + flinger.stop() + return true + } + + override fun onFling( + e1: MotionEvent, + e2: MotionEvent, + velocityX: Float, + velocityY: Float + ): Boolean { + Log.d(TAG, "Flinging $velocityX, $velocityY") + flinger.fling(velocityX, velocityY) + return true + } + + override fun onSingleTapUp(e: MotionEvent): Boolean { + Log.d(TAG, "Tap up") + fullscreenControlsManager.toggleControls() + return true + } + + override fun onDoubleTap(e: MotionEvent): Boolean { + Log.d(TAG, "Double tap") + return false + } + + override fun onSingleTapConfirmed(e: MotionEvent): Boolean { + Log.d(TAG, "Confirmed single tap") + return false + } + + companion object { + private val TAG = getTag(GestureInterpreter::class.java) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/google/android/stardroid/touch/MapMover.java b/app/src/main/java/com/google/android/stardroid/touch/MapMover.java deleted file mode 100644 index 474b87b04..000000000 --- a/app/src/main/java/com/google/android/stardroid/touch/MapMover.java +++ /dev/null @@ -1,70 +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.stardroid.touch; - -import static com.google.android.stardroid.math.MathUtilsKt.RADIANS_TO_DEGREES; - -import android.content.Context; -import android.util.DisplayMetrics; -import android.util.Log; - -import com.google.android.stardroid.control.AstronomerModel; -import com.google.android.stardroid.control.ControllerGroup; -import com.google.android.stardroid.util.MiscUtil; - -/** - * Applies drags, zooms and rotations to the model. - * Listens for events from the DragRotateZoomGestureDetector. - * - * @author John Taylor - */ -public class MapMover implements - DragRotateZoomGestureDetector.DragRotateZoomGestureDetectorListener { - - private static final String TAG = MiscUtil.getTag(MapMover.class); - private AstronomerModel model; - private ControllerGroup controllerGroup; - private float sizeTimesRadiansToDegrees; - - public MapMover(AstronomerModel model, ControllerGroup controllerGroup, Context context) { - this.model = model; - this.controllerGroup = controllerGroup; - DisplayMetrics metrics = context.getResources().getDisplayMetrics(); - int screenLongSize = metrics.heightPixels; - Log.i(TAG, "Screen height is " + screenLongSize + " pixels."); - sizeTimesRadiansToDegrees = screenLongSize * RADIANS_TO_DEGREES; - } - - @Override - public boolean onDrag(float xPixels, float yPixels) { - // Log.d(TAG, "Dragging by " + xPixels + ", " + yPixels); - final float pixelsToRadians = model.getFieldOfView() / sizeTimesRadiansToDegrees; - controllerGroup.changeUpDown(-yPixels * pixelsToRadians); - controllerGroup.changeRightLeft(-xPixels * pixelsToRadians); - return true; - } - - @Override - public boolean onRotate(float degrees) { - controllerGroup.rotate(-degrees); - return true; - } - - @Override - public boolean onStretch(float ratio) { - controllerGroup.zoomBy(1.0f / ratio); - return true; - } -} \ No newline at end of file diff --git a/app/src/main/java/com/google/android/stardroid/touch/MapMover.kt b/app/src/main/java/com/google/android/stardroid/touch/MapMover.kt new file mode 100644 index 000000000..1a8e2c799 --- /dev/null +++ b/app/src/main/java/com/google/android/stardroid/touch/MapMover.kt @@ -0,0 +1,64 @@ +// 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.stardroid.touch + +import android.content.Context +import android.util.Log +import com.google.android.stardroid.control.AstronomerModel +import com.google.android.stardroid.control.ControllerGroup +import com.google.android.stardroid.math.RADIANS_TO_DEGREES +import com.google.android.stardroid.touch.DragRotateZoomGestureDetector.DragRotateZoomGestureDetectorListener +import com.google.android.stardroid.util.MiscUtil.getTag + +/** + * Applies drags, zooms and rotations to the model. + * Listens for events from the DragRotateZoomGestureDetector. + * + * @author John Taylor + */ +class MapMover( + private val model: AstronomerModel, + private val controllerGroup: ControllerGroup, + context: Context +) : DragRotateZoomGestureDetectorListener { + private val sizeTimesRadiansToDegrees: Float + override fun onDrag(xPixels: Float, yPixels: Float): Boolean { + // Log.d(TAG, "Dragging by " + xPixels + ", " + yPixels); + val pixelsToRadians = model.fieldOfView / sizeTimesRadiansToDegrees + controllerGroup.changeUpDown(-yPixels * pixelsToRadians) + controllerGroup.changeRightLeft(-xPixels * pixelsToRadians) + return true + } + + override fun onRotate(degrees: Float): Boolean { + controllerGroup.rotate(-degrees) + return true + } + + override fun onStretch(ratio: Float): Boolean { + controllerGroup.zoomBy(1.0f / ratio) + return true + } + + companion object { + private val TAG = getTag(MapMover::class.java) + } + + init { + val metrics = context.resources.displayMetrics + val screenLongSize = metrics.heightPixels + Log.i(TAG, "Screen height is $screenLongSize pixels.") + sizeTimesRadiansToDegrees = screenLongSize * RADIANS_TO_DEGREES + } +} \ No newline at end of file diff --git a/app/src/main/java/com/google/android/stardroid/util/FixedPoint.java b/app/src/main/java/com/google/android/stardroid/util/FixedPoint.kt similarity index 65% rename from app/src/main/java/com/google/android/stardroid/util/FixedPoint.java rename to app/src/main/java/com/google/android/stardroid/util/FixedPoint.kt index ab4c20088..6ff128eac 100644 --- a/app/src/main/java/com/google/android/stardroid/util/FixedPoint.java +++ b/app/src/main/java/com/google/android/stardroid/util/FixedPoint.kt @@ -11,15 +11,14 @@ // 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.stardroid.util -package com.google.android.stardroid.util; +object FixedPoint { + const val ONE = 0x00010000 -public final class FixedPoint { - private FixedPoint() {} - public static final int ONE = 0x00010000; - - /// Converts a float to a 16.16 fixed point number - public final static int floatToFixedPoint(float f) { - return (int)(65536F*f); - } -} + /// Converts a float to a 16.16 fixed point number + @JvmStatic + fun floatToFixedPoint(f: Float): Int { + return (65536f * f).toInt() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/google/android/stardroid/util/PreferenceChangeAnalyticsTracker.java b/app/src/main/java/com/google/android/stardroid/util/PreferenceChangeAnalyticsTracker.java deleted file mode 100644 index b8e7ae338..000000000 --- a/app/src/main/java/com/google/android/stardroid/util/PreferenceChangeAnalyticsTracker.java +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright 2011 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.stardroid.util; - -import android.content.SharedPreferences; -import android.content.SharedPreferences.OnSharedPreferenceChangeListener; -import android.os.Bundle; -import android.util.Log; - -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; - -import javax.inject.Inject; - -/** - * Tracks changes in preferences and logs them to Google Analytics. - * - * @author John Taylor - */ -public class PreferenceChangeAnalyticsTracker implements OnSharedPreferenceChangeListener { - private Analytics analytics; - private static final String TAG = MiscUtil.getTag(PreferenceChangeAnalyticsTracker.class); - - @Inject - PreferenceChangeAnalyticsTracker(Analytics analytics) { - this.analytics = analytics; - } - - private Set stringPreferenceWhiteList = new HashSet(Arrays.asList(new String[] { - "sensor_speed", "sensor_damping, lightmode" - })); - - private void trackPreferenceChange(SharedPreferences sharedPreferences, String key) { - Log.d(TAG, "Logging pref change " + key); - // There is no way to get a preference without knowing its type. Consequently, we try - // each type and silently swallow the exception if we guess wrong. If this proves expensive - // we might switch to caching the type. - Bundle prefBundle = new Bundle(); - String value = getPreferenceAsString(sharedPreferences, key); - prefBundle.putString(Analytics.PREFERENCE_CHANGE_EVENT_VALUE, key + ":" + value); - analytics.trackEvent(Analytics.PREFERENCE_CHANGE_EVENT, prefBundle); - } - - @Override - public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { - trackPreferenceChange(sharedPreferences, key); - } - - private String getPreferenceAsString(SharedPreferences sharedPreferences, String key) { - String value = "unknown"; - try { - value = sharedPreferences.getString(key, "unknown"); - if (!stringPreferenceWhiteList.contains(key)) { - value = "PII"; - } - } catch (ClassCastException cce) { - // Thrown if the pref wasn't a string. - } - try { - value = Boolean.toString(sharedPreferences.getBoolean(key, false)); - } catch (ClassCastException cce) { - // Thrown if the pref wasn't a boolean. - } - try { - value = Integer.toString(sharedPreferences.getInt(key, 0)); - } catch (ClassCastException cce) { - // Thrown if the pref wasn't an integer. - } - try { - value = Long.toString(sharedPreferences.getLong(key, 0)); - } catch (ClassCastException cce) { - // Thrown if the pref wasn't an integer. - } - try { - value = Float.toString(sharedPreferences.getFloat(key, 0)); - } catch (ClassCastException cce) { - // Thrown if the pref wasn't a float. - } - // Other types are possible, but those are the ones we care about. - return value; - } -} diff --git a/app/src/main/java/com/google/android/stardroid/util/PreferenceChangeAnalyticsTracker.kt b/app/src/main/java/com/google/android/stardroid/util/PreferenceChangeAnalyticsTracker.kt new file mode 100644 index 000000000..826335303 --- /dev/null +++ b/app/src/main/java/com/google/android/stardroid/util/PreferenceChangeAnalyticsTracker.kt @@ -0,0 +1,87 @@ +// Copyright 2011 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.stardroid.util + +import android.content.SharedPreferences +import android.content.SharedPreferences.OnSharedPreferenceChangeListener +import android.os.Bundle +import android.util.Log +import com.google.android.stardroid.util.MiscUtil.getTag +import javax.inject.Inject + +/** + * Tracks changes in preferences and logs them to Google Analytics. + * + * @author John Taylor + */ +class PreferenceChangeAnalyticsTracker @Inject internal constructor(private val analytics: Analytics) : + OnSharedPreferenceChangeListener { + private val stringPreferenceWhiteList: Set = + setOf( + "sensor_speed", "sensor_damping, lightmode" + ) + + private fun trackPreferenceChange(sharedPreferences: SharedPreferences, key: String) { + Log.d(TAG, "Logging pref change $key") + // There is no way to get a preference without knowing its type. Consequently, we try + // each type and silently swallow the exception if we guess wrong. If this proves expensive + // we might switch to caching the type. + val prefBundle = Bundle() + val value = getPreferenceAsString(sharedPreferences, key) + prefBundle.putString(AnalyticsInterface.PREFERENCE_CHANGE_EVENT_VALUE, "$key:$value") + analytics.trackEvent(AnalyticsInterface.PREFERENCE_CHANGE_EVENT, prefBundle) + } + + override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) { + trackPreferenceChange(sharedPreferences, key) + } + + private fun getPreferenceAsString(sharedPreferences: SharedPreferences, key: String): String? { + var value: String? = "unknown" + try { + value = sharedPreferences.getString(key, "unknown") + if (!stringPreferenceWhiteList.contains(key)) { + value = "PII" + } + } catch (cce: ClassCastException) { + // Thrown if the pref wasn't a string. + } + try { + value = sharedPreferences.getBoolean(key, false).toString() + } catch (cce: ClassCastException) { + // Thrown if the pref wasn't a boolean. + } + try { + value = sharedPreferences.getInt(key, 0).toString() + } catch (cce: ClassCastException) { + // Thrown if the pref wasn't an integer. + } + try { + value = sharedPreferences.getLong(key, 0).toString() + } catch (cce: ClassCastException) { + // Thrown if the pref wasn't an integer. + } + try { + value = sharedPreferences.getFloat(key, 0f).toString() + } catch (cce: ClassCastException) { + // Thrown if the pref wasn't a float. + } + // Other types are possible, but those are the ones we care about. + return value + } + + companion object { + private val TAG = getTag(PreferenceChangeAnalyticsTracker::class.java) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/google/android/stardroid/util/SensorAccuracyMonitor.java b/app/src/main/java/com/google/android/stardroid/util/SensorAccuracyMonitor.java deleted file mode 100644 index 94531febb..000000000 --- a/app/src/main/java/com/google/android/stardroid/util/SensorAccuracyMonitor.java +++ /dev/null @@ -1,110 +0,0 @@ -package com.google.android.stardroid.util; - -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; -import android.hardware.Sensor; -import android.hardware.SensorEvent; -import android.hardware.SensorEventListener; -import android.hardware.SensorManager; -import android.util.Log; - -import com.google.android.stardroid.activities.CompassCalibrationActivity; -import com.google.android.stardroid.base.TimeConstants; - -import javax.annotation.Nullable; -import javax.inject.Inject; - -/** - * Monitors the compass accuracy and if it is not medium or high warns the user. - * Created by johntaylor on 4/24/16. - */ -public class SensorAccuracyMonitor implements SensorEventListener { - private static final String TAG = MiscUtil.getTag(SensorAccuracyMonitor.class); - private static final String LAST_CALIBRATION_WARNING_PREF_KEY = "Last calibration warning time"; - - private SensorManager sensorManager; - private Sensor compassSensor; - private Context context; - private SharedPreferences sharedPreferences; - private Toaster toaster; - - @Inject - SensorAccuracyMonitor( - @Nullable SensorManager sensorManager, Context context, - SharedPreferences sharedPreferences, - Toaster toaster) { - Log.d(TAG, "Creating new accuracy monitor"); - this.sensorManager = sensorManager; - this.context = context; - this.sharedPreferences = sharedPreferences; - this.toaster = toaster; - compassSensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD); - } - - private boolean started = false; - private boolean hasReading = false; - - /** - * Starts monitoring. - */ - public void start() { - if (started) { - return; - } - Log.d(TAG, "Starting monitoring compass accuracy"); - if (compassSensor != null) { - sensorManager.registerListener(this, compassSensor, SensorManager.SENSOR_DELAY_UI); - } - started = true; - } - - /** - * Stops monitoring. It's important this is called to disconnect from the sensors and - * ensure the app does not needlessly consume power when in the background. - */ - public void stop() { - Log.d(TAG, "Stopping monitoring compass accuracy"); - started = false; - hasReading = false; - sensorManager.unregisterListener(this); - } - - - @Override - public void onSensorChanged(SensorEvent event) { - if (!hasReading) { - onAccuracyChanged(event.sensor, event.accuracy); - } - } - - private static final long MIN_INTERVAL_BETWEEN_WARNINGS = - 180 * TimeConstants.MILLISECONDS_PER_SECOND; - - @Override - public void onAccuracyChanged(Sensor sensor, int accuracy) { - hasReading = true; - if (accuracy == SensorManager.SENSOR_STATUS_ACCURACY_HIGH - || accuracy == SensorManager.SENSOR_STATUS_ACCURACY_MEDIUM) { - return; // OK - } - Log.d(TAG, "Compass accuracy insufficient"); - long nowMillis = System.currentTimeMillis(); - long lastWarnedMillis = sharedPreferences.getLong(LAST_CALIBRATION_WARNING_PREF_KEY, 0); - if (nowMillis - lastWarnedMillis < MIN_INTERVAL_BETWEEN_WARNINGS) { - Log.d(TAG, "...but too soon to warn again"); - return; - } - sharedPreferences.edit().putLong(LAST_CALIBRATION_WARNING_PREF_KEY, nowMillis).apply(); - boolean dontShowDialog = sharedPreferences.getBoolean( - CompassCalibrationActivity.DONT_SHOW_CALIBRATION_DIALOG, false); - if (dontShowDialog) { - toaster.toastLong("Inaccurate compass - please calibrate"); - } else { - Intent intent = new Intent(context, CompassCalibrationActivity.class); - intent.putExtra(CompassCalibrationActivity.HIDE_CHECKBOX, false); - intent.putExtra(CompassCalibrationActivity.AUTO_DISMISSABLE, true); - context.startActivity(intent); - } - } -} diff --git a/app/src/main/java/com/google/android/stardroid/util/SensorAccuracyMonitor.kt b/app/src/main/java/com/google/android/stardroid/util/SensorAccuracyMonitor.kt new file mode 100644 index 000000000..6c2d9421a --- /dev/null +++ b/app/src/main/java/com/google/android/stardroid/util/SensorAccuracyMonitor.kt @@ -0,0 +1,106 @@ +package com.google.android.stardroid.util + +import android.content.Context +import android.content.Intent +import android.content.SharedPreferences +import android.hardware.Sensor +import android.hardware.SensorEvent +import android.hardware.SensorEventListener +import android.hardware.SensorManager +import android.util.Log +import com.google.android.stardroid.activities.CompassCalibrationActivity +import com.google.android.stardroid.base.TimeConstants +import com.google.android.stardroid.util.MiscUtil.getTag +import javax.inject.Inject + +/** + * Monitors the compass accuracy and if it is not medium or high warns the user. + * Created by johntaylor on 4/24/16. + */ +class SensorAccuracyMonitor @Inject internal constructor( + sensorManager: SensorManager?, context: Context, + sharedPreferences: SharedPreferences, + toaster: Toaster +) : SensorEventListener { + private val sensorManager: SensorManager? + private val compassSensor: Sensor? + private val context: Context + private val sharedPreferences: SharedPreferences + private val toaster: Toaster + private var started = false + private var hasReading = false + + /** + * Starts monitoring. + */ + fun start() { + if (started) { + return + } + Log.d(TAG, "Starting monitoring compass accuracy") + if (compassSensor != null) { + (sensorManager ?: return).registerListener(this, compassSensor, SensorManager.SENSOR_DELAY_UI) + } + started = true + } + + /** + * Stops monitoring. It's important this is called to disconnect from the sensors and + * ensure the app does not needlessly consume power when in the background. + */ + fun stop() { + Log.d(TAG, "Stopping monitoring compass accuracy") + started = false + hasReading = false + (sensorManager ?: return).unregisterListener(this) + } + + override fun onSensorChanged(event: SensorEvent) { + if (!hasReading) { + onAccuracyChanged(event.sensor, event.accuracy) + } + } + + override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) { + hasReading = true + if (accuracy == SensorManager.SENSOR_STATUS_ACCURACY_HIGH + || accuracy == SensorManager.SENSOR_STATUS_ACCURACY_MEDIUM + ) { + return // OK + } + Log.d(TAG, "Compass accuracy insufficient") + val nowMillis = System.currentTimeMillis() + val lastWarnedMillis = sharedPreferences.getLong(LAST_CALIBRATION_WARNING_PREF_KEY, 0) + if (nowMillis - lastWarnedMillis < MIN_INTERVAL_BETWEEN_WARNINGS) { + Log.d(TAG, "...but too soon to warn again") + return + } + sharedPreferences.edit().putLong(LAST_CALIBRATION_WARNING_PREF_KEY, nowMillis).apply() + val dontShowDialog = sharedPreferences.getBoolean( + CompassCalibrationActivity.DONT_SHOW_CALIBRATION_DIALOG, false + ) + if (dontShowDialog) { + toaster.toastLong("Inaccurate compass - please calibrate") + } else { + val intent = Intent(context, CompassCalibrationActivity::class.java) + intent.putExtra(CompassCalibrationActivity.HIDE_CHECKBOX, false) + intent.putExtra(CompassCalibrationActivity.AUTO_DISMISSABLE, true) + context.startActivity(intent) + } + } + + companion object { + private val TAG = getTag(SensorAccuracyMonitor::class.java) + private const val LAST_CALIBRATION_WARNING_PREF_KEY = "Last calibration warning time" + private const val MIN_INTERVAL_BETWEEN_WARNINGS = 180 * TimeConstants.MILLISECONDS_PER_SECOND + } + + init { + Log.d(TAG, "Creating new accuracy monitor") + this.sensorManager = sensorManager + this.context = context + this.sharedPreferences = sharedPreferences + this.toaster = toaster + compassSensor = sensorManager!!.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/google/android/stardroid/util/Toaster.java b/app/src/main/java/com/google/android/stardroid/util/Toaster.java deleted file mode 100644 index f8f161810..000000000 --- a/app/src/main/java/com/google/android/stardroid/util/Toaster.java +++ /dev/null @@ -1,28 +0,0 @@ -package com.google.android.stardroid.util; - -import android.content.Context; -import android.widget.Toast; - -import javax.inject.Inject; - -/** - * A wrapper around the Toast mechanism for easier unit testing. - * - * Created by johntaylor on 4/24/16. - */ -public class Toaster { - private Context context; - - @Inject - public Toaster(Context context) { - this.context = context; - } - - public void toastLong(int resId) { - Toast.makeText(context, resId, Toast.LENGTH_LONG).show(); - } - - public void toastLong(String s) { - Toast.makeText(context, s, Toast.LENGTH_LONG).show(); - } -} diff --git a/app/src/main/java/com/google/android/stardroid/util/Toaster.kt b/app/src/main/java/com/google/android/stardroid/util/Toaster.kt new file mode 100644 index 000000000..666e7dc16 --- /dev/null +++ b/app/src/main/java/com/google/android/stardroid/util/Toaster.kt @@ -0,0 +1,20 @@ +package com.google.android.stardroid.util + +import android.content.Context +import javax.inject.Inject +import android.widget.Toast + +/** + * A wrapper around the Toast mechanism for easier unit testing. + * + * Created by johntaylor on 4/24/16. + */ +class Toaster @Inject constructor(private val context: Context) { + fun toastLong(resId: Int) { + Toast.makeText(context, resId, Toast.LENGTH_LONG).show() + } + + fun toastLong(s: String?) { + Toast.makeText(context, s, Toast.LENGTH_LONG).show() + } +} \ No newline at end of file diff --git a/app/src/main/java/com/google/android/stardroid/views/source/ViewSourceListener.java b/app/src/main/java/com/google/android/stardroid/views/source/ViewSourceListener.java deleted file mode 100644 index 816d0814c..000000000 --- a/app/src/main/java/com/google/android/stardroid/views/source/ViewSourceListener.java +++ /dev/null @@ -1,76 +0,0 @@ -// 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.stardroid.views.source; - -import java.util.List; - -import com.google.android.stardroid.renderables.ImagePrimitive; -import com.google.android.stardroid.renderables.LinePrimitive; -import com.google.android.stardroid.renderables.PointPrimitive; -import com.google.android.stardroid.renderables.TextPrimitive; - -/** - * Defines a simple listener interface which responds to changes in the sources and - * updates the corresponding views. - * - * - * @author Brent Bryan - */ -public interface ViewSourceListener { - - /** - * Sets all of the PointSources for a specific id in response to one or more - * source changing values. Changes include addition of new object, updates of - * current objects, or deletion of current objects. Any PointSources set - * previously with the same id value will be overwritten. - * - * @param id a unique identify integer for this set of point sources. - * @param s a list of PointSources which should be used. - */ - void setPointSources(int id, List s); - - /** - * Sets all of the TextSources for a specific id in response to one or more - * source changing values. Changes include addition of new object, updates of - * current objects, or deletion of current objects. Any TextSources set - * previously with the same id value will be overwritten. - * - * @param id a unique identify integer for this set of point sources. - * @param s a list of TextSources which should be used. - */ - void setTextSources(int id, List s); - - /** - * Sets all of the ImageSources for a specific id in response to one or more - * source changing values. Changes include addition of new object, updates of - * current objects, or deletion of current objects. Any ImageSources set - * previously with the same id value will be overwritten. - * - * @param id a unique identify integer for this set of point sources. - * @param s a list of ImageSources which should be used. - */ - void setImageSources(int id, List s); - - /** - * Sets all of the PolyLineSources for a specific id in response to one or more - * source changing values. Changes include addition of new object, updates of - * current objects, or deletion of current objects. Any PolyLineSources set - * previously with the same id value will be overwritten. - * - * @param id a unique identify integer for this set of point sources. - * @param s a list of PolyLineSources which should be used. - */ - void setPolyLineSources(int id, List s); -}