summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tzdata/prototype_updater/Android.mk24
-rw-r--r--tzdata/prototype_updater/AndroidManifest.xml38
-rw-r--r--tzdata/prototype_updater/res/values/strings.xml20
-rw-r--r--tzdata/prototype_updater/src/libcore/tzdata/prototype_updater/RulesCheckReceiver.java296
4 files changed, 0 insertions, 378 deletions
diff --git a/tzdata/prototype_updater/Android.mk b/tzdata/prototype_updater/Android.mk
deleted file mode 100644
index 0ddaa45062..0000000000
--- a/tzdata/prototype_updater/Android.mk
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (C) 2017 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_PROGUARD_ENABLED := disabled
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_PACKAGE_NAME := PrototypeTimeZoneUpdaterApp
-LOCAL_CERTIFICATE := platform
-LOCAL_PRIVILEGED_MODULE := true
-include $(BUILD_PACKAGE)
diff --git a/tzdata/prototype_updater/AndroidManifest.xml b/tzdata/prototype_updater/AndroidManifest.xml
deleted file mode 100644
index 9b73b0bcc0..0000000000
--- a/tzdata/prototype_updater/AndroidManifest.xml
+++ /dev/null
@@ -1,38 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2017 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.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="libcore.tzdata.prototype_updater"
- android:versionCode="1">
-
- <uses-permission android:name="android.permission.UPDATE_TIME_ZONE_RULES" />
-
- <application
- android:allowBackup="false"
- android:label="@string/app_name">
-
- <receiver android:name=".RulesCheckReceiver"
- android:permission="android.permission.TRIGGER_TIME_ZONE_RULES_CHECK"
- android:exported="true">
- <intent-filter>
- <action android:name="android.intent.action.timezone.TRIGGER_RULES_UPDATE_CHECK" />
- </intent-filter>
- </receiver>
-
- </application>
-
-</manifest>
diff --git a/tzdata/prototype_updater/res/values/strings.xml b/tzdata/prototype_updater/res/values/strings.xml
deleted file mode 100644
index 204ae27389..0000000000
--- a/tzdata/prototype_updater/res/values/strings.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * Copyright (C) 2017 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.
- -->
-
-<resources>
- <string name="app_name">PrototypeUpdaterApp</string>
-</resources>
diff --git a/tzdata/prototype_updater/src/libcore/tzdata/prototype_updater/RulesCheckReceiver.java b/tzdata/prototype_updater/src/libcore/tzdata/prototype_updater/RulesCheckReceiver.java
deleted file mode 100644
index 51f454e1af..0000000000
--- a/tzdata/prototype_updater/src/libcore/tzdata/prototype_updater/RulesCheckReceiver.java
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- * Copyright (C) 2017 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.prototype_updater;
-
-import android.app.timezone.Callback;
-import android.app.timezone.DistroFormatVersion;
-import android.app.timezone.DistroRulesVersion;
-import android.app.timezone.RulesManager;
-import android.app.timezone.RulesState;
-import android.app.timezone.RulesUpdaterContract;
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.database.Cursor;
-import android.os.ParcelFileDescriptor;
-import android.provider.TimeZoneRulesDataContract;
-import android.util.Log;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.Arrays;
-import libcore.io.Streams;
-
-// TODO(nfuller): Prevent multiple broadcasts being handled at once?
-// TODO(nfuller): Improve logging
-// TODO(nfuller): Make the rules check async?
-// TODO(nfuller): Need async generally for SystemService calls from BroadcastReceiver?
-public class RulesCheckReceiver extends BroadcastReceiver {
- final static String TAG = "RulesCheckReceiver";
-
- private RulesManager mRulesManager;
-
- @Override
- public void onReceive(Context context, Intent intent) {
- if (!RulesUpdaterContract.ACTION_TRIGGER_RULES_UPDATE_CHECK.equals(intent.getAction())) {
- // Unknown. Do nothing.
- Log.w(TAG, "Unrecognized intent action received: " + intent
- + ", action=" + intent.getAction());
- return;
- }
-
- mRulesManager = (RulesManager) context.getSystemService("timezone");
-
- byte[] token = intent.getByteArrayExtra(RulesUpdaterContract.EXTRA_CHECK_TOKEN);
-
- // Note: We rely on the system server to check that the configured data application is the
- // one that exposes the content provider with the well-known authority, and is a privileged
- // application as required. It is *not* checked here and it is assumed the updater can trust
- // the data application.
-
- // Obtain the information about what the data app is telling us to do.
- DistroOperation operation = getOperation(context);
- if (operation == null) {
- Log.w(TAG, "Unable to read time zone operation. Halting check.");
- boolean success = true; // No point in retrying.
- handleCheckComplete(token, success);
- return;
- }
-
- // Try to do what the data app asked.
- Log.d(TAG, "Time zone operation: " + operation + " received.");
- switch (operation.mOperationString) {
- case TimeZoneRulesDataContract.OPERATION_NO_OP:
- // No-op. Just acknowledge the check.
- handleCheckComplete(token, true /* success */);
- break;
- case TimeZoneRulesDataContract.OPERATION_UNINSTALL:
- handleUninstall(token);
- break;
- case TimeZoneRulesDataContract.OPERATION_INSTALL:
- handleCopyAndInstall(context, token, operation.mDistroFormatVersion,
- operation.mDistroRulesVersion);
- break;
- default:
- Log.w(TAG, "Unknown time zone operation: " + operation
- + " received. Halting check.");
- final boolean success = true; // No point in retrying.
- handleCheckComplete(token, success);
- }
- }
-
- private DistroOperation getOperation(Context context) {
- Cursor c = context.getContentResolver()
- .query(TimeZoneRulesDataContract.OPERATION_URI,
- new String[] {
- TimeZoneRulesDataContract.COLUMN_OPERATION,
- TimeZoneRulesDataContract.COLUMN_DISTRO_MAJOR_VERSION,
- TimeZoneRulesDataContract.COLUMN_DISTRO_MINOR_VERSION,
- TimeZoneRulesDataContract.COLUMN_RULES_VERSION,
- TimeZoneRulesDataContract.COLUMN_REVISION
- },
- null /* selection */, null /* selectionArgs */, null /* sortOrder */);
- try (Cursor cursor = c) {
- if (cursor == null) {
- Log.e(TAG, "Query returned null");
- return null;
- }
- if (!cursor.moveToFirst()) {
- Log.e(TAG, "Query returned empty results");
- return null;
- }
-
- try {
- String operation = cursor.getString(0);
- DistroFormatVersion distroFormatVersion = null;
- DistroRulesVersion distroRulesVersion = null;
- if (TimeZoneRulesDataContract.OPERATION_INSTALL.equals(operation)) {
- distroFormatVersion = new DistroFormatVersion(cursor.getInt(1),
- cursor.getInt(2));
- distroRulesVersion = new DistroRulesVersion(cursor.getString(3),
- cursor.getInt(4));
- }
- return new DistroOperation(operation, distroFormatVersion, distroRulesVersion);
- } catch (Exception e) {
- Log.e(TAG, "Error looking up distro operation / version", e);
- return null;
- }
- }
- }
-
- private void handleCopyAndInstall(Context context, byte[] checkToken,
- DistroFormatVersion distroFormatVersion, DistroRulesVersion distroRulesVersion) {
- // Decide whether to proceed with the install.
- RulesState rulesState = mRulesManager.getRulesState();
- if (!rulesState.isDistroFormatVersionSupported(distroFormatVersion)
- || rulesState.isSystemVersionNewerThan(distroRulesVersion)) {
- // Nothing to do.
- handleCheckComplete(checkToken, true /* success */);
- return;
- }
-
- ParcelFileDescriptor inputFileDescriptor = getDistroParcelFileDescriptor(context);
- if (inputFileDescriptor == null) {
- Log.e(TAG, "No local file created for distro. Halting.");
- return;
- }
-
- // Copying the ParcelFileDescriptor to a local file proves we can read it before passing it
- // on to the next stage. It also ensures that we have a hermetic copy of the data we know
- // the originating content provider cannot modify unexpectedly. If the next stage wants to
- // "seek" the ParcelFileDescriptor it can do so with fewer processes affected.
- File file = copyDataToLocalFile(context, inputFileDescriptor);
- if (file == null) {
- // It's possible this may get better if the problem is related to storage space so we
- // signal success := false so it may be retried.
- boolean success = false;
- handleCheckComplete(checkToken, success);
- return;
- }
- handleInstall(checkToken, file);
- }
-
- private static ParcelFileDescriptor getDistroParcelFileDescriptor(Context context) {
- ParcelFileDescriptor inputFileDescriptor;
- try {
- inputFileDescriptor = context.getContentResolver().openFileDescriptor(
- TimeZoneRulesDataContract.DATA_URI, "r");
- if (inputFileDescriptor == null) {
- throw new FileNotFoundException("ContentProvider returned null");
- }
- } catch (FileNotFoundException e) {
- Log.e(TAG, "Unable to open file descriptor" + TimeZoneRulesDataContract.DATA_URI, e);
- return null;
- }
- return inputFileDescriptor;
- }
-
- private static File copyDataToLocalFile(
- Context context, ParcelFileDescriptor inputFileDescriptor) {
-
- // Adopt the ParcelFileDescriptor into a try-with-resources so we will close it when we're
- // done regardless of the outcome.
- try (ParcelFileDescriptor pfd = inputFileDescriptor) {
- File localFile;
- try {
- localFile = File.createTempFile("temp", ".zip", context.getFilesDir());
- } catch (IOException e) {
- Log.e(TAG, "Unable to create local storage file", e);
- return null;
- }
-
- InputStream fis = new FileInputStream(pfd.getFileDescriptor(), false /* isFdOwner */);
- try (FileOutputStream fos = new FileOutputStream(localFile, false /* append */)) {
- Streams.copy(fis, fos);
- } catch (IOException e) {
- Log.e(TAG, "Unable to create asset storage file: " + localFile, e);
- return null;
- }
- return localFile;
- } catch (IOException e) {
- Log.e(TAG, "Unable to close ParcelFileDescriptor", e);
- return null;
- }
- }
-
- private void handleInstall(final byte[] checkToken, final File localFile) {
- // Create a ParcelFileDescriptor pointing to localFile.
- final ParcelFileDescriptor distroFileDescriptor;
- try {
- distroFileDescriptor =
- ParcelFileDescriptor.open(localFile, ParcelFileDescriptor.MODE_READ_ONLY);
- } catch (FileNotFoundException e) {
- Log.e(TAG, "Unable to create ParcelFileDescriptor from " + localFile);
- handleCheckComplete(checkToken, false /* success */);
- return;
- } finally {
- // It is safe to delete the File at this point. The ParcelFileDescriptor has an open
- // file descriptor to it if we are successful, or it is not going to be used if we are
- // returning early.
- localFile.delete();
- }
-
- Callback callback = new Callback() {
- @Override
- public void onFinished(int status) {
- Log.i(TAG, "Finished install: " + status);
- }
- };
-
- // Adopt the distroFileDescriptor here so the local file descriptor is closed, whatever the
- // outcome.
- try (ParcelFileDescriptor pfd = distroFileDescriptor) {
- int requestStatus = mRulesManager.requestInstall(pfd, checkToken, callback);
- Log.i(TAG, "requestInstall() called, token=" + Arrays.toString(checkToken)
- + ", returned " + requestStatus);
- } catch (Exception e) {
- Log.e(TAG, "Error calling requestInstall()", e);
- }
- }
-
- private void handleUninstall(byte[] checkToken) {
- Callback callback = new Callback() {
- @Override
- public void onFinished(int status) {
- Log.i(TAG, "Finished uninstall: " + status);
- }
- };
-
- try {
- int requestStatus = mRulesManager.requestUninstall(checkToken, callback);
- Log.i(TAG, "requestUninstall() called, token=" + Arrays.toString(checkToken)
- + ", returned " + requestStatus);
- } catch (Exception e) {
- Log.e(TAG, "Error calling requestUninstall()", e);
- }
- }
-
- private void handleCheckComplete(final byte[] token, final boolean success) {
- try {
- mRulesManager.requestNothing(token, success);
- Log.i(TAG, "requestNothing() called, token=" + Arrays.toString(token)
- + ", success=" + success);
- } catch (Exception e) {
- Log.e(TAG, "Error calling requestNothing()", e);
- }
- }
-
- private static class DistroOperation {
- final String mOperationString;
- final DistroFormatVersion mDistroFormatVersion;
- final DistroRulesVersion mDistroRulesVersion;
-
- DistroOperation(String operationString, DistroFormatVersion distroFormatVersion,
- DistroRulesVersion distroRulesVersion) {
- mOperationString = operationString;
- mDistroFormatVersion = distroFormatVersion;
- mDistroRulesVersion = distroRulesVersion;
- }
-
- @Override
- public String toString() {
- return "DistroOperation{" +
- "mOperationString='" + mOperationString + '\'' +
- ", mDistroFormatVersion=" + mDistroFormatVersion +
- ", mDistroRulesVersion=" + mDistroRulesVersion +
- '}';
- }
- }
-}