Skip to content

Instantly share code, notes, and snippets.

View seadowg's full-sized avatar

Callum Stott seadowg

View GitHub Profile
@seadowg
seadowg / ObjectProvider.kt
Last active June 14, 2022 16:52
Tiny DI/service locator (whatever) framework for Kotlin that uses a shared singleton (like an Android Application object) as a host for dependencies. Includes Android extensions because reified is fun.
import android.app.Activity
import android.content.Context
import androidx.fragment.app.Fragment
import kotlin.reflect.KClass
import kotlin.reflect.KProperty
class ObjectProvider {
private val providers = mutableMapOf<Class<*>, () -> Any?>()
private val singletons = mutableMapOf<Class<*>, Any?>()
@seadowg
seadowg / MediaRecorderTest.java
Last active January 28, 2021 10:49
MediaRecorder pause and then stop fails
package org.odk.collect.android.instrumented;
import android.media.MediaRecorder;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.io.File;
@seadowg
seadowg / Helper.java
Created February 5, 2020 15:59
Default answer in ImageWidget test
public final class Helpers {
private Helpers() {
}
public static String createMockReference(ReferenceManager referenceManager, String referenceURI) throws InvalidReferenceException {
String localURI = UUID.randomUUID().toString();
return createMockReference(referenceManager, referenceURI, localURI);
}
@seadowg
seadowg / pain-experienced.md
Last active January 22, 2020 15:30
Pain experienced during MediaPlayer refactor

Pain experienced during MediaPlayer refactor

I recently spent some time refactoring how Collect interacts with the Android MediaPlayer (PR here). This resulted in my having to touch a fair amount of the stack involed in form entry so I thought it would be good to do a write up of the pain I experienced (within the code) with some suggestions around improvement we could make.

Disclaimer: all the "Next steps" are definitely just my own and first opinion so are very open to discussion.

ODKView having a lifecycle but not being a Fragment

When Collect renders a Form it uses an ODKView to represent each question (FormEntryPrompt) or "group" of questions. This view is hosted inside a FormEntryActivity. When the user swipes from left to right the ODKView is removed from the view hierarchy and a new one is made for the new question.

Post Mortem: Basic auth issue

What did I see?

  • A Slack message form Helene asking me to look at a Github issue that looked like a production bug.

What actually happened?

  • A change in our OpenRosa http layer (from Apache HttpClient to OkHttp) had created a change in behaviour where, after successfully authenticating with a server over HTTPS, Collect would always preemptively send credentials using Basic Authentication regardless of the Authentication scheme initially used.
  • This problem meant that servers that assumed the Authorization header was a Digest one would break.
@seadowg
seadowg / Advantages.md
Last active April 18, 2017 14:58
Kotlin advantages

Null safety

Kotlin adds null safety into into it's type system as a first class concept. The following would not compile:

val maybe: String = null

In Kotlin every type has a corresponding 'optional' type denoted with a ?:

@seadowg
seadowg / direction.swift
Last active March 10, 2017 09:25
ADT examples in Swift
enum Direction {
case Left
case Right
}
func angle(direction: Direction): Int {
switch(direction) {
case Left: return 90
case Right: return -90
}
$ fly --atcURL http://ci.initech.com:8080 execute -c test.yml --exclude-ignored </dev/null | cat
Connecting to 10.0.2.15:8080 (10.0.2.15:8080)
- 100% |*******************************| 10320k 0:00:00 ETA
initializing with docker:///cstott/node-ruby-kitchen-sink
running script/test.sh
+ git submodule init
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
LANGUAGE = (unset),
LC_ALL = (unset),
@seadowg
seadowg / MeasureTest.java
Created August 23, 2013 07:17
Test requestLayout uses correct MeasureSpec
@Test
public void contentViewShouldBeMeasuredWithSpecExactly() {
Activity activity = Robolectric.buildActivity(Activity.class).create().get();
final int[] measureModes = {0, 0};
View contentView = new View(activity) {
@Override
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
measureModes[0] = MeasureSpec.getMode(widthMeasureSpec);
measureModes[1] = MeasureSpec.getMode(heightMeasureSpec);
@seadowg
seadowg / EventActivity.java
Created May 15, 2013 06:48
Cleaner (IMO) Event Handling in Android
// Standard way of hooking up Events:
public class EventActivity extends Activity {
public onCreate(Bundle savedInstanceState) {
findViewById(R.id.button_one).setOnClickListener(new View.OnClickListener) {
@Override
public void onClick(View view) {
Toast toast = Toast.makeText(EventActivity.this, "Clicked One!", Toast.LENGTH_SHORT);
toast.show()
}