upload android base code part6
This commit is contained in:
parent
421e214c7d
commit
4e516ec6ed
35396 changed files with 9188716 additions and 0 deletions
17
android/libcore/tzdata/Android.mk
Normal file
17
android/libcore/tzdata/Android.mk
Normal file
|
@ -0,0 +1,17 @@
|
|||
# Copyright (C) 2015 The Android Open Source Project
|
||||
#
|
||||
# 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.
|
||||
|
||||
LOCAL_PATH:= $(call my-dir)
|
||||
|
||||
include $(call all-subdir-makefiles)
|
46
android/libcore/tzdata/testing/Android.mk
Normal file
46
android/libcore/tzdata/testing/Android.mk
Normal file
|
@ -0,0 +1,46 @@
|
|||
# Copyright (C) 2015 The Android Open Source Project
|
||||
#
|
||||
# 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.
|
||||
|
||||
LOCAL_PATH:= $(call my-dir)
|
||||
|
||||
# Library of test-support classes for tzdata updates. Shared between CTS and other tests.
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := tzdata-testing
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_SRC_FILES := $(call all-java-files-under, src/main)
|
||||
LOCAL_JAVACFLAGS := -encoding UTF-8
|
||||
LOCAL_JAVA_LIBRARIES := core-oj core-libart
|
||||
LOCAL_NO_STANDARD_LIBRARIES := true
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
|
||||
include $(BUILD_STATIC_JAVA_LIBRARY)
|
||||
|
||||
# Library of test-support classes for tzdata updates. Shared between CTS and other tests.
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := tzdata-testing-host
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_SRC_FILES := $(call all-java-files-under, src/main)
|
||||
LOCAL_JAVACFLAGS := -encoding UTF-8
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
|
||||
include $(BUILD_HOST_JAVA_LIBRARY)
|
||||
|
||||
# Host version of the above library. For libcore host testing.
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := tzdata-testing-hostdex
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_SRC_FILES := $(call all-java-files-under, src/main)
|
||||
LOCAL_JAVA_LIBRARIES := core-oj-hostdex core-libart-hostdex
|
||||
LOCAL_NO_STANDARD_LIBRARIES := true
|
||||
LOCAL_JAVACFLAGS := -encoding UTF-8
|
||||
LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk
|
||||
include $(BUILD_HOST_DALVIK_STATIC_JAVA_LIBRARY)
|
|
@ -0,0 +1,323 @@
|
|||
/*
|
||||
* Copyright (C) 2016 The Android Open Source Project
|
||||
*
|
||||
* 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 libcore.tzdata.testing;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Helps with creating valid and invalid test data.
|
||||
*/
|
||||
public class ZoneInfoTestHelper {
|
||||
|
||||
private ZoneInfoTestHelper() {}
|
||||
|
||||
/**
|
||||
* Constructs valid and invalid zic data for tests.
|
||||
*/
|
||||
public static class ZicDataBuilder {
|
||||
|
||||
private int magic = 0x545a6966; // Default, valid magic.
|
||||
private Integer transitionCountOverride; // Used to override the correct transition count.
|
||||
private int[] transitionTimes; // Time of each transition, one per transition.
|
||||
private byte[] transitionTypes; // Type of each transition, one per transition.
|
||||
private Integer typesCountOverride; // Used to override the correct type count.
|
||||
private int[] isDsts; // Whether a type uses DST, one per type.
|
||||
private int[] offsetsSeconds; // The UTC offset, one per type.
|
||||
|
||||
public ZicDataBuilder() {}
|
||||
|
||||
public ZicDataBuilder setMagic(int magic) {
|
||||
this.magic = magic;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ZicDataBuilder setTypeCountOverride(int typesCountOverride) {
|
||||
this.typesCountOverride = typesCountOverride;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ZicDataBuilder setTransitionCountOverride(int transitionCountOverride) {
|
||||
this.transitionCountOverride = transitionCountOverride;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* See {@link #setTransitions(int[][])} and {@link #setTypes(int[][])}.
|
||||
*/
|
||||
public ZicDataBuilder setTransitionsAndTypes(
|
||||
int[][] transitionPairs, int[][] typePairs) {
|
||||
setTransitions(transitionPairs);
|
||||
setTypes(typePairs);
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Sets transition information using an array of pairs of ints. e.g.
|
||||
*
|
||||
* new int[][] {
|
||||
* { transitionTimeSeconds1, typeIndex1 },
|
||||
* { transitionTimeSeconds2, typeIndex1 },
|
||||
* }
|
||||
*/
|
||||
public ZicDataBuilder setTransitions(int[][] transitionPairs) {
|
||||
int[] transitions = new int[transitionPairs.length];
|
||||
byte[] types = new byte[transitionPairs.length];
|
||||
for (int i = 0; i < transitionPairs.length; i++) {
|
||||
transitions[i] = transitionPairs[i][0];
|
||||
types[i] = (byte) transitionPairs[i][1];
|
||||
}
|
||||
this.transitionTimes = transitions;
|
||||
this.transitionTypes = types;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets transition information using an array of pairs of ints. e.g.
|
||||
*
|
||||
* new int[][] {
|
||||
* { typeIsDst1, offsetSeconds1 },
|
||||
* { typeIsDst2, offsetSeconds2 },
|
||||
* }
|
||||
*/
|
||||
public ZicDataBuilder setTypes(int[][] typePairs) {
|
||||
int[] isDsts = new int[typePairs.length];
|
||||
int[] offsetSeconds = new int[typePairs.length];
|
||||
for (int i = 0; i < typePairs.length; i++) {
|
||||
offsetSeconds[i] = typePairs[i][0];
|
||||
isDsts[i] = typePairs[i][1];
|
||||
}
|
||||
this.isDsts = isDsts;
|
||||
this.offsetsSeconds = offsetSeconds;
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Initializes to a minimum viable ZoneInfo data. */
|
||||
public ZicDataBuilder initializeToValid() {
|
||||
setTransitions(new int[0][0]);
|
||||
setTypes(new int[][] {
|
||||
{ 3600, 0}
|
||||
});
|
||||
return this;
|
||||
}
|
||||
|
||||
public byte[] build() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
|
||||
// Magic number.
|
||||
writeInt(baos, magic);
|
||||
|
||||
// Some useless stuff in the header.
|
||||
for (int i = 0; i < 28; ++i) {
|
||||
baos.write(i);
|
||||
}
|
||||
|
||||
// Transition time count
|
||||
int transitionsCount = transitionCountOverride != null
|
||||
? transitionCountOverride : transitionTimes.length;
|
||||
writeInt(baos, transitionsCount);
|
||||
|
||||
// Transition type count.
|
||||
int typesCount = typesCountOverride != null
|
||||
? typesCountOverride : offsetsSeconds.length;
|
||||
writeInt(baos, typesCount);
|
||||
// Useless stuff.
|
||||
writeInt(baos, 0xdeadbeef);
|
||||
|
||||
// Transition time array, as ints.
|
||||
writeIntArray(baos, transitionTimes);
|
||||
|
||||
// Transition type array.
|
||||
writeByteArray(baos, transitionTypes);
|
||||
|
||||
// Offset / DST
|
||||
for (int i = 0; i < offsetsSeconds.length; i++) {
|
||||
writeInt(baos, offsetsSeconds[i]);
|
||||
writeByte(baos, isDsts[i]);
|
||||
// Useless stuff.
|
||||
writeByte(baos, i);
|
||||
}
|
||||
return baos.toByteArray();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs valid and invalid tzdata files for tests. See also ZoneCompactor class in
|
||||
* external/icu which is the real thing.
|
||||
*/
|
||||
public static class TzDataBuilder {
|
||||
|
||||
private String headerMagic;
|
||||
// A list is used in preference to a Map to allow simulation of badly ordered / duplicate
|
||||
// IDs.
|
||||
private List<ZicDatum> zicData = new ArrayList<>();
|
||||
private String zoneTab;
|
||||
private Integer indexOffsetOverride;
|
||||
private Integer dataOffsetOverride;
|
||||
private Integer zoneTabOffsetOverride;
|
||||
|
||||
public TzDataBuilder() {}
|
||||
|
||||
/** Sets the header. A valid header is in the form "tzdata2016g". */
|
||||
public TzDataBuilder setHeaderMagic(String headerMagic) {
|
||||
this.headerMagic = headerMagic;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TzDataBuilder setIndexOffsetOverride(int indexOffset) {
|
||||
this.indexOffsetOverride = indexOffset;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TzDataBuilder setDataOffsetOverride(int dataOffset) {
|
||||
this.dataOffsetOverride = dataOffset;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TzDataBuilder setZoneTabOffsetOverride(int zoneTabOffset) {
|
||||
this.zoneTabOffsetOverride = zoneTabOffset;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds data for a new zone. These must be added in ID string order to generate
|
||||
* a valid file.
|
||||
*/
|
||||
public TzDataBuilder addZicData(String id, byte[] data) {
|
||||
zicData.add(new ZicDatum(id, data));
|
||||
return this;
|
||||
}
|
||||
|
||||
public TzDataBuilder setZoneTab(String zoneTab) {
|
||||
this.zoneTab = zoneTab;
|
||||
return this;
|
||||
}
|
||||
|
||||
public TzDataBuilder initializeToValid() {
|
||||
setHeaderMagic("tzdata9999a");
|
||||
addZicData("Europe/Elbonia", new ZicDataBuilder().initializeToValid().build());
|
||||
setZoneTab("ZoneTab data");
|
||||
return this;
|
||||
}
|
||||
|
||||
public TzDataBuilder clearZicData() {
|
||||
zicData.clear();
|
||||
return this;
|
||||
}
|
||||
|
||||
public byte[] build() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
|
||||
byte[] headerMagicBytes = headerMagic.getBytes(StandardCharsets.US_ASCII);
|
||||
baos.write(headerMagicBytes, 0, headerMagicBytes.length);
|
||||
baos.write(0);
|
||||
|
||||
// Write out the offsets for later manipulation.
|
||||
int indexOffsetOffset = baos.size();
|
||||
writeInt(baos, 0);
|
||||
int dataOffsetOffset = baos.size();
|
||||
writeInt(baos, 0);
|
||||
int zoneTabOffsetOffset = baos.size();
|
||||
writeInt(baos, 0);
|
||||
|
||||
// Construct the data section in advance, so we know the offsets.
|
||||
ByteArrayOutputStream dataBytes = new ByteArrayOutputStream();
|
||||
Map<String, Integer> offsets = new HashMap<>();
|
||||
for (ZicDatum datum : zicData) {
|
||||
int offset = dataBytes.size();
|
||||
offsets.put(datum.id, offset);
|
||||
writeByteArray(dataBytes, datum.data);
|
||||
}
|
||||
|
||||
int indexOffset = baos.size();
|
||||
|
||||
// Write the index section.
|
||||
for (ZicDatum zicDatum : zicData) {
|
||||
// Write the ID.
|
||||
String id = zicDatum.id;
|
||||
byte[] idBytes = id.getBytes(StandardCharsets.US_ASCII);
|
||||
byte[] paddedIdBytes = new byte[40];
|
||||
System.arraycopy(idBytes, 0, paddedIdBytes, 0, idBytes.length);
|
||||
writeByteArray(baos, paddedIdBytes);
|
||||
// Write offset of zic data in the data section.
|
||||
Integer offset = offsets.get(id);
|
||||
writeInt(baos, offset);
|
||||
// Write the length of the zic data.
|
||||
writeInt(baos, zicDatum.data.length);
|
||||
// Write a filler value (not used)
|
||||
writeInt(baos, 0);
|
||||
}
|
||||
|
||||
// Write the data section.
|
||||
int dataOffset = baos.size();
|
||||
writeByteArray(baos, dataBytes.toByteArray());
|
||||
|
||||
// Write the zoneTab section.
|
||||
int zoneTabOffset = baos.size();
|
||||
byte[] zoneTabBytes = zoneTab.getBytes(StandardCharsets.US_ASCII);
|
||||
writeByteArray(baos, zoneTabBytes);
|
||||
|
||||
byte[] bytes = baos.toByteArray();
|
||||
setInt(bytes, indexOffsetOffset,
|
||||
indexOffsetOverride != null ? indexOffsetOverride : indexOffset);
|
||||
setInt(bytes, dataOffsetOffset,
|
||||
dataOffsetOverride != null ? dataOffsetOverride : dataOffset);
|
||||
setInt(bytes, zoneTabOffsetOffset,
|
||||
zoneTabOffsetOverride != null ? zoneTabOffsetOverride : zoneTabOffset);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
private static class ZicDatum {
|
||||
public final String id;
|
||||
public final byte[] data;
|
||||
|
||||
ZicDatum(String id, byte[] data) {
|
||||
this.id = id;
|
||||
this.data = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void writeByteArray(ByteArrayOutputStream baos, byte[] array) {
|
||||
baos.write(array, 0, array.length);
|
||||
}
|
||||
|
||||
static void writeByte(ByteArrayOutputStream baos, int value) {
|
||||
baos.write(value);
|
||||
}
|
||||
|
||||
static void writeIntArray(ByteArrayOutputStream baos, int[] array) {
|
||||
for (int value : array) {
|
||||
writeInt(baos, value);
|
||||
}
|
||||
}
|
||||
|
||||
static void writeInt(ByteArrayOutputStream os, int value) {
|
||||
byte[] bytes = ByteBuffer.allocate(4).putInt(value).array();
|
||||
writeByteArray(os, bytes);
|
||||
}
|
||||
|
||||
static void setInt(byte[] bytes, int offset, int value) {
|
||||
bytes[offset] = (byte) (value >>> 24);
|
||||
bytes[offset + 1] = (byte) (value >>> 16);
|
||||
bytes[offset + 2] = (byte) (value >>> 8);
|
||||
bytes[offset + 3] = (byte) value;
|
||||
}
|
||||
}
|
25
android/libcore/tzdata/update_test_app/Android.mk
Normal file
25
android/libcore/tzdata/update_test_app/Android.mk
Normal file
|
@ -0,0 +1,25 @@
|
|||
# Copyright (C) 2015 The Android Open Source Project
|
||||
#
|
||||
# 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.
|
||||
|
||||
LOCAL_PATH:= $(call my-dir)
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
|
||||
LOCAL_PROGUARD_ENABLED := disabled
|
||||
LOCAL_STATIC_JAVA_LIBRARIES := android-support-v4
|
||||
LOCAL_SRC_FILES := $(call all-java-files-under, src)
|
||||
LOCAL_PACKAGE_NAME := UpdateTestApp
|
||||
LOCAL_CERTIFICATE := platform
|
||||
include $(BUILD_PACKAGE)
|
34
android/libcore/tzdata/update_test_app/AndroidManifest.xml
Normal file
34
android/libcore/tzdata/update_test_app/AndroidManifest.xml
Normal file
|
@ -0,0 +1,34 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="libcore.tzdata.update_test_app.installupdatetestapp" >
|
||||
|
||||
<uses-permission android:name="android.permission.UPDATE_CONFIG" />
|
||||
|
||||
<application
|
||||
android:allowBackup="false"
|
||||
android:icon="@drawable/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@android:style/Theme.Holo.Light">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:label="@string/app_name" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<provider
|
||||
android:name="android.support.v4.content.FileProvider"
|
||||
android:authorities="libcore.tzdata.update_test_app.fileprovider"
|
||||
android:grantUriPermissions="true"
|
||||
android:exported="false">
|
||||
<meta-data
|
||||
android:name="android.support.FILE_PROVIDER_PATHS"
|
||||
android:resource="@xml/filepaths" />
|
||||
</provider>
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
Binary file not shown.
After Width: | Height: | Size: 9.2 KiB |
|
@ -0,0 +1,106 @@
|
|||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
tools:context=".MainActivity">
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/action"
|
||||
android:id="@+id/action_label" />
|
||||
|
||||
<EditText
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/action"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/default_action" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/version"
|
||||
android:id="@+id/version_label" />
|
||||
|
||||
<EditText
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/version"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/default_version" />
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/content_path"
|
||||
android:id="@+id/content_path_label" />
|
||||
|
||||
<EditText
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/default_content_path"
|
||||
android:id="@+id/content_path" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/required_hash"
|
||||
android:id="@+id/required_hash_label" />
|
||||
|
||||
<EditText
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/default_required_hash"
|
||||
android:id="@+id/required_hash" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<Button
|
||||
android:id="@+id/trigger_install_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:text="@string/trigger_install" />
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:scrollbars="vertical"
|
||||
android:fillViewport="true">
|
||||
|
||||
<TextView
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:id="@+id/log"
|
||||
android:singleLine="false" />
|
||||
|
||||
</ScrollView>
|
||||
|
||||
</LinearLayout>
|
|
@ -0,0 +1,13 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">InstallUpdateTestApp</string>
|
||||
<string name="action">Action</string>
|
||||
<string name="content_path">Content Path</string>
|
||||
<string name="default_action">android.intent.action.UPDATE_TZDATA</string>
|
||||
<string name="default_content_path">/data/local/tmp/out.zip</string>
|
||||
<string name="default_required_hash">NONE</string>
|
||||
<string name="default_version">1</string>
|
||||
<string name="required_hash">Required Hash</string>
|
||||
<string name="trigger_install">Trigger Install</string>
|
||||
<string name="version">Version</string>
|
||||
</resources>
|
|
@ -0,0 +1,4 @@
|
|||
<!-- Used by FileProvider. See AndroidManifest.xml -->
|
||||
<paths>
|
||||
<files-path path="temp/" name="temp" />
|
||||
</paths>
|
|
@ -0,0 +1,184 @@
|
|||
/*
|
||||
* Copyright (C) 2015 The Android Open Source Project
|
||||
*
|
||||
* 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 libcore.tzdata.update_test_app.installupdatetestapp;
|
||||
|
||||
import android.app.ActionBar;
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.provider.Settings;
|
||||
import android.support.v4.content.FileProvider;
|
||||
import android.util.Base64;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import libcore.icu.ICU;
|
||||
import libcore.util.ZoneInfoDB;
|
||||
|
||||
public class MainActivity extends Activity implements View.OnClickListener {
|
||||
|
||||
private static final String EXTRA_REQUIRED_HASH = "REQUIRED_HASH";
|
||||
private static final String EXTRA_VERSION_NUMBER = "VERSION";
|
||||
|
||||
private EditText actionEditText;
|
||||
private EditText versionEditText;
|
||||
private EditText contentPathEditText;
|
||||
private EditText requiredHashEditText;
|
||||
private TextView logView;
|
||||
|
||||
private ExecutorService executor;
|
||||
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
Button triggerInstallButton = (Button) findViewById(R.id.trigger_install_button);
|
||||
triggerInstallButton.setOnClickListener(this);
|
||||
|
||||
actionEditText = (EditText) findViewById(R.id.action);
|
||||
versionEditText = (EditText) findViewById(R.id.version);
|
||||
contentPathEditText = (EditText) findViewById(R.id.content_path);
|
||||
requiredHashEditText = (EditText) findViewById(R.id.required_hash);
|
||||
logView = (TextView) findViewById(R.id.log);
|
||||
executor = Executors.newFixedThreadPool(1);
|
||||
logString("Active libcore version: "
|
||||
+ ZoneInfoDB.getInstance().getVersion());
|
||||
logString("Active icu4c version: "
|
||||
+ ICU.getTZDataVersion());
|
||||
logString("Active icu4j version: "
|
||||
+ android.icu.util.TimeZone.getTZDataVersion());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
final String action = actionEditText.getText().toString();
|
||||
final String contentPath = contentPathEditText.getText().toString();
|
||||
final String version = versionEditText.getText().toString();
|
||||
final String requiredHash = requiredHashEditText.getText().toString();
|
||||
|
||||
new AsyncTask<Void, String, Void>() {
|
||||
@Override
|
||||
protected Void doInBackground(Void... params) {
|
||||
final File contentFile = new File(contentPath);
|
||||
File tempDir = new File(getFilesDir(), "temp");
|
||||
if (!tempDir.exists() && !tempDir.mkdir()) {
|
||||
publishProgress("Unable to create: " + tempDir);
|
||||
return null;
|
||||
}
|
||||
|
||||
File copyOfContentFile;
|
||||
try {
|
||||
copyOfContentFile = File.createTempFile("content", ".tmp", tempDir);
|
||||
copyFile(contentFile, copyOfContentFile);
|
||||
} catch (IOException e) {
|
||||
publishProgress("Error", exceptionToString(e));
|
||||
return null;
|
||||
}
|
||||
publishProgress("Created copy of " + contentFile + " at " + copyOfContentFile);
|
||||
|
||||
try {
|
||||
sendIntent(copyOfContentFile, action, version, requiredHash);
|
||||
} catch (Exception e) {
|
||||
publishProgress("Error", exceptionToString(e));
|
||||
}
|
||||
publishProgress("Update intent sent successfully");
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onProgressUpdate(String... values) {
|
||||
for (String message : values) {
|
||||
addToLog(message, null);
|
||||
}
|
||||
}
|
||||
}.executeOnExecutor(executor);
|
||||
}
|
||||
|
||||
private void sleep(long millisDelay) {
|
||||
try {
|
||||
Thread.sleep(millisDelay);
|
||||
} catch (InterruptedException e) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
|
||||
private void sendIntent(
|
||||
File contentFile, String action, String version, String required) {
|
||||
Intent i = new Intent();
|
||||
i.setAction(action);
|
||||
Uri contentUri =
|
||||
FileProvider.getUriForFile(
|
||||
getApplicationContext(), "libcore.tzdata.update_test_app.fileprovider",
|
||||
contentFile);
|
||||
i.setData(contentUri);
|
||||
i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
i.putExtra(EXTRA_VERSION_NUMBER, version);
|
||||
i.putExtra(EXTRA_REQUIRED_HASH, required);
|
||||
sendBroadcast(i);
|
||||
}
|
||||
|
||||
private void addToLog(String message, Exception e) {
|
||||
logString(message);
|
||||
if (e != null) {
|
||||
String text = exceptionToString(e);
|
||||
logString(text);
|
||||
}
|
||||
}
|
||||
|
||||
private void logString(String value) {
|
||||
logView.append(new Date() + " " + value + "\n");
|
||||
android.text.Layout layout = logView.getLayout();
|
||||
if (layout != null) {
|
||||
int scrollAmount =
|
||||
layout.getLineTop(logView.getLineCount()) - logView.getHeight();
|
||||
logView.scrollTo(0, scrollAmount);
|
||||
}
|
||||
}
|
||||
|
||||
private static String exceptionToString(Exception e) {
|
||||
StringWriter writer = new StringWriter();
|
||||
e.printStackTrace(new PrintWriter(writer));
|
||||
return writer.getBuffer().toString();
|
||||
}
|
||||
|
||||
private static void copyFile(File from, File to) throws IOException {
|
||||
byte[] buffer = new byte[8192];
|
||||
int count;
|
||||
try (
|
||||
FileInputStream in = new FileInputStream(from);
|
||||
FileOutputStream out = new FileOutputStream(to)
|
||||
) {
|
||||
while ((count = in.read(buffer)) != -1) {
|
||||
out.write(buffer, 0, count);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue