cmd/gomobile: remove binary XML

It is a full of unused code. Remove it.

Change-Id: I086f244adde57c8c9f1fc73b46e25550f15562f7
Reviewed-on: https://go-review.googlesource.com/c/mobile/+/369197
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
Reviewed-by: Emmanuel Odeke <emmanuel@orijtech.com>
Run-TryBot: Hyang-Ah Hana Kim <hyangah@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
diff --git a/cmd/gomobile/binary_xml.go b/cmd/gomobile/binary_xml.go
deleted file mode 100644
index e8b620a..0000000
--- a/cmd/gomobile/binary_xml.go
+++ /dev/null
@@ -1,784 +0,0 @@
-// 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.
-
-package main
-
-import (
-	"encoding/xml"
-	"fmt"
-	"io"
-	"sort"
-	"strconv"
-	"strings"
-	"unicode/utf16"
-)
-
-// binaryXML converts XML into Android's undocumented binary XML format.
-//
-// The best source of information on this format seems to be the source code
-// in AOSP frameworks-base. Android "resource" types seem to describe the
-// encoded bytes, in particular:
-//
-//	ResChunk_header
-//	ResStringPool_header
-//	ResXMLTree_node
-//
-// These are defined in:
-//
-//	https://android.googlesource.com/platform/frameworks/base/+/master/include/androidfw/ResourceTypes.h
-//
-// The rough format of the file is a resource chunk containing a sequence of
-// chunks. Each chunk is made up of a header and a body. The header begins with
-// the contents of the ResChunk_header struct, which includes the size of both
-// the header and the body.
-//
-// Both the header and body are 4-byte aligned.
-//
-// Values are encoded as little-endian.
-//
-// The android source code for encoding is done in the aapt tool. Its source
-// code lives in AOSP:
-//
-//	https://android.googlesource.com/platform/frameworks/base.git/+/master/tools/aapt
-//
-// A sample layout:
-//
-//	File Header (ResChunk_header, type XML)
-//	Chunk: String Pool (type STRING_POOL)
-//	Sequence of strings, each with the format:
-//		uint16 length
-//		uint16 extended_length -- only if top bit set on length
-//		UTF-16LE string
-//		two zero bytes
-//	Resource Map
-//		The [i]th 4-byte entry in the resource map corresponds with
-//		the [i]th string from the string pool. The 4-bytes are a
-//		Resource ID constant defined:
-//			http://developer.android.com/reference/android/R.attr.html
-//		This appears to be a way to map strings onto enum values.
-//	Chunk: Namespace Start (ResXMLTree_node; ResXMLTree_namespaceExt)
-//	Chunk: Element Start
-//		ResXMLTree_node
-//		ResXMLTree_attrExt
-//		ResXMLTree_attribute (repeated attributeCount times)
-//	Chunk: Element End
-//		(ResXMLTree_node; ResXMLTree_endElementExt)
-//	...
-//	Chunk: Namespace End
-func binaryXML(r io.Reader) ([]byte, error) {
-	lr := &lineReader{r: r}
-	d := xml.NewDecoder(lr)
-
-	pool := new(binStringPool)
-	depth := 0
-	elements := []chunk{}
-	namespaceEnds := make(map[int][]binEndNamespace)
-
-	for {
-		line := lr.line(d.InputOffset())
-		tok, err := d.Token()
-		if err != nil {
-			if err == io.EOF {
-				break
-			}
-			return nil, err
-		}
-		switch tok := tok.(type) {
-		case xml.StartElement:
-			// uses-sdk is synthesized by the writer, disallow declaration in manifest.
-			if tok.Name.Local == "uses-sdk" {
-				return nil, fmt.Errorf("unsupported manifest tag <uses-sdk .../>")
-			} else if tok.Name.Local == "application" {
-				// synthesize <uses-sdk/> before handling <application> token
-				attr := xml.Attr{
-					Name: xml.Name{
-						Space: "http://schemas.android.com/apk/res/android",
-						Local: "minSdkVersion",
-					},
-					Value: "15",
-				}
-				ba, err := pool.getAttr(attr)
-				if err != nil {
-					return nil, fmt.Errorf("failed to synthesize attr minSdkVersion=\"15\"")
-				}
-				elements = append(elements,
-					&binStartElement{
-						line: line - 1, // current testing strategy is not friendly to synthesized tags, -1 for would-be location
-						ns:   pool.getNS(""),
-						name: pool.get("uses-sdk"),
-						attr: []*binAttr{ba},
-					},
-					&binEndElement{
-						line: line - 1,
-						ns:   pool.getNS(""),
-						name: pool.get("uses-sdk"),
-					})
-			}
-			// Intercept namespace definitions.
-			var attr []*binAttr
-			for _, a := range tok.Attr {
-				if a.Name.Space == "xmlns" {
-					elements = append(elements, binStartNamespace{
-						line:   line,
-						prefix: pool.get(a.Name.Local),
-						url:    pool.get(a.Value),
-					})
-					namespaceEnds[depth] = append([]binEndNamespace{{
-						line:   line,
-						prefix: pool.get(a.Name.Local),
-						url:    pool.get(a.Value),
-					}}, namespaceEnds[depth]...)
-					continue
-				}
-				ba, err := pool.getAttr(a)
-				if err != nil {
-					return nil, fmt.Errorf("%d: %s: %v", line, a.Name.Local, err)
-				}
-				attr = append(attr, ba)
-			}
-
-			depth++
-			elements = append(elements, &binStartElement{
-				line: line,
-				ns:   pool.getNS(tok.Name.Space),
-				name: pool.get(tok.Name.Local),
-				attr: attr,
-			})
-		case xml.EndElement:
-			elements = append(elements, &binEndElement{
-				line: line,
-				ns:   pool.getNS(tok.Name.Space),
-				name: pool.get(tok.Name.Local),
-			})
-			depth--
-			if nsEnds := namespaceEnds[depth]; len(nsEnds) > 0 {
-				delete(namespaceEnds, depth)
-				for _, nsEnd := range nsEnds {
-					elements = append(elements, nsEnd)
-				}
-			}
-		case xml.CharData:
-			// The aapt tool appears to "compact" leading and
-			// trailing whitepsace. See XMLNode::removeWhitespace in
-			// https://android.googlesource.com/platform/frameworks/base.git/+/master/tools/aapt/XMLNode.cpp
-			if len(tok) == 0 {
-				continue
-			}
-			start, end := 0, len(tok)
-			for start < len(tok) && isSpace(tok[start]) {
-				start++
-			}
-			for end > start && isSpace(tok[end-1]) {
-				end--
-			}
-			if start == end {
-				continue // all whitespace, skip it
-			}
-
-			// Preserve one character of whitespace.
-			if start > 0 {
-				start--
-			}
-			if end < len(tok) {
-				end++
-			}
-
-			elements = append(elements, &binCharData{
-				line: line,
-				data: pool.get(string(tok[start:end])),
-			})
-		case xml.Comment:
-			// Ignored by Anroid Binary XML format.
-		case xml.ProcInst:
-			// Ignored by Anroid Binary XML format?
-		case xml.Directive:
-			// Ignored by Anroid Binary XML format.
-		default:
-			return nil, fmt.Errorf("apk: unexpected token: %v (%T)", tok, tok)
-		}
-	}
-
-	sortPool(pool)
-	for _, e := range elements {
-		if e, ok := e.(*binStartElement); ok {
-			sortAttr(e, pool)
-		}
-	}
-
-	resMap := &binResMap{pool}
-
-	size := 8 + pool.size() + resMap.size()
-	for _, e := range elements {
-		size += e.size()
-	}
-
-	b := make([]byte, 0, size)
-	b = appendHeader(b, headerXML, size)
-	b = pool.append(b)
-	b = resMap.append(b)
-	for _, e := range elements {
-		b = e.append(b)
-	}
-
-	return b, nil
-}
-
-func isSpace(b byte) bool {
-	switch b {
-	case '\t', '\n', '\v', '\f', '\r', ' ', 0x85, 0xA0:
-		return true
-	}
-	return false
-}
-
-type headerType uint16
-
-const (
-	headerXML            headerType = 0x0003
-	headerStringPool                = 0x0001
-	headerResourceMap               = 0x0180
-	headerStartNamespace            = 0x0100
-	headerEndNamespace              = 0x0101
-	headerStartElement              = 0x0102
-	headerEndElement                = 0x0103
-	headerCharData                  = 0x0104
-)
-
-func appendU16(b []byte, v uint16) []byte {
-	return append(b, byte(v), byte(v>>8))
-}
-
-func appendU32(b []byte, v uint32) []byte {
-	return append(b, byte(v), byte(v>>8), byte(v>>16), byte(v>>24))
-}
-
-func appendHeader(b []byte, typ headerType, size int) []byte {
-	b = appendU16(b, uint16(typ))
-	b = appendU16(b, 8)
-	b = appendU16(b, uint16(size))
-	b = appendU16(b, 0)
-	return b
-}
-
-// Attributes of the form android:key are mapped to resource IDs, which are
-// embedded into the Binary XML format.
-//
-// http://developer.android.com/reference/android/R.attr.html
-var resourceCodes = map[string]uint32{
-	"versionCode":       0x0101021b,
-	"versionName":       0x0101021c,
-	"minSdkVersion":     0x0101020c,
-	"windowFullscreen":  0x0101020d,
-	"theme":             0x01010000,
-	"label":             0x01010001,
-	"hasCode":           0x0101000c,
-	"debuggable":        0x0101000f,
-	"name":              0x01010003,
-	"screenOrientation": 0x0101001e,
-	"configChanges":     0x0101001f,
-	"value":             0x01010024,
-}
-
-// http://developer.android.com/reference/android/R.attr.html#configChanges
-var configChanges = map[string]uint32{
-	"mcc":                0x0001,
-	"mnc":                0x0002,
-	"locale":             0x0004,
-	"touchscreen":        0x0008,
-	"keyboard":           0x0010,
-	"keyboardHidden":     0x0020,
-	"navigation":         0x0040,
-	"orientation":        0x0080,
-	"screenLayout":       0x0100,
-	"uiMode":             0x0200,
-	"screenSize":         0x0400,
-	"smallestScreenSize": 0x0800,
-	"layoutDirection":    0x2000,
-	"fontScale":          0x40000000,
-}
-
-// http://developer.android.com/reference/android/R.attr.html#screenOrientation
-var screenOrientation = map[string]int{
-	"unspecified":      -1,
-	"landscape":        0,
-	"portrait":         1,
-	"user":             2,
-	"behind":           3,
-	"sensor":           4,
-	"nosensor":         5,
-	"sensorLandscape":  6,
-	"sensorPortrait":   7,
-	"reverseLandscape": 8,
-	"reversePortrait":  9,
-	"fullSensor":       10,
-	"userLandscape":    11,
-	"userPortrait":     12,
-	"fullUser":         13,
-	"locked":           14,
-}
-
-// reference is an alias used to write out correct type in bin.
-type reference uint32
-
-// http://developer.android.com/reference/android/R.style.html
-var theme = map[string]reference{
-	"Theme":                                   0x01030005,
-	"Theme_NoTitleBar":                        0x01030006,
-	"Theme_NoTitleBar_Fullscreen":             0x01030007,
-	"Theme_Black":                             0x01030008,
-	"Theme_Black_NoTitleBar":                  0x01030009,
-	"Theme_Black_NoTitleBar_Fullscreen":       0x0103000a,
-	"Theme_Light":                             0x0103000c,
-	"Theme_Light_NoTitleBar":                  0x0103000d,
-	"Theme_Light_NoTitleBar_Fullscreen":       0x0103000e,
-	"Theme_Translucent":                       0x0103000f,
-	"Theme_Translucent_NoTitleBar":            0x01030010,
-	"Theme_Translucent_NoTitleBar_Fullscreen": 0x01030011,
-}
-
-type lineReader struct {
-	off   int64
-	lines []int64
-	r     io.Reader
-}
-
-func (r *lineReader) Read(p []byte) (n int, err error) {
-	n, err = r.r.Read(p)
-	for i := 0; i < n; i++ {
-		if p[i] == '\n' {
-			r.lines = append(r.lines, r.off+int64(i))
-		}
-	}
-	r.off += int64(n)
-	return n, err
-}
-
-func (r *lineReader) line(pos int64) int {
-	return sort.Search(len(r.lines), func(i int) bool {
-		return pos < r.lines[i]
-	}) + 1
-}
-
-type bstring struct {
-	ind uint32
-	str string
-	enc []byte // 2-byte length, utf16le, 2-byte zero
-}
-
-type chunk interface {
-	size() int
-	append([]byte) []byte
-}
-
-type binResMap struct {
-	pool *binStringPool
-}
-
-func (p *binResMap) append(b []byte) []byte {
-	b = appendHeader(b, headerResourceMap, p.size())
-	for _, bstr := range p.pool.s {
-		c, ok := resourceCodes[bstr.str]
-		if !ok {
-			break
-		}
-		b = appendU32(b, c)
-	}
-	return b
-}
-
-func (p *binResMap) size() int {
-	count := 0
-	for _, bstr := range p.pool.s {
-		if _, ok := resourceCodes[bstr.str]; !ok {
-			break
-		}
-		count++
-	}
-	return 8 + 4*count
-}
-
-type binStringPool struct {
-	s []*bstring
-	m map[string]*bstring
-}
-
-func (p *binStringPool) get(str string) *bstring {
-	if p.m == nil {
-		p.m = make(map[string]*bstring)
-	}
-	res := p.m[str]
-	if res != nil {
-		return res
-	}
-	res = &bstring{
-		ind: uint32(len(p.s)),
-		str: str,
-	}
-	p.s = append(p.s, res)
-	p.m[str] = res
-
-	if len(str)>>16 > 0 {
-		panic(fmt.Sprintf("string lengths over 1<<15 not yet supported, got len %d for string that starts %q", len(str), str[:100]))
-	}
-	strUTF16 := utf16.Encode([]rune(str))
-	res.enc = appendU16(nil, uint16(len(strUTF16)))
-	for _, w := range strUTF16 {
-		res.enc = appendU16(res.enc, w)
-	}
-	res.enc = appendU16(res.enc, 0)
-	return res
-}
-
-func (p *binStringPool) getNS(ns string) *bstring {
-	if ns == "" {
-		// Register empty string for inclusion in output (like aapt),
-		// but do not reference it from namespace elements.
-		p.get("")
-		return nil
-	}
-	return p.get(ns)
-}
-
-func (p *binStringPool) getAttr(attr xml.Attr) (*binAttr, error) {
-	a := &binAttr{
-		ns:   p.getNS(attr.Name.Space),
-		name: p.get(attr.Name.Local),
-	}
-	if attr.Name.Space != "http://schemas.android.com/apk/res/android" {
-		a.data = p.get(attr.Value)
-		return a, nil
-	}
-
-	// Some android attributes have interesting values.
-	switch attr.Name.Local {
-	case "versionCode", "minSdkVersion":
-		v, err := strconv.Atoi(attr.Value)
-		if err != nil {
-			return nil, err
-		}
-		a.data = int(v)
-	case "hasCode", "debuggable":
-		v, err := strconv.ParseBool(attr.Value)
-		if err != nil {
-			return nil, err
-		}
-		a.data = v
-	case "configChanges":
-		v := uint32(0)
-		for _, c := range strings.Split(attr.Value, "|") {
-			v |= configChanges[c]
-		}
-		a.data = v
-	case "screenOrientation":
-		v := 0
-		for _, c := range strings.Split(attr.Value, "|") {
-			v |= screenOrientation[c]
-		}
-		a.data = v
-	case "theme":
-		v := attr.Value
-		// strip prefix if present as only platform themes are supported
-		if idx := strings.Index(attr.Value, "/"); idx != -1 {
-			v = v[idx+1:]
-		}
-		v = strings.Replace(v, ".", "_", -1)
-		a.data = theme[v]
-	default:
-		a.data = p.get(attr.Value)
-	}
-	return a, nil
-}
-
-const stringPoolPreamble = 0 +
-	8 + // chunk header
-	4 + // string count
-	4 + // style count
-	4 + // flags
-	4 + // strings start
-	4 + // styles start
-	0
-
-func (p *binStringPool) unpaddedSize() int {
-	strLens := 0
-	for _, s := range p.s {
-		strLens += len(s.enc)
-	}
-	return stringPoolPreamble + 4*len(p.s) + strLens
-}
-
-func (p *binStringPool) size() int {
-	size := p.unpaddedSize()
-	size += size % 0x04
-	return size
-}
-
-// overloaded for testing.
-var (
-	sortPool = func(p *binStringPool) {
-		sort.Sort(p)
-
-		// Move resourceCodes to the front.
-		s := make([]*bstring, 0)
-		m := make(map[string]*bstring)
-		for str := range resourceCodes {
-			bstr := p.m[str]
-			if bstr == nil {
-				continue
-			}
-			bstr.ind = uint32(len(s))
-			s = append(s, bstr)
-			m[str] = bstr
-			delete(p.m, str)
-		}
-		for _, bstr := range p.m {
-			bstr.ind = uint32(len(s))
-			s = append(s, bstr)
-		}
-		p.s = s
-		p.m = m
-	}
-	sortAttr = func(e *binStartElement, p *binStringPool) {}
-)
-
-func (b *binStringPool) Len() int           { return len(b.s) }
-func (b *binStringPool) Less(i, j int) bool { return b.s[i].str < b.s[j].str }
-func (b *binStringPool) Swap(i, j int) {
-	b.s[i], b.s[j] = b.s[j], b.s[i]
-	b.s[i].ind, b.s[j].ind = b.s[j].ind, b.s[i].ind
-}
-
-func (p *binStringPool) append(b []byte) []byte {
-	stringsStart := uint32(stringPoolPreamble + 4*len(p.s))
-	b = appendU16(b, uint16(headerStringPool))
-	b = appendU16(b, 0x1c) // chunk header size
-	b = appendU16(b, uint16(p.size()))
-	b = appendU16(b, 0)
-	b = appendU32(b, uint32(len(p.s)))
-	b = appendU32(b, 0) // style count
-	b = appendU32(b, 0) // flags
-	b = appendU32(b, stringsStart)
-	b = appendU32(b, 0) // styles start
-
-	off := 0
-	for _, bstr := range p.s {
-		b = appendU32(b, uint32(off))
-		off += len(bstr.enc)
-	}
-	for _, bstr := range p.s {
-		b = append(b, bstr.enc...)
-	}
-
-	for i := p.unpaddedSize() % 0x04; i > 0; i-- {
-		b = append(b, 0)
-	}
-	return b
-}
-
-type binStartElement struct {
-	line int
-	ns   *bstring
-	name *bstring
-	attr []*binAttr
-}
-
-func (e *binStartElement) size() int {
-	return 8 + // chunk header
-		4 + // line number
-		4 + // comment
-		4 + // ns
-		4 + // name
-		2 + 2 + 2 + // attribute start, size, count
-		2 + 2 + 2 + // id/class/style index
-		len(e.attr)*(4+4+4+4+4)
-}
-
-func (e *binStartElement) append(b []byte) []byte {
-	b = appendU16(b, uint16(headerStartElement))
-	b = appendU16(b, 0x10) // chunk header size
-	b = appendU16(b, uint16(e.size()))
-	b = appendU16(b, 0)
-	b = appendU32(b, uint32(e.line))
-	b = appendU32(b, 0xffffffff) // comment
-	if e.ns == nil {
-		b = appendU32(b, 0xffffffff)
-	} else {
-		b = appendU32(b, e.ns.ind)
-	}
-	b = appendU32(b, e.name.ind)
-	b = appendU16(b, 0x14) // attribute start
-	b = appendU16(b, 0x14) // attribute size
-	b = appendU16(b, uint16(len(e.attr)))
-	b = appendU16(b, 0) // ID index (none)
-	b = appendU16(b, 0) // class index (none)
-	b = appendU16(b, 0) // style index (none)
-	for _, a := range e.attr {
-		b = a.append(b)
-	}
-	return b
-}
-
-type binAttr struct {
-	ns   *bstring
-	name *bstring
-	data interface{} // either int (INT_DEC) or *bstring (STRING)
-}
-
-func (a *binAttr) append(b []byte) []byte {
-	if a.ns != nil {
-		b = appendU32(b, a.ns.ind)
-	} else {
-		b = appendU32(b, 0xffffffff)
-	}
-	b = appendU32(b, a.name.ind)
-	switch v := a.data.(type) {
-	case int:
-		b = appendU32(b, 0xffffffff) // raw value
-		b = appendU16(b, 8)          // size
-		b = append(b, 0)             // unused padding
-		b = append(b, 0x10)          // INT_DEC
-		b = appendU32(b, uint32(v))
-	case bool:
-		b = appendU32(b, 0xffffffff) // raw value
-		b = appendU16(b, 8)          // size
-		b = append(b, 0)             // unused padding
-		b = append(b, 0x12)          // INT_BOOLEAN
-		if v {
-			b = appendU32(b, 0xffffffff)
-		} else {
-			b = appendU32(b, 0)
-		}
-	case uint32:
-		b = appendU32(b, 0xffffffff) // raw value
-		b = appendU16(b, 8)          // size
-		b = append(b, 0)             // unused padding
-		b = append(b, 0x11)          // INT_HEX
-		b = appendU32(b, uint32(v))
-	case reference:
-		b = appendU32(b, 0xffffffff) // raw value
-		b = appendU16(b, 8)          // size
-		b = append(b, 0)             // unused padding
-		b = append(b, 0x01)          // REFERENCE
-		b = appendU32(b, uint32(v))
-	case *bstring:
-		b = appendU32(b, v.ind) // raw value
-		b = appendU16(b, 8)     // size
-		b = append(b, 0)        // unused padding
-		b = append(b, 0x03)     // STRING
-		b = appendU32(b, v.ind)
-	default:
-		panic(fmt.Sprintf("unexpected attr type: %T (%v)", v, v))
-	}
-	return b
-}
-
-type binEndElement struct {
-	line int
-	ns   *bstring
-	name *bstring
-	attr []*binAttr
-}
-
-func (*binEndElement) size() int {
-	return 8 + // chunk header
-		4 + // line number
-		4 + // comment
-		4 + // ns
-		4 // name
-}
-
-func (e *binEndElement) append(b []byte) []byte {
-	b = appendU16(b, uint16(headerEndElement))
-	b = appendU16(b, 0x10) // chunk header size
-	b = appendU16(b, uint16(e.size()))
-	b = appendU16(b, 0)
-	b = appendU32(b, uint32(e.line))
-	b = appendU32(b, 0xffffffff) // comment
-	if e.ns == nil {
-		b = appendU32(b, 0xffffffff)
-	} else {
-		b = appendU32(b, e.ns.ind)
-	}
-	b = appendU32(b, e.name.ind)
-	return b
-}
-
-type binStartNamespace struct {
-	line   int
-	prefix *bstring
-	url    *bstring
-}
-
-func (binStartNamespace) size() int {
-	return 8 + // chunk header
-		4 + // line number
-		4 + // comment
-		4 + // prefix
-		4 // url
-}
-
-func (e binStartNamespace) append(b []byte) []byte {
-	b = appendU16(b, uint16(headerStartNamespace))
-	b = appendU16(b, 0x10) // chunk header size
-	b = appendU16(b, uint16(e.size()))
-	b = appendU16(b, 0)
-	b = appendU32(b, uint32(e.line))
-	b = appendU32(b, 0xffffffff) // comment
-	b = appendU32(b, e.prefix.ind)
-	b = appendU32(b, e.url.ind)
-	return b
-}
-
-type binEndNamespace struct {
-	line   int
-	prefix *bstring
-	url    *bstring
-}
-
-func (binEndNamespace) size() int {
-	return 8 + // chunk header
-		4 + // line number
-		4 + // comment
-		4 + // prefix
-		4 // url
-}
-
-func (e binEndNamespace) append(b []byte) []byte {
-	b = appendU16(b, uint16(headerEndNamespace))
-	b = appendU16(b, 0x10) // chunk header size
-	b = appendU16(b, uint16(e.size()))
-	b = appendU16(b, 0)
-	b = appendU32(b, uint32(e.line))
-	b = appendU32(b, 0xffffffff) // comment
-	b = appendU32(b, e.prefix.ind)
-	b = appendU32(b, e.url.ind)
-	return b
-}
-
-type binCharData struct {
-	line int
-	data *bstring
-}
-
-func (*binCharData) size() int {
-	return 8 + // chunk header
-		4 + // line number
-		4 + // comment
-		4 + // data
-		8 // junk
-}
-
-func (e *binCharData) append(b []byte) []byte {
-	b = appendU16(b, uint16(headerCharData))
-	b = appendU16(b, 0x10) // chunk header size
-	b = appendU16(b, 0x1c) // size
-	b = appendU16(b, 0)
-	b = appendU32(b, uint32(e.line))
-	b = appendU32(b, 0xffffffff) // comment
-	b = appendU32(b, e.data.ind)
-	b = appendU16(b, 0x08)
-	b = appendU16(b, 0)
-	b = appendU16(b, 0)
-	b = appendU16(b, 0)
-	return b
-}
diff --git a/cmd/gomobile/binary_xml_test.go b/cmd/gomobile/binary_xml_test.go
deleted file mode 100644
index d4705ac..0000000
--- a/cmd/gomobile/binary_xml_test.go
+++ /dev/null
@@ -1,249 +0,0 @@
-// 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.
-
-package main
-
-import (
-	"archive/zip"
-	"bytes"
-	"flag"
-	"fmt"
-	"io/ioutil"
-	"log"
-	"os"
-	"os/exec"
-	"path/filepath"
-	"testing"
-)
-
-var dump = flag.Bool("dump", false, "dump junk.bin binary output")
-
-var (
-	origSortPool = sortPool
-	origSortAttr = sortAttr
-)
-
-func TestBinaryXML(t *testing.T) {
-	sortPool, sortAttr = sortToMatchTest, sortAttrToMatchTest
-	defer func() { sortPool, sortAttr = origSortPool, origSortAttr }()
-
-	bin, err := binaryXML(bytes.NewBufferString(fmt.Sprintf(input, "")))
-	if err != nil {
-		t.Fatal(err)
-	}
-	if *dump {
-		if err := ioutil.WriteFile("junk.bin", bin, 0660); err != nil {
-			t.Fatal(err)
-		}
-	}
-
-	if exec.Command("which", "aapt").Run() != nil {
-		t.Skip("command aapt not found, skipping")
-	}
-
-	apiPath, err := androidAPIPath()
-	if err != nil {
-		t.Fatal(err)
-	}
-	androidJar := filepath.Join(apiPath, "android.jar")
-
-	tmpdir, err := ioutil.TempDir("", "gomobile-test-")
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer os.RemoveAll(tmpdir)
-
-	buf := new(bytes.Buffer)
-	zw := zip.NewWriter(buf)
-	zf, err := zw.Create("AndroidManifest.xml")
-	if err != nil {
-		t.Fatal(err)
-	}
-	if _, err := zf.Write(bin); err != nil {
-		t.Fatal(err)
-	}
-	if err := zw.Close(); err != nil {
-		t.Fatal(err)
-	}
-
-	mblapk := filepath.Join(tmpdir, "mbl.apk")
-	if err := ioutil.WriteFile(mblapk, buf.Bytes(), 0755); err != nil {
-		t.Fatal(err)
-	}
-
-	got, err := exec.Command("aapt", "d", "xmltree", mblapk, "AndroidManifest.xml").Output()
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	manifest := filepath.Join(tmpdir, "AndroidManifest.xml")
-	inp := fmt.Sprintf(input, "<uses-sdk android:minSdkVersion=\"15\" />")
-	if err := ioutil.WriteFile(manifest, []byte(inp), 0755); err != nil {
-		t.Fatal(err)
-	}
-
-	sdkapk := filepath.Join(tmpdir, "sdk.apk")
-	if _, err := exec.Command("aapt", "p", "-M", manifest, "-I", androidJar, "-F", sdkapk).Output(); err != nil {
-		t.Fatal(err)
-	}
-
-	sdkout, err := exec.Command("aapt", "d", "xmltree", sdkapk, "AndroidManifest.xml").Output()
-	if err != nil {
-		t.Fatal(err)
-	}
-	if *dump {
-		b, err := ioutil.ReadFile(sdkapk)
-		if err != nil {
-			t.Fatal(err)
-		}
-		if err := ioutil.WriteFile("junk.sdk.apk", b, 0755); err != nil {
-			t.Fatal(err)
-		}
-	}
-
-	// manifests contain platformBuildVersionCode and platformBuildVersionName
-	// which are not present in gomobile output.
-	var fo [][]byte
-	for _, line := range bytes.Split(sdkout, []byte{'\n'}) {
-		if bytes.Contains(line, []byte("platformBuildVersionCode")) || bytes.Contains(line, []byte("platformBuildVersionName")) {
-			continue
-		}
-		fo = append(fo, line)
-	}
-	want := bytes.Join(fo, []byte{'\n'})
-
-	if !bytes.Equal(want, got) {
-		t.Fatalf("output does not match\nWANT\n%s\nGOT\n%s\n", want, got)
-	}
-}
-
-// The output of the Android encoder seems to be arbitrary. So for testing,
-// we sort the string pool order to match the output we have seen.
-func sortToMatchTest(p *binStringPool) {
-	var names = []string{
-		"versionCode",
-		"versionName",
-		"minSdkVersion",
-		"theme",
-		"label",
-		"hasCode",
-		"debuggable",
-		"name",
-		"screenOrientation",
-		"configChanges",
-		"value",
-		"android",
-		"http://schemas.android.com/apk/res/android",
-		"",
-		"package",
-		"manifest",
-		"com.zentus.balloon",
-		"1.0",
-		"uses-sdk",
-		"application",
-		"Balloon世界",
-		"activity",
-		"android.app.NativeActivity",
-		"Balloon",
-		"meta-data",
-		"android.app.lib_name",
-		"balloon",
-		"intent-filter",
-		"\there is some text\n",
-		"action",
-		"android.intent.action.MAIN",
-		"category",
-		"android.intent.category.LAUNCHER",
-	}
-
-	s := make([]*bstring, 0)
-	m := make(map[string]*bstring)
-
-	for _, str := range names {
-		bstr := p.m[str]
-		if bstr == nil {
-			log.Printf("missing %q", str)
-			continue
-		}
-		bstr.ind = uint32(len(s))
-		s = append(s, bstr)
-		m[str] = bstr
-		delete(p.m, str)
-	}
-	// add unexpected strings
-	for str, bstr := range p.m {
-		log.Printf("unexpected %q", str)
-		bstr.ind = uint32(len(s))
-		s = append(s, bstr)
-	}
-	p.s = s
-	p.m = m
-}
-
-func sortAttrToMatchTest(e *binStartElement, p *binStringPool) {
-	order := []string{
-		"versionCode",
-		"versionName",
-		"versionPackage",
-
-		"theme",
-		"label",
-		"name",
-		"screenOrientation",
-		"configChanges",
-	}
-	ordered := make([]*binAttr, len(order))
-
-outer:
-	for i, n := range order {
-		for j, a := range e.attr {
-			if a != nil && a.name.str == n {
-				ordered[i] = a
-				e.attr[j] = nil
-				continue outer
-			}
-		}
-	}
-	var attr []*binAttr
-	for _, a := range ordered {
-		if a != nil {
-			attr = append(attr, a)
-		}
-	}
-	for _, a := range e.attr {
-		if a != nil {
-			attr = append(attr, a)
-		}
-	}
-	e.attr = attr
-}
-
-const input = `<?xml version="1.0" encoding="utf-8"?>
-<!--
-Copyright 2014 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.
--->
-<manifest
-	xmlns:android="http://schemas.android.com/apk/res/android"
-	package="com.zentus.balloon"
-	android:versionCode="1"
-	android:versionName="1.0">
-
-	%s
-	<application android:label="Balloon世界" android:hasCode="false" android:debuggable="true">
-	<activity android:name="android.app.NativeActivity"
-		android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
-		android:label="Balloon"
-		android:screenOrientation="portrait"
-		android:configChanges="orientation|keyboardHidden">
-		<meta-data android:name="android.app.lib_name" android:value="balloon" />
-		<intent-filter>
-			here is some text
-			<action android:name="android.intent.action.MAIN" />
-			<category android:name="android.intent.category.LAUNCHER" />
-		</intent-filter>
-	</activity>
-	</application>
-</manifest>`