2015: add gophercon go-on-mobile talk slide and demo

Change-Id: I8be9d01dabf8800bf6b37d5144fac3d743b08af9
Reviewed-on: https://go-review.googlesource.com/12040
Reviewed-by: David Crawshaw <crawshaw@golang.org>
diff --git a/2015/gophercon-go-on-mobile.slide b/2015/gophercon-go-on-mobile.slide
new file mode 100644
index 0000000..58a48ac
--- /dev/null
+++ b/2015/gophercon-go-on-mobile.slide
@@ -0,0 +1,340 @@
+Go on Mobile
+
+GopherCon 2015
+
+Hana Kim
+Google
+
+* Caution
+
+.image gophercon-go-on-mobile/caution.png 300 _
+
+The Go Mobile project is experimental. Use this at your own risk.
+
+While we are working hard to improve it, neither Google nor the Go
+team can provide end-user support.
+
+* Background
+
+Mobile support was frequently requested
+
+Some users built their own Go binaries for Android with cgo + external linking through NDK tool chains
+
+Some Android Apps used Go even before Go 1.4
+
+- Camlistore android app (out-of-process model)
+- Goandroid+Mandala (in-process model)
+- ...
+
+* golang.org/x/mobile
+
+Goal: Bring Go to Mobile Platforms
+
+Why?
+
+- Use Go to program a complete system (server/client)
+- Write a single cross-platform Go library
+- Bring a simple language and development tooling to mobile
+
+* Two ways of using Go
+
+Native Apps
+
+- Write the whole app in Go
+- Use Go packages for graphics, event handling, audio, etc.
+
+SDK Apps
+
+- Write Android UI in Java, iOS UI in Objective-C/Swift
+- Write common functionality in Go as a library
+
+* Native Apps
+
+* Challenge #1: Cross-platform APIs
+
+Work for Android, iOS, and Desktop environments
+
+Provide a rich set of APIs
+
+Follow idiomatic Go style
+
+* Demo: Hello, Gopher!
+
+.image gophercon-go-on-mobile/gophercloud.png 400 _
+
+This program uses the packages from golang.org/x/mobile repo
+There is no Java or Objective-C or C in my code
+
+* What's available?
+
+golang.org/x/mobile/...
+
+- [[http://golang.org/x/mobile/app][app: App control]]
+- [[http://golang.org/x/mobile/asset][asset: Asset management]]
+- [[http://golang.org/x/mobile/gl][gl: OpenGL ES 2]]
+- [[https://golang.org/x/mobile/event][event: Events]]
+- [[https://golang.org/x/mobile/geom][geom: Screen geometry]]
+
+golang.org/x/mobile/exp/...
+
+- [[https://golang.org/x/mobile/exp/audio][audio: Audio]]
+- [[https://golang.org/x/mobile/exp/font][font: System font]]
+- [[https://golang.org/x/mobile/exp/sprite][sprite: 2-D rendering]]
+- [[https://golang.org/x/mobile/exp/sensor][sensor: Sensors]]
+
+* Challenge #2: Build systems
+
+Dealing with
+
+- Toolchain installation
+
+- Cross compilation for `GOOS/GOARCH` combos
+
+- Android/iOS-specific build details
+
+That is not fun!
+
+* The gomobile tool
+
+  $ go get golang.org/x/mobile/cmd/gomobile
+
+Simplifies toolchain installation and app deployment
+
+To install the Android/iOS compiler tool chain:
+
+	$ gomobile init
+
+To build an Android APK and an iOS app
+
+	$ gomobile -target=android build
+	$ gomobile -target=ios     build
+
+(Demo)
+
+* SDK Apps
+
+* Go as a library
+
+Go 1.5 can build Go programs as a library that can be used by non-Go programs
+
+- Shared library for dynamic linking (`-buildmode=c-shared`)
+- Archive file for static linking (`-buildmode=c-archive`)
+
+Functions marked with `//export` cgo annotations are callable.
+
+.link http://golang.org/s/execmodes
+
+* Working with Foreign Languages
+
+.image gophercon-go-on-mobile/gobind.png 300 _
+
+Manually mapping data structures and functions between languages is tedious and error-prone!
+
+
+* The gobind tool
+
+	$ go get golang.org/x/mobile/cmd/gobind
+
+Automates language binding through code generation
+
+Defines the language binding from exported Go APIs; no explicit annotation
+
+Currently supports a [[http://golang.org/x/mobile/cmd/gobind][subset of Go types]]
+
+
+* Binding Functions, Basic Types & Errors
+
+Go API
+
+	package mypkg
+
+	func Hello() (string, error) { return "Gopher", nil }
+
+Generated Java API
+
+	public abstract class Mypkg {
+	    public static String Hello() throws Exception { ... }
+	}
+
+Generated Objective-C API
+
+	FOUNDATION_EXPORT BOOL GoMypkgHello(NSString** ret0_, NSError** error);
+
+* Binding Structs
+
+	package mypkg
+
+	type Counter struct {
+		Value int64
+	}
+
+	func (c *Counter) Inc() {
+		c.Value++
+	}
+
+	func NewCounter() *Counter {
+		return &Counter{}
+	}
+
+* Generated Java API
+
+	public abstract class Mypkg {
+		public static final class Counter {
+			public void Inc() { ... }
+			public long GetValue() { ... }
+			public void SetValue(long value) { ... }
+		}
+
+		public static Counter NewCounter() { ... }
+	}
+
+Use it from Java
+
+	Counter counter = NewCounter();
+	counter.SetValue(12345);
+	counter.Inc();
+	
+
+* Generated Objective-C API
+  	
+	@interface GoMypkgCounter : NSObject { }
+	@property(strong, readonly) GoSeqRef *ref;
+	- (int64_t)Value;
+	- (void)setValue:(int64_t)v;
+	- (void)Inc;
+	@end
+	
+	FOUNDATION_EXPORT GoMypkgCounter* GoMypkgNewCounter();
+
+Use it from Objective-C
+
+	GoMypkgCounter* counter = GoMypkgNewCounter();
+	[counter setValue:12345];
+	[counter Inc];
+
+* How to build it?
+
+.image gophercon-go-on-mobile/memegobind.jpg 500 _
+
+
+* The gomobile bind command
+
+Simplifies the build process. For example, for Android,
+
+- Generates language bindings for Go packages
+
+- Compiles Go code to a shared library
+
+- Compiles the generated target language code
+
+- Bundles everything into a `.aar` file (modern way to distribute android libraries)
+
+(DEMO)
+
+iOS support is a work in progress.
+
+* Android Studio Integration
+
+Android Studio 1.2+ supports `.aar` import.
+
+.image gophercon-go-on-mobile/androidstudio2.png 250 _
+
+To update the .aar,
+
+- Build script to invoke `gomobile` `bind`, or
+- Gradle plugin to invoke `gomobile` `bind` and publish the output
+
+
+* The Story of Ivy
+
+The [[robpike.io/ivy][Ivy]] is a command line tool developed by Rob Pike
+
+It's a useful desktop calculator that handles big int, rational and floating-point numbers, vectors, matrices, ...
+
+.image gophercon-go-on-mobile/ivyscreenshot2.png 300 _
+
+It is in fact an interpreter for an [[https://en.wikipedia.org/wiki/APL_(programming_language)][APL]]-like language
+
+* Ivy on Mobile?
+
+~5k lines of Go code (not including tests, docs)
+
+Dependency on `math`, `math/big`, `math/rand`, `unicode`, ...
+
+.image gophercon-go-on-mobile/canihas.jpg 300 _
+
+Rewriting in Java or Objective-C is a non-starter
+
+* Ivy apps
+
+.image gophercon-go-on-mobile/ivymobile.png 300 _
+.caption Ivy logo by [[http://www.reneefrench.com][Renée French]]
+.link https://play.google.com/store/apps/details?id=org.golang.ivy Google Play Store
+.link https://itunes.apple.com/us/app/ivy-big-number-calculator/id1012116478 Apple App Store
+
+* Gomobile bind
+
+Write it once as a library in Go
+
+Enjoy great language features and packages available in Go
+
+* Where are we now?
+
+* Go 1.4: Hello Android!
+
+Released in December 2014
+
+Can build Android apps (`arm`)
+
+Android builder
+ 
+The `gobind` tool for Java and Go language binding
+
+Packages for cross-device apps: basic app control, OpenGL ES 2, touch
+
+.link https://golang.org/s/go14android
+.link https://golang.org/s/gobind
+
+* Go 1.5: Hello iOS!
+
+Planned release early August 2015
+
+Experimental support for iOS (`arm,arm64`)
+
+iOS builder 
+
+* Go 1.5: Go programs as libraries
+
+Can call Go functions from foreign language in a clean way
+
+.link golang.org/s/execmodes
+
+* Go 1.5: Better tools & more packages
+
+`golang.org/x/mobile` repo getting better
+
+- The `gomobile` tool for mobile app/library build
+
+- Extended `gobind` tool: Objective-C binding
+
+- `golang.org/x/mobile/exp`: experimenting with audio, sensor, sprite, ...
+
+* Go 1.6+
+
+- Improvement in GL/UI packages
+
+- More APIs available to "pure Go" apps
+
+- Testing, profiling, debugging
+
+- Support for more platforms (e.g. android/x86, iOS simulator)
+
+- Richer type support in `gobind`
+
+- IDE integration
+
+* Contributions from Go community
+
+.image gophercon-go-on-mobile/contributors.png 480 _
+.caption git log | word_cloud
+
diff --git a/2015/gophercon-go-on-mobile/README b/2015/gophercon-go-on-mobile/README
new file mode 100644
index 0000000..1732cd8
--- /dev/null
+++ b/2015/gophercon-go-on-mobile/README
@@ -0,0 +1,38 @@
+Demo Setup
+----------------------
+
+- Download and install Android SDK
+
+https://developer.android.com/sdk/index.html
+Or, easiest way is to install Android Studio.
+
+
+- Download go1.5 and build for your host.
+
+- Set the following environment variables.
+
+GOPATH: your go path
+ANDROID_HOME: Android SDK directory
+PATH: make sure $GOROOT/bin, $GOPATH/bin are included in the path
+
+- Install the gomobile tool and run init before demo.
+
+% go install golang.org/x/mobile/cmd/gomobile
+% gomobile init
+
+- Hello Gopher demo
+
+% demo1.bash
+
+For android screen mirroring, I used Mobizen (mobizen.com).
+For ios screen mirroring, you can use quicktime.
+
+- Gobind demo
+
+% demo2.bash
+
+- Ivy demo: In my gophercon talk, I used pre-recorded video
+clips for mobile versions and ran the command line version from 
+my laptop in order to emphasize the cross-platform support.
+
+Enjoy.
diff --git a/2015/gophercon-go-on-mobile/androidstudio2.png b/2015/gophercon-go-on-mobile/androidstudio2.png
new file mode 100644
index 0000000..add1106
--- /dev/null
+++ b/2015/gophercon-go-on-mobile/androidstudio2.png
Binary files differ
diff --git a/2015/gophercon-go-on-mobile/canihas.jpg b/2015/gophercon-go-on-mobile/canihas.jpg
new file mode 100644
index 0000000..1d94c61
--- /dev/null
+++ b/2015/gophercon-go-on-mobile/canihas.jpg
Binary files differ
diff --git a/2015/gophercon-go-on-mobile/caution.png b/2015/gophercon-go-on-mobile/caution.png
new file mode 100644
index 0000000..cdb9faa
--- /dev/null
+++ b/2015/gophercon-go-on-mobile/caution.png
Binary files differ
diff --git a/2015/gophercon-go-on-mobile/contributors.png b/2015/gophercon-go-on-mobile/contributors.png
new file mode 100644
index 0000000..0da8a6c
--- /dev/null
+++ b/2015/gophercon-go-on-mobile/contributors.png
Binary files differ
diff --git a/2015/gophercon-go-on-mobile/demo1.bash b/2015/gophercon-go-on-mobile/demo1.bash
new file mode 100755
index 0000000..8d750ed
--- /dev/null
+++ b/2015/gophercon-go-on-mobile/demo1.bash
@@ -0,0 +1,20 @@
+#!/bin/bash
+
+prompt() {
+	read -p "$1"
+}
+
+cd hello
+
+declare -a arr=(
+"wc -l main.go"
+"go run main.go"
+"gomobile install -target=android"
+)
+
+for i in "${arr[@]}"
+do
+	prompt "\$ $i"
+	$i
+	echo
+done
diff --git a/2015/gophercon-go-on-mobile/demo2.bash b/2015/gophercon-go-on-mobile/demo2.bash
new file mode 100755
index 0000000..d377162
--- /dev/null
+++ b/2015/gophercon-go-on-mobile/demo2.bash
@@ -0,0 +1,24 @@
+#!/bin/bash
+
+prompt() {
+	read -p "$1"
+}
+
+declare -a arr=(
+"cd mypkg"
+"tree"
+"cat mypkg.go"
+"export ANDROID_HOME=${ANDROID_HOME}"
+"gomobile bind ."
+"tree"
+"unzip -l mypkg.aar"
+)
+
+for i in "${arr[@]}"
+do
+	prompt "\$ $i"
+	$i
+	echo
+done
+
+rm mypkg.aar
diff --git a/2015/gophercon-go-on-mobile/gobind.png b/2015/gophercon-go-on-mobile/gobind.png
new file mode 100644
index 0000000..905b5ea
--- /dev/null
+++ b/2015/gophercon-go-on-mobile/gobind.png
Binary files differ
diff --git a/2015/gophercon-go-on-mobile/gophercloud.png b/2015/gophercon-go-on-mobile/gophercloud.png
new file mode 100644
index 0000000..2bb5d25
--- /dev/null
+++ b/2015/gophercon-go-on-mobile/gophercloud.png
Binary files differ
diff --git a/2015/gophercon-go-on-mobile/hello/assets/gophersmall.png b/2015/gophercon-go-on-mobile/hello/assets/gophersmall.png
new file mode 100644
index 0000000..53b4b4a
--- /dev/null
+++ b/2015/gophercon-go-on-mobile/hello/assets/gophersmall.png
Binary files differ
diff --git a/2015/gophercon-go-on-mobile/hello/assets/hello.wav b/2015/gophercon-go-on-mobile/hello/assets/hello.wav
new file mode 100644
index 0000000..1551ebf
--- /dev/null
+++ b/2015/gophercon-go-on-mobile/hello/assets/hello.wav
Binary files differ
diff --git a/2015/gophercon-go-on-mobile/hello/main.go b/2015/gophercon-go-on-mobile/hello/main.go
new file mode 100644
index 0000000..32aba94
--- /dev/null
+++ b/2015/gophercon-go-on-mobile/hello/main.go
@@ -0,0 +1,207 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Based on golang.org/x/mobile/example/audio
+
+package main
+
+import (
+	"image"
+	"log"
+	"time"
+
+	_ "image/png"
+
+	"golang.org/x/mobile/app"
+	"golang.org/x/mobile/asset"
+	"golang.org/x/mobile/event/config"
+	"golang.org/x/mobile/event/lifecycle"
+	"golang.org/x/mobile/event/paint"
+	"golang.org/x/mobile/event/touch"
+	"golang.org/x/mobile/exp/app/debug"
+	"golang.org/x/mobile/exp/audio"
+	"golang.org/x/mobile/exp/f32"
+	"golang.org/x/mobile/exp/sprite"
+	"golang.org/x/mobile/exp/sprite/clock"
+	"golang.org/x/mobile/exp/sprite/glsprite"
+	"golang.org/x/mobile/geom"
+	"golang.org/x/mobile/gl"
+)
+
+func main() {
+	app.Main(func(a app.App) {
+		for e := range a.Events() {
+			switch e := app.Filter(e).(type) {
+			case lifecycle.Event:
+				switch e.Crosses(lifecycle.StageVisible) {
+				case lifecycle.CrossOn:
+					onStart()
+				case lifecycle.CrossOff:
+					onStop()
+				}
+			case config.Event:
+				globalCfg = e // dimension change. move to the center.
+				touchLoc = geom.Point{globalCfg.Width / 2, globalCfg.Height / 2}
+			case paint.Event:
+				onPaint(globalCfg)
+				a.EndPaint()
+			case touch.Event:
+				onTouch(e)
+			}
+		}
+	})
+}
+
+const (
+	width  = 72
+	height = 74
+)
+
+var (
+	startClock = time.Now()
+	eng        = glsprite.Engine()
+	scene      *sprite.Node
+
+	player *audio.Player
+
+	started     = false
+	activate    = false
+	acceptTouch = false
+	touchLoc    geom.Point
+	globalCfg   config.Event
+)
+
+func onTouch(t touch.Event) {
+	if t.Type != touch.TypeStart {
+		return
+	}
+
+	touchLoc = t.Loc
+	acceptTouch = true
+	if !activate {
+		activate = true
+	}
+}
+
+func onStart() {
+	gl.Enable(gl.BLEND)
+	gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
+
+	rc, err := asset.Open("hello.wav")
+	if err != nil {
+		log.Fatal(err)
+	}
+	player, err = audio.NewPlayer(rc, 0, 0)
+	if err != nil {
+		log.Fatal(err)
+	}
+}
+
+func onStop() {
+	player.Close()
+}
+
+func onPaint(c config.Event) {
+	if !started {
+		touchLoc = geom.Point{c.Width / 2, c.Height / 2}
+		started = true
+	}
+	if scene == nil {
+		loadScene()
+	}
+	gl.ClearColor(242/255.0, 240/255.0, 217/255.0, 1) // gophercon bg color
+	gl.Clear(gl.COLOR_BUFFER_BIT)
+
+	now := clock.Time(time.Since(startClock) * 60 / time.Second)
+	eng.Render(scene, now, c)
+	debug.DrawFPS(c)
+}
+
+func newNode() *sprite.Node {
+	n := &sprite.Node{}
+	eng.Register(n)
+	scene.AppendChild(n)
+	return n
+}
+
+func loadScene() {
+	gopher := loadGopher()
+	scene = &sprite.Node{}
+	eng.Register(scene)
+	eng.SetTransform(scene, f32.Affine{
+		{1, 0, 0},
+		{0, 1, 0},
+	})
+
+	var x, y float32
+	dx, dy := float32(1), float32(1)
+
+	n := newNode()
+	n.Arranger = arrangerFunc(func(eng sprite.Engine, n *sprite.Node, t clock.Time) {
+		eng.SetSubTex(n, gopher)
+
+		if acceptTouch {
+			dx = (float32(touchLoc.X) - x) / 60
+			dy = (float32(touchLoc.Y) - y) / 60
+			acceptTouch = false
+			hello()
+			x += dx
+			y += dy
+		} else if activate {
+			if x < 0 {
+				dx = 1
+			}
+			if y < 0 {
+				dy = 1
+			}
+			if x+width > float32(globalCfg.Width) {
+				dx = -1
+			}
+			if y+height > float32(globalCfg.Height) {
+				dy = -1
+			}
+			x += dx
+			y += dy
+		}
+
+		if dx < 0 {
+			eng.SetTransform(n, f32.Affine{ // change direction
+				{-width, 0, x + width},
+				{0, height, y},
+			})
+		} else {
+			eng.SetTransform(n, f32.Affine{
+				{width, 0, x},
+				{0, height, y},
+			})
+		}
+	})
+}
+
+func hello() {
+	player.Seek(0)
+	player.Play()
+}
+
+func loadGopher() sprite.SubTex {
+	a, err := asset.Open("gophersmall.png")
+	if err != nil {
+		log.Fatal(err)
+	}
+	defer a.Close()
+
+	img, _, err := image.Decode(a)
+	if err != nil {
+		log.Fatal(err)
+	}
+	t, err := eng.LoadTexture(img)
+	if err != nil {
+		log.Fatal(err)
+	}
+	return sprite.SubTex{t, image.Rect(0, 0, 360, 370)}
+}
+
+type arrangerFunc func(e sprite.Engine, n *sprite.Node, t clock.Time)
+
+func (a arrangerFunc) Arrange(e sprite.Engine, n *sprite.Node, t clock.Time) { a(e, n, t) }
diff --git a/2015/gophercon-go-on-mobile/ivyabout.png b/2015/gophercon-go-on-mobile/ivyabout.png
new file mode 100644
index 0000000..3b515f7
--- /dev/null
+++ b/2015/gophercon-go-on-mobile/ivyabout.png
Binary files differ
diff --git a/2015/gophercon-go-on-mobile/ivymobile.png b/2015/gophercon-go-on-mobile/ivymobile.png
new file mode 100644
index 0000000..3ea7d21
--- /dev/null
+++ b/2015/gophercon-go-on-mobile/ivymobile.png
Binary files differ
diff --git a/2015/gophercon-go-on-mobile/ivyscreenshot2.png b/2015/gophercon-go-on-mobile/ivyscreenshot2.png
new file mode 100644
index 0000000..c0701b7
--- /dev/null
+++ b/2015/gophercon-go-on-mobile/ivyscreenshot2.png
Binary files differ
diff --git a/2015/gophercon-go-on-mobile/memegobind.jpg b/2015/gophercon-go-on-mobile/memegobind.jpg
new file mode 100644
index 0000000..16b5a75
--- /dev/null
+++ b/2015/gophercon-go-on-mobile/memegobind.jpg
Binary files differ
diff --git a/2015/gophercon-go-on-mobile/mypkg/assets/myassets.txt b/2015/gophercon-go-on-mobile/mypkg/assets/myassets.txt
new file mode 100644
index 0000000..7e2f179
--- /dev/null
+++ b/2015/gophercon-go-on-mobile/mypkg/assets/myassets.txt
@@ -0,0 +1 @@
+assets
diff --git a/2015/gophercon-go-on-mobile/mypkg/mypkg.go b/2015/gophercon-go-on-mobile/mypkg/mypkg.go
new file mode 100644
index 0000000..12c88ec
--- /dev/null
+++ b/2015/gophercon-go-on-mobile/mypkg/mypkg.go
@@ -0,0 +1,7 @@
+package mypkg
+
+import "fmt"
+
+func Hello(name string) string {
+	return fmt.Sprintf("Hello, %s!", name)
+}