upload android base code part6

This commit is contained in:
August 2018-08-08 17:48:24 +08:00
parent 421e214c7d
commit 4e516ec6ed
35396 changed files with 9188716 additions and 0 deletions

View 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)

View 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)

View file

@ -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;
}
}

View 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)

View 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

View file

@ -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>

View file

@ -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>

View file

@ -0,0 +1,4 @@
<!-- Used by FileProvider. See AndroidManifest.xml -->
<paths>
<files-path path="temp/" name="temp" />
</paths>

View file

@ -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);
}
}
}
}