Merge "Adding a very simple all-code scenegraph example."
diff --git a/api/current.txt b/api/current.txt
index 8c0dc14..d034b89 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -23310,6 +23310,9 @@
method protected void onMeasure(int, int);
method protected void onOverScrolled(int, int, boolean, boolean);
method public void onPopulateAccessibilityEvent(android.view.accessibility.AccessibilityEvent);
+ method public void onResetResolvedTextDirection();
+ method public void onResolvePadding(int);
+ method public void onResolveTextDirection();
method protected void onRestoreInstanceState(android.os.Parcelable);
method protected android.os.Parcelable onSaveInstanceState();
method protected void onScrollChanged(int, int, int, int);
@@ -23344,10 +23347,11 @@
method public void requestLayout();
method public boolean requestRectangleOnScreen(android.graphics.Rect);
method public boolean requestRectangleOnScreen(android.graphics.Rect, boolean);
- method protected void resetResolvedTextDirection();
+ method public void resetResolvedTextDirection();
+ method public void resolvePadding();
method public static int resolveSize(int, int);
method public static int resolveSizeAndState(int, int, int);
- method protected void resolveTextDirection();
+ method public void resolveTextDirection();
method public void restoreHierarchyState(android.util.SparseArray<android.os.Parcelable>);
method public void saveHierarchyState(android.util.SparseArray<android.os.Parcelable>);
method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long);
diff --git a/cmds/backup/Android.mk b/cmds/backup/Android.mk
index 508aec0..73af0bc 100644
--- a/cmds/backup/Android.mk
+++ b/cmds/backup/Android.mk
@@ -5,7 +5,7 @@
LOCAL_SRC_FILES:= backup.cpp
-LOCAL_SHARED_LIBRARIES := libcutils libutils
+LOCAL_SHARED_LIBRARIES := libcutils libutils libandroidfw
LOCAL_MODULE:= btool
diff --git a/cmds/backup/backup.cpp b/cmds/backup/backup.cpp
index d4e669b..ea1888b 100644
--- a/cmds/backup/backup.cpp
+++ b/cmds/backup/backup.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include <utils/BackupHelpers.h>
+#include <androidfw/BackupHelpers.h>
#include <utils/String8.h>
#include <fcntl.h>
diff --git a/cmds/bootanimation/Android.mk b/cmds/bootanimation/Android.mk
index 7d39912..8c46b21 100644
--- a/cmds/bootanimation/Android.mk
+++ b/cmds/bootanimation/Android.mk
@@ -9,6 +9,7 @@
LOCAL_SHARED_LIBRARIES := \
libcutils \
+ libandroidfw \
libutils \
libbinder \
libui \
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 0d5b4ca..3545ace 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -25,12 +25,12 @@
#include <cutils/properties.h>
+#include <androidfw/AssetManager.h>
#include <binder/IPCThreadState.h>
-#include <utils/threads.h>
#include <utils/Atomic.h>
#include <utils/Errors.h>
#include <utils/Log.h>
-#include <utils/AssetManager.h>
+#include <utils/threads.h>
#include <ui/PixelFormat.h>
#include <ui/Rect.h>
diff --git a/cmds/bootanimation/BootAnimation.h b/cmds/bootanimation/BootAnimation.h
index 8e28bba..c85d72c 100644
--- a/cmds/bootanimation/BootAnimation.h
+++ b/cmds/bootanimation/BootAnimation.h
@@ -20,8 +20,8 @@
#include <stdint.h>
#include <sys/types.h>
+#include <androidfw/AssetManager.h>
#include <utils/threads.h>
-#include <utils/AssetManager.h>
#include <surfaceflinger/ISurfaceComposer.h>
#include <surfaceflinger/SurfaceComposerClient.h>
diff --git a/cmds/content/Android.mk b/cmds/content/Android.mk
new file mode 100644
index 0000000..a3d83cf
--- /dev/null
+++ b/cmds/content/Android.mk
@@ -0,0 +1,35 @@
+# Copyright 2012 The Android Open Source Project
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_MODULE := content
+
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_JAVA_LIBRARY)
+
+include $(CLEAR_VARS)
+ALL_PREBUILT += $(TARGET_OUT)/bin/content
+$(TARGET_OUT)/bin/content : $(LOCAL_PATH)/content | $(ACP)
+ $(transform-prebuilt-to-target)
+
+NOTICE_FILE := NOTICE
+files_noticed := bin/content
+
+# Generate rules for a single file. The argument is the file path relative to
+# the installation root
+define make-notice-file
+
+$(TARGET_OUT_NOTICE_FILES)/src/$(1).txt: $(LOCAL_PATH)/$(NOTICE_FILE)
+ @echo Notice file: $$< -- $$@
+ @mkdir -p $$(dir $$@)
+ @cat $$< >> $$@
+
+$(TARGET_OUT_NOTICE_FILES)/hash-timestamp: $(TARGET_OUT_NOTICE_FILES)/src/$(1).txt
+
+endef
+
+$(foreach file,$(files_noticed),$(eval $(call make-notice-file,$(file))))
diff --git a/cmds/content/MODULE_LICENSE_APACHE2 b/cmds/content/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/cmds/content/MODULE_LICENSE_APACHE2
diff --git a/cmds/content/NOTICE b/cmds/content/NOTICE
new file mode 100644
index 0000000..33ff961
--- /dev/null
+++ b/cmds/content/NOTICE
@@ -0,0 +1,190 @@
+
+ Copyright (c) 2005-2012, 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.
+
+ 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.
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
diff --git a/cmds/content/content b/cmds/content/content
new file mode 100755
index 0000000..a8e056d
--- /dev/null
+++ b/cmds/content/content
@@ -0,0 +1,5 @@
+# Script to start "content" on the device, which has a very rudimentary shell.
+base=/system
+export CLASSPATH=$base/framework/content.jar
+exec app_process $base/bin com.android.commands.content.Content "$@"
+
diff --git a/cmds/content/src/com/android/commands/content/Content.java b/cmds/content/src/com/android/commands/content/Content.java
new file mode 100644
index 0000000..1dcba70
--- /dev/null
+++ b/cmds/content/src/com/android/commands/content/Content.java
@@ -0,0 +1,442 @@
+/*
+** Copyright 2012, 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 com.android.commands.content;
+
+import android.app.ActivityManagerNative;
+import android.app.IActivityManager;
+import android.app.IActivityManager.ContentProviderHolder;
+import android.content.ContentValues;
+import android.content.IContentProvider;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Binder;
+import android.os.IBinder;
+import android.text.TextUtils;
+
+/**
+ * This class is a command line utility for manipulating content. A client
+ * can insert, update, and remove records in a content provider. For example,
+ * some settings may be configured before running the CTS tests, etc.
+ * <p>
+ * Examples:
+ * <ul>
+ * <li>
+ * # Add "new_setting" secure setting with value "new_value".</br>
+ * adb shell content insert --uri content://settings/secure --bind name:s:new_setting
+ * --bind value:s:new_value
+ * </li>
+ * <li>
+ * # Change "new_setting" secure setting to "newer_value" (You have to escape single quotes in
+ * the where clause).</br>
+ * adb shell content update --uri content://settings/secure --bind value:s:newer_value
+ * --where "name=\'new_setting\'"
+ * </li>
+ * <li>
+ * # Remove "new_setting" secure setting.</br>
+ * adb shell content delete --uri content://settings/secure --where "name=\'new_setting\'"
+ * </li>
+ * <li>
+ * # Query \"name\" and \"value\" columns from secure settings where \"name\" is equal to"
+ * \"new_setting\" and sort the result by name in ascending order.\n"
+ * adb shell content query --uri content://settings/secure --projection name:value
+ * --where "name=\'new_setting\'" --sort \"name ASC\"
+ * </li>
+ * </ul>
+ * </p>
+ */
+public class Content {
+
+ private static final String USAGE =
+ "usage: adb shell content [subcommand] [options]\n"
+ + "\n"
+ + "usage: adb shell content insert --uri <URI> --bind <BINDING> [--bind <BINDING>...]\n"
+ + " <URI> a content provider URI.\n"
+ + " <BINDING> binds a typed value to a column and is formatted:\n"
+ + " <COLUMN_NAME>:<TYPE>:<COLUMN_VALUE> where:\n"
+ + " <TYPE> specifies data type such as:\n"
+ + " b - boolean, s - string, i - integer, l - long, f - float, d - double\n"
+ + " Example:\n"
+ + " # Add \"new_setting\" secure setting with value \"new_value\".\n"
+ + " adb shell content insert --uri content://settings/secure --bind name:s:new_setting"
+ + " --bind value:s:new_value\n"
+ + "\n"
+ + "usage: adb shell content update --uri <URI> [--where <WHERE>]\n"
+ + " <WHERE> is a SQL style where clause in quotes (You have to escape single quotes"
+ + " - see example below).\n"
+ + " Example:\n"
+ + " # Change \"new_setting\" secure setting to \"newer_value\".\n"
+ + " adb shell content update --uri content://settings/secure --bind"
+ + " value:s:newer_value --where \"name=\'new_setting\'\"\n"
+ + "\n"
+ + "usage: adb shell content delete --uri <URI> --bind <BINDING>"
+ + " [--bind <BINDING>...] [--where <WHERE>]\n"
+ + " Example:\n"
+ + " # Remove \"new_setting\" secure setting.\n"
+ + " adb shell content delete --uri content://settings/secure "
+ + "--where \"name=\'new_setting\'\"\n"
+ + "\n"
+ + "usage: adb shell content query --uri <URI> [--projection <PROJECTION>]"
+ + " [--where <WHERE>] [--sort <SORT_ORDER>]\n"
+ + " <PROJECTION> is a list of colon separated column names and is formatted:\n"
+ + " <COLUMN_NAME>[:<COLUMN_NAME>...]\n"
+ + " <SORT_OREDER> is the order in which rows in the result should be sorted.\n"
+ + " Example:\n"
+ + " # Select \"name\" and \"value\" columns from secure settings where \"name\" is "
+ + "equal to \"new_setting\" and sort the result by name in ascending order.\n"
+ + " adb shell content query --uri content://settings/secure --projection name:value"
+ + " --where \"name=\'new_setting\'\" --sort \"name ASC\"\n"
+ + "\n";
+
+ private static class Parser {
+ private static final String ARGUMENT_INSERT = "insert";
+ private static final String ARGUMENT_DELETE = "delete";
+ private static final String ARGUMENT_UPDATE = "update";
+ private static final String ARGUMENT_QUERY = "query";
+ private static final String ARGUMENT_WHERE = "--where";
+ private static final String ARGUMENT_BIND = "--bind";
+ private static final String ARGUMENT_URI = "--uri";
+ private static final String ARGUMENT_PROJECTION = "--projection";
+ private static final String ARGUMENT_SORT = "--sort";
+ private static final String TYPE_BOOLEAN = "b";
+ private static final String TYPE_STRING = "s";
+ private static final String TYPE_INTEGER = "i";
+ private static final String TYPE_LONG = "l";
+ private static final String TYPE_FLOAT = "f";
+ private static final String TYPE_DOUBLE = "d";
+ private static final String COLON = ":";
+ private static final String ARGUMENT_PREFIX = "--";
+
+ private final Tokenizer mTokenizer;
+
+ public Parser(String[] args) {
+ mTokenizer = new Tokenizer(args);
+ }
+
+ public Command parseCommand() {
+ try {
+ String operation = mTokenizer.nextArg();
+ if (ARGUMENT_INSERT.equals(operation)) {
+ return parseInsertCommand();
+ } else if (ARGUMENT_DELETE.equals(operation)) {
+ return parseDeleteCommand();
+ } else if (ARGUMENT_UPDATE.equals(operation)) {
+ return parseUpdateCommand();
+ } else if (ARGUMENT_QUERY.equals(operation)) {
+ return parseQueryCommand();
+ } else {
+ throw new IllegalArgumentException("Unsupported operation: " + operation);
+ }
+ } catch (IllegalArgumentException iae) {
+ System.out.println(USAGE);
+ System.out.println("[ERROR] " + iae.getMessage());
+ return null;
+ }
+ }
+
+ private InsertCommand parseInsertCommand() {
+ Uri uri = null;
+ ContentValues values = new ContentValues();
+ for (String argument; (argument = mTokenizer.nextArg()) != null;) {
+ if (ARGUMENT_URI.equals(argument)) {
+ uri = Uri.parse(argumentValueRequired(argument));
+ } else if (ARGUMENT_BIND.equals(argument)) {
+ parseBindValue(values);
+ } else {
+ throw new IllegalArgumentException("Unsupported argument: " + argument);
+ }
+ }
+ if (uri == null) {
+ throw new IllegalArgumentException("Content provider URI not specified."
+ + " Did you specify --uri argument?");
+ }
+ if (values.size() == 0) {
+ throw new IllegalArgumentException("Bindings not specified."
+ + " Did you specify --bind argument(s)?");
+ }
+ return new InsertCommand(uri, values);
+ }
+
+ private DeleteCommand parseDeleteCommand() {
+ Uri uri = null;
+ String where = null;
+ for (String argument; (argument = mTokenizer.nextArg())!= null;) {
+ if (ARGUMENT_URI.equals(argument)) {
+ uri = Uri.parse(argumentValueRequired(argument));
+ } else if (ARGUMENT_WHERE.equals(argument)) {
+ where = argumentValueRequired(argument);
+ } else {
+ throw new IllegalArgumentException("Unsupported argument: " + argument);
+ }
+ }
+ if (uri == null) {
+ throw new IllegalArgumentException("Content provider URI not specified."
+ + " Did you specify --uri argument?");
+ }
+ return new DeleteCommand(uri, where);
+ }
+
+ private UpdateCommand parseUpdateCommand() {
+ Uri uri = null;
+ String where = null;
+ ContentValues values = new ContentValues();
+ for (String argument; (argument = mTokenizer.nextArg())!= null;) {
+ if (ARGUMENT_URI.equals(argument)) {
+ uri = Uri.parse(argumentValueRequired(argument));
+ } else if (ARGUMENT_WHERE.equals(argument)) {
+ where = argumentValueRequired(argument);
+ } else if (ARGUMENT_BIND.equals(argument)) {
+ parseBindValue(values);
+ } else {
+ throw new IllegalArgumentException("Unsupported argument: " + argument);
+ }
+ }
+ if (uri == null) {
+ throw new IllegalArgumentException("Content provider URI not specified."
+ + " Did you specify --uri argument?");
+ }
+ if (values.size() == 0) {
+ throw new IllegalArgumentException("Bindings not specified."
+ + " Did you specify --bind argument(s)?");
+ }
+ return new UpdateCommand(uri, values, where);
+ }
+
+ public QueryCommand parseQueryCommand() {
+ Uri uri = null;
+ String[] projection = null;
+ String sort = null;
+ String where = null;
+ for (String argument; (argument = mTokenizer.nextArg())!= null;) {
+ if (ARGUMENT_URI.equals(argument)) {
+ uri = Uri.parse(argumentValueRequired(argument));
+ } else if (ARGUMENT_WHERE.equals(argument)) {
+ where = argumentValueRequired(argument);
+ } else if (ARGUMENT_SORT.equals(argument)) {
+ sort = argumentValueRequired(argument);
+ } else if (ARGUMENT_PROJECTION.equals(argument)) {
+ projection = argumentValueRequired(argument).split("[\\s]*:[\\s]*");
+ } else {
+ throw new IllegalArgumentException("Unsupported argument: " + argument);
+ }
+ }
+ if (uri == null) {
+ throw new IllegalArgumentException("Content provider URI not specified."
+ + " Did you specify --uri argument?");
+ }
+ return new QueryCommand(uri, projection, where, sort);
+ }
+
+ private void parseBindValue(ContentValues values) {
+ String argument = mTokenizer.nextArg();
+ if (TextUtils.isEmpty(argument)) {
+ throw new IllegalArgumentException("Binding not well formed: " + argument);
+ }
+ String[] binding = argument.split(COLON);
+ if (binding.length != 3) {
+ throw new IllegalArgumentException("Binding not well formed: " + argument);
+ }
+ String column = binding[0];
+ String type = binding[1];
+ String value = binding[2];
+ if (TYPE_STRING.equals(type)) {
+ values.put(column, value);
+ } else if (TYPE_BOOLEAN.equalsIgnoreCase(type)) {
+ values.put(column, Boolean.parseBoolean(value));
+ } else if (TYPE_INTEGER.equalsIgnoreCase(type) || TYPE_LONG.equalsIgnoreCase(type)) {
+ values.put(column, Long.parseLong(value));
+ } else if (TYPE_FLOAT.equalsIgnoreCase(type) || TYPE_DOUBLE.equalsIgnoreCase(type)) {
+ values.put(column, Double.parseDouble(value));
+ } else {
+ throw new IllegalArgumentException("Unsupported type: " + type);
+ }
+ }
+
+ private String argumentValueRequired(String argument) {
+ String value = mTokenizer.nextArg();
+ if (TextUtils.isEmpty(value) || value.startsWith(ARGUMENT_PREFIX)) {
+ throw new IllegalArgumentException("No value for argument: " + argument);
+ }
+ return value;
+ }
+ }
+
+ private static class Tokenizer {
+ private final String[] mArgs;
+ private int mNextArg;
+
+ public Tokenizer(String[] args) {
+ mArgs = args;
+ }
+
+ private String nextArg() {
+ if (mNextArg < mArgs.length) {
+ return mArgs[mNextArg++];
+ } else {
+ return null;
+ }
+ }
+ }
+
+ private static abstract class Command {
+ final Uri mUri;
+
+ public Command(Uri uri) {
+ mUri = uri;
+ }
+
+ public final void execute() {
+ String providerName = mUri.getAuthority();
+ try {
+ IActivityManager activityManager = ActivityManagerNative.getDefault();
+ IContentProvider provider = null;
+ IBinder token = new Binder();
+ try {
+ ContentProviderHolder holder = activityManager.getContentProviderExternal(
+ providerName, token);
+ if (holder == null) {
+ throw new IllegalStateException("Could not find provider: " + providerName);
+ }
+ provider = holder.provider;
+ onExecute(provider);
+ } finally {
+ if (provider != null) {
+ activityManager.removeContentProviderExternal(providerName, token);
+ }
+ }
+ } catch (Exception e) {
+ System.err.println("Error while accessing provider:" + providerName);
+ e.printStackTrace();
+ }
+ }
+
+ protected abstract void onExecute(IContentProvider provider) throws Exception;
+ }
+
+ private static class InsertCommand extends Command {
+ final ContentValues mContentValues;
+
+ public InsertCommand(Uri uri, ContentValues contentValues) {
+ super(uri);
+ mContentValues = contentValues;
+ }
+
+ @Override
+ public void onExecute(IContentProvider provider) throws Exception {
+ provider.insert(mUri, mContentValues);
+ }
+ }
+
+ private static class DeleteCommand extends Command {
+ final String mWhere;
+
+ public DeleteCommand(Uri uri, String where) {
+ super(uri);
+ mWhere = where;
+ }
+
+ @Override
+ public void onExecute(IContentProvider provider) throws Exception {
+ provider.delete(mUri, mWhere, null);
+ }
+ }
+
+ private static class QueryCommand extends DeleteCommand {
+ final String[] mProjection;
+ final String mSortOrder;
+
+ public QueryCommand(Uri uri, String[] projection, String where, String sortOrder) {
+ super(uri, where);
+ mProjection = projection;
+ mSortOrder = sortOrder;
+ }
+
+ @Override
+ public void onExecute(IContentProvider provider) throws Exception {
+ Cursor cursor = provider.query(mUri, mProjection, mWhere, null, mSortOrder, null);
+ if (cursor == null) {
+ System.out.println("No result found.");
+ return;
+ }
+ try {
+ if (cursor.moveToFirst()) {
+ int rowIndex = 0;
+ StringBuilder builder = new StringBuilder();
+ do {
+ builder.setLength(0);
+ builder.append("Row: ").append(rowIndex).append(" ");
+ rowIndex++;
+ final int columnCount = cursor.getColumnCount();
+ for (int i = 0; i < columnCount; i++) {
+ if (i > 0) {
+ builder.append(", ");
+ }
+ String columnName = cursor.getColumnName(i);
+ String columnValue = null;
+ final int columnIndex = cursor.getColumnIndex(columnName);
+ final int type = cursor.getType(columnIndex);
+ switch (type) {
+ case Cursor.FIELD_TYPE_FLOAT:
+ columnValue = String.valueOf(cursor.getFloat(columnIndex));
+ break;
+ case Cursor.FIELD_TYPE_INTEGER:
+ columnValue = String.valueOf(cursor.getInt(columnIndex));
+ break;
+ case Cursor.FIELD_TYPE_STRING:
+ columnValue = cursor.getString(columnIndex);
+ break;
+ case Cursor.FIELD_TYPE_BLOB:
+ columnValue = "BLOB";
+ break;
+ case Cursor.FIELD_TYPE_NULL:
+ columnValue = "NULL";
+ break;
+ }
+ builder.append(columnName).append("=").append(columnValue);
+ }
+ System.out.println(builder);
+ } while (cursor.moveToNext());
+ } else {
+ System.out.println("No reuslt found.");
+ }
+ } finally {
+ cursor.close();
+ }
+ }
+ }
+
+ private static class UpdateCommand extends InsertCommand {
+ final String mWhere;
+
+ public UpdateCommand(Uri uri, ContentValues contentValues, String where) {
+ super(uri, contentValues);
+ mWhere = where;
+ }
+
+ @Override
+ public void onExecute(IContentProvider provider) throws Exception {
+ provider.update(mUri, mContentValues, mWhere, null);
+ }
+ }
+
+ public static void main(String[] args) {
+ Parser parser = new Parser(args);
+ Command command = parser.parseCommand();
+ if (command != null) {
+ command.execute();
+ }
+ }
+}
diff --git a/cmds/screencap/screencap.cpp b/cmds/screencap/screencap.cpp
index bee5880..90dfe76 100644
--- a/cmds/screencap/screencap.cpp
+++ b/cmds/screencap/screencap.cpp
@@ -49,7 +49,6 @@
{
switch (f) {
case PIXEL_FORMAT_A_8:
- case PIXEL_FORMAT_L_8:
return SkBitmap::kA8_Config;
case PIXEL_FORMAT_RGB_565:
return SkBitmap::kRGB_565_Config;
diff --git a/cmds/servicemanager/service_manager.c b/cmds/servicemanager/service_manager.c
index cfc2d16..71c5622 100644
--- a/cmds/servicemanager/service_manager.c
+++ b/cmds/servicemanager/service_manager.c
@@ -43,6 +43,8 @@
{ AID_RADIO, "isms" },
{ AID_RADIO, "iphonesubinfo" },
{ AID_RADIO, "simphonebook" },
+ { AID_MEDIA, "common_time.clock" },
+ { AID_MEDIA, "common_time.config" },
};
void *svcmgr_handle;
diff --git a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
index c9468eb..882dd6b 100644
--- a/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
+++ b/core/java/android/accessibilityservice/IAccessibilityServiceConnection.aidl
@@ -30,14 +30,14 @@
void setServiceInfo(in AccessibilityServiceInfo info);
/**
- * Finds an {@link AccessibilityNodeInfo} by accessibility id.
+ * Finds an {@link android.view.accessibility.AccessibilityNodeInfo} by accessibility id.
*
* @param accessibilityWindowId A unique window id. Use
- * {@link com.android.server.accessibility.AccessibilityManagerService#ACTIVE_WINDOW_ID}
+ * {@link android.view.accessibility.AccessibilityNodeInfo#ACTIVE_WINDOW_ID}
* to query the currently active window.
* @param accessibilityNodeId A unique view id or virtual descendant id from
* where to start the search. Use
- * {@link com.android.server.accessibility.AccessibilityManagerService#ROOT_NODE_ID}
+ * {@link android.view.accessibility.AccessibilityNodeInfo#ROOT_NODE_ID}
* to start from the root.
* @param interactionId The id of the interaction for matching with the callback result.
* @param callback Callback which to receive the result.
@@ -49,17 +49,16 @@
IAccessibilityInteractionConnectionCallback callback, long threadId);
/**
- * Finds {@link AccessibilityNodeInfo}s by View text. The match is case
- * insensitive containment. The search is performed in the window whose
- * id is specified and starts from the node whose accessibility id is
- * specified.
+ * Finds {@link android.view.accessibility.AccessibilityNodeInfo}s by View text.
+ * The match is case insensitive containment. The search is performed in the window
+ * whose id is specified and starts from the node whose accessibility id is specified.
*
* @param accessibilityWindowId A unique window id. Use
- * {@link com.android.server.accessibility.AccessibilityManagerService#ACTIVE_WINDOW_ID}
+ * {@link android.view.accessibility.AccessibilityNodeInfo#ACTIVE_WINDOW_ID}
* to query the currently active window.
* @param accessibilityNodeId A unique view id or virtual descendant id from
* where to start the search. Use
- * {@link com.android.server.accessibility.AccessibilityManagerService#ROOT_NODE_ID}
+ * {@link android.view.accessibility.AccessibilityNodeInfo#ROOT_NODE_ID}
* to start from the root.
* @param text The searched text.
* @param interactionId The id of the interaction for matching with the callback result.
@@ -72,16 +71,16 @@
long threadId);
/**
- * Finds an {@link AccessibilityNodeInfo} by View id. The search is performed in
- * the window whose id is specified and starts from the node whose accessibility
- * id is specified.
+ * Finds an {@link android.view.accessibility.AccessibilityNodeInfo} by View id. The search
+ * is performed in the window whose id is specified and starts from the node whose
+ * accessibility id is specified.
*
* @param accessibilityWindowId A unique window id. Use
- * {@link com.android.server.accessibility.AccessibilityManagerService#ACTIVE_WINDOW_ID}
+ * {@link android.view.accessibility.AccessibilityNodeInfo#ACTIVE_WINDOW_ID}
* to query the currently active window.
* @param accessibilityNodeId A unique view id or virtual descendant id from
* where to start the search. Use
- * {@link com.android.server.accessibility.AccessibilityManagerService#ROOT_NODE_ID}
+ * {@link android.view.accessibility.AccessibilityNodeInfo#ROOT_NODE_ID}
* to start from the root.
* @param id The id of the node.
* @param interactionId The id of the interaction for matching with the callback result.
@@ -94,14 +93,15 @@
long threadId);
/**
- * Performs an accessibility action on an {@link AccessibilityNodeInfo}.
+ * Performs an accessibility action on an
+ * {@link android.view.accessibility.AccessibilityNodeInfo}.
*
* @param accessibilityWindowId A unique window id. Use
- * {@link com.android.server.accessibility.AccessibilityManagerService#ACTIVE_WINDOW_ID}
+ * {@link android.view.accessibility.AccessibilityNodeInfo#ACTIVE_WINDOW_ID}
* to query the currently active window.
* @param accessibilityNodeId A unique view id or virtual descendant id from
* where to start the search. Use
- * {@link com.android.server.accessibility.AccessibilityManagerService#ROOT_NODE_ID}
+ * {@link android.view.accessibility.AccessibilityNodeInfo#ROOT_NODE_ID}
* to start from the root.
* @param action The action to perform.
* @param interactionId The id of the interaction for matching with the callback result.
diff --git a/core/java/android/accessibilityservice/UiTestAutomationBridge.java b/core/java/android/accessibilityservice/UiTestAutomationBridge.java
index 616b796..334981a 100644
--- a/core/java/android/accessibilityservice/UiTestAutomationBridge.java
+++ b/core/java/android/accessibilityservice/UiTestAutomationBridge.java
@@ -49,12 +49,14 @@
private static final String LOG_TAG = UiTestAutomationBridge.class.getSimpleName();
- public static final int ACTIVE_WINDOW_ID = -1;
-
- public static final long ROOT_NODE_ID = -1;
-
private static final int TIMEOUT_REGISTER_SERVICE = 5000;
+ public static final int ACTIVE_WINDOW_ID = AccessibilityNodeInfo.ACTIVE_WINDOW_ID;
+
+ public static final long ROOT_NODE_ID = AccessibilityNodeInfo.ROOT_NODE_ID;
+
+ public static final int UNDEFINED = -1;
+
private final Object mLock = new Object();
private volatile int mConnectionId = AccessibilityInteractionClient.NO_ID;
@@ -63,8 +65,6 @@
private AccessibilityEvent mLastEvent;
- private AccessibilityEvent mLastWindowStateChangeEvent;
-
private volatile boolean mWaitingForEventDelivery;
private volatile boolean mUnprocessedEventAvailable;
@@ -141,17 +141,8 @@
synchronized (mLock) {
while (true) {
mLastEvent = AccessibilityEvent.obtain(event);
-
- final int eventType = event.getEventType();
- if (eventType == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED
- || eventType == AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED) {
- if (mLastWindowStateChangeEvent != null) {
- mLastWindowStateChangeEvent.recycle();
- }
- mLastWindowStateChangeEvent = mLastEvent;
- }
-
if (!mWaitingForEventDelivery) {
+ mLock.notifyAll();
break;
}
if (!mUnprocessedEventAvailable) {
@@ -295,6 +286,43 @@
}
/**
+ * Waits for the accessibility event stream to become idle, which is not to
+ * have received a new accessibility event within <code>idleTimeout</code>,
+ * and do so within a maximal global timeout as specified by
+ * <code>globalTimeout</code>.
+ *
+ * @param idleTimeout The timeout between two event to consider the device idle.
+ * @param globalTimeout The maximal global timeout in which to wait for idle.
+ */
+ public void waitForIdle(long idleTimeout, long globalTimeout) {
+ final long startTimeMillis = SystemClock.uptimeMillis();
+ long lastEventTime = (mLastEvent != null)
+ ? mLastEvent.getEventTime() : SystemClock.uptimeMillis();
+ synchronized (mLock) {
+ while (true) {
+ final long currentTimeMillis = SystemClock.uptimeMillis();
+ final long sinceLastEventTimeMillis = currentTimeMillis - lastEventTime;
+ if (sinceLastEventTimeMillis > idleTimeout) {
+ return;
+ }
+ if (mLastEvent != null) {
+ lastEventTime = mLastEvent.getEventTime();
+ }
+ final long elapsedTimeMillis = SystemClock.uptimeMillis() - startTimeMillis;
+ final long remainingTimeMillis = globalTimeout - elapsedTimeMillis;
+ if (remainingTimeMillis <= 0) {
+ return;
+ }
+ try {
+ mLock.wait(idleTimeout);
+ } catch (InterruptedException e) {
+ /* ignore */
+ }
+ }
+ }
+ }
+
+ /**
* Finds an {@link AccessibilityNodeInfo} by accessibility id in the active
* window. The search is performed from the root node.
*
@@ -310,8 +338,8 @@
/**
* Finds an {@link AccessibilityNodeInfo} by accessibility id.
*
- * @param accessibilityWindowId A unique window id. Use {@link #ACTIVE_WINDOW_ID}
- * to query the currently active window.
+ * @param accessibilityWindowId A unique window id. Use {@link #ACTIVE_WINDOW_ID} to query
+ * the currently active window.
* @param accessibilityNodeId A unique view id or virtual descendant id for
* which to search.
* @return The current window scale, where zero means a failure.
@@ -341,10 +369,10 @@
* the window whose id is specified and starts from the node whose accessibility
* id is specified.
*
- * @param accessibilityWindowId A unique window id. Use {@link #ACTIVE_WINDOW_ID}
- * to query the currently active window.
+ * @param accessibilityWindowId A unique window id. Use
+ * {@link #ACTIVE_WINDOW_ID} to query the currently active window.
* @param accessibilityNodeId A unique view id or virtual descendant id from
- * where to start the search. Use {@link #ROOT_NODE_ID} to start from the root.
+ * where to start the search. Use {@link #ROOT_NODE_ID} to start from the root.
* @return The current window scale, where zero means a failure.
*/
public AccessibilityNodeInfo findAccessibilityNodeInfoByViewId(int accessibilityWindowId,
@@ -374,8 +402,8 @@
* id is specified and starts from the node whose accessibility id is
* specified.
*
- * @param accessibilityWindowId A unique window id. Use {@link #ACTIVE_WINDOW_ID}
- * to query the currently active window.
+ * @param accessibilityWindowId A unique window id. Use
+ * {@link #ACTIVE_WINDOW_ID} to query the currently active window.
* @param accessibilityNodeId A unique view id or virtual descendant id from
* where to start the search. Use {@link #ROOT_NODE_ID} to start from the root.
* @param text The searched text.
@@ -406,8 +434,8 @@
/**
* Performs an accessibility action on an {@link AccessibilityNodeInfo}.
*
- * @param accessibilityWindowId A unique window id. Use {@link #ACTIVE_WINDOW_ID}
- * to query the currently active window.
+ * @param accessibilityWindowId A unique window id. Use
+ * {@link #ACTIVE_WINDOW_ID} to query the currently active window.
* @param accessibilityNodeId A unique node id (accessibility and virtual descendant id).
* @param action The action to perform.
* @return Whether the action was performed.
@@ -427,16 +455,16 @@
* @return The root info.
*/
public AccessibilityNodeInfo getRootAccessibilityNodeInfoInActiveWindow() {
- synchronized (mLock) {
- if (mLastWindowStateChangeEvent != null) {
- return mLastWindowStateChangeEvent.getSource();
- }
- }
- return null;
+ // Cache the id to avoid locking
+ final int connectionId = mConnectionId;
+ ensureValidConnection(connectionId);
+ return AccessibilityInteractionClient.getInstance()
+ .findAccessibilityNodeInfoByAccessibilityId(connectionId, ACTIVE_WINDOW_ID,
+ ROOT_NODE_ID);
}
private void ensureValidConnection(int connectionId) {
- if (connectionId == AccessibilityInteractionClient.NO_ID) {
+ if (connectionId == UNDEFINED) {
throw new IllegalStateException("UiAutomationService not connected."
+ " Did you call #register()?");
}
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index 5a36466..24079a5d 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -581,6 +581,21 @@
return true;
}
+ case GET_CONTENT_PROVIDER_EXTERNAL_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ String name = data.readString();
+ IBinder token = data.readStrongBinder();
+ ContentProviderHolder cph = getContentProviderExternal(name, token);
+ reply.writeNoException();
+ if (cph != null) {
+ reply.writeInt(1);
+ cph.writeToParcel(reply, 0);
+ } else {
+ reply.writeInt(0);
+ }
+ return true;
+ }
+
case PUBLISH_CONTENT_PROVIDERS_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
IBinder b = data.readStrongBinder();
@@ -601,7 +616,16 @@
reply.writeNoException();
return true;
}
-
+
+ case REMOVE_CONTENT_PROVIDER_EXTERNAL_TRANSACTION: {
+ data.enforceInterface(IActivityManager.descriptor);
+ String name = data.readString();
+ IBinder token = data.readStrongBinder();
+ removeContentProviderExternal(name, token);
+ reply.writeNoException();
+ return true;
+ }
+
case GET_RUNNING_SERVICE_CONTROL_PANEL_TRANSACTION: {
data.enforceInterface(IActivityManager.descriptor);
ComponentName comp = ComponentName.CREATOR.createFromParcel(data);
@@ -2178,6 +2202,25 @@
reply.recycle();
return cph;
}
+ public ContentProviderHolder getContentProviderExternal(String name, IBinder token)
+ throws RemoteException
+ {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeString(name);
+ data.writeStrongBinder(token);
+ mRemote.transact(GET_CONTENT_PROVIDER_EXTERNAL_TRANSACTION, data, reply, 0);
+ reply.readException();
+ int res = reply.readInt();
+ ContentProviderHolder cph = null;
+ if (res != 0) {
+ cph = ContentProviderHolder.CREATOR.createFromParcel(reply);
+ }
+ data.recycle();
+ reply.recycle();
+ return cph;
+ }
public void publishContentProviders(IApplicationThread caller,
List<ContentProviderHolder> providers) throws RemoteException
{
@@ -2204,7 +2247,19 @@
data.recycle();
reply.recycle();
}
-
+
+ public void removeContentProviderExternal(String name, IBinder token) throws RemoteException {
+ Parcel data = Parcel.obtain();
+ Parcel reply = Parcel.obtain();
+ data.writeInterfaceToken(IActivityManager.descriptor);
+ data.writeString(name);
+ data.writeStrongBinder(token);
+ mRemote.transact(REMOVE_CONTENT_PROVIDER_EXTERNAL_TRANSACTION, data, reply, 0);
+ reply.readException();
+ data.recycle();
+ reply.recycle();
+ }
+
public PendingIntent getRunningServiceControlPanel(ComponentName service)
throws RemoteException
{
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index ebf692a..6d5cce5 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -911,6 +911,19 @@
}
}
+ /** @hide */
+ @Override
+ public void sendBroadcast(Intent intent, int userId) {
+ String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
+ try {
+ intent.setAllowFds(false);
+ ActivityManagerNative.getDefault().broadcastIntent(mMainThread.getApplicationThread(),
+ intent, resolvedType, null, Activity.RESULT_OK, null, null, null, false, false,
+ userId);
+ } catch (RemoteException e) {
+ }
+ }
+
@Override
public void sendBroadcast(Intent intent, String receiverPermission) {
String resolvedType = intent.resolveTypeIfNeeded(getContentResolver());
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 7deb615..53a71db 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -150,8 +150,11 @@
Bitmap thumbnail, CharSequence description) throws RemoteException;
public ContentProviderHolder getContentProvider(IApplicationThread caller,
String name) throws RemoteException;
+ public ContentProviderHolder getContentProviderExternal(String name, IBinder token)
+ throws RemoteException;
public void removeContentProvider(IApplicationThread caller,
String name) throws RemoteException;
+ public void removeContentProviderExternal(String name, IBinder token) throws RemoteException;
public void publishContentProviders(IApplicationThread caller,
List<ContentProviderHolder> providers) throws RemoteException;
public PendingIntent getRunningServiceControlPanel(ComponentName service)
@@ -415,7 +418,7 @@
source.readStrongBinder());
noReleaseNeeded = source.readInt() != 0;
}
- };
+ }
/** Information returned after waiting for an activity start. */
public static class WaitResult implements Parcelable {
@@ -601,4 +604,6 @@
int SHOW_BOOT_MESSAGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+137;
int DISMISS_KEYGUARD_ON_NEXT_ACTIVITY_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+138;
int KILL_ALL_BACKGROUND_PROCESSES_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+139;
+ int GET_CONTENT_PROVIDER_EXTERNAL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+140;
+ int REMOVE_CONTENT_PROVIDER_EXTERNAL_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+141;
}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 6d4cdae..a1198de 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -905,6 +905,16 @@
public abstract void sendBroadcast(Intent intent);
/**
+ * Same as #sendBroadcast(Intent intent), but for a specific user. Used by the system only.
+ * @param intent the intent to broadcast
+ * @param userId user to send the intent to
+ * @hide
+ */
+ public void sendBroadcast(Intent intent, int userId) {
+ throw new RuntimeException("Not implemented. Must override in a subclass.");
+ }
+
+ /**
* Broadcast the given intent to all interested BroadcastReceivers, allowing
* an optional required permission to be enforced. This
* call is asynchronous; it returns immediately, and you will continue
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index cd8d87f..5ba9dcc 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -294,6 +294,12 @@
mBase.sendBroadcast(intent);
}
+ /** @hide */
+ @Override
+ public void sendBroadcast(Intent intent, int userId) {
+ mBase.sendBroadcast(intent, userId);
+ }
+
@Override
public void sendBroadcast(Intent intent, String receiverPermission) {
mBase.sendBroadcast(intent, receiverPermission);
diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java
index aeb5d92..3fdf246 100644
--- a/core/java/android/hardware/SensorManager.java
+++ b/core/java/android/hardware/SensorManager.java
@@ -616,6 +616,7 @@
Message msg = Message.obtain();
msg.what = 0;
msg.obj = t;
+ msg.setAsynchronous(true);
mHandler.sendMessage(msg);
}
}
diff --git a/core/java/android/net/http/CertificateChainValidator.java b/core/java/android/net/http/CertificateChainValidator.java
index f94d320..06c6c6e 100644
--- a/core/java/android/net/http/CertificateChainValidator.java
+++ b/core/java/android/net/http/CertificateChainValidator.java
@@ -25,15 +25,17 @@
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSocket;
+import javax.net.ssl.X509TrustManager;
import org.apache.harmony.security.provider.cert.X509CertImpl;
import org.apache.harmony.xnet.provider.jsse.SSLParametersImpl;
+import org.apache.harmony.xnet.provider.jsse.TrustManagerImpl;
/**
* Class responsible for all server certificate validation functionality
*
* {@hide}
*/
-class CertificateChainValidator {
+public class CertificateChainValidator {
/**
* The singleton instance of the certificate chain validator
@@ -122,6 +124,18 @@
}
/**
+ * Handles updates to credential storage.
+ */
+ public static void handleTrustStorageUpdate() {
+
+ X509TrustManager x509TrustManager = SSLParametersImpl.getDefaultTrustManager();
+ if( x509TrustManager instanceof TrustManagerImpl ) {
+ TrustManagerImpl trustManager = (TrustManagerImpl) x509TrustManager;
+ trustManager.handleTrustStorageUpdate();
+ }
+ }
+
+ /**
* Common code of doHandshakeAndValidateServerCertificates and verifyServerCertificates.
* Calls DomainNamevalidator to verify the domain, and TrustManager to verify the certs.
* @param chain the cert chain in X509 cert format.
diff --git a/core/java/android/os/CommonClock.java b/core/java/android/os/CommonClock.java
new file mode 100644
index 0000000..3a1da97
--- /dev/null
+++ b/core/java/android/os/CommonClock.java
@@ -0,0 +1,414 @@
+/*
+ * Copyright (C) 2012 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 android.os;
+
+import java.net.InetAddress;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetSocketAddress;
+import java.util.NoSuchElementException;
+import static libcore.io.OsConstants.*;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Binder;
+import android.os.CommonTimeUtils;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+
+/**
+ * Used for accessing the android common time service's common clock and receiving notifications
+ * about common time synchronization status changes.
+ * @hide
+ */
+public class CommonClock {
+ /**
+ * Sentinel value returned by {@link #getTime()} and {@link #getEstimatedError()} when the
+ * common time service is not able to determine the current common time due to a lack of
+ * synchronization.
+ */
+ public static final long TIME_NOT_SYNCED = -1;
+
+ /**
+ * Sentinel value returned by {@link #getTimelineId()} when the common time service is not
+ * currently synced to any timeline.
+ */
+ public static final long INVALID_TIMELINE_ID = 0;
+
+ /**
+ * Sentinel value returned by {@link #getEstimatedError()} when the common time service is not
+ * currently synced to any timeline.
+ */
+ public static final int ERROR_ESTIMATE_UNKNOWN = 0x7FFFFFFF;
+
+ /**
+ * Value used by {@link #getState()} to indicate that there was an internal error while
+ * attempting to determine the state of the common time service.
+ */
+ public static final int STATE_INVALID = -1;
+
+ /**
+ * Value used by {@link #getState()} to indicate that the common time service is in its initial
+ * state and attempting to find the current timeline master, if any. The service will
+ * transition to either {@link #STATE_CLIENT} if it finds an active master, or to
+ * {@link #STATE_MASTER} if no active master is found and this client becomes the master of a
+ * new timeline.
+ */
+ public static final int STATE_INITIAL = 0;
+
+ /**
+ * Value used by {@link #getState()} to indicate that the common time service is in its client
+ * state and is synchronizing its time to a different timeline master on the network.
+ */
+ public static final int STATE_CLIENT = 1;
+
+ /**
+ * Value used by {@link #getState()} to indicate that the common time service is in its master
+ * state and is serving as the timeline master for other common time service clients on the
+ * network.
+ */
+ public static final int STATE_MASTER = 2;
+
+ /**
+ * Value used by {@link #getState()} to indicate that the common time service is in its Ronin
+ * state. Common time service instances in the client state enter the Ronin state after their
+ * timeline master becomes unreachable on the network. Common time services who enter the Ronin
+ * state will begin a new master election for the timeline they were recently clients of. As
+ * clients detect they are not the winner and drop out of the election, they will transition to
+ * the {@link #STATE_WAIT_FOR_ELECTION} state. When there is only one client remaining in the
+ * election, it will assume ownership of the timeline and transition to the
+ * {@link #STATE_MASTER} state. During the election, all clients will allow their timeline to
+ * drift without applying correction.
+ */
+ public static final int STATE_RONIN = 3;
+
+ /**
+ * Value used by {@link #getState()} to indicate that the common time service is waiting for a
+ * master election to conclude and for the new master to announce itself before transitioning to
+ * the {@link #STATE_CLIENT} state. If no new master announces itself within the timeout
+ * threshold, the time service will transition back to the {@link #STATE_RONIN} state in order
+ * to restart the election.
+ */
+ public static final int STATE_WAIT_FOR_ELECTION = 4;
+
+ /**
+ * Name of the underlying native binder service
+ */
+ public static final String SERVICE_NAME = "common_time.clock";
+
+ /**
+ * Class constructor.
+ * @throws android.os.RemoteException
+ */
+ public CommonClock()
+ throws RemoteException {
+ mRemote = ServiceManager.getService(SERVICE_NAME);
+ if (null == mRemote)
+ throw new RemoteException();
+
+ mInterfaceDesc = mRemote.getInterfaceDescriptor();
+ mUtils = new CommonTimeUtils(mRemote, mInterfaceDesc);
+ mRemote.linkToDeath(mDeathHandler, 0);
+ registerTimelineChangeListener();
+ }
+
+ /**
+ * Handy class factory method.
+ */
+ static public CommonClock create() {
+ CommonClock retVal;
+
+ try {
+ retVal = new CommonClock();
+ }
+ catch (RemoteException e) {
+ retVal = null;
+ }
+
+ return retVal;
+ }
+
+ /**
+ * Release all native resources held by this {@link android.os.CommonClock} instance. Once
+ * resources have been released, the {@link android.os.CommonClock} instance is disconnected from
+ * the native service and will throw a {@link android.os.RemoteException} if any of its
+ * methods are called. Clients should always call release on their client instances before
+ * releasing their last Java reference to the instance. Failure to do this will cause
+ * non-deterministic native resource reclamation and may cause the common time service to remain
+ * active on the network for longer than it should.
+ */
+ public void release() {
+ unregisterTimelineChangeListener();
+ if (null != mRemote) {
+ try {
+ mRemote.unlinkToDeath(mDeathHandler, 0);
+ }
+ catch (NoSuchElementException e) { }
+ mRemote = null;
+ }
+ mUtils = null;
+ }
+
+ /**
+ * Gets the common clock's current time.
+ *
+ * @return a signed 64-bit value representing the current common time in microseconds, or the
+ * special value {@link #TIME_NOT_SYNCED} if the common time service is currently not
+ * synchronized.
+ * @throws android.os.RemoteException
+ */
+ public long getTime()
+ throws RemoteException {
+ throwOnDeadServer();
+ return mUtils.transactGetLong(METHOD_GET_COMMON_TIME, TIME_NOT_SYNCED);
+ }
+
+ /**
+ * Gets the current estimation of common clock's synchronization accuracy from the common time
+ * service.
+ *
+ * @return a signed 32-bit value representing the common time service's estimation of
+ * synchronization accuracy in microseconds, or the special value
+ * {@link #ERROR_ESTIMATE_UNKNOWN} if the common time service is currently not synchronized.
+ * Negative values indicate that the local server estimates that the nominal common time is
+ * behind the local server's time (in other words, the local clock is running fast) Positive
+ * values indicate that the local server estimates that the nominal common time is ahead of the
+ * local server's time (in other words, the local clock is running slow)
+ * @throws android.os.RemoteException
+ */
+ public int getEstimatedError()
+ throws RemoteException {
+ throwOnDeadServer();
+ return mUtils.transactGetInt(METHOD_GET_ESTIMATED_ERROR, ERROR_ESTIMATE_UNKNOWN);
+ }
+
+ /**
+ * Gets the ID of the timeline the common time service is currently synchronizing its clock to.
+ *
+ * @return a long representing the unique ID of the timeline the common time service is
+ * currently synchronizing with, or {@link #INVALID_TIMELINE_ID} if the common time service is
+ * currently not synchronized.
+ * @throws android.os.RemoteException
+ */
+ public long getTimelineId()
+ throws RemoteException {
+ throwOnDeadServer();
+ return mUtils.transactGetLong(METHOD_GET_TIMELINE_ID, INVALID_TIMELINE_ID);
+ }
+
+ /**
+ * Gets the current state of this clock's common time service in the the master election
+ * algorithm.
+ *
+ * @return a integer indicating the current state of the this clock's common time service in the
+ * master election algorithm or {@link #STATE_INVALID} if there is an internal error.
+ * @throws android.os.RemoteException
+ */
+ public int getState()
+ throws RemoteException {
+ throwOnDeadServer();
+ return mUtils.transactGetInt(METHOD_GET_STATE, STATE_INVALID);
+ }
+
+ /**
+ * Gets the IP address and UDP port of the current timeline master.
+ *
+ * @return an InetSocketAddress containing the IP address and UDP port of the current timeline
+ * master, or null if there is no current master.
+ * @throws android.os.RemoteException
+ */
+ public InetSocketAddress getMasterAddr()
+ throws RemoteException {
+ throwOnDeadServer();
+ return mUtils.transactGetSockaddr(METHOD_GET_MASTER_ADDRESS);
+ }
+
+ /**
+ * The OnTimelineChangedListener interface defines a method called by the
+ * {@link android.os.CommonClock} instance to indicate that the time synchronization service has
+ * either synchronized with a new timeline, or is no longer a member of any timeline. The
+ * client application can implement this interface and register the listener with the
+ * {@link #setTimelineChangedListener(OnTimelineChangedListener)} method.
+ */
+ public interface OnTimelineChangedListener {
+ /**
+ * Method called when the time service's timeline has changed.
+ *
+ * @param newTimelineId a long which uniquely identifies the timeline the time
+ * synchronization service is now a member of, or {@link #INVALID_TIMELINE_ID} if the the
+ * service is not synchronized to any timeline.
+ */
+ void onTimelineChanged(long newTimelineId);
+ }
+
+ /**
+ * Registers an OnTimelineChangedListener interface.
+ * <p>Call this method with a null listener to stop receiving server death notifications.
+ */
+ public void setTimelineChangedListener(OnTimelineChangedListener listener) {
+ synchronized (mListenerLock) {
+ mTimelineChangedListener = listener;
+ }
+ }
+
+ /**
+ * The OnServerDiedListener interface defines a method called by the
+ * {@link android.os.CommonClock} instance to indicate that the connection to the native media
+ * server has been broken and that the {@link android.os.CommonClock} instance will need to be
+ * released and re-created. The client application can implement this interface and register
+ * the listener with the {@link #setServerDiedListener(OnServerDiedListener)} method.
+ */
+ public interface OnServerDiedListener {
+ /**
+ * Method called when the native media server has died. <p>If the native common time
+ * service encounters a fatal error and needs to restart, the binder connection from the
+ * {@link android.os.CommonClock} instance to the common time service will be broken. To
+ * restore functionality, clients should {@link #release()} their old visualizer and create
+ * a new instance.
+ */
+ void onServerDied();
+ }
+
+ /**
+ * Registers an OnServerDiedListener interface.
+ * <p>Call this method with a null listener to stop receiving server death notifications.
+ */
+ public void setServerDiedListener(OnServerDiedListener listener) {
+ synchronized (mListenerLock) {
+ mServerDiedListener = listener;
+ }
+ }
+
+ protected void finalize() throws Throwable { release(); }
+
+ private void throwOnDeadServer() throws RemoteException {
+ if ((null == mRemote) || (null == mUtils))
+ throw new RemoteException();
+ }
+
+ private final Object mListenerLock = new Object();
+ private OnTimelineChangedListener mTimelineChangedListener = null;
+ private OnServerDiedListener mServerDiedListener = null;
+
+ private IBinder mRemote = null;
+ private String mInterfaceDesc = "";
+ private CommonTimeUtils mUtils;
+
+ private IBinder.DeathRecipient mDeathHandler = new IBinder.DeathRecipient() {
+ public void binderDied() {
+ synchronized (mListenerLock) {
+ if (null != mServerDiedListener)
+ mServerDiedListener.onServerDied();
+ }
+ }
+ };
+
+ private class TimelineChangedListener extends Binder {
+ @Override
+ protected boolean onTransact(int code, Parcel data, Parcel reply, int flags)
+ throws RemoteException {
+ switch (code) {
+ case METHOD_CBK_ON_TIMELINE_CHANGED:
+ data.enforceInterface(DESCRIPTOR);
+ long timelineId = data.readLong();
+ synchronized (mListenerLock) {
+ if (null != mTimelineChangedListener)
+ mTimelineChangedListener.onTimelineChanged(timelineId);
+ }
+ return true;
+ }
+
+ return super.onTransact(code, data, reply, flags);
+ }
+
+ private static final String DESCRIPTOR = "android.os.ICommonClockListener";
+ };
+
+ private TimelineChangedListener mCallbackTgt = null;
+
+ private void registerTimelineChangeListener() throws RemoteException {
+ if (null != mCallbackTgt)
+ return;
+
+ boolean success = false;
+ android.os.Parcel data = android.os.Parcel.obtain();
+ android.os.Parcel reply = android.os.Parcel.obtain();
+ mCallbackTgt = new TimelineChangedListener();
+
+ try {
+ data.writeInterfaceToken(mInterfaceDesc);
+ data.writeStrongBinder(mCallbackTgt);
+ mRemote.transact(METHOD_REGISTER_LISTENER, data, reply, 0);
+ success = (0 == reply.readInt());
+ }
+ catch (RemoteException e) {
+ success = false;
+ }
+ finally {
+ reply.recycle();
+ data.recycle();
+ }
+
+ // Did we catch a remote exception or fail to register our callback target? If so, our
+ // object must already be dead (or be as good as dead). Clear out all of our state so that
+ // our other methods will properly indicate a dead object.
+ if (!success) {
+ mCallbackTgt = null;
+ mRemote = null;
+ mUtils = null;
+ }
+ }
+
+ private void unregisterTimelineChangeListener() {
+ if (null == mCallbackTgt)
+ return;
+
+ android.os.Parcel data = android.os.Parcel.obtain();
+ android.os.Parcel reply = android.os.Parcel.obtain();
+
+ try {
+ data.writeInterfaceToken(mInterfaceDesc);
+ data.writeStrongBinder(mCallbackTgt);
+ mRemote.transact(METHOD_UNREGISTER_LISTENER, data, reply, 0);
+ }
+ catch (RemoteException e) { }
+ finally {
+ reply.recycle();
+ data.recycle();
+ mCallbackTgt = null;
+ }
+ }
+
+ private static final int METHOD_IS_COMMON_TIME_VALID = IBinder.FIRST_CALL_TRANSACTION;
+ private static final int METHOD_COMMON_TIME_TO_LOCAL_TIME = METHOD_IS_COMMON_TIME_VALID + 1;
+ private static final int METHOD_LOCAL_TIME_TO_COMMON_TIME = METHOD_COMMON_TIME_TO_LOCAL_TIME + 1;
+ private static final int METHOD_GET_COMMON_TIME = METHOD_LOCAL_TIME_TO_COMMON_TIME + 1;
+ private static final int METHOD_GET_COMMON_FREQ = METHOD_GET_COMMON_TIME + 1;
+ private static final int METHOD_GET_LOCAL_TIME = METHOD_GET_COMMON_FREQ + 1;
+ private static final int METHOD_GET_LOCAL_FREQ = METHOD_GET_LOCAL_TIME + 1;
+ private static final int METHOD_GET_ESTIMATED_ERROR = METHOD_GET_LOCAL_FREQ + 1;
+ private static final int METHOD_GET_TIMELINE_ID = METHOD_GET_ESTIMATED_ERROR + 1;
+ private static final int METHOD_GET_STATE = METHOD_GET_TIMELINE_ID + 1;
+ private static final int METHOD_GET_MASTER_ADDRESS = METHOD_GET_STATE + 1;
+ private static final int METHOD_REGISTER_LISTENER = METHOD_GET_MASTER_ADDRESS + 1;
+ private static final int METHOD_UNREGISTER_LISTENER = METHOD_REGISTER_LISTENER + 1;
+
+ private static final int METHOD_CBK_ON_TIMELINE_CHANGED = IBinder.FIRST_CALL_TRANSACTION;
+}
diff --git a/core/java/android/os/CommonTimeConfig.java b/core/java/android/os/CommonTimeConfig.java
new file mode 100644
index 0000000..3355ee3
--- /dev/null
+++ b/core/java/android/os/CommonTimeConfig.java
@@ -0,0 +1,448 @@
+/*
+ * Copyright (C) 2012 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 android.os;
+
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.util.NoSuchElementException;
+
+import android.os.CommonTimeUtils;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+
+/**
+ * Used for configuring and controlling the status of the android common time service.
+ * @hide
+ */
+public class CommonTimeConfig {
+ /**
+ * Successful operation.
+ */
+ public static final int SUCCESS = 0;
+ /**
+ * Unspecified error.
+ */
+ public static final int ERROR = -1;
+ /**
+ * Operation failed due to bad parameter value.
+ */
+ public static final int ERROR_BAD_VALUE = -4;
+ /**
+ * Operation failed due to dead remote object.
+ */
+ public static final int ERROR_DEAD_OBJECT = -7;
+
+ /**
+ * Sentinel value returned by {@link #getMasterElectionGroupId()} when an error occurs trying to
+ * fetch the master election group.
+ */
+ public static final long INVALID_GROUP_ID = -1;
+
+ /**
+ * Name of the underlying native binder service
+ */
+ public static final String SERVICE_NAME = "common_time.config";
+
+ /**
+ * Class constructor.
+ * @throws android.os.RemoteException
+ */
+ public CommonTimeConfig()
+ throws RemoteException {
+ mRemote = ServiceManager.getService(SERVICE_NAME);
+ if (null == mRemote)
+ throw new RemoteException();
+
+ mInterfaceDesc = mRemote.getInterfaceDescriptor();
+ mUtils = new CommonTimeUtils(mRemote, mInterfaceDesc);
+ mRemote.linkToDeath(mDeathHandler, 0);
+ }
+
+ /**
+ * Handy class factory method.
+ */
+ static public CommonTimeConfig create() {
+ CommonTimeConfig retVal;
+
+ try {
+ retVal = new CommonTimeConfig();
+ }
+ catch (RemoteException e) {
+ retVal = null;
+ }
+
+ return retVal;
+ }
+
+ /**
+ * Release all native resources held by this {@link android.os.CommonTimeConfig} instance. Once
+ * resources have been released, the {@link android.os.CommonTimeConfig} instance is
+ * disconnected from the native service and will throw a {@link android.os.RemoteException} if
+ * any of its methods are called. Clients should always call release on their client instances
+ * before releasing their last Java reference to the instance. Failure to do this will cause
+ * non-deterministic native resource reclamation and may cause the common time service to remain
+ * active on the network for longer than it should.
+ */
+ public void release() {
+ if (null != mRemote) {
+ try {
+ mRemote.unlinkToDeath(mDeathHandler, 0);
+ }
+ catch (NoSuchElementException e) { }
+ mRemote = null;
+ }
+ mUtils = null;
+ }
+
+ /**
+ * Gets the current priority of the common time service used in the master election protocol.
+ *
+ * @return an 8 bit value indicating the priority of this common time service relative to other
+ * common time services operating in the same domain.
+ * @throws android.os.RemoteException
+ */
+ public byte getMasterElectionPriority()
+ throws RemoteException {
+ throwOnDeadServer();
+ return (byte)mUtils.transactGetInt(METHOD_GET_MASTER_ELECTION_PRIORITY, -1);
+ }
+
+ /**
+ * Sets the current priority of the common time service used in the master election protocol.
+ *
+ * @param priority priority of the common time service used in the master election protocol.
+ * Lower numbers are lower priority.
+ * @return {@link #SUCCESS} in case of success,
+ * {@link #ERROR} or {@link #ERROR_DEAD_OBJECT} in case of failure.
+ */
+ public int setMasterElectionPriority(byte priority) {
+ if (checkDeadServer())
+ return ERROR_DEAD_OBJECT;
+ return mUtils.transactSetInt(METHOD_SET_MASTER_ELECTION_PRIORITY, priority);
+ }
+
+ /**
+ * Gets the IP endpoint used by the time service to participate in the master election protocol.
+ *
+ * @return an InetSocketAddress containing the IP address and UDP port being used by the
+ * system's common time service to participate in the master election protocol.
+ * @throws android.os.RemoteException
+ */
+ public InetSocketAddress getMasterElectionEndpoint()
+ throws RemoteException {
+ throwOnDeadServer();
+ return mUtils.transactGetSockaddr(METHOD_GET_MASTER_ELECTION_ENDPOINT);
+ }
+
+ /**
+ * Sets the IP endpoint used by the common time service to participate in the master election
+ * protocol.
+ *
+ * @param ep The IP address and UDP port to be used by the common time service to participate in
+ * the master election protocol. The supplied IP address must be either the broadcast or
+ * multicast address, unicast addresses are considered to be illegal values.
+ * @return {@link #SUCCESS} in case of success,
+ * {@link #ERROR}, {@link #ERROR_BAD_VALUE} or {@link #ERROR_DEAD_OBJECT} in case of failure.
+ */
+ public int setMasterElectionEndpoint(InetSocketAddress ep) {
+ if (checkDeadServer())
+ return ERROR_DEAD_OBJECT;
+ return mUtils.transactSetSockaddr(METHOD_SET_MASTER_ELECTION_ENDPOINT, ep);
+ }
+
+ /**
+ * Gets the current group ID used by the common time service in the master election protocol.
+ *
+ * @return The 64-bit group ID of the common time service.
+ * @throws android.os.RemoteException
+ */
+ public long getMasterElectionGroupId()
+ throws RemoteException {
+ throwOnDeadServer();
+ return mUtils.transactGetLong(METHOD_GET_MASTER_ELECTION_GROUP_ID, INVALID_GROUP_ID);
+ }
+
+ /**
+ * Sets the current group ID used by the common time service in the master election protocol.
+ *
+ * @param id The 64-bit group ID of the common time service.
+ * @return {@link #SUCCESS} in case of success,
+ * {@link #ERROR}, {@link #ERROR_BAD_VALUE} or {@link #ERROR_DEAD_OBJECT} in case of failure.
+ */
+ public int setMasterElectionGroupId(long id) {
+ if (checkDeadServer())
+ return ERROR_DEAD_OBJECT;
+ return mUtils.transactSetLong(METHOD_SET_MASTER_ELECTION_GROUP_ID, id);
+ }
+
+ /**
+ * Gets the name of the network interface which the common time service attempts to bind to.
+ *
+ * @return a string with the network interface name which the common time service is bound to,
+ * or null if the service is currently unbound. Examples of interface names are things like
+ * "eth0", or "wlan0".
+ * @throws android.os.RemoteException
+ */
+ public String getInterfaceBinding()
+ throws RemoteException {
+ throwOnDeadServer();
+
+ String ifaceName = mUtils.transactGetString(METHOD_GET_INTERFACE_BINDING, null);
+
+ if ((null != ifaceName) && (0 == ifaceName.length()))
+ return null;
+
+ return ifaceName;
+ }
+
+ /**
+ * Sets the name of the network interface which the common time service should attempt to bind
+ * to.
+ *
+ * @param ifaceName The name of the network interface ("eth0", "wlan0", etc...) wich the common
+ * time service should attempt to bind to, or null to force the common time service to unbind
+ * from the network and run in networkless mode.
+ * @return {@link #SUCCESS} in case of success,
+ * {@link #ERROR}, {@link #ERROR_BAD_VALUE} or {@link #ERROR_DEAD_OBJECT} in case of failure.
+ */
+ public int setNetworkBinding(String ifaceName) {
+ if (checkDeadServer())
+ return ERROR_DEAD_OBJECT;
+
+ return mUtils.transactSetString(METHOD_SET_INTERFACE_BINDING,
+ (null == ifaceName) ? "" : ifaceName);
+ }
+
+ /**
+ * Gets the amount of time the common time service will wait between master announcements when
+ * it is the timeline master.
+ *
+ * @return The time (in milliseconds) between master announcements.
+ * @throws android.os.RemoteException
+ */
+ public int getMasterAnnounceInterval()
+ throws RemoteException {
+ throwOnDeadServer();
+ return mUtils.transactGetInt(METHOD_GET_MASTER_ANNOUNCE_INTERVAL, -1);
+ }
+
+ /**
+ * Sets the amount of time the common time service will wait between master announcements when
+ * it is the timeline master.
+ *
+ * @param interval The time (in milliseconds) between master announcements.
+ * @return {@link #SUCCESS} in case of success,
+ * {@link #ERROR}, {@link #ERROR_BAD_VALUE} or {@link #ERROR_DEAD_OBJECT} in case of failure.
+ */
+ public int setMasterAnnounceInterval(int interval) {
+ if (checkDeadServer())
+ return ERROR_DEAD_OBJECT;
+ return mUtils.transactSetInt(METHOD_SET_MASTER_ANNOUNCE_INTERVAL, interval);
+ }
+
+ /**
+ * Gets the amount of time the common time service will wait between time synchronization
+ * requests when it is the client of another common time service on the network.
+ *
+ * @return The time (in milliseconds) between time sync requests.
+ * @throws android.os.RemoteException
+ */
+ public int getClientSyncInterval()
+ throws RemoteException {
+ throwOnDeadServer();
+ return mUtils.transactGetInt(METHOD_GET_CLIENT_SYNC_INTERVAL, -1);
+ }
+
+ /**
+ * Sets the amount of time the common time service will wait between time synchronization
+ * requests when it is the client of another common time service on the network.
+ *
+ * @param interval The time (in milliseconds) between time sync requests.
+ * @return {@link #SUCCESS} in case of success,
+ * {@link #ERROR}, {@link #ERROR_BAD_VALUE} or {@link #ERROR_DEAD_OBJECT} in case of failure.
+ */
+ public int setClientSyncInterval(int interval) {
+ if (checkDeadServer())
+ return ERROR_DEAD_OBJECT;
+ return mUtils.transactSetInt(METHOD_SET_CLIENT_SYNC_INTERVAL, interval);
+ }
+
+ /**
+ * Gets the panic threshold for the estimated error level of the common time service. When the
+ * common time service's estimated error rises above this level, the service will panic and
+ * reset, causing a discontinuity in the currently synchronized timeline.
+ *
+ * @return The threshold (in microseconds) past which the common time service will panic.
+ * @throws android.os.RemoteException
+ */
+ public int getPanicThreshold()
+ throws RemoteException {
+ throwOnDeadServer();
+ return mUtils.transactGetInt(METHOD_GET_PANIC_THRESHOLD, -1);
+ }
+
+ /**
+ * Sets the panic threshold for the estimated error level of the common time service. When the
+ * common time service's estimated error rises above this level, the service will panic and
+ * reset, causing a discontinuity in the currently synchronized timeline.
+ *
+ * @param threshold The threshold (in microseconds) past which the common time service will
+ * panic.
+ * @return {@link #SUCCESS} in case of success,
+ * {@link #ERROR}, {@link #ERROR_BAD_VALUE} or {@link #ERROR_DEAD_OBJECT} in case of failure.
+ */
+ public int setPanicThreshold(int threshold) {
+ if (checkDeadServer())
+ return ERROR_DEAD_OBJECT;
+ return mUtils.transactSetInt(METHOD_SET_PANIC_THRESHOLD, threshold);
+ }
+
+ /**
+ * Gets the current state of the common time service's auto disable flag.
+ *
+ * @return The current state of the common time service's auto disable flag.
+ * @throws android.os.RemoteException
+ */
+ public boolean getAutoDisable()
+ throws RemoteException {
+ throwOnDeadServer();
+ return (1 == mUtils.transactGetInt(METHOD_GET_AUTO_DISABLE, 1));
+ }
+
+ /**
+ * Sets the current state of the common time service's auto disable flag. When the time
+ * service's auto disable flag is set, it will automatically cease all network activity when
+ * it has no active local clients, resuming activity the next time the service has interested
+ * local clients. When the auto disabled flag is cleared, the common time service will continue
+ * to participate the time synchronization group even when it has no active local clients.
+ *
+ * @param autoDisable The desired state of the common time service's auto disable flag.
+ * @return {@link #SUCCESS} in case of success,
+ * {@link #ERROR} or {@link #ERROR_DEAD_OBJECT} in case of failure.
+ */
+ public int setAutoDisable(boolean autoDisable) {
+ if (checkDeadServer())
+ return ERROR_DEAD_OBJECT;
+
+ return mUtils.transactSetInt(METHOD_SET_AUTO_DISABLE, autoDisable ? 1 : 0);
+ }
+
+ /**
+ * At startup, the time service enters the initial state and remains there until it is given a
+ * network interface to bind to. Common time will be unavailable to clients of the common time
+ * service until the service joins a network (even an empty network). Devices may use the
+ * {@link #forceNetworklessMasterMode()} method to force a time service in the INITIAL state
+ * with no network configuration to assume MASTER status for a brand new timeline in order to
+ * allow clients of the common time service to operate, even though the device is isolated and
+ * not on any network. When a networkless master does join a network, it will defer to any
+ * masters already on the network, or continue to maintain the timeline it made up during its
+ * networkless state if no other masters are detected. Attempting to force a client into master
+ * mode while it is actively bound to a network will fail with the status code {@link #ERROR}
+ *
+ * @return {@link #SUCCESS} in case of success,
+ * {@link #ERROR} or {@link #ERROR_DEAD_OBJECT} in case of failure.
+ */
+ public int forceNetworklessMasterMode() {
+ android.os.Parcel data = android.os.Parcel.obtain();
+ android.os.Parcel reply = android.os.Parcel.obtain();
+
+ try {
+ data.writeInterfaceToken(mInterfaceDesc);
+ mRemote.transact(METHOD_FORCE_NETWORKLESS_MASTER_MODE, data, reply, 0);
+
+ return reply.readInt();
+ }
+ catch (RemoteException e) {
+ return ERROR_DEAD_OBJECT;
+ }
+ finally {
+ reply.recycle();
+ data.recycle();
+ }
+ }
+
+ /**
+ * The OnServerDiedListener interface defines a method called by the
+ * {@link android.os.CommonTimeConfig} instance to indicate that the connection to the native
+ * media server has been broken and that the {@link android.os.CommonTimeConfig} instance will
+ * need to be released and re-created. The client application can implement this interface and
+ * register the listener with the {@link #setServerDiedListener(OnServerDiedListener)} method.
+ */
+ public interface OnServerDiedListener {
+ /**
+ * Method called when the native common time service has died. <p>If the native common time
+ * service encounters a fatal error and needs to restart, the binder connection from the
+ * {@link android.os.CommonTimeConfig} instance to the common time service will be broken.
+ */
+ void onServerDied();
+ }
+
+ /**
+ * Registers an OnServerDiedListener interface.
+ * <p>Call this method with a null listener to stop receiving server death notifications.
+ */
+ public void setServerDiedListener(OnServerDiedListener listener) {
+ synchronized (mListenerLock) {
+ mServerDiedListener = listener;
+ }
+ }
+
+ protected void finalize() throws Throwable { release(); }
+
+ private boolean checkDeadServer() {
+ return ((null == mRemote) || (null == mUtils));
+ }
+
+ private void throwOnDeadServer() throws RemoteException {
+ if (checkDeadServer())
+ throw new RemoteException();
+ }
+
+ private final Object mListenerLock = new Object();
+ private OnServerDiedListener mServerDiedListener = null;
+
+ private IBinder mRemote = null;
+ private String mInterfaceDesc = "";
+ private CommonTimeUtils mUtils;
+
+ private IBinder.DeathRecipient mDeathHandler = new IBinder.DeathRecipient() {
+ public void binderDied() {
+ synchronized (mListenerLock) {
+ if (null != mServerDiedListener)
+ mServerDiedListener.onServerDied();
+ }
+ }
+ };
+
+ private static final int METHOD_GET_MASTER_ELECTION_PRIORITY = IBinder.FIRST_CALL_TRANSACTION;
+ private static final int METHOD_SET_MASTER_ELECTION_PRIORITY = METHOD_GET_MASTER_ELECTION_PRIORITY + 1;
+ private static final int METHOD_GET_MASTER_ELECTION_ENDPOINT = METHOD_SET_MASTER_ELECTION_PRIORITY + 1;
+ private static final int METHOD_SET_MASTER_ELECTION_ENDPOINT = METHOD_GET_MASTER_ELECTION_ENDPOINT + 1;
+ private static final int METHOD_GET_MASTER_ELECTION_GROUP_ID = METHOD_SET_MASTER_ELECTION_ENDPOINT + 1;
+ private static final int METHOD_SET_MASTER_ELECTION_GROUP_ID = METHOD_GET_MASTER_ELECTION_GROUP_ID + 1;
+ private static final int METHOD_GET_INTERFACE_BINDING = METHOD_SET_MASTER_ELECTION_GROUP_ID + 1;
+ private static final int METHOD_SET_INTERFACE_BINDING = METHOD_GET_INTERFACE_BINDING + 1;
+ private static final int METHOD_GET_MASTER_ANNOUNCE_INTERVAL = METHOD_SET_INTERFACE_BINDING + 1;
+ private static final int METHOD_SET_MASTER_ANNOUNCE_INTERVAL = METHOD_GET_MASTER_ANNOUNCE_INTERVAL + 1;
+ private static final int METHOD_GET_CLIENT_SYNC_INTERVAL = METHOD_SET_MASTER_ANNOUNCE_INTERVAL + 1;
+ private static final int METHOD_SET_CLIENT_SYNC_INTERVAL = METHOD_GET_CLIENT_SYNC_INTERVAL + 1;
+ private static final int METHOD_GET_PANIC_THRESHOLD = METHOD_SET_CLIENT_SYNC_INTERVAL + 1;
+ private static final int METHOD_SET_PANIC_THRESHOLD = METHOD_GET_PANIC_THRESHOLD + 1;
+ private static final int METHOD_GET_AUTO_DISABLE = METHOD_SET_PANIC_THRESHOLD + 1;
+ private static final int METHOD_SET_AUTO_DISABLE = METHOD_GET_AUTO_DISABLE + 1;
+ private static final int METHOD_FORCE_NETWORKLESS_MASTER_MODE = METHOD_SET_AUTO_DISABLE + 1;
+}
diff --git a/core/java/android/os/CommonTimeUtils.java b/core/java/android/os/CommonTimeUtils.java
new file mode 100644
index 0000000..9081ee4
--- /dev/null
+++ b/core/java/android/os/CommonTimeUtils.java
@@ -0,0 +1,291 @@
+/*
+ * Copyright (C) 2012 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 android.os;
+
+import java.net.InetAddress;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetSocketAddress;
+import static libcore.io.OsConstants.*;
+
+class CommonTimeUtils {
+ /**
+ * Successful operation.
+ */
+ public static final int SUCCESS = 0;
+ /**
+ * Unspecified error.
+ */
+ public static final int ERROR = -1;
+ /**
+ * Operation failed due to bad parameter value.
+ */
+ public static final int ERROR_BAD_VALUE = -4;
+ /**
+ * Operation failed due to dead remote object.
+ */
+ public static final int ERROR_DEAD_OBJECT = -7;
+
+ public CommonTimeUtils(IBinder remote, String interfaceDesc) {
+ mRemote = remote;
+ mInterfaceDesc = interfaceDesc;
+ }
+
+ public int transactGetInt(int method_code, int error_ret_val)
+ throws RemoteException {
+ android.os.Parcel data = android.os.Parcel.obtain();
+ android.os.Parcel reply = android.os.Parcel.obtain();
+ int ret_val;
+
+ try {
+ int res;
+ data.writeInterfaceToken(mInterfaceDesc);
+ mRemote.transact(method_code, data, reply, 0);
+
+ res = reply.readInt();
+ ret_val = (0 == res) ? reply.readInt() : error_ret_val;
+ }
+ finally {
+ reply.recycle();
+ data.recycle();
+ }
+
+ return ret_val;
+ }
+
+ public int transactSetInt(int method_code, int val) {
+ android.os.Parcel data = android.os.Parcel.obtain();
+ android.os.Parcel reply = android.os.Parcel.obtain();
+
+ try {
+ data.writeInterfaceToken(mInterfaceDesc);
+ data.writeInt(val);
+ mRemote.transact(method_code, data, reply, 0);
+
+ return reply.readInt();
+ }
+ catch (RemoteException e) {
+ return ERROR_DEAD_OBJECT;
+ }
+ finally {
+ reply.recycle();
+ data.recycle();
+ }
+ }
+
+ public long transactGetLong(int method_code, long error_ret_val)
+ throws RemoteException {
+ android.os.Parcel data = android.os.Parcel.obtain();
+ android.os.Parcel reply = android.os.Parcel.obtain();
+ long ret_val;
+
+ try {
+ int res;
+ data.writeInterfaceToken(mInterfaceDesc);
+ mRemote.transact(method_code, data, reply, 0);
+
+ res = reply.readInt();
+ ret_val = (0 == res) ? reply.readLong() : error_ret_val;
+ }
+ finally {
+ reply.recycle();
+ data.recycle();
+ }
+
+ return ret_val;
+ }
+
+ public int transactSetLong(int method_code, long val) {
+ android.os.Parcel data = android.os.Parcel.obtain();
+ android.os.Parcel reply = android.os.Parcel.obtain();
+
+ try {
+ data.writeInterfaceToken(mInterfaceDesc);
+ data.writeLong(val);
+ mRemote.transact(method_code, data, reply, 0);
+
+ return reply.readInt();
+ }
+ catch (RemoteException e) {
+ return ERROR_DEAD_OBJECT;
+ }
+ finally {
+ reply.recycle();
+ data.recycle();
+ }
+ }
+
+ public String transactGetString(int method_code, String error_ret_val)
+ throws RemoteException {
+ android.os.Parcel data = android.os.Parcel.obtain();
+ android.os.Parcel reply = android.os.Parcel.obtain();
+ String ret_val;
+
+ try {
+ int res;
+ data.writeInterfaceToken(mInterfaceDesc);
+ mRemote.transact(method_code, data, reply, 0);
+
+ res = reply.readInt();
+ ret_val = (0 == res) ? reply.readString() : error_ret_val;
+ }
+ finally {
+ reply.recycle();
+ data.recycle();
+ }
+
+ return ret_val;
+ }
+
+ public int transactSetString(int method_code, String val) {
+ android.os.Parcel data = android.os.Parcel.obtain();
+ android.os.Parcel reply = android.os.Parcel.obtain();
+
+ try {
+ data.writeInterfaceToken(mInterfaceDesc);
+ data.writeString(val);
+ mRemote.transact(method_code, data, reply, 0);
+
+ return reply.readInt();
+ }
+ catch (RemoteException e) {
+ return ERROR_DEAD_OBJECT;
+ }
+ finally {
+ reply.recycle();
+ data.recycle();
+ }
+ }
+
+ public InetSocketAddress transactGetSockaddr(int method_code)
+ throws RemoteException {
+ android.os.Parcel data = android.os.Parcel.obtain();
+ android.os.Parcel reply = android.os.Parcel.obtain();
+ InetSocketAddress ret_val = null;
+
+ try {
+ int res;
+ data.writeInterfaceToken(mInterfaceDesc);
+ mRemote.transact(method_code, data, reply, 0);
+
+ res = reply.readInt();
+ if (0 == res) {
+ int type;
+ int port = 0;
+ String addrStr = null;
+
+ type = reply.readInt();
+
+ if (AF_INET == type) {
+ int addr = reply.readInt();
+ port = reply.readInt();
+ addrStr = String.format("%d.%d.%d.%d", (addr >> 24) & 0xFF,
+ (addr >> 16) & 0xFF,
+ (addr >> 8) & 0xFF,
+ addr & 0xFF);
+ } else if (AF_INET6 == type) {
+ int addr1 = reply.readInt();
+ int addr2 = reply.readInt();
+ int addr3 = reply.readInt();
+ int addr4 = reply.readInt();
+
+ port = reply.readInt();
+
+ int flowinfo = reply.readInt();
+ int scope_id = reply.readInt();
+
+ addrStr = String.format("[%04X:%04X:%04X:%04X:%04X:%04X:%04X:%04X]",
+ (addr1 >> 16) & 0xFFFF, addr1 & 0xFFFF,
+ (addr2 >> 16) & 0xFFFF, addr2 & 0xFFFF,
+ (addr3 >> 16) & 0xFFFF, addr3 & 0xFFFF,
+ (addr4 >> 16) & 0xFFFF, addr4 & 0xFFFF);
+ }
+
+ if (null != addrStr) {
+ ret_val = new InetSocketAddress(addrStr, port);
+ }
+ }
+ }
+ finally {
+ reply.recycle();
+ data.recycle();
+ }
+
+ return ret_val;
+ }
+
+ public int transactSetSockaddr(int method_code, InetSocketAddress addr) {
+ android.os.Parcel data = android.os.Parcel.obtain();
+ android.os.Parcel reply = android.os.Parcel.obtain();
+ int ret_val = ERROR;
+
+ try {
+ data.writeInterfaceToken(mInterfaceDesc);
+
+ if (null == addr) {
+ data.writeInt(0);
+ } else {
+ data.writeInt(1);
+ final InetAddress a = addr.getAddress();
+ final byte[] b = a.getAddress();
+ final int p = addr.getPort();
+
+ if (a instanceof Inet4Address) {
+ int v4addr = (((int)b[0] & 0xFF) << 24) |
+ (((int)b[1] & 0xFF) << 16) |
+ (((int)b[2] & 0xFF) << 8) |
+ ((int)b[3] & 0xFF);
+
+ data.writeInt(AF_INET);
+ data.writeInt(v4addr);
+ data.writeInt(p);
+ } else
+ if (a instanceof Inet6Address) {
+ int i;
+ Inet6Address v6 = (Inet6Address)a;
+ data.writeInt(AF_INET6);
+ for (i = 0; i < 4; ++i) {
+ int aword = (((int)b[(i*4) + 0] & 0xFF) << 24) |
+ (((int)b[(i*4) + 1] & 0xFF) << 16) |
+ (((int)b[(i*4) + 2] & 0xFF) << 8) |
+ ((int)b[(i*4) + 3] & 0xFF);
+ data.writeInt(aword);
+ }
+ data.writeInt(p);
+ data.writeInt(0); // flow info
+ data.writeInt(v6.getScopeId());
+ } else {
+ return ERROR_BAD_VALUE;
+ }
+ }
+
+ mRemote.transact(method_code, data, reply, 0);
+ ret_val = reply.readInt();
+ }
+ catch (RemoteException e) {
+ ret_val = ERROR_DEAD_OBJECT;
+ }
+ finally {
+ reply.recycle();
+ data.recycle();
+ }
+
+ return ret_val;
+ }
+
+ private IBinder mRemote;
+ private String mInterfaceDesc;
+};
diff --git a/core/java/android/os/Handler.java b/core/java/android/os/Handler.java
index af2fa9b..610b3550 100644
--- a/core/java/android/os/Handler.java
+++ b/core/java/android/os/Handler.java
@@ -513,7 +513,7 @@
* message queue.
*/
public final void removeMessages(int what) {
- mQueue.removeMessages(this, what, null, true);
+ mQueue.removeMessages(this, what, null);
}
/**
@@ -522,7 +522,7 @@
* all messages will be removed.
*/
public final void removeMessages(int what, Object object) {
- mQueue.removeMessages(this, what, object, true);
+ mQueue.removeMessages(this, what, object);
}
/**
@@ -539,7 +539,7 @@
* the message queue.
*/
public final boolean hasMessages(int what) {
- return mQueue.removeMessages(this, what, null, false);
+ return mQueue.hasMessages(this, what, null);
}
/**
@@ -547,7 +547,7 @@
* whose obj is 'object' in the message queue.
*/
public final boolean hasMessages(int what, Object object) {
- return mQueue.removeMessages(this, what, object, false);
+ return mQueue.hasMessages(this, what, object);
}
// if we can get rid of this method, the handler need not remember its loop
diff --git a/core/java/android/os/Looper.java b/core/java/android/os/Looper.java
index 5607f7f..a06aadb6 100644
--- a/core/java/android/os/Looper.java
+++ b/core/java/android/os/Looper.java
@@ -55,13 +55,13 @@
// sThreadLocal.get() will return null unless you've called prepare().
static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
+ private static Looper sMainLooper; // guarded by Looper.class
final MessageQueue mQueue;
final Thread mThread;
volatile boolean mRun;
- private Printer mLogging = null;
- private static Looper mMainLooper = null; // guarded by Looper.class
+ private Printer mLogging;
/** Initialize the current thread as a looper.
* This gives you a chance to create handlers that then reference
@@ -70,10 +70,14 @@
* {@link #quit()}.
*/
public static void prepare() {
+ prepare(true);
+ }
+
+ private static void prepare(boolean quitAllowed) {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
- sThreadLocal.set(new Looper());
+ sThreadLocal.set(new Looper(quitAllowed));
}
/**
@@ -83,19 +87,21 @@
* to call this function yourself. See also: {@link #prepare()}
*/
public static void prepareMainLooper() {
- prepare();
- setMainLooper(myLooper());
- myLooper().mQueue.mQuitAllowed = false;
- }
-
- private synchronized static void setMainLooper(Looper looper) {
- mMainLooper = looper;
+ prepare(false);
+ synchronized (Looper.class) {
+ if (sMainLooper != null) {
+ throw new IllegalStateException("The main Looper has already been prepared.");
+ }
+ sMainLooper = myLooper();
+ }
}
/** Returns the application's main looper, which lives in the main thread of the application.
*/
- public synchronized static Looper getMainLooper() {
- return mMainLooper;
+ public static Looper getMainLooper() {
+ synchronized (Looper.class) {
+ return sMainLooper;
+ }
}
/**
@@ -103,63 +109,61 @@
* {@link #quit()} to end the loop.
*/
public static void loop() {
- Looper me = myLooper();
+ final Looper me = myLooper();
if (me == null) {
throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
}
- MessageQueue queue = me.mQueue;
-
+ final MessageQueue queue = me.mQueue;
+
// Make sure the identity of this thread is that of the local process,
// and keep track of what that identity token actually is.
Binder.clearCallingIdentity();
final long ident = Binder.clearCallingIdentity();
-
- while (true) {
+
+ for (;;) {
Message msg = queue.next(); // might block
- if (msg != null) {
- if (msg.target == null) {
- // No target is a magic identifier for the quit message.
- return;
- }
-
- long wallStart = 0;
- long threadStart = 0;
-
- // This must be in a local variable, in case a UI event sets the logger
- Printer logging = me.mLogging;
- if (logging != null) {
- logging.println(">>>>> Dispatching to " + msg.target + " " +
- msg.callback + ": " + msg.what);
- wallStart = SystemClock.currentTimeMicro();
- threadStart = SystemClock.currentThreadTimeMicro();
- }
-
- msg.target.dispatchMessage(msg);
-
- if (logging != null) {
- long wallTime = SystemClock.currentTimeMicro() - wallStart;
- long threadTime = SystemClock.currentThreadTimeMicro() - threadStart;
-
- logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
- if (logging instanceof Profiler) {
- ((Profiler) logging).profile(msg, wallStart, wallTime,
- threadStart, threadTime);
- }
- }
-
- // Make sure that during the course of dispatching the
- // identity of the thread wasn't corrupted.
- final long newIdent = Binder.clearCallingIdentity();
- if (ident != newIdent) {
- Log.wtf(TAG, "Thread identity changed from 0x"
- + Long.toHexString(ident) + " to 0x"
- + Long.toHexString(newIdent) + " while dispatching to "
- + msg.target.getClass().getName() + " "
- + msg.callback + " what=" + msg.what);
- }
-
- msg.recycle();
+ if (msg == null) {
+ // No message indicates that the message queue is quitting.
+ return;
}
+
+ long wallStart = 0;
+ long threadStart = 0;
+
+ // This must be in a local variable, in case a UI event sets the logger
+ Printer logging = me.mLogging;
+ if (logging != null) {
+ logging.println(">>>>> Dispatching to " + msg.target + " " +
+ msg.callback + ": " + msg.what);
+ wallStart = SystemClock.currentTimeMicro();
+ threadStart = SystemClock.currentThreadTimeMicro();
+ }
+
+ msg.target.dispatchMessage(msg);
+
+ if (logging != null) {
+ long wallTime = SystemClock.currentTimeMicro() - wallStart;
+ long threadTime = SystemClock.currentThreadTimeMicro() - threadStart;
+
+ logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
+ if (logging instanceof Profiler) {
+ ((Profiler) logging).profile(msg, wallStart, wallTime,
+ threadStart, threadTime);
+ }
+ }
+
+ // Make sure that during the course of dispatching the
+ // identity of the thread wasn't corrupted.
+ final long newIdent = Binder.clearCallingIdentity();
+ if (ident != newIdent) {
+ Log.wtf(TAG, "Thread identity changed from 0x"
+ + Long.toHexString(ident) + " to 0x"
+ + Long.toHexString(newIdent) + " while dispatching to "
+ + msg.target.getClass().getName() + " "
+ + msg.callback + " what=" + msg.what);
+ }
+
+ msg.recycle();
}
}
@@ -193,18 +197,61 @@
return myLooper().mQueue;
}
- private Looper() {
- mQueue = new MessageQueue();
+ private Looper(boolean quitAllowed) {
+ mQueue = new MessageQueue(quitAllowed);
mRun = true;
mThread = Thread.currentThread();
}
+ /**
+ * Quits the looper.
+ *
+ * Causes the {@link #loop} method to terminate as soon as possible.
+ */
public void quit() {
- Message msg = Message.obtain();
- // NOTE: By enqueueing directly into the message queue, the
- // message is left with a null target. This is how we know it is
- // a quit message.
- mQueue.enqueueMessage(msg, 0);
+ mQueue.quit();
+ }
+
+ /**
+ * Posts a synchronization barrier to the Looper's message queue.
+ *
+ * Message processing occurs as usual until the message queue encounters the
+ * synchronization barrier that has been posted. When the barrier is encountered,
+ * later synchronous messages in the queue are stalled (prevented from being executed)
+ * until the barrier is released by calling {@link #removeSyncBarrier} and specifying
+ * the token that identifies the synchronization barrier.
+ *
+ * This method is used to immediately postpone execution of all subsequently posted
+ * synchronous messages until a condition is met that releases the barrier.
+ * Asynchronous messages (see {@link Message#isAsynchronous} are exempt from the barrier
+ * and continue to be processed as usual.
+ *
+ * This call must be always matched by a call to {@link #removeSyncBarrier} with
+ * the same token to ensure that the message queue resumes normal operation.
+ * Otherwise the application will probably hang!
+ *
+ * @return A token that uniquely identifies the barrier. This token must be
+ * passed to {@link #removeSyncBarrier} to release the barrier.
+ *
+ * @hide
+ */
+ public final int postSyncBarrier() {
+ return mQueue.enqueueSyncBarrier(SystemClock.uptimeMillis());
+ }
+
+
+ /**
+ * Removes a synchronization barrier.
+ *
+ * @param token The synchronization barrier token that was returned by
+ * {@link #postSyncBarrier}.
+ *
+ * @throws IllegalStateException if the barrier was not found.
+ *
+ * @hide
+ */
+ public final void removeSyncBarrier(int token) {
+ mQueue.removeSyncBarrier(token);
}
/**
diff --git a/core/java/android/os/MessageQueue.java b/core/java/android/os/MessageQueue.java
index 11dc124..64027ef 100644
--- a/core/java/android/os/MessageQueue.java
+++ b/core/java/android/os/MessageQueue.java
@@ -30,21 +30,24 @@
* {@link Looper#myQueue() Looper.myQueue()}.
*/
public class MessageQueue {
+ // True if the message queue can be quit.
+ private final boolean mQuitAllowed;
+
+ @SuppressWarnings("unused")
+ private int mPtr; // used by native code
+
Message mMessages;
private final ArrayList<IdleHandler> mIdleHandlers = new ArrayList<IdleHandler>();
private IdleHandler[] mPendingIdleHandlers;
private boolean mQuiting;
- boolean mQuitAllowed = true;
// Indicates whether next() is blocked waiting in pollOnce() with a non-zero timeout.
private boolean mBlocked;
- // Indicates the barrier nesting level.
- private int mBarrierNestCount;
+ // The next barrier token.
+ // Barriers are indicated by messages with a null target whose arg1 field carries the token.
+ private int mNextBarrierToken;
- @SuppressWarnings("unused")
- private int mPtr; // used by native code
-
private native void nativeInit();
private native void nativeDestroy();
private native void nativePollOnce(int ptr, int timeoutMillis);
@@ -97,56 +100,11 @@
}
}
- /**
- * Acquires a synchronization barrier.
- *
- * While a synchronization barrier is active, only asynchronous messages are
- * permitted to execute. Synchronous messages are retained but are not executed
- * until the synchronization barrier is released.
- *
- * This method is used to immediately postpone execution of all synchronous messages
- * until a condition is met that releases the barrier. Asynchronous messages are
- * exempt from the barrier and continue to be executed as usual.
- *
- * This call nests and must be matched by an equal number of calls to
- * {@link #releaseSyncBarrier}.
- *
- * @hide
- */
- public final void acquireSyncBarrier() {
- synchronized (this) {
- mBarrierNestCount += 1;
- }
- }
-
- /**
- * Releases a synchronization barrier.
- *
- * This class undoes one invocation of {@link #acquireSyncBarrier}.
- *
- * @throws IllegalStateException if the barrier is not acquired.
- *
- * @hide
- */
- public final void releaseSyncBarrier() {
- synchronized (this) {
- if (mBarrierNestCount == 0) {
- throw new IllegalStateException("The message queue synchronization barrier "
- + "has not been acquired.");
- }
-
- mBarrierNestCount -= 1;
- if (!mBlocked || mMessages == null) {
- return;
- }
- }
- nativeWake(mPtr);
- }
-
- MessageQueue() {
+ MessageQueue(boolean quitAllowed) {
+ mQuitAllowed = quitAllowed;
nativeInit();
}
-
+
@Override
protected void finalize() throws Throwable {
try {
@@ -167,26 +125,26 @@
nativePollOnce(mPtr, nextPollTimeoutMillis);
synchronized (this) {
+ if (mQuiting) {
+ return null;
+ }
+
// Try to retrieve the next message. Return if found.
final long now = SystemClock.uptimeMillis();
-
Message prevMsg = null;
Message msg = mMessages;
- for (;;) {
- if (msg == null) {
- // No more messages.
- nextPollTimeoutMillis = -1;
- break;
- }
-
- final long when = msg.when;
- if (now < when) {
+ if (msg != null && msg.target == null) {
+ // Stalled by a barrier. Find the next asynchronous message in the queue.
+ do {
+ prevMsg = msg;
+ msg = msg.next;
+ } while (msg != null && !msg.isAsynchronous());
+ }
+ if (msg != null) {
+ if (now < msg.when) {
// Next message is not ready. Set a timeout to wake up when it is ready.
- nextPollTimeoutMillis = (int) Math.min(when - now, Integer.MAX_VALUE);
- break;
- }
-
- if (mBarrierNestCount == 0 || msg.isAsynchronous()) {
+ nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE);
+ } else {
// Got a message.
mBlocked = false;
if (prevMsg != null) {
@@ -199,16 +157,16 @@
msg.markInUse();
return msg;
}
-
- // We have a message that we could return except that it is
- // blocked by the sync barrier. In particular, this means that
- // we are not idle yet, so we do not want to run the idle handlers.
- prevMsg = msg;
- msg = msg.next;
+ } else {
+ // No more messages.
+ nextPollTimeoutMillis = -1;
}
// If first time idle, then get the number of idlers to run.
- if (pendingIdleHandlerCount < 0 && msg == mMessages) {
+ // Idle handles only run if the queue is empty or if the first message
+ // in the queue (possibly a barrier) is due to be handled in the future.
+ if (pendingIdleHandlerCount < 0
+ && (mMessages == null || now < mMessages.when)) {
pendingIdleHandlerCount = mIdleHandlers.size();
}
if (pendingIdleHandlerCount <= 0) {
@@ -252,27 +210,94 @@
}
}
+ final void quit() {
+ if (!mQuitAllowed) {
+ throw new RuntimeException("Main thread not allowed to quit.");
+ }
+
+ synchronized (this) {
+ if (mQuiting) {
+ return;
+ }
+ mQuiting = true;
+ }
+ nativeWake(mPtr);
+ }
+
+ final int enqueueSyncBarrier(long when) {
+ // Enqueue a new sync barrier token.
+ // We don't need to wake the queue because the purpose of a barrier is to stall it.
+ synchronized (this) {
+ final int token = mNextBarrierToken++;
+ final Message msg = Message.obtain();
+ msg.arg1 = token;
+
+ Message prev = null;
+ Message p = mMessages;
+ if (when != 0) {
+ while (p != null && p.when <= when) {
+ prev = p;
+ p = p.next;
+ }
+ }
+ if (prev != null) { // invariant: p == prev.next
+ msg.next = p;
+ prev.next = msg;
+ } else {
+ msg.next = p;
+ mMessages = msg;
+ }
+ return token;
+ }
+ }
+
+ final void removeSyncBarrier(int token) {
+ // Remove a sync barrier token from the queue.
+ // If the queue is no longer stalled by a barrier then wake it.
+ final boolean needWake;
+ synchronized (this) {
+ Message prev = null;
+ Message p = mMessages;
+ while (p != null && (p.target != null || p.arg1 != token)) {
+ prev = p;
+ p = p.next;
+ }
+ if (p == null) {
+ throw new IllegalStateException("The specified message queue synchronization "
+ + " barrier token has not been posted or has already been removed.");
+ }
+ if (prev != null) {
+ prev.next = p.next;
+ needWake = false;
+ } else {
+ mMessages = p.next;
+ needWake = mMessages == null || mMessages.target != null;
+ }
+ p.recycle();
+ }
+ if (needWake) {
+ nativeWake(mPtr);
+ }
+ }
+
final boolean enqueueMessage(Message msg, long when) {
if (msg.isInUse()) {
- throw new AndroidRuntimeException(msg
- + " This message is already in use.");
+ throw new AndroidRuntimeException(msg + " This message is already in use.");
}
- if (msg.target == null && !mQuitAllowed) {
- throw new RuntimeException("Main thread not allowed to quit");
+ if (msg.target == null) {
+ throw new AndroidRuntimeException("Message must have a target.");
}
- final boolean needWake;
+
+ boolean needWake;
synchronized (this) {
if (mQuiting) {
RuntimeException e = new RuntimeException(
- msg.target + " sending message to a Handler on a dead thread");
+ msg.target + " sending message to a Handler on a dead thread");
Log.w("MessageQueue", e.getMessage(), e);
return false;
- } else if (msg.target == null) {
- mQuiting = true;
}
msg.when = when;
- //Log.d("MessageQueue", "Enqueing: " + msg);
Message p = mMessages;
if (p == null || when == 0 || when < p.when) {
// New head, wake up the event queue if blocked.
@@ -281,18 +306,22 @@
needWake = mBlocked;
} else {
// Inserted within the middle of the queue. Usually we don't have to wake
- // up the event queue unless the message is asynchronous and it might be
- // possible for it to be returned out of sequence relative to an earlier
- // synchronous message at the head of the queue.
- Message prev = null;
- while (p != null && p.when <= when) {
+ // up the event queue unless there is a barrier at the head of the queue
+ // and the message is the earliest asynchronous message in the queue.
+ needWake = mBlocked && p.target == null && msg.isAsynchronous();
+ Message prev;
+ for (;;) {
prev = p;
p = p.next;
+ if (p == null || when < p.when) {
+ break;
+ }
+ if (needWake && p.isAsynchronous()) {
+ needWake = false;
+ }
}
- msg.next = prev.next;
+ msg.next = p; // invariant: p == prev.next
prev.next = msg;
- needWake = mBlocked && mBarrierNestCount != 0 && msg.isAsynchronous()
- && !mMessages.isAsynchronous();
}
}
if (needWake) {
@@ -301,17 +330,34 @@
return true;
}
- final boolean removeMessages(Handler h, int what, Object object,
- boolean doRemove) {
+ final boolean hasMessages(Handler h, int what, Object object) {
+ if (h == null) {
+ return false;
+ }
+
synchronized (this) {
Message p = mMessages;
- boolean found = false;
+ while (p != null) {
+ if (p.target == h && p.what == what && (object == null || p.obj == object)) {
+ return true;
+ }
+ p = p.next;
+ }
+ return false;
+ }
+ }
+
+ final void removeMessages(Handler h, int what, Object object) {
+ if (h == null) {
+ return;
+ }
+
+ synchronized (this) {
+ Message p = mMessages;
// Remove all messages at front.
while (p != null && p.target == h && p.what == what
&& (object == null || p.obj == object)) {
- if (!doRemove) return true;
- found = true;
Message n = p.next;
mMessages = n;
p.recycle();
@@ -324,8 +370,6 @@
if (n != null) {
if (n.target == h && n.what == what
&& (object == null || n.obj == object)) {
- if (!doRemove) return true;
- found = true;
Message nn = n.next;
n.recycle();
p.next = nn;
@@ -334,13 +378,11 @@
}
p = n;
}
-
- return found;
}
}
final void removeMessages(Handler h, Runnable r, Object object) {
- if (r == null) {
+ if (h == null || r == null) {
return;
}
@@ -374,6 +416,10 @@
}
final void removeCallbacksAndMessages(Handler h, Object object) {
+ if (h == null) {
+ return;
+ }
+
synchronized (this) {
Message p = mMessages;
@@ -401,16 +447,4 @@
}
}
}
-
- /*
- private void dumpQueue_l()
- {
- Message p = mMessages;
- System.out.println(this + " queue is:");
- while (p != null) {
- System.out.println(" " + p);
- p = p.next;
- }
- }
- */
}
diff --git a/core/java/android/os/Power.java b/core/java/android/os/Power.java
index 5a79215..58df940 100644
--- a/core/java/android/os/Power.java
+++ b/core/java/android/os/Power.java
@@ -104,4 +104,6 @@
}
private static native void rebootNative(String reason) throws IOException ;
+
+ public static native int powerInitNative();
}
diff --git a/core/java/android/service/textservice/SpellCheckerService.java b/core/java/android/service/textservice/SpellCheckerService.java
index 2b8a458..cac449d 100644
--- a/core/java/android/service/textservice/SpellCheckerService.java
+++ b/core/java/android/service/textservice/SpellCheckerService.java
@@ -27,6 +27,7 @@
import android.os.Process;
import android.os.RemoteException;
import android.util.Log;
+import android.view.textservice.SentenceSuggestionsInfo;
import android.view.textservice.SuggestionsInfo;
import android.view.textservice.TextInfo;
@@ -140,19 +141,21 @@
/**
* @hide
- * The default implementation returns an array of SuggestionsInfo by simply calling
+ * The default implementation returns an array of SentenceSuggestionsInfo by simply calling
* onGetSuggestions().
* When you override this method, make sure that suggestionsLimit is applied to suggestions
* that share the same start position and length.
*/
- public SuggestionsInfo[] onGetSuggestionsMultipleForSentence(TextInfo[] textInfos,
+ public SentenceSuggestionsInfo[] onGetSentenceSuggestionsMultiple(TextInfo[] textInfos,
int suggestionsLimit) {
final int length = textInfos.length;
- final SuggestionsInfo[] retval = new SuggestionsInfo[length];
+ final SentenceSuggestionsInfo[] retval = new SentenceSuggestionsInfo[length];
for (int i = 0; i < length; ++i) {
- retval[i] = onGetSuggestions(textInfos[i], suggestionsLimit);
- retval[i].setCookieAndSequence(
- textInfos[i].getCookie(), textInfos[i].getSequence());
+ final SuggestionsInfo si = onGetSuggestions(textInfos[i], suggestionsLimit);
+ si.setCookieAndSequence(textInfos[i].getCookie(), textInfos[i].getSequence());
+ final int N = textInfos[i].getText().length();
+ retval[i] = new SentenceSuggestionsInfo(
+ new SuggestionsInfo[] {si}, new int[]{0}, new int[]{N});
}
return retval;
}
@@ -220,11 +223,10 @@
}
@Override
- public void onGetSuggestionsMultipleForSentence(
- TextInfo[] textInfos, int suggestionsLimit) {
+ public void onGetSentenceSuggestionsMultiple(TextInfo[] textInfos, int suggestionsLimit) {
try {
- mListener.onGetSuggestionsForSentence(
- mSession.onGetSuggestionsMultipleForSentence(textInfos, suggestionsLimit));
+ mListener.onGetSentenceSuggestions(
+ mSession.onGetSentenceSuggestionsMultiple(textInfos, suggestionsLimit));
} catch (RemoteException e) {
}
}
diff --git a/core/java/android/view/AccessibilityNodeInfoCache.java b/core/java/android/view/AccessibilityNodeInfoCache.java
index 244a491..84b510d 100644
--- a/core/java/android/view/AccessibilityNodeInfoCache.java
+++ b/core/java/android/view/AccessibilityNodeInfoCache.java
@@ -16,6 +16,8 @@
package android.view;
+import android.os.Process;
+import android.util.Log;
import android.util.LongSparseArray;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
@@ -30,7 +32,11 @@
*/
public class AccessibilityNodeInfoCache {
- private final boolean ENABLED = true;
+ private static final String LOG_TAG = AccessibilityNodeInfoCache.class.getSimpleName();
+
+ private static final boolean ENABLED = true;
+
+ private static final boolean DEBUG = false;
/**
* @return A new <strong>not synchronized</strong> AccessibilityNodeInfoCache.
@@ -95,6 +101,7 @@
public void onAccessibilityEvent(AccessibilityEvent event) {
final int eventType = event.getEventType();
switch (eventType) {
+ case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
case AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED:
case AccessibilityEvent.TYPE_VIEW_SCROLLED:
clear();
@@ -117,7 +124,14 @@
*/
public AccessibilityNodeInfo get(long accessibilityNodeId) {
if (ENABLED) {
- return mCacheImpl.get(accessibilityNodeId);
+ if (DEBUG) {
+ AccessibilityNodeInfo info = mCacheImpl.get(accessibilityNodeId);
+ Log.i(LOG_TAG, "Process: " + Process.myPid() +
+ " get(" + accessibilityNodeId + ") = " + info);
+ return info;
+ } else {
+ return mCacheImpl.get(accessibilityNodeId);
+ }
} else {
return null;
}
@@ -131,6 +145,10 @@
*/
public void put(long accessibilityNodeId, AccessibilityNodeInfo info) {
if (ENABLED) {
+ if (DEBUG) {
+ Log.i(LOG_TAG, "Process: " + Process.myPid()
+ + " put(" + accessibilityNodeId + ", " + info + ")");
+ }
mCacheImpl.put(accessibilityNodeId, info);
}
}
@@ -156,6 +174,10 @@
*/
public void remove(long accessibilityNodeId) {
if (ENABLED) {
+ if (DEBUG) {
+ Log.i(LOG_TAG, "Process: " + Process.myPid()
+ + " remove(" + accessibilityNodeId + ")");
+ }
mCacheImpl.remove(accessibilityNodeId);
}
}
@@ -165,6 +187,9 @@
*/
public void clear() {
if (ENABLED) {
+ if (DEBUG) {
+ Log.i(LOG_TAG, "Process: " + Process.myPid() + "clear()");
+ }
mCacheImpl.clear();
}
}
diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java
index a74b737..42c3913 100644
--- a/core/java/android/view/Choreographer.java
+++ b/core/java/android/view/Choreographer.java
@@ -235,8 +235,9 @@
if (isRunningOnLooperThreadLocked()) {
doScheduleVsyncLocked();
} else {
- mHandler.sendMessageAtFrontOfQueue(
- mHandler.obtainMessage(MSG_DO_SCHEDULE_VSYNC));
+ Message msg = mHandler.obtainMessage(MSG_DO_SCHEDULE_VSYNC);
+ msg.setAsynchronous(true);
+ mHandler.sendMessageAtFrontOfQueue(msg);
}
} else {
final long now = SystemClock.uptimeMillis();
@@ -244,7 +245,9 @@
if (DEBUG) {
Log.d(TAG, "Scheduling animation in " + (nextAnimationTime - now) + " ms.");
}
- mHandler.sendEmptyMessageAtTime(MSG_DO_ANIMATION, nextAnimationTime);
+ Message msg = mHandler.obtainMessage(MSG_DO_ANIMATION);
+ msg.setAsynchronous(true);
+ mHandler.sendMessageAtTime(msg, nextAnimationTime);
}
}
}
@@ -258,7 +261,9 @@
if (DEBUG) {
Log.d(TAG, "Scheduling draw immediately.");
}
- mHandler.sendEmptyMessage(MSG_DO_DRAW);
+ Message msg = mHandler.obtainMessage(MSG_DO_DRAW);
+ msg.setAsynchronous(true);
+ mHandler.sendMessage(msg);
}
}
}
diff --git a/core/java/android/view/DisplayList.java b/core/java/android/view/DisplayList.java
index fec0d4b..f60c8f0 100644
--- a/core/java/android/view/DisplayList.java
+++ b/core/java/android/view/DisplayList.java
@@ -27,6 +27,15 @@
*/
public abstract class DisplayList {
/**
+ * Flag used when calling
+ * {@link HardwareCanvas#drawDisplayList(DisplayList, int, int, android.graphics.Rect, int)}.
+ * When this flag is set, draw operations lying outside of the bounds of the
+ * display list will be culled early. It is recommeneded to always set this
+ * flag.
+ */
+ public static final int FLAG_CLIP_CHILDREN = 0x1;
+
+ /**
* Starts recording the display list. All operations performed on the
* returned canvas are recorded and stored in this display list.
*
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index 1e92b43..f5fc708 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -385,13 +385,14 @@
private static native void nSetDisplayListName(int displayList, String name);
@Override
- public boolean drawDisplayList(DisplayList displayList, int width, int height, Rect dirty) {
- return nDrawDisplayList(mRenderer,
- ((GLES20DisplayList) displayList).getNativeDisplayList(), width, height, dirty);
+ public boolean drawDisplayList(DisplayList displayList, int width, int height,
+ Rect dirty, int flags) {
+ return nDrawDisplayList(mRenderer, ((GLES20DisplayList) displayList).getNativeDisplayList(),
+ width, height, dirty, flags);
}
private static native boolean nDrawDisplayList(int renderer, int displayList,
- int width, int height, Rect dirty);
+ int width, int height, Rect dirty, int flags);
@Override
void outputDisplayList(DisplayList displayList) {
@@ -407,9 +408,12 @@
void drawHardwareLayer(HardwareLayer layer, float x, float y, Paint paint) {
final GLES20Layer glLayer = (GLES20Layer) layer;
int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE;
- final int nativePaint = paint == null ? 0 : paint.mNativePaint;
- nDrawLayer(mRenderer, glLayer.getLayer(), x, y, nativePaint);
- if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier);
+ try {
+ final int nativePaint = paint == null ? 0 : paint.mNativePaint;
+ nDrawLayer(mRenderer, glLayer.getLayer(), x, y, nativePaint);
+ } finally {
+ if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier);
+ }
}
private static native void nDrawLayer(int renderer, int layer, float x, float y, int paint);
@@ -607,10 +611,14 @@
return saveLayer(bounds.left, bounds.top, bounds.right, bounds.bottom, paint, saveFlags);
}
+ int count;
int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE;
- final int nativePaint = paint == null ? 0 : paint.mNativePaint;
- int count = nSaveLayer(mRenderer, nativePaint, saveFlags);
- if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier);
+ try {
+ final int nativePaint = paint == null ? 0 : paint.mNativePaint;
+ count = nSaveLayer(mRenderer, nativePaint, saveFlags);
+ } finally {
+ if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier);
+ }
return count;
}
@@ -620,10 +628,14 @@
public int saveLayer(float left, float top, float right, float bottom, Paint paint,
int saveFlags) {
if (left < right && top < bottom) {
+ int count;
int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE;
- final int nativePaint = paint == null ? 0 : paint.mNativePaint;
- int count = nSaveLayer(mRenderer, left, top, right, bottom, nativePaint, saveFlags);
- if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier);
+ try {
+ final int nativePaint = paint == null ? 0 : paint.mNativePaint;
+ count = nSaveLayer(mRenderer, left, top, right, bottom, nativePaint, saveFlags);
+ } finally {
+ if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier);
+ }
return count;
}
return save(saveFlags);
@@ -707,9 +719,12 @@
public void drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter,
Paint paint) {
int modifiers = setupModifiers(paint);
- nDrawArc(mRenderer, oval.left, oval.top, oval.right, oval.bottom, startAngle, sweepAngle,
- useCenter, paint.mNativePaint);
- if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
+ try {
+ nDrawArc(mRenderer, oval.left, oval.top, oval.right, oval.bottom,
+ startAngle, sweepAngle, useCenter, paint.mNativePaint);
+ } finally {
+ if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
+ }
}
private static native void nDrawArc(int renderer, float left, float top,
@@ -726,10 +741,13 @@
if (bitmap.isRecycled()) throw new IllegalArgumentException("Cannot draw recycled bitmaps");
// Shaders are ignored when drawing patches
int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE;
- final int nativePaint = paint == null ? 0 : paint.mNativePaint;
- nDrawPatch(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, chunks,
- dst.left, dst.top, dst.right, dst.bottom, nativePaint);
- if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier);
+ try {
+ final int nativePaint = paint == null ? 0 : paint.mNativePaint;
+ nDrawPatch(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, chunks,
+ dst.left, dst.top, dst.right, dst.bottom, nativePaint);
+ } finally {
+ if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier);
+ }
}
private static native void nDrawPatch(int renderer, int bitmap, byte[] buffer, byte[] chunks,
@@ -740,9 +758,12 @@
if (bitmap.isRecycled()) throw new IllegalArgumentException("Cannot draw recycled bitmaps");
// Shaders are ignored when drawing bitmaps
int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE;
- final int nativePaint = paint == null ? 0 : paint.mNativePaint;
- nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, left, top, nativePaint);
- if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
+ try {
+ final int nativePaint = paint == null ? 0 : paint.mNativePaint;
+ nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, left, top, nativePaint);
+ } finally {
+ if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
+ }
}
private static native void nDrawBitmap(
@@ -753,10 +774,13 @@
if (bitmap.isRecycled()) throw new IllegalArgumentException("Cannot draw recycled bitmaps");
// Shaders are ignored when drawing bitmaps
int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE;
- final int nativePaint = paint == null ? 0 : paint.mNativePaint;
- nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer,
- matrix.native_instance, nativePaint);
- if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
+ try {
+ final int nativePaint = paint == null ? 0 : paint.mNativePaint;
+ nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer,
+ matrix.native_instance, nativePaint);
+ } finally {
+ if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
+ }
}
private static native void nDrawBitmap(int renderer, int bitmap, byte[] buff,
@@ -767,23 +791,26 @@
if (bitmap.isRecycled()) throw new IllegalArgumentException("Cannot draw recycled bitmaps");
// Shaders are ignored when drawing bitmaps
int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE;
- final int nativePaint = paint == null ? 0 : paint.mNativePaint;
+ try {
+ final int nativePaint = paint == null ? 0 : paint.mNativePaint;
- int left, top, right, bottom;
- if (src == null) {
- left = top = 0;
- right = bitmap.getWidth();
- bottom = bitmap.getHeight();
- } else {
- left = src.left;
- right = src.right;
- top = src.top;
- bottom = src.bottom;
+ int left, top, right, bottom;
+ if (src == null) {
+ left = top = 0;
+ right = bitmap.getWidth();
+ bottom = bitmap.getHeight();
+ } else {
+ left = src.left;
+ right = src.right;
+ top = src.top;
+ bottom = src.bottom;
+ }
+
+ nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, left, top, right, bottom,
+ dst.left, dst.top, dst.right, dst.bottom, nativePaint);
+ } finally {
+ if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
}
-
- nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, left, top, right, bottom,
- dst.left, dst.top, dst.right, dst.bottom, nativePaint);
- if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
}
@Override
@@ -791,23 +818,26 @@
if (bitmap.isRecycled()) throw new IllegalArgumentException("Cannot draw recycled bitmaps");
// Shaders are ignored when drawing bitmaps
int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE;
- final int nativePaint = paint == null ? 0 : paint.mNativePaint;
-
- float left, top, right, bottom;
- if (src == null) {
- left = top = 0;
- right = bitmap.getWidth();
- bottom = bitmap.getHeight();
- } else {
- left = src.left;
- right = src.right;
- top = src.top;
- bottom = src.bottom;
+ try {
+ final int nativePaint = paint == null ? 0 : paint.mNativePaint;
+
+ float left, top, right, bottom;
+ if (src == null) {
+ left = top = 0;
+ right = bitmap.getWidth();
+ bottom = bitmap.getHeight();
+ } else {
+ left = src.left;
+ right = src.right;
+ top = src.top;
+ bottom = src.bottom;
+ }
+
+ nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, left, top, right, bottom,
+ dst.left, dst.top, dst.right, dst.bottom, nativePaint);
+ } finally {
+ if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
}
-
- nDrawBitmap(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, left, top, right, bottom,
- dst.left, dst.top, dst.right, dst.bottom, nativePaint);
- if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
}
private static native void nDrawBitmap(int renderer, int bitmap, byte[] buffer,
@@ -819,12 +849,15 @@
int width, int height, boolean hasAlpha, Paint paint) {
// Shaders are ignored when drawing bitmaps
int modifier = paint != null ? setupColorFilter(paint) : MODIFIER_NONE;
- final Bitmap.Config config = hasAlpha ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
- final Bitmap b = Bitmap.createBitmap(colors, offset, stride, width, height, config);
- final int nativePaint = paint == null ? 0 : paint.mNativePaint;
- nDrawBitmap(mRenderer, b.mNativeBitmap, b.mBuffer, x, y, nativePaint);
- b.recycle();
- if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier);
+ try {
+ final Bitmap.Config config = hasAlpha ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565;
+ final Bitmap b = Bitmap.createBitmap(colors, offset, stride, width, height, config);
+ final int nativePaint = paint == null ? 0 : paint.mNativePaint;
+ nDrawBitmap(mRenderer, b.mNativeBitmap, b.mBuffer, x, y, nativePaint);
+ b.recycle();
+ } finally {
+ if (modifier != MODIFIER_NONE) nResetModifiers(mRenderer, modifier);
+ }
}
@Override
@@ -854,10 +887,13 @@
colorOffset = 0;
int modifiers = paint != null ? setupModifiers(bitmap, paint) : MODIFIER_NONE;
- final int nativePaint = paint == null ? 0 : paint.mNativePaint;
- nDrawBitmapMesh(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, meshWidth, meshHeight,
- verts, vertOffset, colors, colorOffset, nativePaint);
- if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
+ try {
+ final int nativePaint = paint == null ? 0 : paint.mNativePaint;
+ nDrawBitmapMesh(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, meshWidth, meshHeight,
+ verts, vertOffset, colors, colorOffset, nativePaint);
+ } finally {
+ if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
+ }
}
private static native void nDrawBitmapMesh(int renderer, int bitmap, byte[] buffer,
@@ -867,8 +903,11 @@
@Override
public void drawCircle(float cx, float cy, float radius, Paint paint) {
int modifiers = setupModifiers(paint);
- nDrawCircle(mRenderer, cx, cy, radius, paint.mNativePaint);
- if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
+ try {
+ nDrawCircle(mRenderer, cx, cy, radius, paint.mNativePaint);
+ } finally {
+ if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
+ }
}
private static native void nDrawCircle(int renderer, float cx, float cy,
@@ -901,8 +940,11 @@
throw new IllegalArgumentException("The lines array must contain 4 elements per line.");
}
int modifiers = setupModifiers(paint);
- nDrawLines(mRenderer, pts, offset, count, paint.mNativePaint);
- if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
+ try {
+ nDrawLines(mRenderer, pts, offset, count, paint.mNativePaint);
+ } finally {
+ if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
+ }
}
private static native void nDrawLines(int renderer, float[] points,
@@ -916,8 +958,11 @@
@Override
public void drawOval(RectF oval, Paint paint) {
int modifiers = setupModifiers(paint);
- nDrawOval(mRenderer, oval.left, oval.top, oval.right, oval.bottom, paint.mNativePaint);
- if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
+ try {
+ nDrawOval(mRenderer, oval.left, oval.top, oval.right, oval.bottom, paint.mNativePaint);
+ } finally {
+ if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
+ }
}
private static native void nDrawOval(int renderer, float left, float top,
@@ -933,14 +978,17 @@
@Override
public void drawPath(Path path, Paint paint) {
int modifiers = setupModifiers(paint);
- if (path.isSimplePath) {
- if (path.rects != null) {
- nDrawRects(mRenderer, path.rects.mNativeRegion, paint.mNativePaint);
+ try {
+ if (path.isSimplePath) {
+ if (path.rects != null) {
+ nDrawRects(mRenderer, path.rects.mNativeRegion, paint.mNativePaint);
+ }
+ } else {
+ nDrawPath(mRenderer, path.mNativePath, paint.mNativePaint);
}
- } else {
- nDrawPath(mRenderer, path.mNativePath, paint.mNativePaint);
+ } finally {
+ if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
}
- if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
}
private static native void nDrawPath(int renderer, int path, int paint);
@@ -1001,8 +1049,11 @@
@Override
public void drawPoints(float[] pts, int offset, int count, Paint paint) {
int modifiers = setupModifiers(paint);
- nDrawPoints(mRenderer, pts, offset, count, paint.mNativePaint);
- if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
+ try {
+ nDrawPoints(mRenderer, pts, offset, count, paint.mNativePaint);
+ } finally {
+ if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
+ }
}
private static native void nDrawPoints(int renderer, float[] points,
@@ -1047,8 +1098,11 @@
@Override
public void drawRect(float left, float top, float right, float bottom, Paint paint) {
int modifiers = setupModifiers(paint);
- nDrawRect(mRenderer, left, top, right, bottom, paint.mNativePaint);
- if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
+ try {
+ nDrawRect(mRenderer, left, top, right, bottom, paint.mNativePaint);
+ } finally {
+ if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
+ }
}
private static native void nDrawRect(int renderer, float left, float top,
@@ -1072,9 +1126,12 @@
@Override
public void drawRoundRect(RectF rect, float rx, float ry, Paint paint) {
int modifiers = setupModifiers(paint);
- nDrawRoundRect(mRenderer, rect.left, rect.top, rect.right, rect.bottom,
- rx, ry, paint.mNativePaint);
- if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
+ try {
+ nDrawRoundRect(mRenderer, rect.left, rect.top, rect.right, rect.bottom,
+ rx, ry, paint.mNativePaint);
+ } finally {
+ if (modifiers != MODIFIER_NONE) nResetModifiers(mRenderer, modifiers);
+ }
}
private static native void nDrawRoundRect(int renderer, float left, float top,
@@ -1223,17 +1280,17 @@
}
private int setupModifiers(Bitmap b, Paint paint) {
- if (b.getConfig() == Bitmap.Config.ALPHA_8) {
+ if (b.getConfig() != Bitmap.Config.ALPHA_8) {
+ final ColorFilter filter = paint.getColorFilter();
+ if (filter != null) {
+ nSetupColorFilter(mRenderer, filter.nativeColorFilter);
+ return MODIFIER_COLOR_FILTER;
+ }
+
+ return MODIFIER_NONE;
+ } else {
return setupModifiers(paint);
}
-
- final ColorFilter filter = paint.getColorFilter();
- if (filter != null) {
- nSetupColorFilter(mRenderer, filter.nativeColorFilter);
- return MODIFIER_COLOR_FILTER;
- }
-
- return MODIFIER_NONE;
}
private int setupModifiers(Paint paint) {
diff --git a/core/java/android/view/GLES20RecordingCanvas.java b/core/java/android/view/GLES20RecordingCanvas.java
index c987f48..c9ba65f 100644
--- a/core/java/android/view/GLES20RecordingCanvas.java
+++ b/core/java/android/view/GLES20RecordingCanvas.java
@@ -143,8 +143,8 @@
@Override
public void drawBitmapMesh(Bitmap bitmap, int meshWidth, int meshHeight, float[] verts,
int vertOffset, int[] colors, int colorOffset, Paint paint) {
- super.drawBitmapMesh(bitmap, meshWidth, meshHeight, verts, vertOffset, colors, colorOffset,
- paint);
+ super.drawBitmapMesh(bitmap, meshWidth, meshHeight, verts, vertOffset,
+ colors, colorOffset, paint);
mDisplayList.mBitmaps.add(bitmap);
// Shaders in the Paint are ignored when drawing a Bitmap
}
diff --git a/core/java/android/view/HardwareCanvas.java b/core/java/android/view/HardwareCanvas.java
index cbdbbde..838c03c 100644
--- a/core/java/android/view/HardwareCanvas.java
+++ b/core/java/android/view/HardwareCanvas.java
@@ -57,11 +57,14 @@
* @param height The height of the display list.
* @param dirty The dirty region to redraw in the next pass, matters only
* if this method returns true, can be null.
+ * @param flags Optional flags about drawing, see {@link DisplayList} for
+ * the possible flags.
*
* @return True if the content of the display list requires another
* drawing pass (invalidate()), false otherwise
*/
- public abstract boolean drawDisplayList(DisplayList displayList, int width, int height, Rect dirty);
+ public abstract boolean drawDisplayList(DisplayList displayList, int width, int height,
+ Rect dirty, int flags);
/**
* Outputs the specified display list to the log. This method exists for use by
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java
index 67466a4..ec95863 100644
--- a/core/java/android/view/HardwareRenderer.java
+++ b/core/java/android/view/HardwareRenderer.java
@@ -969,7 +969,8 @@
}
boolean invalidateNeeded = canvas.drawDisplayList(displayList,
- view.getWidth(), view.getHeight(), mRedrawClip);
+ view.getWidth(), view.getHeight(), mRedrawClip,
+ DisplayList.FLAG_CLIP_CHILDREN);
if (mProfileEnabled) {
long now = System.nanoTime();
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 6726c56e..c658a80 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -384,7 +384,7 @@
if (!mHaveFrame) {
return;
}
- ViewRootImpl viewRoot = (ViewRootImpl) getRootView().getParent();
+ ViewRootImpl viewRoot = getViewRootImpl();
if (viewRoot != null) {
mTranslator = viewRoot.mTranslator;
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 363c30d..81151b0 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -601,6 +601,8 @@
* @attr ref android.R.styleable#View_paddingLeft
* @attr ref android.R.styleable#View_paddingRight
* @attr ref android.R.styleable#View_paddingTop
+ * @attr ref android.R.styleable#View_paddingStart
+ * @attr ref android.R.styleable#View_paddingEnd
* @attr ref android.R.styleable#View_saveEnabled
* @attr ref android.R.styleable#View_rotation
* @attr ref android.R.styleable#View_rotationX
@@ -1757,6 +1759,16 @@
static final int LAYOUT_DIRECTION_RESOLVED = 0x00000008;
+ /**
+ * Indicates that the view is tracking some sort of transient state
+ * that the app should not need to be aware of, but that the framework
+ * should take special care to preserve.
+ *
+ * @hide
+ */
+ static final int HAS_TRANSIENT_STATE = 0x00000010;
+
+
/* End of masks for mPrivateFlags2 */
static final int DRAG_MASK = DRAG_CAN_ACCEPT | DRAG_HOVERED;
@@ -4887,6 +4899,43 @@
}
/**
+ * Indicates whether the view is currently tracking transient state that the
+ * app should not need to concern itself with saving and restoring, but that
+ * the framework should take special note to preserve when possible.
+ *
+ * @return true if the view has transient state
+ *
+ * @hide
+ */
+ @ViewDebug.ExportedProperty(category = "layout")
+ public boolean hasTransientState() {
+ return (mPrivateFlags2 & HAS_TRANSIENT_STATE) == HAS_TRANSIENT_STATE;
+ }
+
+ /**
+ * Set whether this view is currently tracking transient state that the
+ * framework should attempt to preserve when possible.
+ *
+ * @param hasTransientState true if this view has transient state
+ *
+ * @hide
+ */
+ public void setHasTransientState(boolean hasTransientState) {
+ if (hasTransientState() == hasTransientState) return;
+
+ mPrivateFlags2 = (mPrivateFlags2 & ~HAS_TRANSIENT_STATE) |
+ (hasTransientState ? HAS_TRANSIENT_STATE : 0);
+ if (mParent != null) {
+ try {
+ mParent.childHasTransientStateChanged(this, hasTransientState);
+ } catch (AbstractMethodError e) {
+ Log.e(VIEW_LOG_TAG, mParent.getClass().getSimpleName() +
+ " does not fully implement ViewParent", e);
+ }
+ }
+ }
+
+ /**
* If this view doesn't do any drawing on its own, set this flag to
* allow further optimizations. By default, this flag is not set on
* View, but could be set on some View subclasses such as ViewGroup.
@@ -4997,6 +5046,10 @@
* the View's internal state from a previously set "pressed" state.
*/
public void setPressed(boolean pressed) {
+ if (pressed == ((mPrivateFlags & PRESSED) == PRESSED)) {
+ return;
+ }
+
if (pressed) {
mPrivateFlags |= PRESSED;
} else {
@@ -5440,12 +5493,6 @@
return true;
}
- /** Gets the ViewAncestor, or null if not attached. */
- /*package*/ ViewRootImpl getViewRootImpl() {
- View root = getRootView();
- return root != null ? (ViewRootImpl)root.getParent() : null;
- }
-
/**
* Call this to try to give focus to a specific view or to one of its descendants. This is a
* special variant of {@link #requestFocus() } that will allow views that are not focuable in
@@ -6505,8 +6552,7 @@
if ((viewFlags & ENABLED_MASK) == DISABLED) {
if (event.getAction() == MotionEvent.ACTION_UP && (mPrivateFlags & PRESSED) != 0) {
- mPrivateFlags &= ~PRESSED;
- refreshDrawableState();
+ setPressed(false);
}
// A disabled view that is clickable still consumes the touch
// events, it just doesn't respond to them.
@@ -6538,8 +6584,7 @@
// showed it as pressed. Make it show the pressed
// state now (before scheduling the click) to ensure
// the user sees it.
- mPrivateFlags |= PRESSED;
- refreshDrawableState();
+ setPressed(true);
}
if (!mHasPerformedLongPress) {
@@ -6595,15 +6640,13 @@
postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout());
} else {
// Not inside a scrolling container, so show the feedback right away
- mPrivateFlags |= PRESSED;
- refreshDrawableState();
+ setPressed(true);
checkForLongClick(0);
}
break;
case MotionEvent.ACTION_CANCEL:
- mPrivateFlags &= ~PRESSED;
- refreshDrawableState();
+ setPressed(false);
removeTapCallback();
break;
@@ -6619,9 +6662,7 @@
// Remove any future long press/tap checks
removeLongPressCallback();
- // Need to switch from pressed to not pressed
- mPrivateFlags &= ~PRESSED;
- refreshDrawableState();
+ setPressed(false);
}
}
break;
@@ -8683,6 +8724,18 @@
}
/**
+ * Gets the view root associated with the View.
+ * @return The view root, or null if none.
+ * @hide
+ */
+ public ViewRootImpl getViewRootImpl() {
+ if (mAttachInfo != null) {
+ return mAttachInfo.mViewRootImpl;
+ }
+ return null;
+ }
+
+ /**
* <p>Causes the Runnable to be added to the message queue.
* The runnable will be run on the user interface thread.</p>
*
@@ -8696,17 +8749,13 @@
* looper processing the message queue is exiting.
*/
public boolean post(Runnable action) {
- Handler handler;
- AttachInfo attachInfo = mAttachInfo;
+ final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
- handler = attachInfo.mHandler;
- } else {
- // Assume that post will succeed later
- ViewRootImpl.getRunQueue().post(action);
- return true;
+ return attachInfo.mHandler.post(action);
}
-
- return handler.post(action);
+ // Assume that post will succeed later
+ ViewRootImpl.getRunQueue().post(action);
+ return true;
}
/**
@@ -8729,17 +8778,13 @@
* occurs then the message will be dropped.
*/
public boolean postDelayed(Runnable action, long delayMillis) {
- Handler handler;
- AttachInfo attachInfo = mAttachInfo;
+ final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
- handler = attachInfo.mHandler;
- } else {
- // Assume that post will succeed later
- ViewRootImpl.getRunQueue().postDelayed(action, delayMillis);
- return true;
+ return attachInfo.mHandler.postDelayed(action, delayMillis);
}
-
- return handler.postDelayed(action, delayMillis);
+ // Assume that post will succeed later
+ ViewRootImpl.getRunQueue().postDelayed(action, delayMillis);
+ return true;
}
/**
@@ -8756,17 +8801,13 @@
* (for instance, if the Runnable was not in the queue already.)
*/
public boolean removeCallbacks(Runnable action) {
- Handler handler;
- AttachInfo attachInfo = mAttachInfo;
+ final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
- handler = attachInfo.mHandler;
+ attachInfo.mHandler.removeCallbacks(action);
} else {
// Assume that post will succeed later
ViewRootImpl.getRunQueue().removeCallbacks(action);
- return true;
}
-
- handler.removeCallbacks(action);
return true;
}
@@ -8815,12 +8856,9 @@
public void postInvalidateDelayed(long delayMilliseconds) {
// We try only with the AttachInfo because there's no point in invalidating
// if we are not attached to our window
- AttachInfo attachInfo = mAttachInfo;
+ final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
- Message msg = Message.obtain();
- msg.what = AttachInfo.INVALIDATE_MSG;
- msg.obj = this;
- attachInfo.mHandler.sendMessageDelayed(msg, delayMilliseconds);
+ attachInfo.mViewRootImpl.dispatchInvalidateDelayed(this, delayMilliseconds);
}
}
@@ -8843,7 +8881,7 @@
// We try only with the AttachInfo because there's no point in invalidating
// if we are not attached to our window
- AttachInfo attachInfo = mAttachInfo;
+ final AttachInfo attachInfo = mAttachInfo;
if (attachInfo != null) {
final AttachInfo.InvalidateInfo info = AttachInfo.InvalidateInfo.acquire();
info.target = this;
@@ -8852,10 +8890,7 @@
info.right = right;
info.bottom = bottom;
- final Message msg = Message.obtain();
- msg.what = AttachInfo.INVALIDATE_RECT_MSG;
- msg.obj = info;
- attachInfo.mHandler.sendMessageDelayed(msg, delayMilliseconds);
+ attachInfo.mViewRootImpl.dispatchInvalidateRectDelayed(info, delayMilliseconds);
}
}
@@ -9540,10 +9575,6 @@
// Clear any previous layout direction resolution
mPrivateFlags2 &= ~LAYOUT_DIRECTION_RESOLVED_RTL;
- // Reset also TextDirection as a change into LayoutDirection may impact the selected
- // TextDirectionHeuristic
- resetResolvedTextDirection();
-
// Set resolved depending on layout direction
switch (getLayoutDirection()) {
case LAYOUT_DIRECTION_INHERIT:
@@ -9580,14 +9611,15 @@
}
/**
- * @hide
+ * Force padding depending on layout direction.
*/
- protected void resolvePadding() {
+ public void resolvePadding() {
// If the user specified the absolute padding (either with android:padding or
// android:paddingLeft/Top/Right/Bottom), use this padding, otherwise
// use the default padding or the padding from the background drawable
// (stored at this point in mPadding*)
- switch (getResolvedLayoutDirection()) {
+ int resolvedLayoutDirection = getResolvedLayoutDirection();
+ switch (resolvedLayoutDirection) {
case LAYOUT_DIRECTION_RTL:
// Start user padding override Right user padding. Otherwise, if Right user
// padding is not defined, use the default Right padding. If Right user padding
@@ -9623,6 +9655,18 @@
mUserPaddingBottom = (mUserPaddingBottom >= 0) ? mUserPaddingBottom : mPaddingBottom;
recomputePadding();
+ onResolvePadding(resolvedLayoutDirection);
+ }
+
+ /**
+ * Resolve padding depending on the layout direction. Subclasses that care about
+ * padding resolution should override this method. The default implementation does
+ * nothing.
+ *
+ * @param layoutDirection the direction of the layout
+ *
+ */
+ public void onResolvePadding(int layoutDirection) {
}
/**
@@ -9649,8 +9693,10 @@
* @hide
*/
protected void resetResolvedLayoutDirection() {
- // Reset the current View resolution
+ // Reset the layout direction resolution
mPrivateFlags2 &= ~LAYOUT_DIRECTION_RESOLVED;
+ // Reset also the text direction
+ resetResolvedTextDirection();
}
/**
@@ -9689,13 +9735,12 @@
}
if (mAttachInfo != null) {
- mAttachInfo.mHandler.removeMessages(AttachInfo.INVALIDATE_MSG, this);
+ mAttachInfo.mViewRootImpl.cancelInvalidate(this);
}
mCurrentAnimation = null;
resetResolvedLayoutDirection();
- resetResolvedTextDirection();
}
/**
@@ -11209,7 +11254,7 @@
} else {
mPrivateFlags &= ~DIRTY_MASK;
((HardwareCanvas) canvas).drawDisplayList(displayList,
- mRight - mLeft, mBottom - mTop, null);
+ mRight - mLeft, mBottom - mTop, null, flags);
}
}
} else if (cache != null) {
@@ -14070,7 +14115,6 @@
* {@link #TEXT_DIRECTION_LTR},
* {@link #TEXT_DIRECTION_RTL},
* {@link #TEXT_DIRECTION_LOCALE},
- *
*/
public int getTextDirection() {
return mTextDirection;
@@ -14087,7 +14131,6 @@
* {@link #TEXT_DIRECTION_LTR},
* {@link #TEXT_DIRECTION_RTL},
* {@link #TEXT_DIRECTION_LOCALE},
- *
*/
public void setTextDirection(int textDirection) {
if (textDirection != mTextDirection) {
@@ -14107,7 +14150,6 @@
* {@link #TEXT_DIRECTION_LTR},
* {@link #TEXT_DIRECTION_RTL},
* {@link #TEXT_DIRECTION_LOCALE},
- *
*/
public int getResolvedTextDirection() {
if (mResolvedTextDirection == TEXT_DIRECTION_INHERIT) {
@@ -14117,27 +14159,47 @@
}
/**
- * Resolve the text direction.
- *
+ * Resolve the text direction. Will call {@link View#onResolveTextDirection()} when resolution
+ * is done.
*/
- protected void resolveTextDirection() {
+ public void resolveTextDirection() {
+ if (mResolvedTextDirection != TEXT_DIRECTION_INHERIT) {
+ // Resolution has already been done.
+ return;
+ }
if (mTextDirection != TEXT_DIRECTION_INHERIT) {
mResolvedTextDirection = mTextDirection;
- return;
- }
- if (mParent != null && mParent instanceof ViewGroup) {
+ } else if (mParent != null && mParent instanceof ViewGroup) {
mResolvedTextDirection = ((ViewGroup) mParent).getResolvedTextDirection();
- return;
+ } else {
+ mResolvedTextDirection = TEXT_DIRECTION_FIRST_STRONG;
}
- mResolvedTextDirection = TEXT_DIRECTION_FIRST_STRONG;
+ onResolveTextDirection();
}
/**
- * Reset resolved text direction. Will be resolved during a call to getResolvedTextDirection().
- *
+ * Called when text direction has been resolved. Subclasses that care about text direction
+ * resolution should override this method. The default implementation does nothing.
*/
- protected void resetResolvedTextDirection() {
+ public void onResolveTextDirection() {
+ }
+
+ /**
+ * Reset resolved text direction. Text direction can be resolved with a call to
+ * getResolvedTextDirection(). Will call {@link View#onResetResolvedTextDirection()} when
+ * reset is done.
+ */
+ public void resetResolvedTextDirection() {
mResolvedTextDirection = TEXT_DIRECTION_INHERIT;
+ onResetResolvedTextDirection();
+ }
+
+ /**
+ * Called when text direction is reset. Subclasses that care about text direction reset should
+ * override this method and do a reset of the text direction of their children. The default
+ * implementation does nothing.
+ */
+ public void onResetResolvedTextDirection() {
}
//
@@ -14441,8 +14503,7 @@
private final class CheckForTap implements Runnable {
public void run() {
mPrivateFlags &= ~PREPRESSED;
- mPrivateFlags |= PRESSED;
- refreshDrawableState();
+ setPressed(true);
checkForLongClick(ViewConfiguration.getTapTimeout());
}
}
@@ -14962,24 +15023,17 @@
Canvas mCanvas;
/**
+ * The view root impl.
+ */
+ final ViewRootImpl mViewRootImpl;
+
+ /**
* A Handler supplied by a view's {@link android.view.ViewRootImpl}. This
* handler can be used to pump events in the UI events queue.
*/
final Handler mHandler;
/**
- * Identifier for messages requesting the view to be invalidated.
- * Such messages should be sent to {@link #mHandler}.
- */
- static final int INVALIDATE_MSG = 0x1;
-
- /**
- * Identifier for messages requesting the view to invalidate a region.
- * Such messages should be sent to {@link #mHandler}.
- */
- static final int INVALIDATE_RECT_MSG = 0x2;
-
- /**
* Temporary for use in computing invalidate rectangles while
* calling up the hierarchy.
*/
@@ -15007,10 +15061,11 @@
* @param handler the events handler the view must use
*/
AttachInfo(IWindowSession session, IWindow window,
- Handler handler, Callbacks effectPlayer) {
+ ViewRootImpl viewRootImpl, Handler handler, Callbacks effectPlayer) {
mSession = session;
mWindow = window;
mWindowToken = window.asBinder();
+ mViewRootImpl = viewRootImpl;
mHandler = handler;
mRootCallbacks = effectPlayer;
}
diff --git a/core/java/android/view/ViewDebug.java b/core/java/android/view/ViewDebug.java
index c1db572..2a17845 100644
--- a/core/java/android/view/ViewDebug.java
+++ b/core/java/android/view/ViewDebug.java
@@ -375,7 +375,7 @@
}
private static BufferedWriter sHierarchyTraces;
- private static ViewRootImpl sHierarhcyRoot;
+ private static ViewRootImpl sHierarchyRoot;
private static String sHierarchyTracePrefix;
/**
@@ -855,7 +855,7 @@
return;
}
- if (sHierarhcyRoot != null) {
+ if (sHierarchyRoot != null) {
throw new IllegalStateException("You must call stopHierarchyTracing() before running" +
" a new trace!");
}
@@ -874,7 +874,7 @@
return;
}
- sHierarhcyRoot = (ViewRootImpl) view.getRootView().getParent();
+ sHierarchyRoot = view.getViewRootImpl();
}
/**
@@ -896,7 +896,7 @@
return;
}
- if (sHierarhcyRoot == null || sHierarchyTraces == null) {
+ if (sHierarchyRoot == null || sHierarchyTraces == null) {
throw new IllegalStateException("You must call startHierarchyTracing() before" +
" stopHierarchyTracing()!");
}
@@ -921,7 +921,7 @@
return;
}
- View view = sHierarhcyRoot.getView();
+ View view = sHierarchyRoot.getView();
if (view instanceof ViewGroup) {
ViewGroup group = (ViewGroup) view;
dumpViewHierarchy(group, out, 0);
@@ -932,7 +932,7 @@
}
}
- sHierarhcyRoot = null;
+ sHierarchyRoot = null;
}
static void dispatchCommand(View view, String command, String parameters,
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index e6a8334..c68d77d 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -77,6 +77,7 @@
* @attr ref android.R.styleable#ViewGroup_animateLayoutChanges
*/
public abstract class ViewGroup extends View implements ViewParent, ViewManager {
+ private static final String TAG = "ViewGroup";
private static final boolean DBG = false;
@@ -168,6 +169,11 @@
*/
protected int mGroupFlags;
+ /**
+ * NOTE: If you change the flags below make sure to reflect the changes
+ * the DisplayList class
+ */
+
// When set, ViewGroup invalidates only the child's rectangle
// Set by default
static final int FLAG_CLIP_CHILDREN = 0x1;
@@ -370,6 +376,10 @@
@ViewDebug.ExportedProperty(category = "drawing")
boolean mDrawLayers = true;
+ // Indicates how many of this container's child subtrees contain transient state
+ @ViewDebug.ExportedProperty(category = "layout")
+ private int mChildCountWithTransientState = 0;
+
public ViewGroup(Context context) {
super(context);
initViewGroup();
@@ -648,6 +658,38 @@
}
/**
+ * Called when a child view has changed whether or not it is tracking transient state.
+ *
+ * @hide
+ */
+ public void childHasTransientStateChanged(View child, boolean childHasTransientState) {
+ final boolean oldHasTransientState = hasTransientState();
+ if (childHasTransientState) {
+ mChildCountWithTransientState++;
+ } else {
+ mChildCountWithTransientState--;
+ }
+
+ final boolean newHasTransientState = hasTransientState();
+ if (mParent != null && oldHasTransientState != newHasTransientState) {
+ try {
+ mParent.childHasTransientStateChanged(this, newHasTransientState);
+ } catch (AbstractMethodError e) {
+ Log.e(TAG, mParent.getClass().getSimpleName() +
+ " does not fully implement ViewParent", e);
+ }
+ }
+ }
+
+ /**
+ * @hide
+ */
+ @Override
+ public boolean hasTransientState() {
+ return mChildCountWithTransientState > 0 || super.hasTransientState();
+ }
+
+ /**
* {@inheritDoc}
*/
@Override
@@ -3094,6 +3136,10 @@
if ((child.mViewFlags & DUPLICATE_PARENT_STATE) == DUPLICATE_PARENT_STATE) {
mGroupFlags |= FLAG_NOTIFY_CHILDREN_ON_DRAWABLE_STATE_CHANGE;
}
+
+ if (child.hasTransientState()) {
+ childHasTransientStateChanged(child, true);
+ }
}
private void addInArray(View child, int index) {
@@ -3290,6 +3336,10 @@
view.dispatchDetachedFromWindow();
}
+ if (view.hasTransientState()) {
+ childHasTransientStateChanged(view, false);
+ }
+
onViewRemoved(view);
needGlobalAttributesUpdate(false);
@@ -3361,6 +3411,10 @@
view.dispatchDetachedFromWindow();
}
+ if (view.hasTransientState()) {
+ childHasTransientStateChanged(view, false);
+ }
+
needGlobalAttributesUpdate(false);
onViewRemoved(view);
@@ -3426,6 +3480,10 @@
view.dispatchDetachedFromWindow();
}
+ if (view.hasTransientState()) {
+ childHasTransientStateChanged(view, false);
+ }
+
onViewRemoved(view);
view.mParent = null;
@@ -3466,6 +3524,10 @@
child.dispatchDetachedFromWindow();
}
+ if (child.hasTransientState()) {
+ childHasTransientStateChanged(child, false);
+ }
+
onViewRemoved(child);
}
@@ -3727,7 +3789,8 @@
RectF boundingRect = attachInfo.mTmpTransformRect;
boundingRect.set(dirty);
m.mapRect(boundingRect);
- dirty.set((int) boundingRect.left, (int) boundingRect.top,
+ dirty.set((int) (boundingRect.left - 0.5f),
+ (int) (boundingRect.top - 0.5f),
(int) (boundingRect.right + 0.5f),
(int) (boundingRect.bottom + 0.5f));
}
@@ -4857,9 +4920,7 @@
}
@Override
- protected void resetResolvedTextDirection() {
- super.resetResolvedTextDirection();
-
+ public void onResetResolvedTextDirection() {
// Take care of resetting the children resolution too
final int count = getChildCount();
for (int i = 0; i < count; i++) {
diff --git a/core/java/android/view/ViewParent.java b/core/java/android/view/ViewParent.java
index 873d4bb..8395f1b 100644
--- a/core/java/android/view/ViewParent.java
+++ b/core/java/android/view/ViewParent.java
@@ -261,4 +261,14 @@
* @return True if the event was sent.
*/
public boolean requestSendAccessibilityEvent(View child, AccessibilityEvent event);
+
+ /**
+ * Called when a child view now has or no longer is tracking transient state.
+ *
+ * @param child Child view whose state has changed
+ * @param hasTransientState true if this child has transient state
+ *
+ * @hide
+ */
+ public void childHasTransientStateChanged(View child, boolean hasTransientState);
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index fbcb423..28737fc 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -61,6 +61,7 @@
import android.util.Pools;
import android.util.Slog;
import android.util.TypedValue;
+import android.view.View.AttachInfo;
import android.view.View.MeasureSpec;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityInteractionClient;
@@ -96,7 +97,7 @@
* {@hide}
*/
@SuppressWarnings({"EmptyCatchBlock", "PointlessBooleanExpression"})
-public final class ViewRootImpl extends Handler implements ViewParent,
+public final class ViewRootImpl implements ViewParent,
View.AttachInfo.Callbacks, HardwareRenderer.HardwareDrawCallbacks {
private static final String TAG = "ViewRootImpl";
private static final boolean DBG = false;
@@ -212,6 +213,7 @@
final Rect mVisRect; // used to retrieve visible rect of focused view.
boolean mTraversalScheduled;
+ int mTraversalBarrier;
long mLastTraversalFinishedTimeNanos;
long mLastDrawFinishedTimeNanos;
boolean mWillDrawSoon;
@@ -379,7 +381,7 @@
new AccessibilityInteractionConnectionManager();
mAccessibilityManager.addAccessibilityStateChangeListener(
mAccessibilityInteractionConnectionManager);
- mAttachInfo = new View.AttachInfo(sWindowSession, mWindow, this, this);
+ mAttachInfo = new View.AttachInfo(sWindowSession, mWindow, this, mHandler, this);
mViewConfiguration = ViewConfiguration.get(context);
mDensity = context.getResources().getDisplayMetrics().densityDpi;
mFallbackEventHandler = PolicyManager.makeNewFallbackEventHandler(context);
@@ -838,22 +840,28 @@
public void scheduleTraversals() {
if (!mTraversalScheduled) {
mTraversalScheduled = true;
+ mTraversalBarrier = mHandler.getLooper().postSyncBarrier();
scheduleFrame();
}
}
public void unscheduleTraversals() {
- mTraversalScheduled = false;
+ if (mTraversalScheduled) {
+ mTraversalScheduled = false;
+ mHandler.getLooper().removeSyncBarrier(mTraversalBarrier);
+ }
}
void scheduleFrame() {
if (!mFrameScheduled) {
- mChoreographer.postDrawCallback(mFrameRunnable);
mFrameScheduled = true;
+ mChoreographer.postDrawCallback(mFrameRunnable);
}
}
void unscheduleFrame() {
+ unscheduleTraversals();
+
if (mFrameScheduled) {
mFrameScheduled = false;
mChoreographer.removeDrawCallback(mFrameRunnable);
@@ -868,6 +876,7 @@
if (mTraversalScheduled) {
mTraversalScheduled = false;
+ mHandler.getLooper().removeSyncBarrier(mTraversalBarrier);
doTraversal();
}
}
@@ -1929,7 +1938,7 @@
sFirstDrawComplete = true;
final int count = sFirstDrawHandlers.size();
for (int i = 0; i< count; i++) {
- post(sFirstDrawHandlers.get(i));
+ mHandler.post(sFirstDrawHandlers.get(i));
}
}
}
@@ -2441,283 +2450,289 @@
}
}
- public final static int DIE = 1001;
- public final static int RESIZED = 1002;
- public final static int RESIZED_REPORT = 1003;
- public final static int WINDOW_FOCUS_CHANGED = 1004;
- public final static int DISPATCH_KEY = 1005;
- public final static int DISPATCH_APP_VISIBILITY = 1008;
- public final static int DISPATCH_GET_NEW_SURFACE = 1009;
- public final static int IME_FINISHED_EVENT = 1010;
- public final static int DISPATCH_KEY_FROM_IME = 1011;
- public final static int FINISH_INPUT_CONNECTION = 1012;
- public final static int CHECK_FOCUS = 1013;
- public final static int CLOSE_SYSTEM_DIALOGS = 1014;
- public final static int DISPATCH_DRAG_EVENT = 1015;
- public final static int DISPATCH_DRAG_LOCATION_EVENT = 1016;
- public final static int DISPATCH_SYSTEM_UI_VISIBILITY = 1017;
- public final static int DISPATCH_GENERIC_MOTION = 1018;
- public final static int UPDATE_CONFIGURATION = 1019;
- public final static int DO_PERFORM_ACCESSIBILITY_ACTION = 1020;
- public final static int DO_FIND_ACCESSIBLITY_NODE_INFO_BY_ACCESSIBILITY_ID = 1021;
- public final static int DO_FIND_ACCESSIBLITY_NODE_INFO_BY_VIEW_ID = 1022;
- public final static int DO_FIND_ACCESSIBLITY_NODE_INFO_BY_TEXT = 1023;
- public final static int DO_PROCESS_INPUT_EVENTS = 1024;
+ private final static int MSG_INVALIDATE = 1;
+ private final static int MSG_INVALIDATE_RECT = 2;
+ private final static int MSG_DIE = 3;
+ private final static int MSG_RESIZED = 4;
+ private final static int MSG_RESIZED_REPORT = 5;
+ private final static int MSG_WINDOW_FOCUS_CHANGED = 6;
+ private final static int MSG_DISPATCH_KEY = 7;
+ private final static int MSG_DISPATCH_APP_VISIBILITY = 8;
+ private final static int MSG_DISPATCH_GET_NEW_SURFACE = 9;
+ private final static int MSG_IME_FINISHED_EVENT = 10;
+ private final static int MSG_DISPATCH_KEY_FROM_IME = 11;
+ private final static int MSG_FINISH_INPUT_CONNECTION = 12;
+ private final static int MSG_CHECK_FOCUS = 13;
+ private final static int MSG_CLOSE_SYSTEM_DIALOGS = 14;
+ private final static int MSG_DISPATCH_DRAG_EVENT = 15;
+ private final static int MSG_DISPATCH_DRAG_LOCATION_EVENT = 16;
+ private final static int MSG_DISPATCH_SYSTEM_UI_VISIBILITY = 17;
+ private final static int MSG_UPDATE_CONFIGURATION = 18;
+ private final static int MSG_PERFORM_ACCESSIBILITY_ACTION = 19;
+ private final static int MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_ACCESSIBILITY_ID = 20;
+ private final static int MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_VIEW_ID = 21;
+ private final static int MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_TEXT = 22;
+ private final static int MSG_PROCESS_INPUT_EVENTS = 23;
- @Override
- public String getMessageName(Message message) {
- switch (message.what) {
- case DIE:
- return "DIE";
- case RESIZED:
- return "RESIZED";
- case RESIZED_REPORT:
- return "RESIZED_REPORT";
- case WINDOW_FOCUS_CHANGED:
- return "WINDOW_FOCUS_CHANGED";
- case DISPATCH_KEY:
- return "DISPATCH_KEY";
- case DISPATCH_APP_VISIBILITY:
- return "DISPATCH_APP_VISIBILITY";
- case DISPATCH_GET_NEW_SURFACE:
- return "DISPATCH_GET_NEW_SURFACE";
- case IME_FINISHED_EVENT:
- return "IME_FINISHED_EVENT";
- case DISPATCH_KEY_FROM_IME:
- return "DISPATCH_KEY_FROM_IME";
- case FINISH_INPUT_CONNECTION:
- return "FINISH_INPUT_CONNECTION";
- case CHECK_FOCUS:
- return "CHECK_FOCUS";
- case CLOSE_SYSTEM_DIALOGS:
- return "CLOSE_SYSTEM_DIALOGS";
- case DISPATCH_DRAG_EVENT:
- return "DISPATCH_DRAG_EVENT";
- case DISPATCH_DRAG_LOCATION_EVENT:
- return "DISPATCH_DRAG_LOCATION_EVENT";
- case DISPATCH_SYSTEM_UI_VISIBILITY:
- return "DISPATCH_SYSTEM_UI_VISIBILITY";
- case DISPATCH_GENERIC_MOTION:
- return "DISPATCH_GENERIC_MOTION";
- case UPDATE_CONFIGURATION:
- return "UPDATE_CONFIGURATION";
- case DO_PERFORM_ACCESSIBILITY_ACTION:
- return "DO_PERFORM_ACCESSIBILITY_ACTION";
- case DO_FIND_ACCESSIBLITY_NODE_INFO_BY_ACCESSIBILITY_ID:
- return "DO_FIND_ACCESSIBLITY_NODE_INFO_BY_ACCESSIBILITY_ID";
- case DO_FIND_ACCESSIBLITY_NODE_INFO_BY_VIEW_ID:
- return "DO_FIND_ACCESSIBLITY_NODE_INFO_BY_VIEW_ID";
- case DO_FIND_ACCESSIBLITY_NODE_INFO_BY_TEXT:
- return "DO_FIND_ACCESSIBLITY_NODE_INFO_BY_TEXT";
- case DO_PROCESS_INPUT_EVENTS:
- return "DO_PROCESS_INPUT_EVENTS";
+ final class ViewRootHandler extends Handler {
+ @Override
+ public String getMessageName(Message message) {
+ switch (message.what) {
+ case MSG_INVALIDATE:
+ return "MSG_INVALIDATE";
+ case MSG_INVALIDATE_RECT:
+ return "MSG_INVALIDATE_RECT";
+ case MSG_DIE:
+ return "MSG_DIE";
+ case MSG_RESIZED:
+ return "MSG_RESIZED";
+ case MSG_RESIZED_REPORT:
+ return "MSG_RESIZED_REPORT";
+ case MSG_WINDOW_FOCUS_CHANGED:
+ return "MSG_WINDOW_FOCUS_CHANGED";
+ case MSG_DISPATCH_KEY:
+ return "MSG_DISPATCH_KEY";
+ case MSG_DISPATCH_APP_VISIBILITY:
+ return "MSG_DISPATCH_APP_VISIBILITY";
+ case MSG_DISPATCH_GET_NEW_SURFACE:
+ return "MSG_DISPATCH_GET_NEW_SURFACE";
+ case MSG_IME_FINISHED_EVENT:
+ return "MSG_IME_FINISHED_EVENT";
+ case MSG_DISPATCH_KEY_FROM_IME:
+ return "MSG_DISPATCH_KEY_FROM_IME";
+ case MSG_FINISH_INPUT_CONNECTION:
+ return "MSG_FINISH_INPUT_CONNECTION";
+ case MSG_CHECK_FOCUS:
+ return "MSG_CHECK_FOCUS";
+ case MSG_CLOSE_SYSTEM_DIALOGS:
+ return "MSG_CLOSE_SYSTEM_DIALOGS";
+ case MSG_DISPATCH_DRAG_EVENT:
+ return "MSG_DISPATCH_DRAG_EVENT";
+ case MSG_DISPATCH_DRAG_LOCATION_EVENT:
+ return "MSG_DISPATCH_DRAG_LOCATION_EVENT";
+ case MSG_DISPATCH_SYSTEM_UI_VISIBILITY:
+ return "MSG_DISPATCH_SYSTEM_UI_VISIBILITY";
+ case MSG_UPDATE_CONFIGURATION:
+ return "MSG_UPDATE_CONFIGURATION";
+ case MSG_PERFORM_ACCESSIBILITY_ACTION:
+ return "MSG_PERFORM_ACCESSIBILITY_ACTION";
+ case MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_ACCESSIBILITY_ID:
+ return "MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_ACCESSIBILITY_ID";
+ case MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_VIEW_ID:
+ return "MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_VIEW_ID";
+ case MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_TEXT:
+ return "MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_TEXT";
+ case MSG_PROCESS_INPUT_EVENTS:
+ return "MSG_PROCESS_INPUT_EVENTS";
+ }
+ return super.getMessageName(message);
}
- return super.getMessageName(message);
- }
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case View.AttachInfo.INVALIDATE_MSG:
- ((View) msg.obj).invalidate();
- break;
- case View.AttachInfo.INVALIDATE_RECT_MSG:
- final View.AttachInfo.InvalidateInfo info = (View.AttachInfo.InvalidateInfo) msg.obj;
- info.target.invalidate(info.left, info.top, info.right, info.bottom);
- info.release();
- break;
- case IME_FINISHED_EVENT:
- handleImeFinishedEvent(msg.arg1, msg.arg2 != 0);
- break;
- case DO_PROCESS_INPUT_EVENTS:
- mProcessInputEventsScheduled = false;
- doProcessInputEvents();
- break;
- case DISPATCH_APP_VISIBILITY:
- handleAppVisibility(msg.arg1 != 0);
- break;
- case DISPATCH_GET_NEW_SURFACE:
- handleGetNewSurface();
- break;
- case RESIZED:
- ResizedInfo ri = (ResizedInfo)msg.obj;
-
- if (mWinFrame.width() == msg.arg1 && mWinFrame.height() == msg.arg2
- && mPendingContentInsets.equals(ri.coveredInsets)
- && mPendingVisibleInsets.equals(ri.visibleInsets)
- && ((ResizedInfo)msg.obj).newConfig == null) {
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_INVALIDATE:
+ ((View) msg.obj).invalidate();
break;
- }
- // fall through...
- case RESIZED_REPORT:
- if (mAdded) {
- Configuration config = ((ResizedInfo)msg.obj).newConfig;
- if (config != null) {
- updateConfiguration(config, false);
- }
- mWinFrame.left = 0;
- mWinFrame.right = msg.arg1;
- mWinFrame.top = 0;
- mWinFrame.bottom = msg.arg2;
- mPendingContentInsets.set(((ResizedInfo)msg.obj).coveredInsets);
- mPendingVisibleInsets.set(((ResizedInfo)msg.obj).visibleInsets);
- if (msg.what == RESIZED_REPORT) {
- mReportNextDraw = true;
- }
+ case MSG_INVALIDATE_RECT:
+ final View.AttachInfo.InvalidateInfo info = (View.AttachInfo.InvalidateInfo) msg.obj;
+ info.target.invalidate(info.left, info.top, info.right, info.bottom);
+ info.release();
+ break;
+ case MSG_IME_FINISHED_EVENT:
+ handleImeFinishedEvent(msg.arg1, msg.arg2 != 0);
+ break;
+ case MSG_PROCESS_INPUT_EVENTS:
+ mProcessInputEventsScheduled = false;
+ doProcessInputEvents();
+ break;
+ case MSG_DISPATCH_APP_VISIBILITY:
+ handleAppVisibility(msg.arg1 != 0);
+ break;
+ case MSG_DISPATCH_GET_NEW_SURFACE:
+ handleGetNewSurface();
+ break;
+ case MSG_RESIZED:
+ ResizedInfo ri = (ResizedInfo)msg.obj;
- if (mView != null) {
- forceLayout(mView);
+ if (mWinFrame.width() == msg.arg1 && mWinFrame.height() == msg.arg2
+ && mPendingContentInsets.equals(ri.coveredInsets)
+ && mPendingVisibleInsets.equals(ri.visibleInsets)
+ && ((ResizedInfo)msg.obj).newConfig == null) {
+ break;
}
- requestLayout();
- }
- break;
- case WINDOW_FOCUS_CHANGED: {
- if (mAdded) {
- boolean hasWindowFocus = msg.arg1 != 0;
- mAttachInfo.mHasWindowFocus = hasWindowFocus;
-
- profileRendering(hasWindowFocus);
+ // fall through...
+ case MSG_RESIZED_REPORT:
+ if (mAdded) {
+ Configuration config = ((ResizedInfo)msg.obj).newConfig;
+ if (config != null) {
+ updateConfiguration(config, false);
+ }
+ mWinFrame.left = 0;
+ mWinFrame.right = msg.arg1;
+ mWinFrame.top = 0;
+ mWinFrame.bottom = msg.arg2;
+ mPendingContentInsets.set(((ResizedInfo)msg.obj).coveredInsets);
+ mPendingVisibleInsets.set(((ResizedInfo)msg.obj).visibleInsets);
+ if (msg.what == MSG_RESIZED_REPORT) {
+ mReportNextDraw = true;
+ }
- if (hasWindowFocus) {
- boolean inTouchMode = msg.arg2 != 0;
- ensureTouchModeLocally(inTouchMode);
+ if (mView != null) {
+ forceLayout(mView);
+ }
+ requestLayout();
+ }
+ break;
+ case MSG_WINDOW_FOCUS_CHANGED: {
+ if (mAdded) {
+ boolean hasWindowFocus = msg.arg1 != 0;
+ mAttachInfo.mHasWindowFocus = hasWindowFocus;
- if (mAttachInfo.mHardwareRenderer != null &&
- mSurface != null && mSurface.isValid()) {
- mFullRedrawNeeded = true;
- try {
- mAttachInfo.mHardwareRenderer.initializeIfNeeded(mWidth, mHeight,
- mHolder);
- } catch (Surface.OutOfResourcesException e) {
- Log.e(TAG, "OutOfResourcesException locking surface", e);
+ profileRendering(hasWindowFocus);
+
+ if (hasWindowFocus) {
+ boolean inTouchMode = msg.arg2 != 0;
+ ensureTouchModeLocally(inTouchMode);
+
+ if (mAttachInfo.mHardwareRenderer != null &&
+ mSurface != null && mSurface.isValid()) {
+ mFullRedrawNeeded = true;
try {
- if (!sWindowSession.outOfMemory(mWindow)) {
- Slog.w(TAG, "No processes killed for memory; killing self");
- Process.killProcess(Process.myPid());
+ mAttachInfo.mHardwareRenderer.initializeIfNeeded(mWidth, mHeight,
+ mHolder);
+ } catch (Surface.OutOfResourcesException e) {
+ Log.e(TAG, "OutOfResourcesException locking surface", e);
+ try {
+ if (!sWindowSession.outOfMemory(mWindow)) {
+ Slog.w(TAG, "No processes killed for memory; killing self");
+ Process.killProcess(Process.myPid());
+ }
+ } catch (RemoteException ex) {
}
- } catch (RemoteException ex) {
+ // Retry in a bit.
+ sendMessageDelayed(obtainMessage(msg.what, msg.arg1, msg.arg2), 500);
+ return;
}
- // Retry in a bit.
- sendMessageDelayed(obtainMessage(msg.what, msg.arg1, msg.arg2), 500);
- return;
}
}
- }
- mLastWasImTarget = WindowManager.LayoutParams
- .mayUseInputMethod(mWindowAttributes.flags);
+ mLastWasImTarget = WindowManager.LayoutParams
+ .mayUseInputMethod(mWindowAttributes.flags);
- InputMethodManager imm = InputMethodManager.peekInstance();
- if (mView != null) {
- if (hasWindowFocus && imm != null && mLastWasImTarget) {
- imm.startGettingWindowFocus(mView);
+ InputMethodManager imm = InputMethodManager.peekInstance();
+ if (mView != null) {
+ if (hasWindowFocus && imm != null && mLastWasImTarget) {
+ imm.startGettingWindowFocus(mView);
+ }
+ mAttachInfo.mKeyDispatchState.reset();
+ mView.dispatchWindowFocusChanged(hasWindowFocus);
}
- mAttachInfo.mKeyDispatchState.reset();
- mView.dispatchWindowFocusChanged(hasWindowFocus);
- }
- // Note: must be done after the focus change callbacks,
- // so all of the view state is set up correctly.
- if (hasWindowFocus) {
- if (imm != null && mLastWasImTarget) {
- imm.onWindowFocus(mView, mView.findFocus(),
- mWindowAttributes.softInputMode,
- !mHasHadWindowFocus, mWindowAttributes.flags);
- }
- // Clear the forward bit. We can just do this directly, since
- // the window manager doesn't care about it.
- mWindowAttributes.softInputMode &=
- ~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION;
- ((WindowManager.LayoutParams)mView.getLayoutParams())
- .softInputMode &=
+ // Note: must be done after the focus change callbacks,
+ // so all of the view state is set up correctly.
+ if (hasWindowFocus) {
+ if (imm != null && mLastWasImTarget) {
+ imm.onWindowFocus(mView, mView.findFocus(),
+ mWindowAttributes.softInputMode,
+ !mHasHadWindowFocus, mWindowAttributes.flags);
+ }
+ // Clear the forward bit. We can just do this directly, since
+ // the window manager doesn't care about it.
+ mWindowAttributes.softInputMode &=
~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION;
- mHasHadWindowFocus = true;
- }
+ ((WindowManager.LayoutParams)mView.getLayoutParams())
+ .softInputMode &=
+ ~WindowManager.LayoutParams.SOFT_INPUT_IS_FORWARD_NAVIGATION;
+ mHasHadWindowFocus = true;
+ }
- if (hasWindowFocus && mView != null) {
- sendAccessibilityEvents();
+ if (hasWindowFocus && mView != null && mAccessibilityManager.isEnabled()) {
+ mView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
+ }
}
+ } break;
+ case MSG_DIE:
+ doDie();
+ break;
+ case MSG_DISPATCH_KEY: {
+ KeyEvent event = (KeyEvent)msg.obj;
+ enqueueInputEvent(event, null, 0, true);
+ } break;
+ case MSG_DISPATCH_KEY_FROM_IME: {
+ if (LOCAL_LOGV) Log.v(
+ TAG, "Dispatching key "
+ + msg.obj + " from IME to " + mView);
+ KeyEvent event = (KeyEvent)msg.obj;
+ if ((event.getFlags()&KeyEvent.FLAG_FROM_SYSTEM) != 0) {
+ // The IME is trying to say this event is from the
+ // system! Bad bad bad!
+ //noinspection UnusedAssignment
+ event = KeyEvent.changeFlags(event, event.getFlags() & ~KeyEvent.FLAG_FROM_SYSTEM);
+ }
+ enqueueInputEvent(event, null, QueuedInputEvent.FLAG_DELIVER_POST_IME, true);
+ } break;
+ case MSG_FINISH_INPUT_CONNECTION: {
+ InputMethodManager imm = InputMethodManager.peekInstance();
+ if (imm != null) {
+ imm.reportFinishInputConnection((InputConnection)msg.obj);
+ }
+ } break;
+ case MSG_CHECK_FOCUS: {
+ InputMethodManager imm = InputMethodManager.peekInstance();
+ if (imm != null) {
+ imm.checkFocus();
+ }
+ } break;
+ case MSG_CLOSE_SYSTEM_DIALOGS: {
+ if (mView != null) {
+ mView.onCloseSystemDialogs((String)msg.obj);
+ }
+ } break;
+ case MSG_DISPATCH_DRAG_EVENT:
+ case MSG_DISPATCH_DRAG_LOCATION_EVENT: {
+ DragEvent event = (DragEvent)msg.obj;
+ event.mLocalState = mLocalDragState; // only present when this app called startDrag()
+ handleDragEvent(event);
+ } break;
+ case MSG_DISPATCH_SYSTEM_UI_VISIBILITY: {
+ handleDispatchSystemUiVisibilityChanged((SystemUiVisibilityInfo)msg.obj);
+ } break;
+ case MSG_UPDATE_CONFIGURATION: {
+ Configuration config = (Configuration)msg.obj;
+ if (config.isOtherSeqNewer(mLastConfiguration)) {
+ config = mLastConfiguration;
+ }
+ updateConfiguration(config, false);
+ } break;
+ case MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_ACCESSIBILITY_ID: {
+ if (mView != null) {
+ getAccessibilityInteractionController()
+ .findAccessibilityNodeInfoByAccessibilityIdUiThread(msg);
+ }
+ } break;
+ case MSG_PERFORM_ACCESSIBILITY_ACTION: {
+ if (mView != null) {
+ getAccessibilityInteractionController()
+ .perfromAccessibilityActionUiThread(msg);
+ }
+ } break;
+ case MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_VIEW_ID: {
+ if (mView != null) {
+ getAccessibilityInteractionController()
+ .findAccessibilityNodeInfoByViewIdUiThread(msg);
+ }
+ } break;
+ case MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_TEXT: {
+ if (mView != null) {
+ getAccessibilityInteractionController()
+ .findAccessibilityNodeInfosByTextUiThread(msg);
+ }
+ } break;
}
- } break;
- case DIE:
- doDie();
- break;
- case DISPATCH_KEY: {
- KeyEvent event = (KeyEvent)msg.obj;
- enqueueInputEvent(event, null, 0, true);
- } break;
- case DISPATCH_KEY_FROM_IME: {
- if (LOCAL_LOGV) Log.v(
- TAG, "Dispatching key "
- + msg.obj + " from IME to " + mView);
- KeyEvent event = (KeyEvent)msg.obj;
- if ((event.getFlags()&KeyEvent.FLAG_FROM_SYSTEM) != 0) {
- // The IME is trying to say this event is from the
- // system! Bad bad bad!
- //noinspection UnusedAssignment
- event = KeyEvent.changeFlags(event, event.getFlags() & ~KeyEvent.FLAG_FROM_SYSTEM);
- }
- enqueueInputEvent(event, null, QueuedInputEvent.FLAG_DELIVER_POST_IME, true);
- } break;
- case FINISH_INPUT_CONNECTION: {
- InputMethodManager imm = InputMethodManager.peekInstance();
- if (imm != null) {
- imm.reportFinishInputConnection((InputConnection)msg.obj);
- }
- } break;
- case CHECK_FOCUS: {
- InputMethodManager imm = InputMethodManager.peekInstance();
- if (imm != null) {
- imm.checkFocus();
- }
- } break;
- case CLOSE_SYSTEM_DIALOGS: {
- if (mView != null) {
- mView.onCloseSystemDialogs((String)msg.obj);
- }
- } break;
- case DISPATCH_DRAG_EVENT:
- case DISPATCH_DRAG_LOCATION_EVENT: {
- DragEvent event = (DragEvent)msg.obj;
- event.mLocalState = mLocalDragState; // only present when this app called startDrag()
- handleDragEvent(event);
- } break;
- case DISPATCH_SYSTEM_UI_VISIBILITY: {
- handleDispatchSystemUiVisibilityChanged((SystemUiVisibilityInfo)msg.obj);
- } break;
- case UPDATE_CONFIGURATION: {
- Configuration config = (Configuration)msg.obj;
- if (config.isOtherSeqNewer(mLastConfiguration)) {
- config = mLastConfiguration;
- }
- updateConfiguration(config, false);
- } break;
- case DO_FIND_ACCESSIBLITY_NODE_INFO_BY_ACCESSIBILITY_ID: {
- if (mView != null) {
- getAccessibilityInteractionController()
- .findAccessibilityNodeInfoByAccessibilityIdUiThread(msg);
- }
- } break;
- case DO_PERFORM_ACCESSIBILITY_ACTION: {
- if (mView != null) {
- getAccessibilityInteractionController()
- .perfromAccessibilityActionUiThread(msg);
- }
- } break;
- case DO_FIND_ACCESSIBLITY_NODE_INFO_BY_VIEW_ID: {
- if (mView != null) {
- getAccessibilityInteractionController()
- .findAccessibilityNodeInfoByViewIdUiThread(msg);
- }
- } break;
- case DO_FIND_ACCESSIBLITY_NODE_INFO_BY_TEXT: {
- if (mView != null) {
- getAccessibilityInteractionController()
- .findAccessibilityNodeInfosByTextUiThread(msg);
- }
- } break;
}
}
+ final ViewRootHandler mHandler = new ViewRootHandler();
/**
* Something in the current window tells us we need to change the touch mode. For
@@ -3684,7 +3699,7 @@
if (immediate) {
doDie();
} else {
- sendEmptyMessage(DIE);
+ mHandler.sendEmptyMessage(MSG_DIE);
}
}
@@ -3721,8 +3736,8 @@
}
public void requestUpdateConfiguration(Configuration config) {
- Message msg = obtainMessage(UPDATE_CONFIGURATION, config);
- sendMessage(msg);
+ Message msg = mHandler.obtainMessage(MSG_UPDATE_CONFIGURATION, config);
+ mHandler.sendMessage(msg);
}
private void destroyHardwareRenderer() {
@@ -3734,10 +3749,15 @@
}
void dispatchImeFinishedEvent(int seq, boolean handled) {
- Message msg = obtainMessage(IME_FINISHED_EVENT);
+ Message msg = mHandler.obtainMessage(MSG_IME_FINISHED_EVENT);
msg.arg1 = seq;
msg.arg2 = handled ? 1 : 0;
- sendMessage(msg);
+ mHandler.sendMessage(msg);
+ }
+
+ public void dispatchFinishInputConnection(InputConnection connection) {
+ Message msg = mHandler.obtainMessage(MSG_FINISH_INPUT_CONNECTION, connection);
+ mHandler.sendMessage(msg);
}
public void dispatchResized(int w, int h, Rect coveredInsets,
@@ -3746,7 +3766,7 @@
+ " h=" + h + " coveredInsets=" + coveredInsets.toShortString()
+ " visibleInsets=" + visibleInsets.toShortString()
+ " reportDraw=" + reportDraw);
- Message msg = obtainMessage(reportDraw ? RESIZED_REPORT :RESIZED);
+ Message msg = mHandler.obtainMessage(reportDraw ? MSG_RESIZED_REPORT :MSG_RESIZED);
if (mTranslator != null) {
mTranslator.translateRectInScreenToAppWindow(coveredInsets);
mTranslator.translateRectInScreenToAppWindow(visibleInsets);
@@ -3760,7 +3780,7 @@
ri.visibleInsets = new Rect(visibleInsets);
ri.newConfig = newConfig;
msg.obj = ri;
- sendMessage(msg);
+ mHandler.sendMessage(msg);
}
/**
@@ -3857,7 +3877,7 @@
private void scheduleProcessInputEvents() {
if (!mProcessInputEventsScheduled) {
mProcessInputEventsScheduled = true;
- sendEmptyMessage(DO_PROCESS_INPUT_EVENTS);
+ mHandler.sendEmptyMessage(MSG_PROCESS_INPUT_EVENTS);
}
}
@@ -3874,7 +3894,7 @@
// so we can clear the pending flag immediately.
if (mProcessInputEventsScheduled) {
mProcessInputEventsScheduled = false;
- removeMessages(DO_PROCESS_INPUT_EVENTS);
+ mHandler.removeMessages(MSG_PROCESS_INPUT_EVENTS);
}
}
@@ -3960,47 +3980,69 @@
}
WindowInputEventReceiver mInputEventReceiver;
+ public void dispatchInvalidateDelayed(View view, long delayMilliseconds) {
+ Message msg = mHandler.obtainMessage(MSG_INVALIDATE, view);
+ mHandler.sendMessageDelayed(msg, delayMilliseconds);
+ }
+
+ public void cancelInvalidate(View view) {
+ mHandler.removeMessages(MSG_INVALIDATE, view);
+ }
+
+ public void dispatchInvalidateRectDelayed(AttachInfo.InvalidateInfo info,
+ long delayMilliseconds) {
+ final Message msg = mHandler.obtainMessage(MSG_INVALIDATE_RECT, info);
+ mHandler.sendMessageDelayed(msg, delayMilliseconds);
+ }
+
public void dispatchKey(KeyEvent event) {
- Message msg = obtainMessage(DISPATCH_KEY, event);
- sendMessage(msg);
+ Message msg = mHandler.obtainMessage(MSG_DISPATCH_KEY, event);
+ msg.setAsynchronous(true);
+ mHandler.sendMessage(msg);
+ }
+
+ public void dispatchKeyFromIme(KeyEvent event) {
+ Message msg = mHandler.obtainMessage(MSG_DISPATCH_KEY_FROM_IME, event);
+ msg.setAsynchronous(true);
+ mHandler.sendMessage(msg);
}
public void dispatchAppVisibility(boolean visible) {
- Message msg = obtainMessage(DISPATCH_APP_VISIBILITY);
+ Message msg = mHandler.obtainMessage(MSG_DISPATCH_APP_VISIBILITY);
msg.arg1 = visible ? 1 : 0;
- sendMessage(msg);
+ mHandler.sendMessage(msg);
}
public void dispatchGetNewSurface() {
- Message msg = obtainMessage(DISPATCH_GET_NEW_SURFACE);
- sendMessage(msg);
+ Message msg = mHandler.obtainMessage(MSG_DISPATCH_GET_NEW_SURFACE);
+ mHandler.sendMessage(msg);
}
public void windowFocusChanged(boolean hasFocus, boolean inTouchMode) {
Message msg = Message.obtain();
- msg.what = WINDOW_FOCUS_CHANGED;
+ msg.what = MSG_WINDOW_FOCUS_CHANGED;
msg.arg1 = hasFocus ? 1 : 0;
msg.arg2 = inTouchMode ? 1 : 0;
- sendMessage(msg);
+ mHandler.sendMessage(msg);
}
public void dispatchCloseSystemDialogs(String reason) {
Message msg = Message.obtain();
- msg.what = CLOSE_SYSTEM_DIALOGS;
+ msg.what = MSG_CLOSE_SYSTEM_DIALOGS;
msg.obj = reason;
- sendMessage(msg);
+ mHandler.sendMessage(msg);
}
public void dispatchDragEvent(DragEvent event) {
final int what;
if (event.getAction() == DragEvent.ACTION_DRAG_LOCATION) {
- what = DISPATCH_DRAG_LOCATION_EVENT;
- removeMessages(what);
+ what = MSG_DISPATCH_DRAG_LOCATION_EVENT;
+ mHandler.removeMessages(what);
} else {
- what = DISPATCH_DRAG_EVENT;
+ what = MSG_DISPATCH_DRAG_EVENT;
}
- Message msg = obtainMessage(what, event);
- sendMessage(msg);
+ Message msg = mHandler.obtainMessage(what, event);
+ mHandler.sendMessage(msg);
}
public void dispatchSystemUiVisibilityChanged(int seq, int globalVisibility,
@@ -4010,21 +4052,13 @@
args.globalVisibility = globalVisibility;
args.localValue = localValue;
args.localChanges = localChanges;
- sendMessage(obtainMessage(DISPATCH_SYSTEM_UI_VISIBILITY, args));
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_DISPATCH_SYSTEM_UI_VISIBILITY, args));
}
- /**
- * The window is getting focus so if there is anything focused/selected
- * send an {@link AccessibilityEvent} to announce that.
- */
- private void sendAccessibilityEvents() {
- if (!mAccessibilityManager.isEnabled()) {
- return;
- }
- mView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
- View focusedView = mView.findFocus();
- if (focusedView != null && focusedView != mView) {
- focusedView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
+ public void dispatchCheckFocus() {
+ if (!mHandler.hasMessages(MSG_CHECK_FOCUS)) {
+ // This will result in a call to checkFocus() below.
+ mHandler.sendEmptyMessage(MSG_CHECK_FOCUS);
}
}
@@ -4041,7 +4075,7 @@
}
if (!mSendWindowContentChangedAccessibilityEvent.mIsPending) {
mSendWindowContentChangedAccessibilityEvent.mIsPending = true;
- postDelayed(mSendWindowContentChangedAccessibilityEvent,
+ mHandler.postDelayed(mSendWindowContentChangedAccessibilityEvent,
ViewConfiguration.getSendRecurringAccessibilityEventsInterval());
}
}
@@ -4052,7 +4086,7 @@
*/
private void removeSendWindowContentChangedCallback() {
if (mSendWindowContentChangedAccessibilityEvent != null) {
- removeCallbacks(mSendWindowContentChangedAccessibilityEvent);
+ mHandler.removeCallbacks(mSendWindowContentChangedAccessibilityEvent);
}
}
@@ -4095,6 +4129,10 @@
return scrollToRectOrFocus(rectangle, immediate);
}
+ public void childHasTransientStateChanged(View child, boolean hasTransientState) {
+ // Do nothing.
+ }
+
class TakenSurfaceHolder extends BaseSurfaceHolder {
@Override
public boolean onAllowLockCanvas() {
@@ -4512,6 +4550,9 @@
}
/**
+ * The run queue is used to enqueue pending work from Views when no Handler is
+ * attached. The work is executed during the next call to performTraversals on
+ * the thread.
* @hide
*/
static final class RunQueue {
@@ -4590,24 +4631,35 @@
public void onAccessibilityStateChanged(boolean enabled) {
if (enabled) {
ensureConnection();
+ if (mAttachInfo != null && mAttachInfo.mHasWindowFocus) {
+ mView.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
+ View focusedView = mView.findFocus();
+ if (focusedView != null && focusedView != mView) {
+ focusedView.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
+ }
+ }
} else {
ensureNoConnection();
}
}
public void ensureConnection() {
- final boolean registered = mAttachInfo.mAccessibilityWindowId != View.NO_ID;
- if (!registered) {
- mAttachInfo.mAccessibilityWindowId =
- mAccessibilityManager.addAccessibilityInteractionConnection(mWindow,
- new AccessibilityInteractionConnection(ViewRootImpl.this));
+ if (mAttachInfo != null) {
+ final boolean registered =
+ mAttachInfo.mAccessibilityWindowId != AccessibilityNodeInfo.UNDEFINED;
+ if (!registered) {
+ mAttachInfo.mAccessibilityWindowId =
+ mAccessibilityManager.addAccessibilityInteractionConnection(mWindow,
+ new AccessibilityInteractionConnection(ViewRootImpl.this));
+ }
}
}
public void ensureNoConnection() {
- final boolean registered = mAttachInfo.mAccessibilityWindowId != View.NO_ID;
+ final boolean registered =
+ mAttachInfo.mAccessibilityWindowId != AccessibilityNodeInfo.UNDEFINED;
if (registered) {
- mAttachInfo.mAccessibilityWindowId = View.NO_ID;
+ mAttachInfo.mAccessibilityWindowId = AccessibilityNodeInfo.UNDEFINED;
mAccessibilityManager.removeAccessibilityInteractionConnection(mWindow);
}
}
@@ -4770,8 +4822,8 @@
long accessibilityNodeId, int interactionId,
IAccessibilityInteractionConnectionCallback callback, int interrogatingPid,
long interrogatingTid) {
- Message message = Message.obtain();
- message.what = DO_FIND_ACCESSIBLITY_NODE_INFO_BY_ACCESSIBILITY_ID;
+ Message message = mHandler.obtainMessage();
+ message.what = MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_ACCESSIBILITY_ID;
message.arg1 = interrogatingPid;
SomeArgs args = mPool.acquire();
args.argi1 = AccessibilityNodeInfo.getAccessibilityViewId(accessibilityNodeId);
@@ -4785,11 +4837,10 @@
// client can handle the message to generate the result.
if (interrogatingPid == Process.myPid()
&& interrogatingTid == Looper.getMainLooper().getThread().getId()) {
- message.setTarget(ViewRootImpl.this);
AccessibilityInteractionClient.getInstanceForThread(
interrogatingTid).setSameThreadMessage(message);
} else {
- sendMessage(message);
+ mHandler.sendMessage(message);
}
}
@@ -4805,14 +4856,21 @@
List<AccessibilityNodeInfo> infos = mTempAccessibilityNodeInfoList;
infos.clear();
try {
- View target = findViewByAccessibilityId(accessibilityViewId);
- if (target != null && target.getVisibility() == View.VISIBLE) {
- AccessibilityNodeProvider provider = target.getAccessibilityNodeProvider();
- if (provider != null) {
- infos.add(provider.createAccessibilityNodeInfo(virtualDescendantId));
- } else if (virtualDescendantId == View.NO_ID) {
- getAccessibilityPrefetchStrategy().prefetchAccessibilityNodeInfos(
- interrogatingPid, target, infos);
+ if (accessibilityViewId == AccessibilityNodeInfo.UNDEFINED) {
+ View target = ViewRootImpl.this.mView;
+ if (target != null && target.getVisibility() == View.VISIBLE) {
+ infos.add(target.createAccessibilityNodeInfo());
+ }
+ } else {
+ View target = findViewByAccessibilityId(accessibilityViewId);
+ if (target != null && target.getVisibility() == View.VISIBLE) {
+ AccessibilityNodeProvider provider = target.getAccessibilityNodeProvider();
+ if (provider != null) {
+ infos.add(provider.createAccessibilityNodeInfo(virtualDescendantId));
+ } else if (virtualDescendantId == AccessibilityNodeInfo.UNDEFINED) {
+ getAccessibilityPrefetchStrategy().prefetchAccessibilityNodeInfos(
+ interrogatingPid, target, infos);
+ }
}
}
} finally {
@@ -4828,8 +4886,8 @@
public void findAccessibilityNodeInfoByViewIdClientThread(long accessibilityNodeId,
int viewId, int interactionId, IAccessibilityInteractionConnectionCallback callback,
int interrogatingPid, long interrogatingTid) {
- Message message = Message.obtain();
- message.what = DO_FIND_ACCESSIBLITY_NODE_INFO_BY_VIEW_ID;
+ Message message = mHandler.obtainMessage();
+ message.what = MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_VIEW_ID;
message.arg1 = AccessibilityNodeInfo.getAccessibilityViewId(accessibilityNodeId);
SomeArgs args = mPool.acquire();
args.argi1 = viewId;
@@ -4842,11 +4900,10 @@
// client can handle the message to generate the result.
if (interrogatingPid == Process.myPid()
&& interrogatingTid == Looper.getMainLooper().getThread().getId()) {
- message.setTarget(ViewRootImpl.this);
AccessibilityInteractionClient.getInstanceForThread(
interrogatingTid).setSameThreadMessage(message);
} else {
- sendMessage(message);
+ mHandler.sendMessage(message);
}
}
@@ -4861,7 +4918,7 @@
AccessibilityNodeInfo info = null;
try {
View root = null;
- if (accessibilityViewId != View.NO_ID) {
+ if (accessibilityViewId != AccessibilityNodeInfo.UNDEFINED) {
root = findViewByAccessibilityId(accessibilityViewId);
} else {
root = ViewRootImpl.this.mView;
@@ -4885,8 +4942,8 @@
String text, int interactionId,
IAccessibilityInteractionConnectionCallback callback, int interrogatingPid,
long interrogatingTid) {
- Message message = Message.obtain();
- message.what = DO_FIND_ACCESSIBLITY_NODE_INFO_BY_TEXT;
+ Message message = mHandler.obtainMessage();
+ message.what = MSG_FIND_ACCESSIBLITY_NODE_INFO_BY_TEXT;
SomeArgs args = mPool.acquire();
args.arg1 = text;
args.argi1 = AccessibilityNodeInfo.getAccessibilityViewId(accessibilityNodeId);
@@ -4900,11 +4957,10 @@
// client can handle the message to generate the result.
if (interrogatingPid == Process.myPid()
&& interrogatingTid == Looper.getMainLooper().getThread().getId()) {
- message.setTarget(ViewRootImpl.this);
AccessibilityInteractionClient.getInstanceForThread(
interrogatingTid).setSameThreadMessage(message);
} else {
- sendMessage(message);
+ mHandler.sendMessage(message);
}
}
@@ -4920,7 +4976,7 @@
List<AccessibilityNodeInfo> infos = null;
try {
View target;
- if (accessibilityViewId != View.NO_ID) {
+ if (accessibilityViewId != AccessibilityNodeInfo.UNDEFINED) {
target = findViewByAccessibilityId(accessibilityViewId);
} else {
target = ViewRootImpl.this.mView;
@@ -4930,7 +4986,7 @@
if (provider != null) {
infos = provider.findAccessibilityNodeInfosByText(text,
virtualDescendantId);
- } else if (virtualDescendantId == View.NO_ID) {
+ } else if (virtualDescendantId == AccessibilityNodeInfo.UNDEFINED) {
ArrayList<View> foundViews = mAttachInfo.mFocusablesTempList;
foundViews.clear();
target.findViewsWithText(foundViews, text, View.FIND_VIEWS_WITH_TEXT
@@ -4971,8 +5027,8 @@
public void performAccessibilityActionClientThread(long accessibilityNodeId, int action,
int interactionId, IAccessibilityInteractionConnectionCallback callback,
int interogatingPid, long interrogatingTid) {
- Message message = Message.obtain();
- message.what = DO_PERFORM_ACCESSIBILITY_ACTION;
+ Message message = mHandler.obtainMessage();
+ message.what = MSG_PERFORM_ACCESSIBILITY_ACTION;
message.arg1 = AccessibilityNodeInfo.getAccessibilityViewId(accessibilityNodeId);
message.arg2 = AccessibilityNodeInfo.getVirtualDescendantId(accessibilityNodeId);
SomeArgs args = mPool.acquire();
@@ -4986,11 +5042,10 @@
// client can handle the message to generate the result.
if (interogatingPid == Process.myPid()
&& interrogatingTid == Looper.getMainLooper().getThread().getId()) {
- message.setTarget(ViewRootImpl.this);
AccessibilityInteractionClient.getInstanceForThread(
interrogatingTid).setSameThreadMessage(message);
} else {
- sendMessage(message);
+ mHandler.sendMessage(message);
}
}
@@ -5011,7 +5066,7 @@
if (provider != null) {
succeeded = provider.performAccessibilityAction(action,
virtualDescendantId);
- } else if (virtualDescendantId == View.NO_ID) {
+ } else if (virtualDescendantId == AccessibilityNodeInfo.UNDEFINED) {
switch (action) {
case AccessibilityNodeInfo.ACTION_FOCUS: {
if (!target.hasFocus()) {
@@ -5119,7 +5174,7 @@
private void addAndCacheNotCachedNodeInfo(long interrogatingPid,
View view, List<AccessibilityNodeInfo> outInfos) {
final long accessibilityNodeId = AccessibilityNodeInfo.makeNodeId(
- view.getAccessibilityViewId(), View.NO_ID);
+ view.getAccessibilityViewId(), AccessibilityNodeInfo.UNDEFINED);
AccessibilityNodeInfoCache cache = getCacheForInterrogatingPid(interrogatingPid);
if (!cache.containsKey(accessibilityNodeId)) {
// Account for the ids of the fetched infos. The infos will be
diff --git a/core/java/android/view/accessibility/AccessibilityInteractionClient.java b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
index 072fdd8..105c010 100644
--- a/core/java/android/view/accessibility/AccessibilityInteractionClient.java
+++ b/core/java/android/view/accessibility/AccessibilityInteractionClient.java
@@ -153,10 +153,12 @@
*
* @param connectionId The id of a connection for interacting with the system.
* @param accessibilityWindowId A unique window id. Use
- * {@link com.android.server.accessibility.AccessibilityManagerService#ACTIVE_WINDOW_ID}
+ * {@link android.view.accessibility.AccessibilityNodeInfo#ACTIVE_WINDOW_ID}
* to query the currently active window.
- * @param accessibilityNodeId A unique node accessibility id
- * (accessibility view and virtual descendant id).
+ * @param accessibilityNodeId A unique view id or virtual descendant id from
+ * where to start the search. Use
+ * {@link android.view.accessibility.AccessibilityNodeInfo#ROOT_NODE_ID}
+ * to start from the root.
* @return An {@link AccessibilityNodeInfo} if found, null otherwise.
*/
public AccessibilityNodeInfo findAccessibilityNodeInfoByAccessibilityId(int connectionId,
@@ -164,7 +166,8 @@
try {
IAccessibilityServiceConnection connection = getConnection(connectionId);
if (connection != null) {
- AccessibilityNodeInfo cachedInfo = sAccessibilityNodeInfoCache.get(accessibilityNodeId);
+ AccessibilityNodeInfo cachedInfo = sAccessibilityNodeInfoCache.get(
+ accessibilityNodeId);
if (cachedInfo != null) {
return cachedInfo;
}
@@ -176,7 +179,7 @@
if (windowScale > 0) {
List<AccessibilityNodeInfo> infos = getFindAccessibilityNodeInfosResultAndClear(
interactionId);
- finalizeAccessibilityNodeInfos(infos, connectionId, windowScale);
+ finalizeAndCacheAccessibilityNodeInfos(infos, connectionId, windowScale);
if (infos != null && !infos.isEmpty()) {
return infos.get(0);
}
@@ -202,10 +205,11 @@
*
* @param connectionId The id of a connection for interacting with the system.
* @param accessibilityWindowId A unique window id. Use
- * {@link com.android.server.accessibility.AccessibilityManagerService#ACTIVE_WINDOW_ID}
+ * {@link android.view.accessibility.AccessibilityNodeInfo#ACTIVE_WINDOW_ID}
* to query the currently active window.
- * @param accessibilityNodeId A unique view id from where to start the search. Use
- * {@link com.android.server.accessibility.AccessibilityManagerService#ROOT_NODE_ID}
+ * @param accessibilityNodeId A unique view id or virtual descendant id from
+ * where to start the search. Use
+ * {@link android.view.accessibility.AccessibilityNodeInfo#ROOT_NODE_ID}
* to start from the root.
* @param viewId The id of the view.
* @return An {@link AccessibilityNodeInfo} if found, null otherwise.
@@ -224,7 +228,7 @@
if (windowScale > 0) {
AccessibilityNodeInfo info = getFindAccessibilityNodeInfoResultAndClear(
interactionId);
- finalizeAccessibilityNodeInfo(info, connectionId, windowScale);
+ finalizeAndCacheAccessibilityNodeInfo(info, connectionId, windowScale);
return info;
}
} else {
@@ -249,10 +253,12 @@
*
* @param connectionId The id of a connection for interacting with the system.
* @param accessibilityWindowId A unique window id. Use
- * {@link com.android.server.accessibility.AccessibilityManagerService#ACTIVE_WINDOW_ID}
+ * {@link android.view.accessibility.AccessibilityNodeInfo#ACTIVE_WINDOW_ID}
* to query the currently active window.
- * @param accessibilityNodeId A unique view id from where to start the search. Use
- * {@link com.android.server.accessibility.AccessibilityManagerService#ROOT_NODE_ID}
+ * @param accessibilityNodeId A unique view id or virtual descendant id from
+ * where to start the search. Use
+ * {@link android.view.accessibility.AccessibilityNodeInfo#ROOT_NODE_ID}
+ * to start from the root.
* @param text The searched text.
* @return A list of found {@link AccessibilityNodeInfo}s.
*/
@@ -269,7 +275,7 @@
if (windowScale > 0) {
List<AccessibilityNodeInfo> infos = getFindAccessibilityNodeInfosResultAndClear(
interactionId);
- finalizeAccessibilityNodeInfos(infos, connectionId, windowScale);
+ finalizeAndCacheAccessibilityNodeInfos(infos, connectionId, windowScale);
return infos;
}
} else {
@@ -291,9 +297,12 @@
*
* @param connectionId The id of a connection for interacting with the system.
* @param accessibilityWindowId A unique window id. Use
- * {@link com.android.server.accessibility.AccessibilityManagerService#ACTIVE_WINDOW_ID}
+ * {@link android.view.accessibility.AccessibilityNodeInfo#ACTIVE_WINDOW_ID}
* to query the currently active window.
- * @param accessibilityNodeId A unique node id (accessibility and virtual descendant id).
+ * @param accessibilityNodeId A unique view id or virtual descendant id from
+ * where to start the search. Use
+ * {@link android.view.accessibility.AccessibilityNodeInfo#ROOT_NODE_ID}
+ * to start from the root.
* @param action The action to perform.
* @return Whether the action was performed.
*/
@@ -323,16 +332,10 @@
}
public void clearCache() {
- if (DEBUG) {
- Log.w(LOG_TAG, "clearCache()");
- }
sAccessibilityNodeInfoCache.clear();
}
public void removeCachedNode(long accessibilityNodeId) {
- if (DEBUG) {
- Log.w(LOG_TAG, "removeCachedNode(" + accessibilityNodeId +")");
- }
sAccessibilityNodeInfoCache.remove(accessibilityNodeId);
}
@@ -364,9 +367,6 @@
if (interactionId > mInteractionId) {
mFindAccessibilityNodeInfoResult = info;
mInteractionId = interactionId;
- if (info != null) {
- sAccessibilityNodeInfoCache.put(info.getSourceNodeId(), info);
- }
}
mInstanceLock.notifyAll();
}
@@ -404,11 +404,6 @@
mFindAccessibilityNodeInfosResult = infos;
}
mInteractionId = interactionId;
- final int infoCount = infos.size();
- for (int i = 0; i < infoCount; i ++) {
- AccessibilityNodeInfo info = infos.get(i);
- sAccessibilityNodeInfoCache.put(info.getSourceNodeId(), info);
- }
}
mInstanceLock.notifyAll();
}
@@ -513,12 +508,13 @@
* @param connectionId The id of the connection to the system.
* @param windowScale The source window compatibility scale.
*/
- private void finalizeAccessibilityNodeInfo(AccessibilityNodeInfo info, int connectionId,
+ private void finalizeAndCacheAccessibilityNodeInfo(AccessibilityNodeInfo info, int connectionId,
float windowScale) {
if (info != null) {
applyCompatibilityScaleIfNeeded(info, windowScale);
info.setConnectionId(connectionId);
info.setSealed(true);
+ sAccessibilityNodeInfoCache.put(info.getSourceNodeId(), info);
}
}
@@ -529,13 +525,13 @@
* @param connectionId The id of the connection to the system.
* @param windowScale The source window compatibility scale.
*/
- private void finalizeAccessibilityNodeInfos(List<AccessibilityNodeInfo> infos,
+ private void finalizeAndCacheAccessibilityNodeInfos(List<AccessibilityNodeInfo> infos,
int connectionId, float windowScale) {
if (infos != null) {
final int infosCount = infos.size();
for (int i = 0; i < infosCount; i++) {
AccessibilityNodeInfo info = infos.get(i);
- finalizeAccessibilityNodeInfo(info, connectionId, windowScale);
+ finalizeAndCacheAccessibilityNodeInfo(info, connectionId, windowScale);
}
}
}
diff --git a/core/java/android/view/accessibility/AccessibilityNodeInfo.java b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
index d7d6792..84ad268 100644
--- a/core/java/android/view/accessibility/AccessibilityNodeInfo.java
+++ b/core/java/android/view/accessibility/AccessibilityNodeInfo.java
@@ -52,7 +52,14 @@
private static final boolean DEBUG = false;
- private static final int UNDEFINED = -1;
+ /** @hide */
+ public static final int UNDEFINED = -1;
+
+ /** @hide */
+ public static final long ROOT_NODE_ID = makeNodeId(UNDEFINED, UNDEFINED);
+
+ /** @hide */
+ public static final int ACTIVE_WINDOW_ID = UNDEFINED;
// Actions.
@@ -162,8 +169,8 @@
// Data.
private int mWindowId = UNDEFINED;
- private long mSourceNodeId = makeNodeId(UNDEFINED, UNDEFINED);
- private long mParentNodeId = makeNodeId(UNDEFINED, UNDEFINED);
+ private long mSourceNodeId = ROOT_NODE_ID;
+ private long mParentNodeId = ROOT_NODE_ID;
private int mBooleanProperties;
private final Rect mBoundsInParent = new Rect();
@@ -1160,8 +1167,8 @@
*/
private void clear() {
mSealed = false;
- mSourceNodeId = makeNodeId(UNDEFINED, UNDEFINED);
- mParentNodeId = makeNodeId(UNDEFINED, UNDEFINED);
+ mSourceNodeId = ROOT_NODE_ID;
+ mParentNodeId = ROOT_NODE_ID;
mWindowId = UNDEFINED;
mConnectionId = UNDEFINED;
mChildIds.clear();
diff --git a/core/java/android/view/inputmethod/BaseInputConnection.java b/core/java/android/view/inputmethod/BaseInputConnection.java
index bd02d62..89aba3c 100644
--- a/core/java/android/view/inputmethod/BaseInputConnection.java
+++ b/core/java/android/view/inputmethod/BaseInputConnection.java
@@ -19,7 +19,6 @@
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Bundle;
-import android.os.Handler;
import android.os.SystemClock;
import android.text.Editable;
import android.text.NoCopySpan;
@@ -497,15 +496,14 @@
*/
public boolean sendKeyEvent(KeyEvent event) {
synchronized (mIMM.mH) {
- Handler h = mTargetView != null ? mTargetView.getHandler() : null;
- if (h == null) {
+ ViewRootImpl viewRootImpl = mTargetView != null ? mTargetView.getViewRootImpl() : null;
+ if (viewRootImpl == null) {
if (mIMM.mServedView != null) {
- h = mIMM.mServedView.getHandler();
+ viewRootImpl = mIMM.mServedView.getViewRootImpl();
}
}
- if (h != null) {
- h.sendMessage(h.obtainMessage(ViewRootImpl.DISPATCH_KEY_FROM_IME,
- event));
+ if (viewRootImpl != null) {
+ viewRootImpl.dispatchKeyFromIme(event);
}
}
return false;
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index f79ac93..c51d244 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -336,6 +336,7 @@
}
case MSG_UNBIND: {
final int sequence = msg.arg1;
+ boolean startInput = false;
synchronized (mH) {
if (mBindSequence == sequence) {
if (false) {
@@ -356,10 +357,13 @@
mServedConnecting = true;
}
if (mActive) {
- startInputInner();
+ startInput = true;
}
}
}
+ if (startInput) {
+ startInputInner();
+ }
return;
}
case MSG_SET_ACTIVE: {
@@ -671,11 +675,10 @@
// longer the input target, so it can reset its state. Schedule
// this call on its window's Handler so it will be on the correct
// thread and outside of our lock.
- Handler vh = mServedView.getHandler();
- if (vh != null) {
+ ViewRootImpl viewRootImpl = mServedView.getViewRootImpl();
+ if (viewRootImpl != null) {
// This will result in a call to reportFinishInputConnection() below.
- vh.sendMessage(vh.obtainMessage(ViewRootImpl.FINISH_INPUT_CONNECTION,
- mServedInputConnection));
+ viewRootImpl.dispatchFinishInputConnection(mServedInputConnection);
}
}
}
@@ -1126,13 +1129,12 @@
}
static void scheduleCheckFocusLocked(View view) {
- Handler vh = view.getHandler();
- if (vh != null && !vh.hasMessages(ViewRootImpl.CHECK_FOCUS)) {
- // This will result in a call to checkFocus() below.
- vh.sendMessage(vh.obtainMessage(ViewRootImpl.CHECK_FOCUS));
+ ViewRootImpl viewRootImpl = view.getViewRootImpl();
+ if (viewRootImpl != null) {
+ viewRootImpl.dispatchCheckFocus();
}
}
-
+
/**
* @hide
*/
@@ -1217,12 +1219,13 @@
mService.windowGainedFocus(mClient, rootView.getWindowToken(),
focusedView != null, isTextEditor, softInputMode, first,
windowFlags);
- if (startInput) {
- startInputInner();
- }
} catch (RemoteException e) {
}
}
+
+ if (startInput) {
+ startInputInner();
+ }
}
/** @hide */
diff --git a/core/java/android/view/textservice/SentenceSuggestionsInfo.aidl b/core/java/android/view/textservice/SentenceSuggestionsInfo.aidl
new file mode 100644
index 0000000..d0b6ba6
--- /dev/null
+++ b/core/java/android/view/textservice/SentenceSuggestionsInfo.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2012 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 android.view.textservice;
+
+parcelable SentenceSuggestionsInfo;
diff --git a/core/java/android/view/textservice/SentenceSuggestionsInfo.java b/core/java/android/view/textservice/SentenceSuggestionsInfo.java
new file mode 100644
index 0000000..8d7c6cf
--- /dev/null
+++ b/core/java/android/view/textservice/SentenceSuggestionsInfo.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2012 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 android.view.textservice;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Arrays;
+
+/**
+ * @hide
+ * This class contains a metadata of sentence level suggestions from the text service
+ */
+public final class SentenceSuggestionsInfo implements Parcelable {
+
+ private final SuggestionsInfo[] mSuggestionsInfos;
+ private final int[] mOffsets;
+ private final int[] mLengths;
+
+ /**
+ * Constructor.
+ * @param suggestionsInfos from the text service
+ * @param offsets the array of offsets of suggestions
+ * @param lengths the array of lengths of suggestions
+ */
+ public SentenceSuggestionsInfo(
+ SuggestionsInfo[] suggestionsInfos, int[] offsets, int[] lengths) {
+ if (suggestionsInfos == null || offsets == null || lengths == null) {
+ throw new NullPointerException();
+ }
+ if (suggestionsInfos.length != offsets.length || offsets.length != lengths.length) {
+ throw new IllegalArgumentException();
+ }
+ final int infoSize = suggestionsInfos.length;
+ mSuggestionsInfos = Arrays.copyOf(suggestionsInfos, infoSize);
+ mOffsets = Arrays.copyOf(offsets, infoSize);
+ mLengths = Arrays.copyOf(lengths, infoSize);
+ }
+
+ public SentenceSuggestionsInfo(Parcel source) {
+ final int infoSize = source.readInt();
+ mSuggestionsInfos = new SuggestionsInfo[infoSize];
+ source.readTypedArray(mSuggestionsInfos, SuggestionsInfo.CREATOR);
+ mOffsets = new int[mSuggestionsInfos.length];
+ source.readIntArray(mOffsets);
+ mLengths = new int[mSuggestionsInfos.length];
+ source.readIntArray(mLengths);
+ }
+
+ /**
+ * Used to package this object into a {@link Parcel}.
+ *
+ * @param dest The {@link Parcel} to be written.
+ * @param flags The flags used for parceling.
+ */
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ final int infoSize = mSuggestionsInfos.length;
+ dest.writeInt(infoSize);
+ dest.writeTypedArray(mSuggestionsInfos, 0);
+ dest.writeIntArray(mOffsets);
+ dest.writeIntArray(mLengths);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ /**
+ * @hide
+ */
+ public SuggestionsInfo getSuggestionsInfoAt(int i) {
+ if (i >= 0 && i < mSuggestionsInfos.length) {
+ return mSuggestionsInfos[i];
+ }
+ return null;
+ }
+
+ /**
+ * @hide
+ */
+ public int getOffsetAt(int i) {
+ if (i >= 0 && i < mOffsets.length) {
+ return mOffsets[i];
+ }
+ return -1;
+ }
+
+ /**
+ * @hide
+ */
+ public int getLengthAt(int i) {
+ if (i >= 0 && i < mLengths.length) {
+ return mLengths[i];
+ }
+ return -1;
+ }
+
+ /**
+ * Used to make this class parcelable.
+ */
+ public static final Parcelable.Creator<SentenceSuggestionsInfo> CREATOR
+ = new Parcelable.Creator<SentenceSuggestionsInfo>() {
+ @Override
+ public SentenceSuggestionsInfo createFromParcel(Parcel source) {
+ return new SentenceSuggestionsInfo(source);
+ }
+
+ @Override
+ public SentenceSuggestionsInfo[] newArray(int size) {
+ return new SentenceSuggestionsInfo[size];
+ }
+ };
+}
diff --git a/core/java/android/view/textservice/SpellCheckerSession.java b/core/java/android/view/textservice/SpellCheckerSession.java
index f6418ce..3491a537 100644
--- a/core/java/android/view/textservice/SpellCheckerSession.java
+++ b/core/java/android/view/textservice/SpellCheckerSession.java
@@ -115,7 +115,7 @@
handleOnGetSuggestionsMultiple((SuggestionsInfo[]) msg.obj);
break;
case MSG_ON_GET_SUGGESTION_MULTIPLE_FOR_SENTENCE:
- handleOnGetSuggestionsMultipleForSentence((SuggestionsInfo[]) msg.obj);
+ handleOnGetSentenceSuggestionsMultiple((SentenceSuggestionsInfo[]) msg.obj);
break;
}
}
@@ -180,8 +180,8 @@
/**
* @hide
*/
- public void getSuggestionsForSentence(TextInfo textInfo, int suggestionsLimit) {
- mSpellCheckerSessionListenerImpl.getSuggestionsMultipleForSentence(
+ public void getSentenceSuggestions(TextInfo textInfo, int suggestionsLimit) {
+ mSpellCheckerSessionListenerImpl.getSentenceSuggestionsMultiple(
new TextInfo[] {textInfo}, suggestionsLimit);
}
@@ -214,8 +214,8 @@
mSpellCheckerSessionListener.onGetSuggestions(suggestionInfos);
}
- private void handleOnGetSuggestionsMultipleForSentence(SuggestionsInfo[] suggestionInfos) {
- mSpellCheckerSessionListener.onGetSuggestionsForSentence(suggestionInfos);
+ private void handleOnGetSentenceSuggestionsMultiple(SentenceSuggestionsInfo[] suggestionInfos) {
+ mSpellCheckerSessionListener.onGetSentenceSuggestions(suggestionInfos);
}
private static class SpellCheckerSessionListenerImpl extends ISpellCheckerSessionListener.Stub {
@@ -285,7 +285,7 @@
throw new IllegalArgumentException();
}
try {
- session.onGetSuggestionsMultipleForSentence(
+ session.onGetSentenceSuggestionsMultiple(
scp.mTextInfos, scp.mSuggestionsLimit);
} catch (RemoteException e) {
Log.e(TAG, "Failed to get suggestions " + e);
@@ -366,9 +366,9 @@
suggestionsLimit, sequentialWords));
}
- public void getSuggestionsMultipleForSentence(TextInfo[] textInfos, int suggestionsLimit) {
+ public void getSentenceSuggestionsMultiple(TextInfo[] textInfos, int suggestionsLimit) {
if (DBG) {
- Log.w(TAG, "getSuggestionsMultipleForSentence");
+ Log.w(TAG, "getSentenceSuggestionsMultiple");
}
processOrEnqueueTask(
new SpellCheckerParams(TASK_GET_SUGGESTIONS_MULTIPLE_FOR_SENTENCE,
@@ -399,8 +399,8 @@
while (!mPendingTasks.isEmpty()) {
final SpellCheckerParams tmp = mPendingTasks.poll();
if (tmp.mWhat == TASK_CLOSE) {
- // Only one close task should be processed, while we need to remove all
- // close tasks from the queue
+ // Only one close task should be processed, while we need to remove
+ // all close tasks from the queue
closeTask = tmp;
}
}
@@ -426,7 +426,7 @@
}
@Override
- public void onGetSuggestionsForSentence(SuggestionsInfo[] results) {
+ public void onGetSentenceSuggestions(SentenceSuggestionsInfo[] results) {
mHandler.sendMessage(
Message.obtain(mHandler, MSG_ON_GET_SUGGESTION_MULTIPLE_FOR_SENTENCE, results));
}
@@ -444,7 +444,7 @@
/**
* @hide
*/
- public void onGetSuggestionsForSentence(SuggestionsInfo[] results);
+ public void onGetSentenceSuggestions(SentenceSuggestionsInfo[] results);
}
private static class InternalListener extends ITextServicesSessionListener.Stub {
diff --git a/core/java/android/view/textservice/SuggestionsInfo.java b/core/java/android/view/textservice/SuggestionsInfo.java
index 9b99770..78bc1a9 100644
--- a/core/java/android/view/textservice/SuggestionsInfo.java
+++ b/core/java/android/view/textservice/SuggestionsInfo.java
@@ -21,14 +21,11 @@
import android.os.Parcel;
import android.os.Parcelable;
-import java.util.Arrays;
-
/**
* This class contains a metadata of suggestions from the text service
*/
public final class SuggestionsInfo implements Parcelable {
private static final String[] EMPTY = ArrayUtils.emptyArray(String.class);
- private static final int NOT_A_LENGTH = -1;
/**
* Flag of the attributes of the suggestions that can be obtained by
@@ -50,8 +47,6 @@
public static final int RESULT_ATTR_HAS_RECOMMENDED_SUGGESTIONS = 0x0004;
private final int mSuggestionsAttributes;
private final String[] mSuggestions;
- private final int[] mStartPosArray;
- private final int[] mLengthArray;
private final boolean mSuggestionsAvailable;
private int mCookie;
private int mSequence;
@@ -74,46 +69,12 @@
*/
public SuggestionsInfo(
int suggestionsAttributes, String[] suggestions, int cookie, int sequence) {
- this(suggestionsAttributes, suggestions, cookie, sequence, null, null);
- }
-
- /**
- * @hide
- * Constructor.
- * @param suggestionsAttributes from the text service
- * @param suggestions from the text service
- * @param cookie the cookie of the input TextInfo
- * @param sequence the cookie of the input TextInfo
- * @param startPosArray the array of start positions of suggestions
- * @param lengthArray the array of length of suggestions
- */
- public SuggestionsInfo(
- int suggestionsAttributes, String[] suggestions, int cookie, int sequence,
- int[] startPosArray, int[] lengthArray) {
- final int suggestsLen;
if (suggestions == null) {
mSuggestions = EMPTY;
mSuggestionsAvailable = false;
- suggestsLen = 0;
- mStartPosArray = new int[0];
- mLengthArray = new int[0];
} else {
mSuggestions = suggestions;
mSuggestionsAvailable = true;
- suggestsLen = suggestions.length;
- if (startPosArray == null || lengthArray == null) {
- mStartPosArray = new int[suggestsLen];
- mLengthArray = new int[suggestsLen];
- for (int i = 0; i < suggestsLen; ++i) {
- mStartPosArray[i] = 0;
- mLengthArray[i] = NOT_A_LENGTH;
- }
- } else if (suggestsLen != startPosArray.length || suggestsLen != lengthArray.length) {
- throw new IllegalArgumentException();
- } else {
- mStartPosArray = Arrays.copyOf(startPosArray, suggestsLen);
- mLengthArray = Arrays.copyOf(lengthArray, suggestsLen);
- }
}
mSuggestionsAttributes = suggestionsAttributes;
mCookie = cookie;
@@ -126,10 +87,6 @@
mCookie = source.readInt();
mSequence = source.readInt();
mSuggestionsAvailable = source.readInt() == 1;
- mStartPosArray = new int[mSuggestions.length];
- mLengthArray = new int[mSuggestions.length];
- source.readIntArray(mStartPosArray);
- source.readIntArray(mLengthArray);
}
/**
@@ -145,8 +102,6 @@
dest.writeInt(mCookie);
dest.writeInt(mSequence);
dest.writeInt(mSuggestionsAvailable ? 1 : 0);
- dest.writeIntArray(mStartPosArray);
- dest.writeIntArray(mLengthArray);
}
/**
@@ -227,24 +182,4 @@
public int describeContents() {
return 0;
}
-
- /**
- * @hide
- */
- public int getSuggestionStartPosAt(int i) {
- if (i >= 0 && i < mStartPosArray.length) {
- return mStartPosArray[i];
- }
- return -1;
- }
-
- /**
- * @hide
- */
- public int getSuggestionLengthAt(int i) {
- if (i >= 0 && i < mLengthArray.length) {
- return mLengthArray[i];
- }
- return -1;
- }
}
diff --git a/core/java/android/webkit/CacheManager.java b/core/java/android/webkit/CacheManager.java
index e21a02e..e2342e9 100644
--- a/core/java/android/webkit/CacheManager.java
+++ b/core/java/android/webkit/CacheManager.java
@@ -37,18 +37,18 @@
import com.android.org.bouncycastle.crypto.digests.SHA1Digest;
/**
- * The class CacheManager provides the persistent cache of content that is
- * received over the network. The component handles parsing of HTTP headers and
- * utilizes the relevant cache headers to determine if the content should be
- * stored and if so, how long it is valid for. Network requests are provided to
- * this component and if they can not be resolved by the cache, the HTTP headers
- * are attached, as appropriate, to the request for revalidation of content. The
- * class also manages the cache size.
- *
- * CacheManager may only be used if your activity contains a WebView.
- *
+ * Manages the HTTP cache used by an application's {@link WebView} instances.
* @deprecated Access to the HTTP cache will be removed in a future release.
*/
+// The class CacheManager provides the persistent cache of content that is
+// received over the network. The component handles parsing of HTTP headers and
+// utilizes the relevant cache headers to determine if the content should be
+// stored and if so, how long it is valid for. Network requests are provided to
+// this component and if they can not be resolved by the cache, the HTTP headers
+// are attached, as appropriate, to the request for revalidation of content. The
+// class also manages the cache size.
+//
+// CacheManager may only be used if your activity contains a WebView.
@Deprecated
public final class CacheManager {
@@ -87,10 +87,9 @@
private static boolean mClearCacheOnInit = false;
/**
- * This class represents a resource retrieved from the HTTP cache.
- * Instances of this class can be obtained by invoking the
- * CacheManager.getCacheFile() method.
- *
+ * Represents a resource stored in the HTTP cache. Instances of this class
+ * can be obtained by calling
+ * {@link CacheManager#getCacheFile CacheManager.getCacheFile(String, Map<String, String>))}.
* @deprecated Access to the HTTP cache will be removed in a future release.
*/
@Deprecated
@@ -114,64 +113,136 @@
OutputStream outStream;
File outFile;
+ /**
+ * Gets the status code of this cache entry.
+ * @return The status code of this cache entry
+ */
public int getHttpStatusCode() {
return httpStatusCode;
}
+ /**
+ * Gets the content length of this cache entry.
+ * @return The content length of this cache entry
+ */
public long getContentLength() {
return contentLength;
}
+ /**
+ * Gets the path of the file used to store the content of this cache
+ * entry, relative to the base directory of the cache. See
+ * {@link CacheManager#getCacheFileBaseDir CacheManager.getCacheFileBaseDir()}.
+ * @return The path of the file used to store this cache entry
+ */
public String getLocalPath() {
return localPath;
}
+ /**
+ * Gets the expiry date of this cache entry, expressed in milliseconds
+ * since midnight, January 1, 1970 UTC.
+ * @return The expiry date of this cache entry
+ */
public long getExpires() {
return expires;
}
+ /**
+ * Gets the expiry date of this cache entry, expressed as a string.
+ * @return The expiry date of this cache entry
+ *
+ */
public String getExpiresString() {
return expiresString;
}
+ /**
+ * Gets the date at which this cache entry was last modified, expressed
+ * as a string.
+ * @return The date at which this cache entry was last modified
+ */
public String getLastModified() {
return lastModified;
}
+ /**
+ * Gets the entity tag of this cache entry.
+ * @return The entity tag of this cache entry
+ */
public String getETag() {
return etag;
}
+ /**
+ * Gets the MIME type of this cache entry.
+ * @return The MIME type of this cache entry
+ */
public String getMimeType() {
return mimeType;
}
+ /**
+ * Gets the value of the HTTP 'Location' header with which this cache
+ * entry was received.
+ * @return The HTTP 'Location' header for this cache entry
+ */
public String getLocation() {
return location;
}
+ /**
+ * Gets the encoding of this cache entry.
+ * @return The encoding of this cache entry
+ */
public String getEncoding() {
return encoding;
}
+ /**
+ * Gets the value of the HTTP 'Content-Disposition' header with which
+ * this cache entry was received.
+ * @return The HTTP 'Content-Disposition' header for this cache entry
+ *
+ */
public String getContentDisposition() {
return contentdisposition;
}
- // For out-of-package access to the underlying streams.
+ /**
+ * Gets the input stream to the content of this cache entry, to allow
+ * content to be read. See
+ * {@link CacheManager#getCacheFile CacheManager.getCacheFile(String, Map<String, String>)}.
+ * @return An input stream to the content of this cache entry
+ */
public InputStream getInputStream() {
return inStream;
}
+ /**
+ * Gets an output stream to the content of this cache entry, to allow
+ * content to be written. See
+ * {@link CacheManager#saveCacheFile CacheManager.saveCacheFile(String, CacheResult)}.
+ * @return An output stream to the content of this cache entry
+ */
+ // Note that this is always null for objects returned by getCacheFile()!
public OutputStream getOutputStream() {
return outStream;
}
- // These fields can be set manually.
+
+ /**
+ * Sets an input stream to the content of this cache entry.
+ * @param stream An input stream to the content of this cache entry
+ */
public void setInputStream(InputStream stream) {
this.inStream = stream;
}
+ /**
+ * Sets the encoding of this cache entry.
+ * @param encoding The encoding of this cache entry
+ */
public void setEncoding(String encoding) {
this.encoding = encoding;
}
@@ -185,11 +256,10 @@
}
/**
- * Initialize the CacheManager.
- *
- * Note that this is called automatically when a {@link android.webkit.WebView} is created.
- *
- * @param context The application context.
+ * Initializes the HTTP cache. This method must be called before any
+ * CacheManager methods are used. Note that this is called automatically
+ * when a {@link WebView} is created.
+ * @param context The application context
*/
static void init(Context context) {
if (JniUtil.useChromiumHttpStack()) {
@@ -240,15 +310,10 @@
}
/**
- * Get the base directory of the cache. Together with the local path of the CacheResult,
- * obtained from {@link android.webkit.CacheManager.CacheResult#getLocalPath}, this
- * identifies the cache file.
- *
- * Cache files are not guaranteed to be in this directory before
- * CacheManager#getCacheFile(String, Map<String, String>) is called.
- *
- * @return File The base directory of the cache.
- *
+ * Gets the base directory in which the files used to store the contents of
+ * cache entries are placed. See
+ * {@link CacheManager.CacheResult#getLocalPath CacheManager.CacheResult.getLocalPath()}.
+ * @return The base directory of the cache
* @deprecated Access to the HTTP cache will be removed in a future release.
*/
@Deprecated
@@ -257,8 +322,7 @@
}
/**
- * Sets whether the cache is disabled.
- *
+ * Sets whether the HTTP cache should be disabled.
* @param disabled Whether the cache should be disabled
*/
static void setCacheDisabled(boolean disabled) {
@@ -274,10 +338,8 @@
}
/**
- * Whether the cache is disabled.
- *
- * @return return Whether the cache is disabled
- *
+ * Gets whether the HTTP cache is disabled.
+ * @return True if the HTTP cache is disabled
* @deprecated Access to the HTTP cache will be removed in a future release.
*/
@Deprecated
@@ -330,20 +392,23 @@
return ret;
}
- // only called from WebCore Thread
- // make sure to call startCacheTransaction/endCacheTransaction in pair
/**
- * @deprecated Always returns false.
+ * Starts a cache transaction. Returns true if this is the only running
+ * transaction. Otherwise, this transaction is nested inside currently
+ * running transactions and false is returned.
+ * @return True if this is the only running transaction
+ * @deprecated This method no longer has any effect and always returns false
*/
@Deprecated
public static boolean startCacheTransaction() {
return false;
}
- // only called from WebCore Thread
- // make sure to call startCacheTransaction/endCacheTransaction in pair
/**
- * @deprecated Always returns false.
+ * Ends the innermost cache transaction and returns whether this was the
+ * only running transaction.
+ * @return True if this was the only running transaction
+ * @deprecated This method no longer has any effect and always returns false
*/
@Deprecated
public static boolean endCacheTransaction() {
@@ -351,15 +416,15 @@
}
/**
- * Given a URL, returns the corresponding CacheResult if it exists, or null otherwise.
- *
- * The input stream of the CacheEntry object is initialized and opened and should be closed by
- * the caller when access to the underlying file is no longer required.
- * If a non-zero value is provided for the headers map, and the cache entry needs validation,
- * HEADER_KEY_IFNONEMATCH or HEADER_KEY_IFMODIFIEDSINCE will be set in headers.
- *
- * @return The CacheResult for the given URL
- *
+ * Gets the cache entry for the specified URL, or null if none is found.
+ * If a non-null value is provided for the HTTP headers map, and the cache
+ * entry needs validation, appropriate headers will be added to the map.
+ * The input stream of the CacheEntry object should be closed by the caller
+ * when access to the underlying file is no longer required.
+ * @param url The URL for which a cache entry is requested
+ * @param headers A map from HTTP header name to value, to be populated
+ * for the returned cache entry
+ * @return The cache entry for the specified URL
* @deprecated Access to the HTTP cache will be removed in a future release.
*/
@Deprecated
@@ -368,32 +433,32 @@
return getCacheFile(url, 0, headers);
}
- static CacheResult getCacheFile(String url, long postIdentifier,
- Map<String, String> headers) {
- if (mDisabled) {
+ private static CacheResult getCacheFileChromiumHttpStack(String url) {
+ assert JniUtil.useChromiumHttpStack();
+
+ CacheResult result = nativeGetCacheResult(url);
+ if (result == null) {
return null;
}
-
- if (JniUtil.useChromiumHttpStack()) {
- CacheResult result = nativeGetCacheResult(url);
- if (result == null) {
- return null;
- }
- // A temporary local file will have been created native side and localPath set
- // appropriately.
- File src = new File(mBaseDir, result.localPath);
- try {
- // Open the file here so that even if it is deleted, the content
- // is still readable by the caller until close() is called.
- result.inStream = new FileInputStream(src);
- } catch (FileNotFoundException e) {
- Log.v(LOGTAG, "getCacheFile(): Failed to open file: " + e);
- // TODO: The files in the cache directory can be removed by the
- // system. If it is gone, what should we do?
- return null;
- }
- return result;
+ // A temporary local file will have been created native side and localPath set
+ // appropriately.
+ File src = new File(mBaseDir, result.localPath);
+ try {
+ // Open the file here so that even if it is deleted, the content
+ // is still readable by the caller until close() is called.
+ result.inStream = new FileInputStream(src);
+ } catch (FileNotFoundException e) {
+ Log.v(LOGTAG, "getCacheFile(): Failed to open file: " + e);
+ // TODO: The files in the cache directory can be removed by the
+ // system. If it is gone, what should we do?
+ return null;
}
+ return result;
+ }
+
+ private static CacheResult getCacheFileAndroidHttpStack(String url,
+ long postIdentifier) {
+ assert !JniUtil.useChromiumHttpStack();
String databaseKey = getDatabaseKey(url, postIdentifier);
CacheResult result = mDataBase.getCache(databaseKey);
@@ -419,6 +484,22 @@
return null;
}
}
+ return result;
+ }
+
+ static CacheResult getCacheFile(String url, long postIdentifier,
+ Map<String, String> headers) {
+ if (mDisabled) {
+ return null;
+ }
+
+ CacheResult result = JniUtil.useChromiumHttpStack() ?
+ getCacheFileChromiumHttpStack(url) :
+ getCacheFileAndroidHttpStack(url, postIdentifier);
+
+ if (result == null) {
+ return null;
+ }
// A null value for headers is used by CACHE_MODE_CACHE_ONLY to imply
// that we should provide the cache result even if it is expired.
@@ -454,13 +535,8 @@
* CacheResult, and is used to supply surrogate responses for URL
* interception.
* @return CacheResult for a given url
- * @hide - hide createCacheFile since it has a parameter of type headers, which is
- * in a hidden package.
- *
- * @deprecated Access to the HTTP cache will be removed in a future release.
*/
- @Deprecated
- public static CacheResult createCacheFile(String url, int statusCode,
+ static CacheResult createCacheFile(String url, int statusCode,
Headers headers, String mimeType, boolean forceCache) {
if (JniUtil.useChromiumHttpStack()) {
// This method is public but hidden. We break functionality.
@@ -529,14 +605,15 @@
}
/**
- * Save the info of a cache file for a given url to the CacheMap so that it
- * can be reused later
- *
+ * Adds a cache entry to the HTTP cache for the specicifed URL. Also closes
+ * the cache entry's output stream.
+ * @param url The URL for which the cache entry should be added
+ * @param cacheResult The cache entry to add
* @deprecated Access to the HTTP cache will be removed in a future release.
*/
@Deprecated
- public static void saveCacheFile(String url, CacheResult cacheRet) {
- saveCacheFile(url, 0, cacheRet);
+ public static void saveCacheFile(String url, CacheResult cacheResult) {
+ saveCacheFile(url, 0, cacheResult);
}
static void saveCacheFile(String url, long postIdentifier,
@@ -548,16 +625,26 @@
}
if (JniUtil.useChromiumHttpStack()) {
- // This method is exposed in the public API but the API provides no way to obtain a
- // new CacheResult object with a non-null output stream ...
- // - CacheResult objects returned by getCacheFile() have a null output stream.
- // - new CacheResult objects have a null output stream and no setter is provided.
- // Since for the Android HTTP stack this method throws a null pointer exception in this
- // case, this method is effectively useless from the point of view of the public API.
-
- // We should already have thrown an exception above, to maintain 'backward
- // compatibility' with the Android HTTP stack.
+ // This method is exposed in the public API but the API provides no
+ // way to obtain a new CacheResult object with a non-null output
+ // stream ...
+ // - CacheResult objects returned by getCacheFile() have a null
+ // output stream.
+ // - new CacheResult objects have a null output stream and no
+ // setter is provided.
+ // Since this method throws a null pointer exception in this case,
+ // it is effectively useless from the point of view of the public
+ // API.
+ //
+ // With the Chromium HTTP stack we continue to throw the same
+ // exception for 'backwards compatibility' with the Android HTTP
+ // stack.
+ //
+ // This method is not used from within this package with the
+ // Chromium HTTP stack, and for public API use, we should already
+ // have thrown an exception above.
assert false;
+ return;
}
if (!cacheRet.outFile.exists()) {
diff --git a/core/java/android/webkit/CallbackProxy.java b/core/java/android/webkit/CallbackProxy.java
index 75ee338..95d9275 100644
--- a/core/java/android/webkit/CallbackProxy.java
+++ b/core/java/android/webkit/CallbackProxy.java
@@ -920,7 +920,10 @@
if (PERF_PROBE) {
mWebCoreThreadTime = SystemClock.currentThreadTimeMillis();
mWebCoreIdleTime = 0;
- Network.getInstance(mContext).startTiming();
+ if (!JniUtil.useChromiumHttpStack()) {
+ // Network is only used with the Android HTTP stack.
+ Network.getInstance(mContext).startTiming();
+ }
// un-comment this if PERF_PROBE is true
// Looper.myQueue().setWaitCallback(mIdleCallback);
}
@@ -938,7 +941,10 @@
Log.d("WebCore", "WebCore thread used " +
(SystemClock.currentThreadTimeMillis() - mWebCoreThreadTime)
+ " ms and idled " + mWebCoreIdleTime + " ms");
- Network.getInstance(mContext).stopTiming();
+ if (!JniUtil.useChromiumHttpStack()) {
+ // Network is only used with the Android HTTP stack.
+ Network.getInstance(mContext).stopTiming();
+ }
}
Message msg = obtainMessage(PAGE_FINISHED, url);
sendMessage(msg);
diff --git a/core/java/android/webkit/CookieManager.java b/core/java/android/webkit/CookieManager.java
index 9fa5593..c500a76 100644
--- a/core/java/android/webkit/CookieManager.java
+++ b/core/java/android/webkit/CookieManager.java
@@ -34,7 +34,8 @@
import java.util.TreeSet;
/**
- * CookieManager manages cookies according to RFC2109 spec.
+ * Manages the cookies used by an application's {@link WebView} instances.
+ * Cookies are manipulated according to RFC2109.
*/
public final class CookieManager {
@@ -99,7 +100,7 @@
private boolean mAcceptCookie = true;
- private int pendingCookieOperations = 0;
+ private int mPendingCookieOperations = 0;
/**
* This contains a list of 2nd-level domains that aren't allowed to have
@@ -246,12 +247,12 @@
}
/**
- * Get a singleton CookieManager. If this is called before any
- * {@link WebView} is created or outside of {@link WebView} context, the
- * caller needs to call {@link CookieSyncManager#createInstance(Context)}
+ * Gets the singleton CookieManager instance. If this method is used
+ * before the application instantiates a {@link WebView} instance,
+ * {@link CookieSyncManager#createInstance(Context)} must be called
* first.
*
- * @return CookieManager
+ * @return The singleton CookieManager instance
*/
public static synchronized CookieManager getInstance() {
if (sRef == null) {
@@ -261,8 +262,10 @@
}
/**
- * Control whether cookie is enabled or disabled
- * @param accept TRUE if accept cookie
+ * Sets whether the application's {@link WebView} instances should send and
+ * accept cookies.
+ * @param accept Whether {@link WebView} instances should send and accept
+ * cookies
*/
public synchronized void setAcceptCookie(boolean accept) {
if (JniUtil.useChromiumHttpStack()) {
@@ -274,8 +277,9 @@
}
/**
- * Return whether cookie is enabled
- * @return TRUE if accept cookie
+ * Gets whether the application's {@link WebView} instances send and accept
+ * cookies.
+ * @return True if {@link WebView} instances send and accept cookies
*/
public synchronized boolean acceptCookie() {
if (JniUtil.useChromiumHttpStack()) {
@@ -286,11 +290,13 @@
}
/**
- * Set cookie for a given url. The old cookie with same host/path/name will
- * be removed. The new cookie will be added if it is not expired or it does
- * not have expiration which implies it is session cookie.
- * @param url The url which cookie is set for
- * @param value The value for set-cookie: in http response header
+ * Sets a cookie for the given URL. Any existing cookie with the same host,
+ * path and name will be replaced with the new cookie. The cookie being set
+ * must not have expired and must not be a session cookie, otherwise it
+ * will be ignored.
+ * @param url The URL for which the cookie is set
+ * @param value The cookie as a string, using the format of the
+ * 'Set-Cookie' HTTP response header
*/
public void setCookie(String url, String value) {
if (JniUtil.useChromiumHttpStack()) {
@@ -310,15 +316,13 @@
}
/**
- * Set cookie for a given url. The old cookie with same host/path/name will
- * be removed. The new cookie will be added if it is not expired or it does
- * not have expiration which implies it is session cookie.
- * @param url The url which cookie is set for
- * @param value The value for set-cookie: in http response header
- * @param privateBrowsing cookie jar to use
- * @hide hiding private browsing
+ * See {@link setCookie(String, String)}
+ * @param url The URL for which the cookie is set
+ * @param value The value of the cookie, as a string, using the format of
+ * the 'Set-Cookie' HTTP response header
+ * @param privateBrowsing Whether to use the private browsing cookie jar
*/
- public void setCookie(String url, String value, boolean privateBrowsing) {
+ void setCookie(String url, String value, boolean privateBrowsing) {
if (!JniUtil.useChromiumHttpStack()) {
setCookie(url, value);
return;
@@ -336,15 +340,12 @@
}
/**
- * Set cookie for a given uri. The old cookie with same host/path/name will
- * be removed. The new cookie will be added if it is not expired or it does
- * not have expiration which implies it is session cookie.
- * @param uri The uri which cookie is set for
- * @param value The value for set-cookie: in http response header
- * @hide - hide this because it takes in a parameter of type WebAddress,
- * a system private class.
+ * See {@link setCookie(String, String)}
+ * @param uri The WebAddress for which the cookie is set
+ * @param value The value of the cookie, as a string, using the format of
+ * the 'Set-Cookie' HTTP response header
*/
- public synchronized void setCookie(WebAddress uri, String value) {
+ synchronized void setCookie(WebAddress uri, String value) {
if (JniUtil.useChromiumHttpStack()) {
nativeSetCookie(uri.toString(), value, false);
return;
@@ -450,10 +451,10 @@
}
/**
- * Get cookie(s) for a given url so that it can be set to "cookie:" in http
- * request header.
- * @param url The url needs cookie
- * @return The cookies in the format of NAME=VALUE [; NAME=VALUE]
+ * Gets the cookies for the given URL.
+ * @param url The URL for which the cookies are requested
+ * @return value The cookies as a string, using the format of the 'Cookie'
+ * HTTP request header
*/
public String getCookie(String url) {
if (JniUtil.useChromiumHttpStack()) {
@@ -472,12 +473,12 @@
}
/**
- * Get cookie(s) for a given url so that it can be set to "cookie:" in http
- * request header.
- * @param url The url needs cookie
- * @param privateBrowsing cookie jar to use
- * @return The cookies in the format of NAME=VALUE [; NAME=VALUE]
- * @hide Private mode is not very well exposed for now
+ * See {@link getCookie(String)}
+ * @param url The URL for which the cookies are requested
+ * @param privateBrowsing Whether to use the private browsing cookie jar
+ * @return value The cookies as a string, using the format of the 'Cookie'
+ * HTTP request header
+ * @hide Used by Browser, no intention to publish.
*/
public String getCookie(String url, boolean privateBrowsing) {
if (!JniUtil.useChromiumHttpStack()) {
@@ -499,10 +500,10 @@
/**
* Get cookie(s) for a given uri so that it can be set to "cookie:" in http
* request header.
- * @param uri The uri needs cookie
- * @return The cookies in the format of NAME=VALUE [; NAME=VALUE]
- * @hide - hide this because it has a parameter of type WebAddress, which
- * is a system private class.
+ * @param uri The WebAddress for which the cookies are requested
+ * @return value The cookies as a string, using the format of the 'Cookie'
+ * HTTP request header
+ * @hide Used by RequestHandle, no intention to publish.
*/
public synchronized String getCookie(WebAddress uri) {
if (JniUtil.useChromiumHttpStack()) {
@@ -579,13 +580,12 @@
/**
* Waits for pending operations to completed.
- * {@hide} Too late to release publically.
*/
- public void waitForCookieOperationsToComplete() {
+ void waitForCookieOperationsToComplete() {
// Note that this function is applicable for both the java
// and native http stacks, and works correctly with either.
synchronized (this) {
- while (pendingCookieOperations > 0) {
+ while (mPendingCookieOperations > 0) {
try {
wait();
} catch (InterruptedException e) { }
@@ -594,17 +594,18 @@
}
private synchronized void signalCookieOperationsComplete() {
- pendingCookieOperations--;
- assert pendingCookieOperations > -1;
+ mPendingCookieOperations--;
+ assert mPendingCookieOperations > -1;
notify();
}
private synchronized void signalCookieOperationsStart() {
- pendingCookieOperations++;
+ mPendingCookieOperations++;
}
/**
- * Remove all session cookies, which are cookies without expiration date
+ * Removes all session cookies, which are cookies without an expiration
+ * date.
*/
public void removeSessionCookie() {
signalCookieOperationsStart();
@@ -643,7 +644,7 @@
}
/**
- * Remove all cookies
+ * Removes all cookies.
*/
public void removeAllCookie() {
if (JniUtil.useChromiumHttpStack()) {
@@ -664,7 +665,8 @@
}
/**
- * Return true if there are stored cookies.
+ * Gets whether there are stored cookies.
+ * @return True if there are stored cookies.
*/
public synchronized boolean hasCookies() {
if (JniUtil.useChromiumHttpStack()) {
@@ -675,9 +677,9 @@
}
/**
- * Return true if there are stored cookies.
- * @param privateBrowsing cookie jar to use
- * @hide Hiding private mode
+ * See {@link hasCookies()}.
+ * @param privateBrowsing Whether to use the private browsing cookie jar
+ * @hide Used by Browser, no intention to publish.
*/
public synchronized boolean hasCookies(boolean privateBrowsing) {
if (!JniUtil.useChromiumHttpStack()) {
@@ -688,7 +690,7 @@
}
/**
- * Remove all expired cookies
+ * Removes all expired cookies.
*/
public void removeExpiredCookie() {
if (JniUtil.useChromiumHttpStack()) {
@@ -733,7 +735,10 @@
}
/**
- * Whether cookies are accepted for file scheme URLs.
+ * Gets whether the application's {@link WebView} instances send and accept
+ * cookies for file scheme URLs.
+ * @return True if {@link WebView} instances send and accept cookies for
+ * file scheme URLs
*/
public static boolean allowFileSchemeCookies() {
if (JniUtil.useChromiumHttpStack()) {
@@ -744,13 +749,14 @@
}
/**
- * Sets whether cookies are accepted for file scheme URLs.
- *
- * Use of cookies with file scheme URLs is potentially insecure. Do not use this feature unless
- * you can be sure that no unintentional sharing of cookie data can take place.
+ * Sets whether the application's {@link WebView} instances should send and
+ * accept cookies for file scheme URLs.
+ * Use of cookies with file scheme URLs is potentially insecure. Do not use
+ * this feature unless you can be sure that no unintentional sharing of
+ * cookie data can take place.
* <p>
- * Note that calls to this method will have no effect if made after a WebView or CookieManager
- * instance has been created.
+ * Note that calls to this method will have no effect if made after a
+ * {@link WebView} or CookieManager instance has been created.
*/
public static void setAcceptFileSchemeCookies(boolean accept) {
if (JniUtil.useChromiumHttpStack()) {
diff --git a/core/java/android/webkit/FindActionModeCallback.java b/core/java/android/webkit/FindActionModeCallback.java
index fffa90b..10b0885 100644
--- a/core/java/android/webkit/FindActionModeCallback.java
+++ b/core/java/android/webkit/FindActionModeCallback.java
@@ -43,7 +43,9 @@
private Resources mResources;
private boolean mMatchesFound;
private int mNumberOfMatches;
+ private int mActiveMatchIndex;
private ActionMode mActionMode;
+ private String mLastFind;
FindActionModeCallback(Context context) {
mCustomView = LayoutInflater.from(context).inflate(
@@ -132,16 +134,13 @@
mWebView.clearMatches();
mMatches.setVisibility(View.GONE);
mMatchesFound = false;
+ mLastFind = null;
} else {
mMatchesFound = true;
- mMatches.setVisibility(View.VISIBLE);
- mNumberOfMatches = mWebView.findAll(find.toString());
- if (0 == mNumberOfMatches) {
- mMatches.setText(mResources.getString(
- com.android.internal.R.string.no_matches));
- } else {
- updateMatchesString();
- }
+ mMatches.setVisibility(View.INVISIBLE);
+ mNumberOfMatches = 0;
+ mLastFind = find.toString();
+ mWebView.findAllAsync(mLastFind);
}
}
@@ -151,17 +150,31 @@
mInput.showSoftInput(mEditText, 0);
}
+ public void updateMatchCount(int matchIndex, int matchCount,
+ String findText) {
+ if (mLastFind != null && mLastFind.equals(findText)) {
+ mNumberOfMatches = matchCount;
+ mActiveMatchIndex = matchIndex;
+ updateMatchesString();
+ } else {
+ mMatches.setVisibility(View.INVISIBLE);
+ mNumberOfMatches = 0;
+ }
+ }
+
/*
* Update the string which tells the user how many matches were found, and
* which match is currently highlighted.
- * Not to be called when mNumberOfMatches is 0.
*/
private void updateMatchesString() {
- String template = mResources.getQuantityString(
+ if (mNumberOfMatches == 0) {
+ mMatches.setText(com.android.internal.R.string.no_matches);
+ } else {
+ mMatches.setText(mResources.getQuantityString(
com.android.internal.R.plurals.matches_found, mNumberOfMatches,
- mWebView.findIndex() + 1, mNumberOfMatches);
-
- mMatches.setText(template);
+ mActiveMatchIndex + 1, mNumberOfMatches));
+ }
+ mMatches.setVisibility(View.VISIBLE);
}
// OnLongClickListener implementation
diff --git a/core/java/android/webkit/LoadListener.java b/core/java/android/webkit/LoadListener.java
index 37e8bc0..4d7ade51 100644
--- a/core/java/android/webkit/LoadListener.java
+++ b/core/java/android/webkit/LoadListener.java
@@ -985,7 +985,7 @@
* be used. This is just for forward/back navigation to a POST
* URL.
*/
- static boolean willLoadFromCache(String url, long identifier) {
+ private static boolean willLoadFromCache(String url, long identifier) {
assert !JniUtil.useChromiumHttpStack();
boolean inCache =
CacheManager.getCacheFile(url, identifier, null) != null;
diff --git a/core/java/android/webkit/WebResourceResponse.java b/core/java/android/webkit/WebResourceResponse.java
index e786838..24e0d11 100644
--- a/core/java/android/webkit/WebResourceResponse.java
+++ b/core/java/android/webkit/WebResourceResponse.java
@@ -21,9 +21,9 @@
import java.io.InputStream;
/**
- * A WebResourceResponse is return by
- * {@link WebViewClient#shouldInterceptRequest} and
- * contains the response information for a particular resource.
+ * Encapsulates a resource response. Applications can return an instance of this
+ * class from {@link WebViewClient#shouldInterceptRequest} to provide a custom
+ * response when the WebView requests a particular resource.
*/
public class WebResourceResponse {
@@ -50,11 +50,13 @@
private InputStream mInputStream;
/**
- * Construct a response with the given mime type, encoding, and data.
- * @param mimeType The mime type of the data (i.e. text/html).
- * @param encoding The encoding of the bytes read from data.
- * @param data An InputStream for reading custom data. The implementation
- * must implement {@link InputStream#read(byte[])}.
+ * Constructs a resource response with the given MIME type, encoding, and
+ * input stream. Callers must implement
+ * {@link InputStream#read(byte[]) InputStream.read(byte[])} for the input
+ * stream.
+ * @param mimeType The resource response's MIME type, for example text/html
+ * @param encoding The resource response's encoding
+ * @param data The input stream that provides the resource response's data
*/
public WebResourceResponse(String mimeType, String encoding,
InputStream data) {
@@ -64,47 +66,50 @@
}
/**
- * Set the mime type of the response data (i.e. text/html).
- * @param mimeType
+ * Sets the resource response's MIME type, for example text/html.
+ * @param mimeType The resource response's MIME type
*/
public void setMimeType(String mimeType) {
mMimeType = mimeType;
}
/**
- * @see #setMimeType
+ * Gets the resource response's MIME type.
+ * @return The resource response's MIME type
*/
public String getMimeType() {
return mMimeType;
}
/**
- * Set the encoding of the response data (i.e. utf-8). This will be used to
- * decode the raw bytes from the input stream.
- * @param encoding
+ * Sets the resource response's encoding, for example UTF-8. This is used
+ * to decode the data from the input stream.
+ * @param encoding The resource response's encoding
*/
public void setEncoding(String encoding) {
mEncoding = encoding;
}
/**
- * @see #setEncoding
+ * Gets the resource response's encoding.
+ * @return The resource response's encoding
*/
public String getEncoding() {
return mEncoding;
}
/**
- * Set the input stream containing the data for this resource.
- * @param data An InputStream for reading custom data. The implementation
- * must implement {@link InputStream#read(byte[])}.
+ * Sets the input stream that provides the resource respone's data. Callers
+ * must implement {@link InputStream#read(byte[]) InputStream.read(byte[])}.
+ * @param data The input stream that provides the resource response's data
*/
public void setData(InputStream data) {
mInputStream = data;
}
/**
- * @see #setData
+ * Gets the input stream that provides the resource respone's data.
+ * @return The input stream that provides the resource response's data
*/
public InputStream getData() {
return mInputStream;
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 9cd51d0..79bd35b 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -16,6 +16,7 @@
package android.webkit;
+import android.animation.ObjectAnimator;
import android.annotation.Widget;
import android.app.ActivityManager;
import android.app.AlertDialog;
@@ -36,6 +37,7 @@
import android.graphics.BitmapShader;
import android.graphics.Canvas;
import android.graphics.Color;
+import android.graphics.ColorFilter;
import android.graphics.DrawFilter;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
@@ -59,6 +61,7 @@
import android.os.StrictMode;
import android.os.SystemClock;
import android.provider.Settings;
+import android.security.KeyChain;
import android.speech.tts.TextToSpeech;
import android.text.Editable;
import android.text.InputType;
@@ -913,7 +916,7 @@
static final int REPLACE_BASE_CONTENT = 123;
static final int FORM_DID_BLUR = 124;
static final int RETURN_LABEL = 125;
- static final int FIND_AGAIN = 126;
+ static final int UPDATE_MATCH_COUNT = 126;
static final int CENTER_FIT_RECT = 127;
static final int REQUEST_KEYBOARD_WITH_SELECTION_MSG_ID = 128;
static final int SET_SCROLLBAR_MODES = 129;
@@ -978,7 +981,7 @@
"REPLACE_BASE_CONTENT", // = 123;
"FORM_DID_BLUR", // = 124;
"RETURN_LABEL", // = 125;
- "FIND_AGAIN", // = 126;
+ "UPDATE_MATCH_COUNT", // = 126;
"CENTER_FIT_RECT", // = 127;
"REQUEST_KEYBOARD_WITH_SELECTION_MSG_ID", // = 128;
"SET_SCROLLBAR_MODES", // = 129;
@@ -1020,9 +1023,8 @@
// keep these in sync with their counterparts in WebView.cpp
private static final int DRAW_EXTRAS_NONE = 0;
- private static final int DRAW_EXTRAS_FIND = 1;
- private static final int DRAW_EXTRAS_SELECTION = 2;
- private static final int DRAW_EXTRAS_CURSOR_RING = 3;
+ private static final int DRAW_EXTRAS_SELECTION = 1;
+ private static final int DRAW_EXTRAS_CURSOR_RING = 2;
// keep this in sync with WebCore:ScrollbarMode in WebKit
private static final int SCROLLBAR_AUTO = 0;
@@ -1303,6 +1305,7 @@
init();
setupPackageListener(context);
setupProxyListener(context);
+ setupTrustStorageListener(context);
updateMultiTouchSupport(context);
if (privateBrowsing) {
@@ -1312,6 +1315,41 @@
mAutoFillData = new WebViewCore.AutoFillData();
}
+ private static class TrustStorageListener extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent.getAction().equals(KeyChain.ACTION_STORAGE_CHANGED)) {
+ handleCertTrustChanged();
+ }
+ }
+ }
+ private static TrustStorageListener sTrustStorageListener;
+
+ /**
+ * Handles update to the trust storage.
+ */
+ private static void handleCertTrustChanged() {
+ // send a message for indicating trust storage change
+ WebViewCore.sendStaticMessage(EventHub.TRUST_STORAGE_UPDATED, null);
+ }
+
+ /*
+ * @param context This method expects this to be a valid context.
+ */
+ private static void setupTrustStorageListener(Context context) {
+ if (sTrustStorageListener != null ) {
+ return;
+ }
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(KeyChain.ACTION_STORAGE_CHANGED);
+ sTrustStorageListener = new TrustStorageListener();
+ Intent current =
+ context.getApplicationContext().registerReceiver(sTrustStorageListener, filter);
+ if (current != null) {
+ handleCertTrustChanged();
+ }
+ }
+
private static class ProxyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
@@ -1703,7 +1741,7 @@
}
/**
- * returns the height of the titlebarview (if any). Does not care about
+ * Returns the height (in pixels) of the embedded title bar (if any). Does not care about
* scrolling
* @hide
*/
@@ -1712,12 +1750,15 @@
}
/**
- * Return the amount of the titlebarview (if any) that is visible
+ * Return the visible height (in pixels) of the embedded title bar (if any).
*
+ * @return This method is obsolete and always returns 0.
* @deprecated This method is now obsolete.
*/
@Deprecated
public int getVisibleTitleHeight() {
+ // Actually, this method returns the height of the embedded title bar if one is set via the
+ // hidden setEmbeddedTitleBar method.
checkThread();
return getVisibleTitleHeightImpl();
}
@@ -3671,7 +3712,7 @@
public void findNext(boolean forward) {
checkThread();
if (0 == mNativeClass) return; // client isn't initialized
- nativeFindNext(forward);
+ mWebViewCore.sendMessage(EventHub.FIND_NEXT, forward ? 1 : 0);
}
/*
@@ -3681,13 +3722,40 @@
* that were found.
*/
public int findAll(String find) {
+ return findAllBody(find, false);
+ }
+
+ /**
+ * @hide
+ */
+ public void findAllAsync(String find) {
+ findAllBody(find, true);
+ }
+
+ private int findAllBody(String find, boolean isAsync) {
checkThread();
if (0 == mNativeClass) return 0; // client isn't initialized
- int result = find != null ? nativeFindAll(find.toLowerCase(),
- find.toUpperCase(), find.equalsIgnoreCase(mLastFind)) : 0;
- invalidate();
mLastFind = find;
- return result;
+ mWebViewCore.removeMessages(EventHub.FIND_ALL);
+ WebViewCore.FindAllRequest request = new
+ WebViewCore.FindAllRequest(find);
+ if (isAsync) {
+ mWebViewCore.sendMessage(EventHub.FIND_ALL, request);
+ return 0; // no need to wait for response
+ }
+ synchronized(request) {
+ try {
+ mWebViewCore.sendMessageAtFrontOfQueue(EventHub.FIND_ALL,
+ request);
+ while (request.mMatchCount == -1) {
+ request.wait();
+ }
+ }
+ catch (InterruptedException e) {
+ return 0;
+ }
+ }
+ return request.mMatchCount;
}
/**
@@ -3723,6 +3791,7 @@
}
if (text != null) {
mFindCallback.setText(text);
+ mFindCallback.findAll();
}
return true;
}
@@ -3742,14 +3811,6 @@
nativeSetFindIsUp(isUp);
}
- /**
- * Return the index of the currently highlighted match.
- */
- int findIndex() {
- if (0 == mNativeClass) return -1;
- return nativeFindIndex();
- }
-
// Used to know whether the find dialog is open. Affects whether
// or not we draw the highlights for matches.
private boolean mFindIsUp;
@@ -3816,10 +3877,11 @@
checkThread();
if (mNativeClass == 0)
return;
- nativeSetFindIsEmpty();
- invalidate();
+ mWebViewCore.removeMessages(EventHub.FIND_ALL);
+ mWebViewCore.sendMessage(EventHub.FIND_ALL, null);
}
+
/**
* Called when the find ActionMode ends.
*/
@@ -4561,15 +4623,7 @@
if (mTitleBar != null) {
canvas.translate(0, getTitleHeight());
}
- boolean drawJavaRings = !mTouchHighlightRegion.isEmpty()
- && (mTouchMode == TOUCH_INIT_MODE
- || mTouchMode == TOUCH_SHORTPRESS_START_MODE
- || mTouchMode == TOUCH_SHORTPRESS_MODE
- || mTouchMode == TOUCH_DONE_MODE);
- boolean drawNativeRings = !drawJavaRings;
- if (sDisableNavcache) {
- drawNativeRings = !drawJavaRings && !isInTouchMode();
- }
+ boolean drawNativeRings = !sDisableNavcache;
drawContent(canvas, drawNativeRings);
canvas.restoreToCount(saveCount);
@@ -4582,18 +4636,13 @@
invalidate();
}
- // paint the highlight in the end
- if (drawJavaRings) {
- long delay = System.currentTimeMillis() - mTouchHighlightRequested;
- if (delay < ViewConfiguration.getTapTimeout()) {
- Rect r = mTouchHighlightRegion.getBounds();
- postInvalidateDelayed(delay, r.left, r.top, r.right, r.bottom);
- } else {
- RegionIterator iter = new RegionIterator(mTouchHighlightRegion);
- Rect r = new Rect();
- while (iter.next(r)) {
- canvas.drawRect(r, mTouchHightlightPaint);
- }
+ if (mFocusTransition != null) {
+ mFocusTransition.draw(canvas);
+ } else if (shouldDrawHighlightRect()) {
+ RegionIterator iter = new RegionIterator(mTouchHighlightRegion);
+ Rect r = new Rect();
+ while (iter.next(r)) {
+ canvas.drawRect(r, mTouchHightlightPaint);
}
}
if (DEBUG_TOUCH_HIGHLIGHT) {
@@ -4914,12 +4963,12 @@
// decide which adornments to draw
int extras = DRAW_EXTRAS_NONE;
- if (mFindIsUp) {
- extras = DRAW_EXTRAS_FIND;
- } else if (mSelectingText) {
- extras = DRAW_EXTRAS_SELECTION;
- } else if (drawCursorRing) {
- extras = DRAW_EXTRAS_CURSOR_RING;
+ if (!mFindIsUp) {
+ if (mSelectingText) {
+ extras = DRAW_EXTRAS_SELECTION;
+ } else if (drawCursorRing) {
+ extras = DRAW_EXTRAS_CURSOR_RING;
+ }
}
if (DebugFlags.WEB_VIEW) {
Log.v(LOGTAG, "mFindIsUp=" + mFindIsUp
@@ -8844,13 +8893,6 @@
}
break;
- case FIND_AGAIN:
- // Ignore if find has been dismissed.
- if (mFindIsUp && mFindCallback != null) {
- mFindCallback.findAll();
- }
- break;
-
case DRAG_HELD_MOTIONLESS:
mHeldMotionless = MOTIONLESS_TRUE;
invalidate();
@@ -9055,6 +9097,14 @@
break;
}
+ case UPDATE_MATCH_COUNT: {
+ if (mFindCallback != null) {
+ mFindCallback.updateMatchCount(msg.arg1, msg.arg2,
+ (String) msg.obj);
+ }
+ break;
+ }
+
default:
super.handleMessage(msg);
break;
@@ -9062,10 +9112,112 @@
}
}
+ private boolean shouldDrawHighlightRect() {
+ if (mFocusedNode == null || mInitialHitTestResult == null) {
+ return false;
+ }
+ if (mTouchHighlightRegion.isEmpty()) {
+ return false;
+ }
+ if (mFocusedNode.mHasFocus) {
+ return !mFocusedNode.mEditable;
+ }
+ if (mInitialHitTestResult.mType == HitTestResult.UNKNOWN_TYPE) {
+ return false;
+ }
+ long delay = System.currentTimeMillis() - mTouchHighlightRequested;
+ if (delay < ViewConfiguration.getTapTimeout()) {
+ Rect r = mTouchHighlightRegion.getBounds();
+ postInvalidateDelayed(delay, r.left, r.top, r.right, r.bottom);
+ return false;
+ }
+ return true;
+ }
+
+
+ private FocusTransitionDrawable mFocusTransition = null;
+ static class FocusTransitionDrawable extends Drawable {
+ Region mPreviousRegion;
+ Region mNewRegion;
+ float mProgress = 0;
+ WebView mWebView;
+ Paint mPaint;
+ int mMaxAlpha;
+ Point mTranslate;
+
+ public FocusTransitionDrawable(WebView view) {
+ mWebView = view;
+ mPaint = new Paint(mWebView.mTouchHightlightPaint);
+ mMaxAlpha = mPaint.getAlpha();
+ }
+
+ @Override
+ public void setColorFilter(ColorFilter cf) {
+ }
+
+ @Override
+ public void setAlpha(int alpha) {
+ }
+
+ @Override
+ public int getOpacity() {
+ return 0;
+ }
+
+ public void setProgress(float p) {
+ mProgress = p;
+ if (mWebView.mFocusTransition == this) {
+ if (mProgress == 1f)
+ mWebView.mFocusTransition = null;
+ mWebView.invalidate();
+ }
+ }
+
+ public float getProgress() {
+ return mProgress;
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ if (mTranslate == null) {
+ Rect bounds = mPreviousRegion.getBounds();
+ Point from = new Point(bounds.centerX(), bounds.centerY());
+ mNewRegion.getBounds(bounds);
+ Point to = new Point(bounds.centerX(), bounds.centerY());
+ mTranslate = new Point(from.x - to.x, from.y - to.y);
+ }
+ int alpha = (int) (mProgress * mMaxAlpha);
+ RegionIterator iter = new RegionIterator(mPreviousRegion);
+ Rect r = new Rect();
+ mPaint.setAlpha(mMaxAlpha - alpha);
+ float tx = mTranslate.x * mProgress;
+ float ty = mTranslate.y * mProgress;
+ int save = canvas.save(Canvas.MATRIX_SAVE_FLAG);
+ canvas.translate(-tx, -ty);
+ while (iter.next(r)) {
+ canvas.drawRect(r, mPaint);
+ }
+ canvas.restoreToCount(save);
+ iter = new RegionIterator(mNewRegion);
+ r = new Rect();
+ mPaint.setAlpha(alpha);
+ save = canvas.save(Canvas.MATRIX_SAVE_FLAG);
+ tx = mTranslate.x - tx;
+ ty = mTranslate.y - ty;
+ canvas.translate(tx, ty);
+ while (iter.next(r)) {
+ canvas.drawRect(r, mPaint);
+ }
+ canvas.restoreToCount(save);
+ }
+ };
+
private void setTouchHighlightRects(WebKitHitTest hit) {
+ FocusTransitionDrawable transition = new FocusTransitionDrawable(this);
Rect[] rects = hit != null ? hit.mTouchRects : null;
if (!mTouchHighlightRegion.isEmpty()) {
invalidate(mTouchHighlightRegion.getBounds());
+ transition.mPreviousRegion = new Region(mTouchHighlightRegion);
mTouchHighlightRegion.setEmpty();
}
if (rects != null) {
@@ -9084,7 +9236,13 @@
+ viewRect);
}
}
+ transition.mNewRegion = new Region(mTouchHighlightRegion);
invalidate(mTouchHighlightRegion.getBounds());
+ if (hit.mHasFocus && transition.mPreviousRegion != null) {
+ mFocusTransition = transition;
+ ObjectAnimator animator = ObjectAnimator.ofFloat(mFocusTransition, "progress", 1f);
+ animator.start();
+ }
}
}
@@ -9891,9 +10049,6 @@
private native void nativeUpdateDrawGLFunction(Rect rect, Rect viewRect,
RectF visibleRect, float scale);
private native void nativeExtendSelection(int x, int y);
- private native int nativeFindAll(String findLower, String findUpper,
- boolean sameAsLastSearch);
- private native void nativeFindNext(boolean forward);
/* package */ native int nativeFocusCandidateFramePointer();
/* package */ native boolean nativeFocusCandidateHasNextTextfield();
/* package */ native boolean nativeFocusCandidateIsPassword();
@@ -9951,9 +10106,7 @@
private native boolean nativePointInNavCache(int x, int y, int slop);
private native void nativeSelectBestAt(Rect rect);
private native void nativeSelectAt(int x, int y);
- private native int nativeFindIndex();
private native void nativeSetExtendSelection();
- private native void nativeSetFindIsEmpty();
private native void nativeSetFindIsUp(boolean isUp);
private native void nativeSetHeightCanMeasure(boolean measure);
private native boolean nativeSetBaseLayer(int nativeInstance,
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index 14ecfbd..ee27dd4 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -26,6 +26,7 @@
import android.media.MediaFile;
import android.net.ProxyProperties;
import android.net.Uri;
+import android.net.http.CertificateChainValidator;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
@@ -775,6 +776,11 @@
Message m = (Message)msg.obj;
m.sendToTarget();
break;
+ case EventHub.TRUST_STORAGE_UPDATED:
+ // post a task to network thread for updating trust manager
+ nativeCertTrustChanged();
+ CertificateChainValidator.handleTrustStorageUpdate();
+ break;
}
}
};
@@ -881,6 +887,7 @@
boolean mEditable;
int mTapHighlightColor = WebView.HIGHLIGHT_COLOR;
Rect[] mEnclosingParentRects;
+ boolean mHasFocus;
// These are the input values that produced this hit test
int mHitTestX;
@@ -995,6 +1002,15 @@
"REMOVE_JS_INTERFACE", // = 149;
};
+ static class FindAllRequest {
+ public FindAllRequest(String text) {
+ mSearchText = text;
+ mMatchCount = -1;
+ }
+ public String mSearchText;
+ public int mMatchCount;
+ }
+
/**
* @hide
*/
@@ -1133,6 +1149,13 @@
static final int SELECT_WORD_AT = 214;
static final int SELECT_ALL = 215;
+ // for updating state on trust storage change
+ static final int TRUST_STORAGE_UPDATED = 220;
+
+ // find-on-page controls
+ static final int FIND_ALL = 220;
+ static final int FIND_NEXT = 221;
+
// Private handler for WebCore messages.
private Handler mHandler;
// Message queue for containing messages before the WebCore thread is
@@ -1776,6 +1799,22 @@
case SELECT_ALL:
nativeSelectAll(mNativeClass);
break;
+ case FIND_ALL: {
+ FindAllRequest request = (FindAllRequest) msg.obj;
+ if (request == null) {
+ nativeFindAll(mNativeClass, null);
+ } else {
+ request.mMatchCount = nativeFindAll(
+ mNativeClass, request.mSearchText);
+ synchronized(request) {
+ request.notify();
+ }
+ }
+ break;
+ }
+ case FIND_NEXT:
+ nativeFindNext(mNativeClass, msg.arg1 != 0);
+ break;
}
}
};
@@ -2774,13 +2813,6 @@
}
// called by JNI
- private void sendFindAgain() {
- if (mWebView == null) return;
- Message.obtain(mWebView.mPrivateHandler,
- WebView.FIND_AGAIN).sendToTarget();
- }
-
- // called by JNI
private void initEditField(int pointer, String text, int start, int end) {
if (mWebView == null) {
return;
@@ -2793,6 +2825,17 @@
.sendToTarget();
}
+ // called by JNI
+ private void updateMatchCount(int matchIndex, int matchCount,
+ String findText) {
+ if (mWebView == null) {
+ return;
+ }
+ Message.obtain(mWebView.mPrivateHandler,
+ WebView.UPDATE_MATCH_COUNT, matchIndex, matchCount,
+ findText).sendToTarget();
+ }
+
private native void nativeUpdateFrameCacheIfLoading(int nativeClass);
private native void nativeRevealSelection(int nativeClass);
private native String nativeRequestLabel(int nativeClass, int framePtr,
@@ -3046,6 +3089,8 @@
private native void nativeAutoFillForm(int nativeClass, int queryId);
private native void nativeScrollLayer(int nativeClass, int layer, Rect rect);
+ private native int nativeFindAll(int nativeClass, String text);
+ private native void nativeFindNext(int nativeClass, boolean forward);
/**
* Deletes editable text between two points. Note that the selection may
@@ -3082,4 +3127,6 @@
private native void nativeClearTextSelection(int nativeClass);
private native void nativeSelectWordAt(int nativeClass, int x, int y);
private native void nativeSelectAll(int nativeClass);
+
+ private static native void nativeCertTrustChanged();
}
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index e94b1cb..e7bc1e1 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -36,6 +36,7 @@
import android.util.AttributeSet;
import android.util.Log;
import android.util.LongSparseArray;
+import android.util.SparseArray;
import android.util.SparseBooleanArray;
import android.util.StateSet;
import android.view.ActionMode;
@@ -87,6 +88,8 @@
ViewTreeObserver.OnTouchModeChangeListener,
RemoteViewsAdapter.RemoteAdapterConnectionCallback {
+ private static final String TAG = "AbsListView";
+
/**
* Disables the transcript mode.
*
@@ -263,6 +266,11 @@
private RemoteViewsAdapter mRemoteAdapter;
/**
+ * If mAdapter != null, whenever this is true the adapter has stable IDs.
+ */
+ boolean mAdapterHasStableIds;
+
+ /**
* This flag indicates the a full notify is required when the RemoteViewsAdapter connects
*/
private boolean mDeferNotifyDataSetChanged = false;
@@ -812,7 +820,8 @@
@Override
public void setAdapter(ListAdapter adapter) {
if (adapter != null) {
- if (mChoiceMode != CHOICE_MODE_NONE && mAdapter.hasStableIds() &&
+ mAdapterHasStableIds = mAdapter.hasStableIds();
+ if (mChoiceMode != CHOICE_MODE_NONE && mAdapterHasStableIds &&
mCheckedIdStates == null) {
mCheckedIdStates = new LongSparseArray<Integer>();
}
@@ -2011,6 +2020,11 @@
isScrap[0] = false;
View scrapView;
+ scrapView = mRecycler.getTransientStateView(position);
+ if (scrapView != null) {
+ return scrapView;
+ }
+
scrapView = mRecycler.getScrapView(position);
View child;
@@ -2021,6 +2035,13 @@
}
child = mAdapter.getView(position, scrapView, this);
+ if (mAdapterHasStableIds) {
+ LayoutParams lp = (LayoutParams) child.getLayoutParams();
+ if (lp == null) {
+ lp = (LayoutParams) generateDefaultLayoutParams();
+ }
+ lp.itemId = mAdapter.getItemId(position);
+ }
if (ViewDebug.TRACE_RECYCLER) {
ViewDebug.trace(child, ViewDebug.RecyclerTraceType.BIND_VIEW,
@@ -4543,7 +4564,9 @@
if (count > 0) {
detachViewsFromParent(start, count);
+ mRecycler.removeSkippedScrap();
}
+
offsetChildrenTopAndBottom(incrementalDeltaY);
if (down) {
@@ -4853,6 +4876,9 @@
confirmCheckedPositionsById();
}
+ // TODO: In the future we can recycle these views based on stable ID instead.
+ mRecycler.clearTransientStateViews();
+
if (count > 0) {
int newPos;
int selectablePos;
@@ -5735,6 +5761,11 @@
*/
int scrappedFromPosition;
+ /**
+ * The ID the view represents
+ */
+ long itemId = -1;
+
public LayoutParams(Context c, AttributeSet attrs) {
super(c, attrs);
}
@@ -5807,6 +5838,10 @@
private ArrayList<View> mCurrentScrap;
+ private ArrayList<View> mSkippedScrap;
+
+ private SparseArray<View> mTransientStateViews;
+
public void setViewTypeCount(int viewTypeCount) {
if (viewTypeCount < 1) {
throw new IllegalArgumentException("Can't have a viewTypeCount < 1");
@@ -5838,6 +5873,12 @@
}
}
}
+ if (mTransientStateViews != null) {
+ final int count = mTransientStateViews.size();
+ for (int i = 0; i < count; i++) {
+ mTransientStateViews.valueAt(i).forceLayout();
+ }
+ }
}
public boolean shouldRecycleViewType(int viewType) {
@@ -5864,6 +5905,9 @@
}
}
}
+ if (mTransientStateViews != null) {
+ mTransientStateViews.clear();
+ }
}
/**
@@ -5910,6 +5954,28 @@
return null;
}
+ View getTransientStateView(int position) {
+ if (mTransientStateViews == null) {
+ return null;
+ }
+ final int index = mTransientStateViews.indexOfKey(position);
+ if (index < 0) {
+ return null;
+ }
+ final View result = mTransientStateViews.valueAt(index);
+ mTransientStateViews.removeAt(index);
+ return result;
+ }
+
+ /**
+ * Dump any currently saved views with transient state.
+ */
+ void clearTransientStateViews() {
+ if (mTransientStateViews != null) {
+ mTransientStateViews.clear();
+ }
+ }
+
/**
* @return A view from the ScrapViews collection. These are unordered.
*/
@@ -5926,7 +5992,7 @@
}
/**
- * Put a view into the ScapViews list. These views are unordered.
+ * Put a view into the ScrapViews list. These views are unordered.
*
* @param scrap The view to add
*/
@@ -5936,23 +6002,32 @@
return;
}
+ lp.scrappedFromPosition = position;
+
// Don't put header or footer views or views that should be ignored
// into the scrap heap
int viewType = lp.viewType;
- if (!shouldRecycleViewType(viewType)) {
- if (viewType != ITEM_VIEW_TYPE_HEADER_OR_FOOTER) {
- removeDetachedView(scrap, false);
+ final boolean scrapHasTransientState = scrap.hasTransientState();
+ if (!shouldRecycleViewType(viewType) || scrapHasTransientState) {
+ if (viewType != ITEM_VIEW_TYPE_HEADER_OR_FOOTER || scrapHasTransientState) {
+ if (mSkippedScrap == null) {
+ mSkippedScrap = new ArrayList<View>();
+ }
+ mSkippedScrap.add(scrap);
+ }
+ if (scrapHasTransientState) {
+ if (mTransientStateViews == null) {
+ mTransientStateViews = new SparseArray<View>();
+ }
+ mTransientStateViews.put(position, scrap);
}
return;
}
- lp.scrappedFromPosition = position;
-
+ scrap.dispatchStartTemporaryDetach();
if (mViewTypeCount == 1) {
- scrap.dispatchStartTemporaryDetach();
mCurrentScrap.add(scrap);
} else {
- scrap.dispatchStartTemporaryDetach();
mScrapViews[viewType].add(scrap);
}
@@ -5962,6 +6037,20 @@
}
/**
+ * Finish the removal of any views that skipped the scrap heap.
+ */
+ void removeSkippedScrap() {
+ if (mSkippedScrap == null) {
+ return;
+ }
+ final int count = mSkippedScrap.size();
+ for (int i = 0; i < count; i++) {
+ removeDetachedView(mSkippedScrap.get(i), false);
+ }
+ mSkippedScrap.clear();
+ }
+
+ /**
* Move all views remaining in mActiveViews to mScrapViews.
*/
void scrapActiveViews() {
@@ -5980,11 +6069,19 @@
activeViews[i] = null;
- if (!shouldRecycleViewType(whichScrap)) {
+ final boolean scrapHasTransientState = victim.hasTransientState();
+ if (!shouldRecycleViewType(whichScrap) || scrapHasTransientState) {
// Do not move views that should be ignored
- if (whichScrap != ITEM_VIEW_TYPE_HEADER_OR_FOOTER) {
+ if (whichScrap != ITEM_VIEW_TYPE_HEADER_OR_FOOTER ||
+ scrapHasTransientState) {
removeDetachedView(victim, false);
}
+ if (scrapHasTransientState) {
+ if (mTransientStateViews == null) {
+ mTransientStateViews = new SparseArray<View>();
+ }
+ mTransientStateViews.put(mFirstActivePosition + i, victim);
+ }
continue;
}
diff --git a/core/java/android/widget/CheckedTextView.java b/core/java/android/widget/CheckedTextView.java
index 5c7e5a3..dd53325 100644
--- a/core/java/android/widget/CheckedTextView.java
+++ b/core/java/android/widget/CheckedTextView.java
@@ -142,12 +142,8 @@
resolvePadding();
}
- /**
- * @hide
- */
@Override
- protected void resolvePadding() {
- super.resolvePadding();
+ public void onResolvePadding(int layoutDirection) {
int newPadding = (mCheckMarkDrawable != null) ?
mCheckMarkWidth + mBasePadding : mBasePadding;
mNeedRequestlayout |= (mPaddingRight != newPadding);
diff --git a/core/java/android/widget/EdgeEffect.java b/core/java/android/widget/EdgeEffect.java
index 326587e..83aa8ba 100644
--- a/core/java/android/widget/EdgeEffect.java
+++ b/core/java/android/widget/EdgeEffect.java
@@ -56,7 +56,7 @@
// Time it will take in ms for a pulled glow to decay to partial strength before release
private static final int PULL_DECAY_TIME = 1000;
- private static final float MAX_ALPHA = 0.8f;
+ private static final float MAX_ALPHA = 1.f;
private static final float HELD_EDGE_ALPHA = 0.7f;
private static final float HELD_EDGE_SCALE_Y = 0.5f;
private static final float HELD_GLOW_ALPHA = 0.5f;
diff --git a/core/java/android/widget/GridLayout.java b/core/java/android/widget/GridLayout.java
index ea40dc2..fc08cc5 100644
--- a/core/java/android/widget/GridLayout.java
+++ b/core/java/android/widget/GridLayout.java
@@ -127,8 +127,7 @@
*
* GridLayout does not provide support for the principle of <em>weight</em>, as defined in
* {@link LinearLayout.LayoutParams#weight}. In general, it is not therefore possible
- * to configure a GridLayout to distribute excess space in non-trivial proportions between
- * multiple rows or columns.
+ * to configure a GridLayout to distribute excess space between multiple components.
* <p>
* Some common use-cases may nevertheless be accommodated as follows.
* To place equal amounts of space around a component in a cell group;
@@ -209,7 +208,6 @@
static final String TAG = GridLayout.class.getName();
static final boolean DEBUG = false;
- static final int PRF = 1;
static final int MAX_SIZE = 100000;
static final int DEFAULT_CONTAINER_MARGIN = 0;
static final int UNINITIALIZED_HASH = 0;
@@ -779,7 +777,7 @@
}
}
- private void drawRect(Canvas canvas, int x1, int y1, int x2, int y2, Paint paint) {
+ private static void drawRect(Canvas canvas, int x1, int y1, int x2, int y2, Paint paint) {
canvas.drawRect(x1, y1, x2 - 1, y2 - 1, paint);
}
@@ -957,10 +955,6 @@
resolveSizeAndState(measuredHeight, heightSpec, 0));
}
- private int protect(int alignment) {
- return (alignment == UNDEFINED) ? 0 : alignment;
- }
-
private int getMeasurement(View c, boolean horizontal) {
return horizontal ? c.getMeasuredWidth() : c.getMeasuredHeight();
}
@@ -1040,42 +1034,31 @@
Alignment hAlign = getAlignment(columnSpec.alignment, true);
Alignment vAlign = getAlignment(rowSpec.alignment, false);
- Bounds colBounds = horizontalAxis.getGroupBounds().getValue(i);
- Bounds rowBounds = verticalAxis.getGroupBounds().getValue(i);
+ Bounds boundsX = horizontalAxis.getGroupBounds().getValue(i);
+ Bounds boundsY = verticalAxis.getGroupBounds().getValue(i);
// Gravity offsets: the location of the alignment group relative to its cell group.
- //noinspection NullableProblems
- int gravityOffsetX = protect(hAlign.getAlignmentValue(null,
- cellWidth - colBounds.size(true)));
- //noinspection NullableProblems
- int gravityOffsetY = protect(vAlign.getAlignmentValue(null,
- cellHeight - rowBounds.size(true)));
+ int gravityOffsetX = hAlign.getGravityOffset(c, cellWidth - boundsX.size(true));
+ int gravityOffsetY = vAlign.getGravityOffset(c, cellHeight - boundsY.size(true));
- boolean rtl = isLayoutRtl();
- int startMargin = getMargin(c, true, !rtl);
+ int leftMargin = getMargin(c, true, true);
int topMargin = getMargin(c, false, true);
- int endMargin = getMargin(c, true, rtl);
+ int rightMargin = getMargin(c, true, false);
int bottomMargin = getMargin(c, false, false);
- // Same calculation as getMeasurementIncludingMargin()
- int mWidth = startMargin + pWidth + endMargin;
- int mHeight = topMargin + pHeight + bottomMargin;
-
// Alignment offsets: the location of the view relative to its alignment group.
- int alignmentOffsetX = colBounds.getOffset(c, hAlign, mWidth);
- int alignmentOffsetY = rowBounds.getOffset(c, vAlign, mHeight);
+ int alignmentOffsetX = boundsX.getOffset(c, hAlign, leftMargin + pWidth + rightMargin);
+ int alignmentOffsetY = boundsY.getOffset(c, vAlign, topMargin + pHeight + bottomMargin);
- int dx = gravityOffsetX + alignmentOffsetX + startMargin;
- int dy = gravityOffsetY + alignmentOffsetY + topMargin;
+ int width = hAlign.getSizeInCell(c, pWidth, cellWidth - leftMargin - rightMargin);
+ int height = vAlign.getSizeInCell(c, pHeight, cellHeight - topMargin - bottomMargin);
- cellWidth -= startMargin + endMargin;
- cellHeight -= topMargin + bottomMargin;
+ int dx = x1 + gravityOffsetX + alignmentOffsetX;
- int width = hAlign.getSizeInCell(c, pWidth, cellWidth, PRF);
- int height = vAlign.getSizeInCell(c, pHeight, cellHeight, PRF);
+ int cx = !isLayoutRtl() ? paddingLeft + leftMargin + dx :
+ targetWidth - width - paddingRight - rightMargin - dx;
+ int cy = paddingTop + y1 + gravityOffsetY + alignmentOffsetY + topMargin;
- int cx = rtl ? targetWidth - paddingRight - x1 - dx - width : paddingLeft + x1 + dx;
- int cy = paddingTop + y1 + dy;
if (width != c.getMeasuredWidth() || height != c.getMeasuredHeight()) {
c.measure(makeMeasureSpec(width, EXACTLY), makeMeasureSpec(height, EXACTLY));
}
@@ -1694,7 +1677,7 @@
* each cell group. The fundamental parameters associated with each cell group are
* gathered into their vertical and horizontal components and stored
* in the {@link #rowSpec} and {@link #columnSpec} layout parameters.
- * {@link android.widget.GridLayout.Spec Specs} are immutable structures
+ * {@link GridLayout.Spec Specs} are immutable structures
* and may be shared between the layout parameters of different children.
* <p>
* The row and column specs contain the leading and trailing indices along each axis
@@ -1747,7 +1730,7 @@
* <li>{@link #rowSpec}<code>.alignment</code> = {@link #BASELINE} </li>
* <li>{@link #columnSpec}<code>.column</code> = {@link #UNDEFINED} </li>
* <li>{@link #columnSpec}<code>.columnSpan</code> = 1 </li>
- * <li>{@link #columnSpec}<code>.alignment</code> = {@link #LEFT} </li>
+ * <li>{@link #columnSpec}<code>.alignment</code> = {@link #START} </li>
* </ul>
*
* See {@link GridLayout} for a more complete description of the conventions
@@ -1936,7 +1919,7 @@
/**
* Describes how the child views are positioned. Default is {@code LEFT | BASELINE}.
- * See {@link android.view.Gravity}.
+ * See {@link Gravity}.
*
* @param gravity the new gravity value
*
@@ -2426,8 +2409,8 @@
* group is specified by the two alignments which act along each axis independently.
* <p>
* The GridLayout class defines the most common alignments used in general layout:
- * {@link #TOP}, {@link #LEFT}, {@link #BOTTOM}, {@link #RIGHT}, {@link #CENTER}, {@link
- * #BASELINE} and {@link #FILL}.
+ * {@link #TOP}, {@link #LEFT}, {@link #BOTTOM}, {@link #RIGHT}, {@link #START},
+ * {@link #END}, {@link #CENTER}, {@link #BASELINE} and {@link #FILL}.
*/
/*
* An Alignment implementation must define {@link #getAlignmentValue(View, int, int)},
@@ -2441,6 +2424,8 @@
Alignment() {
}
+ abstract int getGravityOffset(View view, int cellDelta);
+
/**
* Returns an alignment value. In the case of vertical alignments the value
* returned should indicate the distance from the top of the view to the
@@ -2463,12 +2448,9 @@
* @param view the view to which this alignment should be applied
* @param viewSize the measured size of the view
* @param cellSize the size of the cell into which this view will be placed
- * @param measurementType This parameter is currently unused as GridLayout only supports
- * one type of measurement: {@link View#measure(int, int)}.
- *
* @return the aligned size
*/
- int getSizeInCell(View view, int viewSize, int cellSize, int measurementType) {
+ int getSizeInCell(View view, int viewSize, int cellSize) {
return viewSize;
}
@@ -2479,6 +2461,11 @@
static final Alignment UNDEFINED_ALIGNMENT = new Alignment() {
@Override
+ int getGravityOffset(View view, int cellDelta) {
+ return UNDEFINED;
+ }
+
+ @Override
public int getAlignmentValue(View view, int viewSize) {
return UNDEFINED;
}
@@ -2490,6 +2477,11 @@
*/
private static final Alignment LEADING = new Alignment() {
@Override
+ int getGravityOffset(View view, int cellDelta) {
+ return 0;
+ }
+
+ @Override
public int getAlignmentValue(View view, int viewSize) {
return 0;
}
@@ -2501,6 +2493,11 @@
*/
private static final Alignment TRAILING = new Alignment() {
@Override
+ int getGravityOffset(View view, int cellDelta) {
+ return cellDelta;
+ }
+
+ @Override
public int getAlignmentValue(View view, int viewSize) {
return viewSize;
}
@@ -2530,15 +2527,16 @@
*/
public static final Alignment END = TRAILING;
- private static Alignment getAbsoluteAlignment(final Alignment a1, final Alignment a2) {
+ private static Alignment createSwitchingAlignment(final Alignment ltr, final Alignment rtl) {
return new Alignment() {
@Override
+ int getGravityOffset(View view, int cellDelta) {
+ return (!view.isLayoutRtl() ? ltr : rtl).getGravityOffset(view, cellDelta);
+ }
+
+ @Override
public int getAlignmentValue(View view, int viewSize) {
- if (view == null) {
- return UNDEFINED;
- }
- Alignment alignment = view.isLayoutRtl() ? a2 : a1;
- return alignment.getAlignmentValue(view, viewSize);
+ return (!view.isLayoutRtl() ? ltr : rtl).getAlignmentValue(view, viewSize);
}
};
}
@@ -2547,13 +2545,13 @@
* Indicates that a view should be aligned with the <em>left</em>
* edges of the other views in its cell group.
*/
- public static final Alignment LEFT = getAbsoluteAlignment(START, END);
+ public static final Alignment LEFT = createSwitchingAlignment(START, END);
/**
* Indicates that a view should be aligned with the <em>right</em>
* edges of the other views in its cell group.
*/
- public static final Alignment RIGHT = getAbsoluteAlignment(END, START);
+ public static final Alignment RIGHT = createSwitchingAlignment(END, START);
/**
* Indicates that a view should be <em>centered</em> with the other views in its cell group.
@@ -2562,6 +2560,11 @@
*/
public static final Alignment CENTER = new Alignment() {
@Override
+ int getGravityOffset(View view, int cellDelta) {
+ return cellDelta >> 1;
+ }
+
+ @Override
public int getAlignmentValue(View view, int viewSize) {
return viewSize >> 1;
}
@@ -2576,10 +2579,12 @@
*/
public static final Alignment BASELINE = new Alignment() {
@Override
+ int getGravityOffset(View view, int cellDelta) {
+ return 0; // baseline gravity is top
+ }
+
+ @Override
public int getAlignmentValue(View view, int viewSize) {
- if (view == null) {
- return UNDEFINED;
- }
int baseline = view.getBaseline();
return (baseline == -1) ? UNDEFINED : baseline;
}
@@ -2627,12 +2632,17 @@
*/
public static final Alignment FILL = new Alignment() {
@Override
+ int getGravityOffset(View view, int cellDelta) {
+ return 0;
+ }
+
+ @Override
public int getAlignmentValue(View view, int viewSize) {
return UNDEFINED;
}
@Override
- public int getSizeInCell(View view, int viewSize, int cellSize, int measurementType) {
+ public int getSizeInCell(View view, int viewSize, int cellSize) {
return cellSize;
}
};
diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java
index be2df8e..6bc5a15 100644
--- a/core/java/android/widget/GridView.java
+++ b/core/java/android/widget/GridView.java
@@ -1205,6 +1205,7 @@
// Clear out old views
//removeAllViewsInLayout();
detachAllViewsFromParent();
+ recycleBin.removeSkippedScrap();
switch (mLayoutMode) {
case LAYOUT_SET_SELECTION:
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 67fd059..46c2c07 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -1591,6 +1591,7 @@
// Clear out old views
detachAllViewsFromParent();
+ recycleBin.removeSkippedScrap();
switch (mLayoutMode) {
case LAYOUT_SET_SELECTION:
diff --git a/core/java/android/widget/SpellChecker.java b/core/java/android/widget/SpellChecker.java
index 909f383..a1cf205 100644
--- a/core/java/android/widget/SpellChecker.java
+++ b/core/java/android/widget/SpellChecker.java
@@ -24,6 +24,7 @@
import android.text.method.WordIterator;
import android.text.style.SpellCheckSpan;
import android.text.style.SuggestionSpan;
+import android.view.textservice.SentenceSuggestionsInfo;
import android.view.textservice.SpellCheckerSession;
import android.view.textservice.SpellCheckerSession.SpellCheckerSessionListener;
import android.view.textservice.SuggestionsInfo;
@@ -277,9 +278,9 @@
}
@Override
- public void onGetSuggestionsForSentence(SuggestionsInfo[] results) {
+ public void onGetSentenceSuggestions(SentenceSuggestionsInfo[] results) {
// TODO: Handle the position and length for each suggestion
- onGetSuggestions(results);
+ // do nothing for now
}
@Override
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 13798ef..f66da29 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -3807,21 +3807,21 @@
}
}
- Handler h = getHandler();
- if (h != null) {
+ ViewRootImpl viewRootImpl = getViewRootImpl();
+ if (viewRootImpl != null) {
long eventTime = SystemClock.uptimeMillis();
- h.sendMessage(h.obtainMessage(ViewRootImpl.DISPATCH_KEY_FROM_IME,
+ viewRootImpl.dispatchKeyFromIme(
new KeyEvent(eventTime, eventTime,
KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_ENTER, 0, 0,
KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE
- | KeyEvent.FLAG_EDITOR_ACTION)));
- h.sendMessage(h.obtainMessage(ViewRootImpl.DISPATCH_KEY_FROM_IME,
+ | KeyEvent.FLAG_EDITOR_ACTION));
+ viewRootImpl.dispatchKeyFromIme(
new KeyEvent(SystemClock.uptimeMillis(), eventTime,
KeyEvent.ACTION_UP, KeyEvent.KEYCODE_ENTER, 0, 0,
KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE
- | KeyEvent.FLAG_EDITOR_ACTION)));
+ | KeyEvent.FLAG_EDITOR_ACTION));
}
}
@@ -5022,15 +5022,19 @@
hardwareCanvas.setViewport(width, height);
// The dirty rect should always be null for a display list
hardwareCanvas.onPreDraw(null);
+ hardwareCanvas.translate(-mScrollX, -mScrollY);
layout.draw(hardwareCanvas, highlight, mHighlightPaint, cursorOffsetVertical);
+ hardwareCanvas.translate(mScrollX, mScrollY);
} finally {
hardwareCanvas.onPostDraw();
mTextDisplayList.end();
mTextDisplayListIsValid = true;
}
}
- ((HardwareCanvas) canvas).drawDisplayList(mTextDisplayList,
- mScrollX + width, mScrollY + height, null);
+ canvas.translate(mScrollX, mScrollY);
+ ((HardwareCanvas) canvas).drawDisplayList(mTextDisplayList, width, height, null,
+ DisplayList.FLAG_CLIP_CHILDREN);
+ canvas.translate(-mScrollX, -mScrollY);
} else {
layout.draw(canvas, highlight, mHighlightPaint, cursorOffsetVertical);
}
@@ -11407,7 +11411,7 @@
}
@Override
- protected void resolveTextDirection() {
+ public void onResolveTextDirection() {
if (hasPasswordTransformationMethod()) {
mTextDir = TextDirectionHeuristics.LOCALE;
return;
@@ -11416,9 +11420,6 @@
// Always need to resolve layout direction first
final boolean defaultIsRtl = (getResolvedLayoutDirection() == LAYOUT_DIRECTION_RTL);
- // Then resolve text direction on the parent
- super.resolveTextDirection();
-
// Now, we can select the heuristic
int textDir = getResolvedTextDirection();
switch (textDir) {
@@ -11447,7 +11448,6 @@
* drawables depending on the layout direction.
*
* A call to the super method will be required from the subclasses implementation.
- *
*/
protected void resolveDrawables() {
// No need to resolve twice
diff --git a/core/java/android/widget/ZoomButtonsController.java b/core/java/android/widget/ZoomButtonsController.java
index f3d891d1..02dc27b 100644
--- a/core/java/android/widget/ZoomButtonsController.java
+++ b/core/java/android/widget/ZoomButtonsController.java
@@ -501,7 +501,7 @@
} else {
- ViewRootImpl viewRoot = getOwnerViewRootImpl();
+ ViewRootImpl viewRoot = mOwnerView.getViewRootImpl();
if (viewRoot != null) {
viewRoot.dispatchKey(event);
}
@@ -526,20 +526,6 @@
}
}
- private ViewRootImpl getOwnerViewRootImpl() {
- View rootViewOfOwner = mOwnerView.getRootView();
- if (rootViewOfOwner == null) {
- return null;
- }
-
- ViewParent parentOfRootView = rootViewOfOwner.getParent();
- if (parentOfRootView instanceof ViewRootImpl) {
- return (ViewRootImpl) parentOfRootView;
- } else {
- return null;
- }
- }
-
/**
* @hide The ZoomButtonsController implements the OnTouchListener, but this
* does not need to be shown in its public API.
diff --git a/core/java/com/android/internal/textservice/ISpellCheckerSession.aidl b/core/java/com/android/internal/textservice/ISpellCheckerSession.aidl
index ba0aa1a..4553f9f 100644
--- a/core/java/com/android/internal/textservice/ISpellCheckerSession.aidl
+++ b/core/java/com/android/internal/textservice/ISpellCheckerSession.aidl
@@ -24,7 +24,7 @@
oneway interface ISpellCheckerSession {
void onGetSuggestionsMultiple(
in TextInfo[] textInfos, int suggestionsLimit, boolean multipleWords);
- void onGetSuggestionsMultipleForSentence(in TextInfo[] textInfos, int suggestionsLimit);
+ void onGetSentenceSuggestionsMultiple(in TextInfo[] textInfos, int suggestionsLimit);
void onCancel();
void onClose();
}
diff --git a/core/java/com/android/internal/textservice/ISpellCheckerSessionListener.aidl b/core/java/com/android/internal/textservice/ISpellCheckerSessionListener.aidl
index b44dbc8..641ed8c 100644
--- a/core/java/com/android/internal/textservice/ISpellCheckerSessionListener.aidl
+++ b/core/java/com/android/internal/textservice/ISpellCheckerSessionListener.aidl
@@ -16,6 +16,7 @@
package com.android.internal.textservice;
+import android.view.textservice.SentenceSuggestionsInfo;
import android.view.textservice.SuggestionsInfo;
/**
@@ -23,5 +24,5 @@
*/
oneway interface ISpellCheckerSessionListener {
void onGetSuggestions(in SuggestionsInfo[] results);
- void onGetSuggestionsForSentence(in SuggestionsInfo[] results);
+ void onGetSentenceSuggestions(in SentenceSuggestionsInfo[] result);
}
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index 517ce4e..2f325bf 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -606,6 +606,9 @@
((mDisplayOptions & ActionBar.DISPLAY_USE_LOGO) == 0 || mLogo == null)) {
mHomeLayout.setIcon(icon);
}
+ if (mExpandedActionView != null) {
+ mExpandedHomeLayout.setIcon(mIcon.getConstantState().newDrawable(getResources()));
+ }
}
public void setIcon(int resId) {
diff --git a/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java b/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java
index 2e7810f..26518eb 100644
--- a/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java
+++ b/core/java/com/android/internal/widget/PasswordEntryKeyboardHelper.java
@@ -147,7 +147,7 @@
}
private void sendKeyEventsToTarget(int character) {
- Handler handler = mTargetView.getHandler();
+ ViewRootImpl viewRootImpl = mTargetView.getViewRootImpl();
KeyEvent[] events = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD).getEvents(
new char[] { (char) character });
if (events != null) {
@@ -156,22 +156,22 @@
KeyEvent event = events[i];
event = KeyEvent.changeFlags(event, event.getFlags()
| KeyEvent.FLAG_SOFT_KEYBOARD | KeyEvent.FLAG_KEEP_TOUCH_MODE);
- handler.sendMessage(handler.obtainMessage(ViewRootImpl.DISPATCH_KEY, event));
+ viewRootImpl.dispatchKey(event);
}
}
}
public void sendDownUpKeyEvents(int keyEventCode) {
long eventTime = SystemClock.uptimeMillis();
- Handler handler = mTargetView.getHandler();
- handler.sendMessage(handler.obtainMessage(ViewRootImpl.DISPATCH_KEY_FROM_IME,
+ ViewRootImpl viewRootImpl = mTargetView.getViewRootImpl();
+ viewRootImpl.dispatchKeyFromIme(
new KeyEvent(eventTime, eventTime, KeyEvent.ACTION_DOWN, keyEventCode, 0, 0,
KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
- KeyEvent.FLAG_SOFT_KEYBOARD|KeyEvent.FLAG_KEEP_TOUCH_MODE)));
- handler.sendMessage(handler.obtainMessage(ViewRootImpl.DISPATCH_KEY_FROM_IME,
+ KeyEvent.FLAG_SOFT_KEYBOARD|KeyEvent.FLAG_KEEP_TOUCH_MODE));
+ viewRootImpl.dispatchKeyFromIme(
new KeyEvent(eventTime, eventTime, KeyEvent.ACTION_UP, keyEventCode, 0, 0,
KeyCharacterMap.VIRTUAL_KEYBOARD, 0,
- KeyEvent.FLAG_SOFT_KEYBOARD|KeyEvent.FLAG_KEEP_TOUCH_MODE)));
+ KeyEvent.FLAG_SOFT_KEYBOARD|KeyEvent.FLAG_KEEP_TOUCH_MODE));
}
public void onKey(int primaryCode, int[] keyCodes) {
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 78e8df3..c6d3cee 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -185,6 +185,7 @@
libcore/include
LOCAL_SHARED_LIBRARIES := \
+ libandroidfw \
libexpat \
libnativehelper \
libcutils \
diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp
index ea35006..4b64bf3 100644
--- a/core/jni/android/graphics/BitmapFactory.cpp
+++ b/core/jni/android/graphics/BitmapFactory.cpp
@@ -15,8 +15,8 @@
#include "JNIHelp.h"
#include <android_runtime/AndroidRuntime.h>
-#include <utils/Asset.h>
-#include <utils/ResourceTypes.h>
+#include <androidfw/Asset.h>
+#include <androidfw/ResourceTypes.h>
#include <netinet/in.h>
#include <sys/mman.h>
#include <sys/stat.h>
diff --git a/core/jni/android/graphics/BitmapRegionDecoder.cpp b/core/jni/android/graphics/BitmapRegionDecoder.cpp
index d437929..682877a 100644
--- a/core/jni/android/graphics/BitmapRegionDecoder.cpp
+++ b/core/jni/android/graphics/BitmapRegionDecoder.cpp
@@ -37,7 +37,7 @@
#include <binder/Parcel.h>
#include <jni.h>
-#include <utils/Asset.h>
+#include <androidfw/Asset.h>
#include <sys/stat.h>
#if 0
diff --git a/core/jni/android/graphics/Movie.cpp b/core/jni/android/graphics/Movie.cpp
index c1acaa3..4f64ff8 100644
--- a/core/jni/android/graphics/Movie.cpp
+++ b/core/jni/android/graphics/Movie.cpp
@@ -5,8 +5,8 @@
#include "SkUtils.h"
#include "CreateJavaOutputStreamAdaptor.h"
-#include <utils/Asset.h>
-#include <utils/ResourceTypes.h>
+#include <androidfw/Asset.h>
+#include <androidfw/ResourceTypes.h>
#include <netinet/in.h>
#if 0
diff --git a/core/jni/android/graphics/NinePatch.cpp b/core/jni/android/graphics/NinePatch.cpp
index f3b28a9..684b1c1 100644
--- a/core/jni/android/graphics/NinePatch.cpp
+++ b/core/jni/android/graphics/NinePatch.cpp
@@ -18,7 +18,7 @@
#define LOG_TAG "9patch"
#define LOG_NDEBUG 1
-#include <utils/ResourceTypes.h>
+#include <androidfw/ResourceTypes.h>
#include <utils/Log.h>
#include "SkCanvas.h"
diff --git a/core/jni/android/graphics/NinePatchImpl.cpp b/core/jni/android/graphics/NinePatchImpl.cpp
index 1d0bb506..ff0eb45 100644
--- a/core/jni/android/graphics/NinePatchImpl.cpp
+++ b/core/jni/android/graphics/NinePatchImpl.cpp
@@ -18,7 +18,7 @@
#define LOG_TAG "NinePatch"
#define LOG_NDEBUG 1
-#include <utils/ResourceTypes.h>
+#include <androidfw/ResourceTypes.h>
#include <utils/Log.h>
#include "SkBitmap.h"
diff --git a/core/jni/android/graphics/NinePatchPeeker.h b/core/jni/android/graphics/NinePatchPeeker.h
index 8567e23..207536c 100644
--- a/core/jni/android/graphics/NinePatchPeeker.h
+++ b/core/jni/android/graphics/NinePatchPeeker.h
@@ -18,7 +18,7 @@
#define NinePatchPeeker_h
#include "SkImageDecoder.h"
-#include <utils/ResourceTypes.h>
+#include <androidfw/ResourceTypes.h>
using namespace android;
diff --git a/core/jni/android/graphics/Typeface.cpp b/core/jni/android/graphics/Typeface.cpp
index b25598a..7f4c37b 100644
--- a/core/jni/android/graphics/Typeface.cpp
+++ b/core/jni/android/graphics/Typeface.cpp
@@ -2,10 +2,10 @@
#include <android_runtime/AndroidRuntime.h>
#include "GraphicsJNI.h"
-#include <android_runtime/android_util_AssetManager.h>
#include "SkStream.h"
#include "SkTypeface.h"
-#include <utils/AssetManager.h>
+#include <android_runtime/android_util_AssetManager.h>
+#include <androidfw/AssetManager.h>
using namespace android;
diff --git a/core/jni/android/graphics/Utils.h b/core/jni/android/graphics/Utils.h
index 9a7a697..75ceaa2 100644
--- a/core/jni/android/graphics/Utils.h
+++ b/core/jni/android/graphics/Utils.h
@@ -22,7 +22,7 @@
#include "android_util_Binder.h"
#include <jni.h>
-#include <utils/Asset.h>
+#include <androidfw/Asset.h>
namespace android {
diff --git a/core/jni/android_app_NativeActivity.cpp b/core/jni/android_app_NativeActivity.cpp
index 536681b..4b3324b 100644
--- a/core/jni/android_app_NativeActivity.cpp
+++ b/core/jni/android_app_NativeActivity.cpp
@@ -27,7 +27,7 @@
#include <android_runtime/android_util_AssetManager.h>
#include <surfaceflinger/Surface.h>
#include <ui/egl/android_natives.h>
-#include <ui/InputTransport.h>
+#include <androidfw/InputTransport.h>
#include <utils/Looper.h>
#include "JNIHelp.h"
diff --git a/core/jni/android_app_backup_FullBackup.cpp b/core/jni/android_app_backup_FullBackup.cpp
index 066a23e..2ca645a 100644
--- a/core/jni/android_app_backup_FullBackup.cpp
+++ b/core/jni/android_app_backup_FullBackup.cpp
@@ -21,7 +21,7 @@
#include "JNIHelp.h"
#include <android_runtime/AndroidRuntime.h>
-#include <utils/BackupHelpers.h>
+#include <androidfw/BackupHelpers.h>
#include <string.h>
diff --git a/core/jni/android_backup_BackupDataInput.cpp b/core/jni/android_backup_BackupDataInput.cpp
index 2fb0076..25b0007 100644
--- a/core/jni/android_backup_BackupDataInput.cpp
+++ b/core/jni/android_backup_BackupDataInput.cpp
@@ -20,7 +20,7 @@
#include "JNIHelp.h"
#include <android_runtime/AndroidRuntime.h>
-#include <utils/BackupHelpers.h>
+#include <androidfw/BackupHelpers.h>
namespace android
{
diff --git a/core/jni/android_backup_BackupDataOutput.cpp b/core/jni/android_backup_BackupDataOutput.cpp
index abe0104..e8f0fb8 100644
--- a/core/jni/android_backup_BackupDataOutput.cpp
+++ b/core/jni/android_backup_BackupDataOutput.cpp
@@ -20,7 +20,7 @@
#include "JNIHelp.h"
#include <android_runtime/AndroidRuntime.h>
-#include <utils/BackupHelpers.h>
+#include <androidfw/BackupHelpers.h>
namespace android
{
diff --git a/core/jni/android_backup_FileBackupHelperBase.cpp b/core/jni/android_backup_FileBackupHelperBase.cpp
index 0dfd8db..bb3a751 100644
--- a/core/jni/android_backup_FileBackupHelperBase.cpp
+++ b/core/jni/android_backup_FileBackupHelperBase.cpp
@@ -20,7 +20,7 @@
#include "JNIHelp.h"
#include <android_runtime/AndroidRuntime.h>
-#include <utils/BackupHelpers.h>
+#include <androidfw/BackupHelpers.h>
namespace android
{
diff --git a/core/jni/android_bluetooth_BluetoothAudioGateway.cpp b/core/jni/android_bluetooth_BluetoothAudioGateway.cpp
old mode 100755
new mode 100644
diff --git a/core/jni/android_bluetooth_c.c b/core/jni/android_bluetooth_c.c
old mode 100755
new mode 100644
diff --git a/core/jni/android_content_res_ObbScanner.cpp b/core/jni/android_content_res_ObbScanner.cpp
index 8837538..5d51ee2 100644
--- a/core/jni/android_content_res_ObbScanner.cpp
+++ b/core/jni/android_content_res_ObbScanner.cpp
@@ -18,7 +18,7 @@
#include <utils/Log.h>
#include <utils/String8.h>
-#include <utils/ObbFile.h>
+#include <androidfw/ObbFile.h>
#include "jni.h"
#include "JNIHelp.h"
diff --git a/core/jni/android_os_Power.cpp b/core/jni/android_os_Power.cpp
index dc16990..48845f6 100644
--- a/core/jni/android_os_Power.cpp
+++ b/core/jni/android_os_Power.cpp
@@ -15,13 +15,18 @@
** limitations under the License.
*/
+#define LOG_TAG "Power-JNI"
+
#include "JNIHelp.h"
#include "jni.h"
#include "android_runtime/AndroidRuntime.h"
#include <utils/misc.h>
+#include <hardware/power.h>
#include <hardware_legacy/power.h>
#include <cutils/android_reboot.h>
+static struct power_module *sPowerModule;
+
namespace android
{
@@ -65,7 +70,9 @@
static int
setScreenState(JNIEnv *env, jobject clazz, jboolean on)
{
- return set_screen_state(on);
+ if (sPowerModule)
+ sPowerModule->setInteractive(sPowerModule, on);
+ return 0;
}
static void android_os_Power_shutdown(JNIEnv *env, jobject clazz)
@@ -85,12 +92,26 @@
jniThrowIOException(env, errno);
}
+static int android_os_Power_init(JNIEnv *env, jobject clazz)
+{
+ status_t err = hw_get_module(POWER_HARDWARE_MODULE_ID,
+ (hw_module_t const**)&sPowerModule);
+ ALOGE_IF(err, "couldn't load %s module (%s)",
+ POWER_HARDWARE_MODULE_ID, strerror(-err));
+
+ if (!err)
+ sPowerModule->init(sPowerModule);
+
+ return err;
+}
+
static JNINativeMethod method_table[] = {
{ "acquireWakeLock", "(ILjava/lang/String;)V", (void*)acquireWakeLock },
{ "releaseWakeLock", "(Ljava/lang/String;)V", (void*)releaseWakeLock },
{ "setLastUserActivityTimeout", "(J)I", (void*)setLastUserActivityTimeout },
{ "setScreenState", "(Z)I", (void*)setScreenState },
{ "shutdown", "()V", (void*)android_os_Power_shutdown },
+ { "powerInitNative", "()I", (void*)android_os_Power_init },
{ "rebootNative", "(Ljava/lang/String;)V", (void*)android_os_Power_reboot },
};
diff --git a/core/jni/android_server_BluetoothEventLoop.cpp b/core/jni/android_server_BluetoothEventLoop.cpp
index 9292fc0..8a69ba4 100644
--- a/core/jni/android_server_BluetoothEventLoop.cpp
+++ b/core/jni/android_server_BluetoothEventLoop.cpp
@@ -164,7 +164,6 @@
ALOGE("%s: out of memory!", __FUNCTION__);
return;
}
- memset(nat, 0, sizeof(native_data_t));
pthread_mutex_init(&(nat->thread_mutex), NULL);
@@ -722,24 +721,20 @@
return JNI_FALSE;
}
- nat->pollData = (struct pollfd *)malloc(sizeof(struct pollfd) *
- DEFAULT_INITIAL_POLLFD_COUNT);
+ nat->pollData = (struct pollfd *)calloc(
+ DEFAULT_INITIAL_POLLFD_COUNT, sizeof(struct pollfd));
if (!nat->pollData) {
ALOGE("out of memory error starting EventLoop!");
goto done;
}
- nat->watchData = (DBusWatch **)malloc(sizeof(DBusWatch *) *
- DEFAULT_INITIAL_POLLFD_COUNT);
+ nat->watchData = (DBusWatch **)calloc(
+ DEFAULT_INITIAL_POLLFD_COUNT, sizeof(DBusWatch *));
if (!nat->watchData) {
ALOGE("out of memory error starting EventLoop!");
goto done;
}
- memset(nat->pollData, 0, sizeof(struct pollfd) *
- DEFAULT_INITIAL_POLLFD_COUNT);
- memset(nat->watchData, 0, sizeof(DBusWatch *) *
- DEFAULT_INITIAL_POLLFD_COUNT);
nat->pollDataSize = DEFAULT_INITIAL_POLLFD_COUNT;
nat->pollMemberCount = 1;
diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp
index 17130af..7146667 100644
--- a/core/jni/android_util_AssetManager.cpp
+++ b/core/jni/android_util_AssetManager.cpp
@@ -31,9 +31,9 @@
#include <android_runtime/AndroidRuntime.h>
#include <utils/Log.h>
-#include <utils/Asset.h>
-#include <utils/AssetManager.h>
-#include <utils/ResourceTypes.h>
+#include <androidfw/Asset.h>
+#include <androidfw/AssetManager.h>
+#include <androidfw/ResourceTypes.h>
#include <stdio.h>
diff --git a/core/jni/android_util_StringBlock.cpp b/core/jni/android_util_StringBlock.cpp
index 958ddb2..28746ce 100644
--- a/core/jni/android_util_StringBlock.cpp
+++ b/core/jni/android_util_StringBlock.cpp
@@ -23,7 +23,7 @@
#include <android_runtime/AndroidRuntime.h>
#include <utils/Log.h>
-#include <utils/ResourceTypes.h>
+#include <androidfw/ResourceTypes.h>
#include <stdio.h>
diff --git a/core/jni/android_util_XmlBlock.cpp b/core/jni/android_util_XmlBlock.cpp
index 45728db..ad6033b 100644
--- a/core/jni/android_util_XmlBlock.cpp
+++ b/core/jni/android_util_XmlBlock.cpp
@@ -19,12 +19,11 @@
#include "jni.h"
#include "JNIHelp.h"
-#include <utils/misc.h>
#include <android_runtime/AndroidRuntime.h>
-#include <utils/AssetManager.h>
+#include <androidfw/AssetManager.h>
+#include <androidfw/ResourceTypes.h>
#include <utils/Log.h>
-
-#include <utils/ResourceTypes.h>
+#include <utils/misc.h>
#include <stdio.h>
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index e19bb38..cdce4f9 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -24,7 +24,7 @@
#include <android_runtime/AndroidRuntime.h>
#include <android_runtime/android_graphics_SurfaceTexture.h>
#include <cutils/properties.h>
-#include <utils/ResourceTypes.h>
+#include <androidfw/ResourceTypes.h>
#include <gui/SurfaceTexture.h>
@@ -652,9 +652,9 @@
static bool android_view_GLES20Canvas_drawDisplayList(JNIEnv* env,
jobject clazz, OpenGLRenderer* renderer, DisplayList* displayList,
- jint width, jint height, jobject dirty) {
+ jint width, jint height, jobject dirty, jint flags) {
android::uirenderer::Rect bounds;
- bool redraw = renderer->drawDisplayList(displayList, width, height, bounds);
+ bool redraw = renderer->drawDisplayList(displayList, width, height, bounds, flags);
if (redraw && dirty != NULL) {
env->CallVoidMethod(dirty, gRectClassInfo.set,
int(bounds.left), int(bounds.top), int(bounds.right), int(bounds.bottom));
@@ -901,7 +901,7 @@
{ "nGetDisplayListSize", "(I)I", (void*) android_view_GLES20Canvas_getDisplayListSize },
{ "nSetDisplayListName", "(ILjava/lang/String;)V",
(void*) android_view_GLES20Canvas_setDisplayListName },
- { "nDrawDisplayList", "(IIIILandroid/graphics/Rect;)Z",
+ { "nDrawDisplayList", "(IIIILandroid/graphics/Rect;I)Z",
(void*) android_view_GLES20Canvas_drawDisplayList },
{ "nCreateDisplayListRenderer", "()I", (void*) android_view_GLES20Canvas_createDisplayListRenderer },
diff --git a/core/jni/android_view_InputChannel.cpp b/core/jni/android_view_InputChannel.cpp
index 6d783de..8350e73 100644
--- a/core/jni/android_view_InputChannel.cpp
+++ b/core/jni/android_view_InputChannel.cpp
@@ -21,7 +21,7 @@
#include <android_runtime/AndroidRuntime.h>
#include <binder/Parcel.h>
#include <utils/Log.h>
-#include <ui/InputTransport.h>
+#include <androidfw/InputTransport.h>
#include "android_view_InputChannel.h"
#include "android_util_Binder.h"
diff --git a/core/jni/android_view_InputChannel.h b/core/jni/android_view_InputChannel.h
index fa2d282..0967021 100644
--- a/core/jni/android_view_InputChannel.h
+++ b/core/jni/android_view_InputChannel.h
@@ -19,7 +19,7 @@
#include "jni.h"
-#include <ui/InputTransport.h>
+#include <androidfw/InputTransport.h>
namespace android {
diff --git a/core/jni/android_view_InputEventReceiver.cpp b/core/jni/android_view_InputEventReceiver.cpp
index 47b3f66..e7d4244 100644
--- a/core/jni/android_view_InputEventReceiver.cpp
+++ b/core/jni/android_view_InputEventReceiver.cpp
@@ -28,7 +28,7 @@
#include <utils/Log.h>
#include <utils/Looper.h>
#include <utils/threads.h>
-#include <ui/InputTransport.h>
+#include <androidfw/InputTransport.h>
#include "android_os_MessageQueue.h"
#include "android_view_InputChannel.h"
#include "android_view_KeyEvent.h"
@@ -264,7 +264,7 @@
sp<NativeInputEventReceiver> receiver =
reinterpret_cast<NativeInputEventReceiver*>(receiverPtr);
status_t status = receiver->finishInputEvent(seq, handled);
- if (status) {
+ if (status && status != DEAD_OBJECT) {
String8 message;
message.appendFormat("Failed to finish input event. status=%d", status);
jniThrowRuntimeException(env, message.string());
@@ -275,7 +275,7 @@
sp<NativeInputEventReceiver> receiver =
reinterpret_cast<NativeInputEventReceiver*>(receiverPtr);
status_t status = receiver->consumeEvents(true /*consumeBatches*/);
- if (status) {
+ if (status && status != DEAD_OBJECT) {
String8 message;
message.appendFormat("Failed to consume batched input event. status=%d", status);
jniThrowRuntimeException(env, message.string());
diff --git a/core/jni/android_view_KeyCharacterMap.cpp b/core/jni/android_view_KeyCharacterMap.cpp
index b9f3738..7245d9d 100644
--- a/core/jni/android_view_KeyCharacterMap.cpp
+++ b/core/jni/android_view_KeyCharacterMap.cpp
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#include <ui/KeyCharacterMap.h>
-#include <ui/Input.h>
+#include <androidfw/KeyCharacterMap.h>
+#include <androidfw/Input.h>
#include <android_runtime/AndroidRuntime.h>
#include <nativehelper/jni.h>
diff --git a/core/jni/android_view_KeyEvent.cpp b/core/jni/android_view_KeyEvent.cpp
index 27469a2..36a98f9 100644
--- a/core/jni/android_view_KeyEvent.cpp
+++ b/core/jni/android_view_KeyEvent.cpp
@@ -20,7 +20,7 @@
#include <android_runtime/AndroidRuntime.h>
#include <utils/Log.h>
-#include <ui/Input.h>
+#include <androidfw/Input.h>
#include "android_view_KeyEvent.h"
namespace android {
diff --git a/core/jni/android_view_MotionEvent.cpp b/core/jni/android_view_MotionEvent.cpp
index 2def1d1..0fb1b17 100644
--- a/core/jni/android_view_MotionEvent.cpp
+++ b/core/jni/android_view_MotionEvent.cpp
@@ -20,7 +20,7 @@
#include <android_runtime/AndroidRuntime.h>
#include <utils/Log.h>
-#include <ui/Input.h>
+#include <androidfw/Input.h>
#include "android_view_MotionEvent.h"
#include "android_util_Binder.h"
#include "android/graphics/Matrix.h"
diff --git a/core/jni/android_view_VelocityTracker.cpp b/core/jni/android_view_VelocityTracker.cpp
index 0da90d7..668d3bb 100644
--- a/core/jni/android_view_VelocityTracker.cpp
+++ b/core/jni/android_view_VelocityTracker.cpp
@@ -20,7 +20,7 @@
#include <android_runtime/AndroidRuntime.h>
#include <utils/Log.h>
-#include <ui/Input.h>
+#include <androidfw/Input.h>
#include "android_view_MotionEvent.h"
diff --git a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
index b68c97a..afbcfc2 100644
--- a/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
+++ b/core/jni/com_android_internal_content_NativeLibraryHelper.cpp
@@ -21,7 +21,7 @@
#include <utils/Log.h>
#include <ScopedUtfChars.h>
-#include <utils/ZipFileRO.h>
+#include <androidfw/ZipFileRO.h>
#include <zlib.h>
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 68c919e..a2b1117 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1521,6 +1521,17 @@
android:description="@string/permdesc_serialPort"
android:protectionLevel="normal" />
+ <!-- Allows the holder to access content providers from outside an ApplicationThread.
+ This permission is enforced by the ActivityManagerService on the corresponding APIs,
+ in particular ActivityManagerService#getContentProviderExternal(String) and
+ ActivityManagerService#removeContentProviderExternal(String).
+ @hide
+ -->
+ <permission android:name="android.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY"
+ android:label="@string/permlab_accessContentProvidersExternally"
+ android:description="@string/permdesc_accessContentProvidersExternally"
+ android:protectionLevel="signature" />
+
<!-- The system process is explicitly the only one allowed to launch the
confirmation UI for full backup/restore -->
<uses-permission android:name="android.permission.CONFIRM_FULL_BACKUP"/>
diff --git a/core/res/assets/webkit/youtube.html b/core/res/assets/webkit/youtube.html
index d808bcf..8e103c1 100644
--- a/core/res/assets/webkit/youtube.html
+++ b/core/res/assets/webkit/youtube.html
@@ -13,94 +13,59 @@
height: 100%;
padding: 0%;
z-index: 10;
+ background-size: 100%;
+ background: no-repeat;
+ background-position: center;
+ }
+ #play {
+ position: absolute;
+ left: 50%;
+ top: 50%;
+ }
+ #logo {
+ position: absolute;
+ bottom: 0;
+ right: 0;
}
</style>
</head>
<body id="body">
<script type="text/javascript">
- // Nominal original size. If the embed is smaller than this, the play and logo
- // images get scaled appropriately. These are actually 3/4 of the sizes suggested
- // by youtube, so the images don't get too tiny.
- defHeight = 258;
- defWidth = 318;
-
function setup() {
var width = document.body.clientWidth;
var height = document.body.clientHeight;
- var canvas = document.getElementById("canvas");
- // Resize the canvas to the right size
- canvas.width = width;
- canvas.height = height;
- var ctx = canvas.getContext('2d');
+ var mainElement = document.getElementById("main");
+ var playElement = document.getElementById("play");
var loadcount = 0;
+ var POSTER = "http://img.youtube.com/vi/VIDEO_ID/0.jpg";
+
function doload() {
- if (++loadcount == 3) {
- // All images are loaded, so display them.
- // (Note that the images are loaded from javascript, so might load
- // after document.onload fires)
-
- playWidth = play.width;
- playHeight = play.height;
- logoWidth = logo.width;
- logoHeight = logo.height;
- var ratio = 1;
- // If the page is smaller than it 'should' be in either dimension
- // we scale the background, play button and logo according to the
- // dimension that has been shrunk the most.
- if (width / height > defWidth / defHeight && height < defHeight) {
- ratio = height / defHeight;
- // Stretch the background in this dimension only.
- backgroundHeight = background.height / ratio;
- ctx.drawImage(background, 0, 0, background.width, background.height,
- 0, (height - backgroundHeight) / 2, width, backgroundHeight);
- } else if (width / height < defWidth / defHeight && width < defWidth) {
- ratio = width / defWidth;
- backgroundWidth = background.width / ratio;
- ctx.drawImage(background, 0, 0, background.width, background.height,
- (width - backgroundWidth) / 2, 0, backgroundWidth, height);
- } else {
- // In this case stretch the background in both dimensions to fill the space.
- ctx.drawImage(background, 0, 0, width, height);
- }
- playWidth *= ratio;
- playHeight *= ratio;
- logoWidth *= ratio;
- logoHeight *= ratio;
- playLeft = (width - playWidth) / 2;
- playTop = (height - playHeight) / 2;
- ctx.drawImage(play, playLeft, playTop, playWidth, playHeight);
- ctx.globalAlpha = 0.7
- ctx.drawImage(logo, width - logoWidth, height - logoHeight, logoWidth, logoHeight);
- // To make it slightly easier to hit, the click target is twice the width/height of the unscaled play button
- targetLeft = width / 2 - play.width;
- targetRight = width / 2 + play.width;
- targetTop = height / 2 - play.height;
- targetBottom = height / 2 + play.height;
-
- canvas.addEventListener("click", function(e) {
- var posx = e.clientX-canvas.offsetLeft;
- var posy = e.clientY-canvas.offsetTop;
- if (posx >= targetLeft && posx <= targetRight &&
- posy >= targetTop && posy <= targetBottom) {
- top.location.href = "vnd.youtube:VIDEO_ID";
- }
- }, false);
+ if (++loadcount == 2) {
+ // Resize the element to the right size
+ mainElement.width = width;
+ mainElement.height = height;
+ mainElement.style.backgroundImage = "url('" + POSTER + "')";
+ // Center the play button
+ playElement.style.marginTop = "-" + play.height/2 + "px";
+ playElement.style.marginLeft = "-" + play.width/2 + "px";
+ playElement.addEventListener("click", function(e) {
+ top.location.href = "vnd.youtube:VIDEO_ID";
+ }, false);
}
}
var background = new Image();
background.onload = doload;
- background.src = "http://img.youtube.com/vi/VIDEO_ID/0.jpg";
+ background.src = POSTER;
play = new Image();
play.onload = doload;
play.src = "play.png";
- logo = new Image();
- logo.onload = doload;
- logo.src = "youtube.png";
}
+
window.onload = setup;
</script>
<div id="main">
- <canvas id="canvas"></canvas>
+ <img src="play.png" id="play"></img>
+ <img src="youtube.png" id="logo"></img>
</div>
</body>
</html>
diff --git a/core/res/res/drawable-hdpi/stat_sys_data_wimax_signal_3_fully.png b/core/res/res/drawable-hdpi/stat_sys_data_wimax_signal_3_fully.png
index f58a19c..cb08eed 100644
--- a/core/res/res/drawable-hdpi/stat_sys_data_wimax_signal_3_fully.png
+++ b/core/res/res/drawable-hdpi/stat_sys_data_wimax_signal_3_fully.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/stat_sys_data_wimax_signal_disconnected.png b/core/res/res/drawable-hdpi/stat_sys_data_wimax_signal_disconnected.png
index 744b1fa..ea065c3 100644
--- a/core/res/res/drawable-hdpi/stat_sys_data_wimax_signal_disconnected.png
+++ b/core/res/res/drawable-hdpi/stat_sys_data_wimax_signal_disconnected.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_data_wimax_signal_3_fully.png b/core/res/res/drawable-mdpi/stat_sys_data_wimax_signal_3_fully.png
new file mode 100644
index 0000000..d3ba98c
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_data_wimax_signal_3_fully.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/stat_sys_data_wimax_signal_disconnected.png b/core/res/res/drawable-mdpi/stat_sys_data_wimax_signal_disconnected.png
new file mode 100644
index 0000000..153c6ad
--- /dev/null
+++ b/core/res/res/drawable-mdpi/stat_sys_data_wimax_signal_disconnected.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/stat_sys_data_wimax_signal_3_fully.png b/core/res/res/drawable-xhdpi/stat_sys_data_wimax_signal_3_fully.png
new file mode 100644
index 0000000..ec6bc54
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/stat_sys_data_wimax_signal_3_fully.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/stat_sys_data_wimax_signal_disconnected.png b/core/res/res/drawable-xhdpi/stat_sys_data_wimax_signal_disconnected.png
new file mode 100644
index 0000000..9fd4f33
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/stat_sys_data_wimax_signal_disconnected.png
Binary files differ
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 840323e..6f861fb 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -766,6 +766,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Laat die houer toe om versoeke aan pakketverifieerders te rig. Dit moet nooit vir normale programme nodig wees nie."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"kry toegang tot reekspoorte"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"Laat die houer toe om toegang te verkry tot reekspoorte wat die SerialManager API gebruik."</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"Wil jy hê die blaaier moet hierdie wagwoord onthou?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Nie nou nie"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Onthou"</string>
@@ -975,6 +979,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Kon nie aan Wi-Fikoppel nie"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" het \'n swak internetverbinding."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Begin Wi-Fi Direct. Dit sal die Wi-Fi-kliënt/warmkol afskakel."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Kon nie Wi-Fi Direct begin nie."</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direk is aan"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Raak vir instellings"</string>
<string name="accept" msgid="1645267259272829559">"Aanvaar"</string>
<string name="decline" msgid="2112225451706137894">"Weier"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Uitnodiging gestuur"</string>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 905b90c..bb6246a 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -764,6 +764,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"የፓኬጅ አረጋጋጮችን ጥየቃ ለማድረግ ያዡ ይፈቅዳሉ። ለመደበኛ ትግበራዎች በፍፁም አያስፈልግም።"</string>
<string name="permlab_serialPort" msgid="546083327654631076">"ተከታታይ ወደቦችን ድረስ"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"Allows the holder to access serial ports using the SerialManager API. የተከታታይ አደራጅ APIን በመጠቀም ያዡ የተከታታይ ወደቦችን እንዲደርስ ይፈቅዳል።"</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"አሳሹ ይህን ይለፍ ቃል እንዲያስታወስ ይፈልጋሉ?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"አሁን አይደለም"</string>
<string name="save_password_remember" msgid="6491879678996749466">"አስታውስ"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"ወደ Wi-Fi ለማያያዝ አልተቻለም"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" ደካማ የበይነመረብ ግንኙነት ኣለው።"</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi ቀጥታ"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"የWi-Fi በቀጥታ ጀምር።ይህ የWi-Fi ደንበኛ /ድረስ ነጥብ ያጠፋል።"</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"በቀጥታ Wi-Fi ማስጀመር አልተቻለም።"</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"የWi-Fi ቀጥታ በርቷል"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"ለቅንብሮች ንካ"</string>
<string name="accept" msgid="1645267259272829559">"ተቀበል"</string>
<string name="decline" msgid="2112225451706137894">"ውድቅ አድርግ"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"ግብዣ ተልኳል"</string>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index a7c37e7..580f9bc 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -764,6 +764,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"السماح للمالك بإجراء طلبات محققي الحزمة. لن تكون هناك حاجة إليه مطلقًا مع التطبيقات العادية."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"الدخول إلى المنافذ التسلسلية"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"يسمح لحامله بالدخول إلى المنافذ التسلسلية باستخدام واجهة برمجة التطبيقات."</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"هل تريد من المتصفح تذكر كلمة المرور هذه؟"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"ليس الآن"</string>
<string name="save_password_remember" msgid="6491879678996749466">"تذكّر"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"تعذر الاتصال بـ Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" لديها اتصال إنترنت رديء."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"اتصال Wi-Fi مباشر"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"ابدأ Wi-Fi Direct. يؤدي هذا إلى إيقاف عميل/نقطة اتصال Wi-Fi."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"تعذر بدء Wi-Fi Direct."</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"تم تشغيل اتصال Wi-Fi المباشر"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"المس للحصول على الإعدادات"</string>
<string name="accept" msgid="1645267259272829559">"قبول"</string>
<string name="decline" msgid="2112225451706137894">"رفض"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"تم إرسال الدعوة"</string>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 4a226a1..8de1cf5 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -764,6 +764,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Дазваляе ўладальніку рабіць запыты верыфікатараў пакету. Не патрабуецца для звычайных прыкладанняў."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"атрымаць доступ да паслядоўных партоў"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"Дазваляе ўладальніку атрымліваць доступ да паслядоўных партоў з дапамогай API SerialManager."</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"Вы хочаце, каб браўзэр запомніў гэты пароль?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Не цяпер"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Запомніць"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Немагчыма падключыцца да Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" дрэннае падключэнне да Інтэрнэту."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Пачаць работу Wi-Fi Direct. Гэта адключыць кліента або кропку доступу Wi-Fi."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Немагчыма запусціць Wi-Fi Direct."</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct уключаны"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Дакраніцеся, каб наладзіць"</string>
<string name="accept" msgid="1645267259272829559">"Прыняць"</string>
<string name="decline" msgid="2112225451706137894">"Адхіліць"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Запрашэнне адпраўлена"</string>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index f311a28..ec2e0bf 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -764,6 +764,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Разрешава на притежателя да прави заявки за верификатори на пакета. Нормалните приложения би трябвало никога да не се нуждаят от това."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"достъп до серийни портове"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"Разрешава на притежателя достъп до серийни портове посредством приложния програмен интерфейс (API) SerialManager."</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"Искате ли браузърът да запомни тази парола?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Не сега"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Запомняне"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Не можа да се свърже с Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" има лоша връзка с интернет."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Стартиране на Wi-Fi Direct. Това ще изключи клиентската програма/точката за достъп до Wi-Fi."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Wi-Fi Direct не можа да се стартира."</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct е включено"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Докоснете за настройки"</string>
<string name="accept" msgid="1645267259272829559">"Приемам"</string>
<string name="decline" msgid="2112225451706137894">"Отхвърлям"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Поканата е изпратена"</string>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 95dae9d..173f1fc 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -764,6 +764,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Permet que el titular sol·liciti verificadors de paquets. No s\'hauria de necessitar mai per a les aplicacions normals."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"accedeix a ports sèrie"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"Permet que el titular accedeixi a ports sèrie amb l\'API SerialManager."</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"Voleu que el navegador recordi aquesta contrasenya?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Ara no"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Recorda-ho"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"No s\'ha pogut connectar a la Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" té una mala connexió a Internet."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Inicia Wi-Fi Direct. Això desactivarà el client/la zona Wi-Fi."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"No s\'ha pogut iniciar Wi-Fi Direct."</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct està activat"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Toca per accedir a la configuració"</string>
<string name="accept" msgid="1645267259272829559">"Accepta"</string>
<string name="decline" msgid="2112225451706137894">"Rebutja"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"S\'ha enviat la invitació"</string>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index c01526d..d3b5276 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -764,6 +764,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Umožňuje držiteli podávat žádosti o ověření balíčků. Běžné aplikace by toto oprávnění neměly nikdy požadovat."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"přístup k sériovým portům"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"Umožňuje držiteli přístup k sériovým portům pomocí rozhraní SerialManager API."</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"Chcete, aby si prohlížeč zapamatoval toto heslo?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Nyní ne"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Zapamatovat"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Připojení k síti Wi-Fi se nezdařilo"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" má pomalé připojení k internetu."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Přímé připojení sítě Wi-Fi"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Spustit přímé připojení sítě Wi-Fi. Tato možnost vypne provoz sítě Wi-Fi v režimu klient/hotspot."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Přímé připojení sítě Wi-Fi se nepodařilo spustit."</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Přímé připojení sítě Wi-Fi je zapnuto"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Nastavení otevřete dotykem"</string>
<string name="accept" msgid="1645267259272829559">"Přijmout"</string>
<string name="decline" msgid="2112225451706137894">"Odmítnout"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Pozvánka odeslána."</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 4904a99..78aff33 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -757,13 +757,17 @@
<string name="permlab_addVoicemail" msgid="5525660026090959044">"tilføj telefonsvarer"</string>
<string name="permdesc_addVoicemail" msgid="6604508651428252437">"Tillader, at appen kan tilføje beskeder på din telefonsvarer."</string>
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"skifte tilladelser til geografisk placering i Browser"</string>
- <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Tillader, at appen kan ændre browserens tilladelser angående geografisk placering. Ondsindede apps kan benytte dette til at sende oplysninger om placering til vilkårlige websteder."</string>
+ <string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"Tillader, at appen kan ændre browserens tilladelser angående geografisk placering. Ondsindede apps kan benytte dette til at sende oplysninger om placering til vilkårlige websites."</string>
<string name="permlab_packageVerificationAgent" msgid="5568139100645829117">"bekræft pakker"</string>
<string name="permdesc_packageVerificationAgent" msgid="8437590190990843381">"Tillader, at appen kan bekræfte, at en pakke kan installeres."</string>
<string name="permlab_bindPackageVerifier" msgid="4187786793360326654">"bind til en bekræftelse af pakker"</string>
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Tillader, at indehaveren kan sende anmodninger om bekræftelser af pakker. Dette bør aldrig være nødvendigt for almindelige apps."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"adgang til serielle porte"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"Tillader, at indehaveren kan få adgang til serielle porte ved hjælp af SerialManager API."</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"Ønsker du, at browseren skal huske denne adgangskode?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Ikke nu"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Husk"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Kunne ikke oprette forbindelse til Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" har en dårlig internetforbindelse."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Start Wi-Fi Direct. Dette slår Wi-Fi-klient/hotspot fra."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Wi-Fi Direct kunne ikke startes."</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct er slået til"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Tryk for indstillinger"</string>
<string name="accept" msgid="1645267259272829559">"Accepter"</string>
<string name="decline" msgid="2112225451706137894">"Afvis"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Invitationen er sendt"</string>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 20ef4d7..78845c4 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -764,6 +764,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Ermöglicht dem Halter, Anfragen für die Paketprüfung zu senden. Sollte nie für normale Apps benötigt werden."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"Zugriff auf serielle Schnittstellen"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"Ermöglicht dem Inhaber den Zugriff auf serielle Schnittstellen über das SerialManager-API"</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"Möchten Sie, dass der Browser dieses Passwort speichert?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Nicht jetzt"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Speichern"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Es konnte keine WLAN-Verbindung hergestellt werden."</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" hat eine schlechte Internetverbindung."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Wi-Fi Direct-Betrieb starten. Hierdurch wird der WLAN-Client-/-Hotspot-Betrieb deaktiviert."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Starten von Wi-Fi Direct nicht möglich"</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct ist aktiviert."</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Zum Aufrufen der Einstellungen berühren"</string>
<string name="accept" msgid="1645267259272829559">"Akzeptieren"</string>
<string name="decline" msgid="2112225451706137894">"Ablehnen"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Einladung gesendet"</string>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 200f702..9244dab 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -764,6 +764,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Επιτρέπει στον κάτοχο να υποβάλλει ερωτήματα σε προγράμματα επαλήθευσης πακέτου. Δεν απαιτείται για συνήθεις εφαρμογές."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"πρόσβαση στις σειριακές θύρες"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"Επιτρέπει στον κάτοχο την πρόσβαση στις σειριακές θύρες με τη χρήση του SerialManager API."</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"Θέλετε το πρόγραμμα περιήγησης να διατηρήσει αυτόν τον κωδικό πρόσβασης;"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Να μην γίνει τώρα"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Διατήρηση"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Δεν είναι δυνατή η σύνδεση στο Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" έχει κακή σύνδεση στο Διαδίκτυο."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Ξεκινήστε τη λειτουργία Wi-Fi Direct. Θα απενεργοποιηθεί η λειτουργία πελάτη/φορητού σημείου πρόσβασης Wi-Fi."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Δεν ήταν δυνατή η εκκίνηση του Wi-Fi Direct."</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Το Wi-Fi Direct έχει ενεργοποιηθεί"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Αγγίξτε για ρυθμίσεις"</string>
<string name="accept" msgid="1645267259272829559">"Αποδοχή"</string>
<string name="decline" msgid="2112225451706137894">"Απόρριψη"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Η πρόσκληση στάλθηκε"</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 2859942..dbd2218 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -764,6 +764,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Allows the holder to make requests of package verifiers. Should never be needed for normal apps."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"access serial ports"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"Allows the holder to access serial ports using the SerialManager API."</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"Do you want the browser to remember this password?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Not now"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Remember"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Couldn\'t connect to Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" has a poor Internet connection."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Start Wi-Fi Direct. This will turn off Wi-Fi client/hotspot."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Couldn\'t start Wi-Fi Direct."</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct is on"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Touch for settings"</string>
<string name="accept" msgid="1645267259272829559">"Accept"</string>
<string name="decline" msgid="2112225451706137894">"Decline"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Invitation sent"</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index dbc96e7..42cc24a 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -764,6 +764,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Permite que el titular solicite verificadores de paquetes. Las aplicaciones normales no deberían necesitar este permiso."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"Acceder a los puertos serie"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"Permite acceder a puertos serie a través de la API SerialManager."</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"¿Quieres recordar esta contraseña en el navegador?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Ahora no."</string>
<string name="save_password_remember" msgid="6491879678996749466">"Recuerda"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"No se pudo conectar a la red Wi-Fi."</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" tiene una mala conexión a Internet."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Iniciar Wi-Fi Direct. Se desactivará el funcionamiento de la zona o del cliente Wi-Fi."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"No se pudo iniciar Wi-Fi Direct."</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Se activó Wi-Fi Direct."</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Tocar para ajustar los parámetros de configuración"</string>
<string name="accept" msgid="1645267259272829559">"Aceptar"</string>
<string name="decline" msgid="2112225451706137894">"Rechazar"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Se envió la invitación."</string>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index d3c55a6..a09a6bf 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -764,6 +764,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Permite que se envíen solicitudes de detectores de paquetes. Las aplicaciones normales no deberían necesitar este permiso."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"acceder a puertos serie"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"Permite acceder a puertos serie a través de SerialManager API."</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"¿Quieres que el navegador recuerde esta contraseña?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Ahora no"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Recordar"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"No se ha podido establecer conexión con la red Wi-Fi."</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" tiene una conexión inestable a Internet."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Iniciar Wi-Fi Direct. Se desactivará el funcionamiento de la zona o del cliente Wi-Fi."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"No se ha podido iniciar Wi-Fi Direct."</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct activado"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Toca para acceder a Ajustes"</string>
<string name="accept" msgid="1645267259272829559">"Aceptar"</string>
<string name="decline" msgid="2112225451706137894">"Rechazar"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Invitación enviada"</string>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index c3a6169..07e732a 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -764,6 +764,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Lubab omanikul teha taotlusi paketi kinnitajate kohta. Tavarakenduste puhul ei peaks seda kunagi vaja minema."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"juurdepääs jadaportidele"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"Võimaldab omanikul SerialManageri API-liidese abil jadaportidele juurde pääseda."</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"Kas soovite, et brauser jätaks selle parooli meelde?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Mitte praegu"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Pidage meeles"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Ei saanud WiFi-ga ühendust"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" on halb Interneti-ühendus."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"WiFi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Käivitage WiFi otseühendus. See lülitab välja WiFi kliendi/leviala."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"WiFi otseühenduse käivitamine ebaõnnestus."</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"WiFi Direct on sees"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Puuted seadete jaoks"</string>
<string name="accept" msgid="1645267259272829559">"Nõustu"</string>
<string name="decline" msgid="2112225451706137894">"Keeldu"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Kutse on saadetud"</string>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 87eee68..ddb0438 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -764,6 +764,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"به دارنده اجازه میدهد تا تاییدکنندگان بسته را درخواست کند. برای برنامههای عادی نیاز نیست."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"دسترسی به درگاههای سریال"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"به دارنده اجازه میدهد با استفاده از SerialManager API به درگاههای سریال دسترسی داشته باشد."</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"می خواهید مرورگر این رمز ورود را به خاطر داشته باشد؟"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"اکنون خیر"</string>
<string name="save_password_remember" msgid="6491879678996749466">"به خاطر سپردن"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"اتصال به Wi-Fi ممکن نیست"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" اتصال اینترنتی ضعیفی دارد."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Wi-Fi Direct را شروع کنید. این کار نقطه اتصال/سرویس گیرنده Wi-Fi را غیرفعال خواهد کرد."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Wi-Fi Direct شروع نشد."</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct روشن است"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"لمس کردن برای تنظیمات"</string>
<string name="accept" msgid="1645267259272829559">"پذیرش"</string>
<string name="decline" msgid="2112225451706137894">"عدم پذیرش"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"دعوتنامه ارسال شد"</string>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 5ab7158..b837c5a 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -764,6 +764,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Antaa sovelluksen tehdä pakettien vahvistuspyyntöjä. Ei tavallisten sovellusten käyttöön."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"käytä sarjaportteja"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"Luvan haltija voi käyttää sarjaportteja SerialManager-sovellusliittymän avulla."</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"Haluatko selaimen muistavan tämän salasanan?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Ei nyt"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Muista"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wifi-yhteyden muodostaminen epäonnistui"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" : huono internetyhteys."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Suora wifi-yhteys"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Käynnistä suora wifi-yhteys. Wifi-asiakas/-hotspot poistetaan käytöstä."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Suoran wifi-yhteyden käynnistäminen epäonnistui."</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct on käytössä"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Tarkastele asetuksia koskettamalla"</string>
<string name="accept" msgid="1645267259272829559">"Hyväksy"</string>
<string name="decline" msgid="2112225451706137894">"Hylkää"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Kutsu lähetetty."</string>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 6067350..aebe460 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -764,6 +764,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Permet à l\'application autorisée d\'effectuer des requêtes de vérificateurs de package. Les applications standards ne doivent jamais avoir recours à cette fonctionnalité."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"accéder aux ports série"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"Permet à l\'application autorisée d\'accéder aux ports série avec l\'API SerialManager."</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"Voulez-vous que le navigateur se souvienne de ce mot de passe ?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Pas maintenant"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Mémoriser"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Impossible de se connecter au Wi-Fi."</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" dispose d\'une mauvaise connexion Internet."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Lancer le Wi-Fi Direct. Cela désactive le fonctionnement du Wi-Fi client ou via un point d\'accès."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Impossible d\'activer le Wi-Fi Direct."</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct activé"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Appuyez pour accéder aux paramètres."</string>
<string name="accept" msgid="1645267259272829559">"Accepter"</string>
<string name="decline" msgid="2112225451706137894">"Refuser"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Invitation envoyée"</string>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 1aaedbd..11bad07 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -764,6 +764,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"धारक को पैकेज प्रमाणक के अनुरोध की अनुमति देता है. सामान्य एप्लिकेशन के लिए कभी भी आवश्यक नहीं होना चाहिए."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"सीरियल पोर्ट पर पहुंचें"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"SerialManager API का उपयोग करके धारक को सीरियल पोर्ट पर पहुंच प्रदान करता है."</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"क्या आप चाहते हैं कि ब्राउज़र पासवर्ड को याद रखे?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"अभी नहीं"</string>
<string name="save_password_remember" msgid="6491879678996749466">"याद रखें"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wi-Fi से कनेक्ट नहीं हो सका"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" के पास एक कमज़ोर इंटरनेट कनेक्शन है."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi प्रत्यक्ष"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Wi-Fi डायरेक्ट प्रारंभ करें. इससे Wi-Fi क्लाइंट/हॉटस्पॉट कार्यवाही बंद हो जाएगी."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Wi-Fi डायरेक्ट प्रारंभ नहीं किया जा सका."</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi प्रत्यक्ष चालू है"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"सेटिंग के लिए स्पर्श करें"</string>
<string name="accept" msgid="1645267259272829559">"स्वीकार करें"</string>
<string name="decline" msgid="2112225451706137894">"अस्वीकार करें"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"आमंत्रण भेजा गया"</string>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 0775984..462cb52 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -215,8 +215,8 @@
<string name="permdesc_reorderTasks" msgid="4175137612205663399">"Omogućuje aplikaciji da premjesti zadatke u prednji plan ili pozadinu. Zlonamjerne aplikacije mogu na silu doći u prednji plan bez vašeg nadzora."</string>
<string name="permlab_removeTasks" msgid="6821513401870377403">"zaustavljanje pokrenutih aplikacija"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"Omogućuje aplikaciji uklanjanje zadataka i uklanjanje njihovih aplikacija. Zlonamjerne aplikacije mogu poremetiti rad drugih aplikacija."</string>
- <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"postavljanje zaslona kompatibilnost"</string>
- <string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Aplikaciji omogućuje upravljanje načinom kompatibilnosti zaslona drugih aplikacija. Zlonamjerne aplikacije mogu prekinuti takvo ponašanje ostalih aplikacija."</string>
+ <string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"postavljanje kompatibilnosti sa zaslonom"</string>
+ <string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Aplikaciji omogućuje upravljanje načinom kompatibilnosti aplikacija sa zaslonom. Zlonamjerne aplikacije mogu prekinuti takvo ponašanje ostalih aplikacija."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"omogućavanje rješavanja programskih pogrešaka u aplikaciji"</string>
<string name="permdesc_setDebugApp" msgid="4474512416299013256">"Omogućuje aplikaciji uključivanje uklanjanja programskih pogrešaka za drugu aplikaciju. Zlonamjerne aplikacije mogu na taj način ukloniti druge aplikacije."</string>
<string name="permlab_changeConfiguration" msgid="8214475779521218295">"promjena postavki korisničkog sučelja"</string>
@@ -764,6 +764,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Nositelju omogućuje da traži paketnu provjeru. Ne bi smjelo biti potrebno za normalne aplikacije."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"pristup serijskim priključcima"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"Rukovatelju omogućuje pristup serijskim priključcima pomoću značajke SerialManager API."</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"Želite li da preglednik zapamti ovu zaporku?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Ne sada"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Zapamti"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Ne može se spojiti na Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" ima lošu internetsku vezu."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Izravni Wi-Fi"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Pokreni izravan rad s Wi-Fi mrežom. To će isključiti rad s Wi-Fi klijentom/žarišnom točkom."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Pokretanje izravne Wi-Fi veze nije moguće."</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct uključen"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Dodirnite za postavke"</string>
<string name="accept" msgid="1645267259272829559">"Prihvaćam"</string>
<string name="decline" msgid="2112225451706137894">"Odbaci"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Pozivnica je poslana"</string>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index e125ba8..c74ef36 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -764,6 +764,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Lehetővé teszi, hogy a tulajdonos kérelmeket nyújtson be a csomag hitelesítőivel kapcsolatban. A normál alkalmazásoknak erre soha nincs szüksége."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"soros portok elérése"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"Lehetővé teszi a tulajdonos számára a soros portok elérését a SerialManager API segítségével."</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"Szeretné, hogy a böngésző megjegyezze a jelszót?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Most nem"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Megjegyzés"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Nem sikerült csatlakozni a Wi-Fi hálózathoz"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" rossz internetkapcsolattal rendelkezik."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Wi-Fi Direct elindítása. A Wi-Fi kliens/hotspot ettől leáll."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Nem sikerült elindítani a Wi-Fi Direct kapcsolatot."</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"A Wi-Fi Direct be van kapcsolva"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"A beállításokhoz érintse meg"</string>
<string name="accept" msgid="1645267259272829559">"Elfogadás"</string>
<string name="decline" msgid="2112225451706137894">"Elutasítás"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Meghívó elküldve"</string>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 72fcb50..068356e 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -764,6 +764,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Mengizinkan pemegang mengajukan permintaan pemverifikasian paket. Tidak pernah dibutuhkan oleh apl normal."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"akses port serial"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"Memungkinkan pemegangnya mengakses port serial menggunakan API SerialManager."</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"Apakah Anda ingin peramban menyimpan sandi ini?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Tidak sekarang"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Ingat"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Tidak dapat tersambung ke Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" memiliki sambungan internet yang buruk."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Langsung"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Memulai Wi-Fi Langsung. Opsi ini akan mematikan hotspot/klien Wi-Fi."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Tidak dapat memulai Wi-Fi Langsung."</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Langsung aktif"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Sentuh untuk setelan"</string>
<string name="accept" msgid="1645267259272829559">"Terima"</string>
<string name="decline" msgid="2112225451706137894">"Tolak"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Undangan terkirim"</string>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index ec9457b..221fff0 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -764,6 +764,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Consente al proprietario di effettuare richieste relative alle verifiche dei pacchetti. Non dovrebbe mai essere necessario per le normali applicazioni."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"accesso alle porte seriali"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"Permette al proprietario di accedere alle porte seriali utilizzando l\'API SerialManager."</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"Memorizzare la password nel browser?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Non ora"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Memorizza"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Impossibile connettersi alla rete Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" ha una connessione Internet debole."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Avvia Wi-Fi Direct. Verrà disattivato il client/hotspot Wi-Fi."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Avvio di Wi-Fi Direct non riuscito."</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct è attivo"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Tocca per le impostazioni"</string>
<string name="accept" msgid="1645267259272829559">"Accetto"</string>
<string name="decline" msgid="2112225451706137894">"Rifiuto"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Invito inviato"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 5fc15c7..c1d7d82 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -764,6 +764,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"מאפשר למשתמש להגיש בקשות של מאמתי חבילות. הרשאה זו לעולם אינה נחוצה ליישומים רגילים."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"גישה ליציאות טוריות"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"מאפשר לבעלים לגשת ליציאות טוריות באמצעות ממשק ה- API של SerialManager."</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"האם ברצונך שהדפדפן יזכור סיסמה זו?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"לא כעת"</string>
<string name="save_password_remember" msgid="6491879678996749466">"זכור"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"אין אפשרות להתחבר ל-Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" אינו מחובר היטב לאינטרנט."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi ישיר"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"הפעל Wi-Fi ישיר. פעולה זו תכבה את הלקוח/הנקודה החמה של ה-Wi-Fi."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"לא ניתן להפעיל Wi-Fi ישיר"</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi ישיר מופעל"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"גע עבור הגדרות"</string>
<string name="accept" msgid="1645267259272829559">"קבל"</string>
<string name="decline" msgid="2112225451706137894">"דחה"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"ההזמנה נשלחה"</string>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 63b8c73..b3476db 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -216,7 +216,7 @@
<string name="permlab_removeTasks" msgid="6821513401870377403">"実行中のアプリの停止"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"タスクの削除とアプリの終了をアプリに許可します。この許可を悪意のあるアプリケーションに利用されると、他のアプリの動作が妨害される恐れがあります。"</string>
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"画面互換性の設定"</string>
- <string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"他のアプリケーションの画面互換性モードをコントロールすることをアプリに許可します。この許可を悪意のあるアプリケーションに利用されると、他のアプリケーションの動作が中断される恐れがあります。"</string>
+ <string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"他のアプリの画面互換性モードをコントロールすることをアプリに許可します。この許可を悪意のあるアプリに利用されると、他のアプリの動作が中断される恐れがあります。"</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"アプリのデバッグの有効化"</string>
<string name="permdesc_setDebugApp" msgid="4474512416299013256">"別のアプリをデバッグモードにすることをアプリに許可します。この許可を悪意のあるアプリに利用されると、他のアプリが強制終了される恐れがあります。"</string>
<string name="permlab_changeConfiguration" msgid="8214475779521218295">"UI設定の変更"</string>
@@ -764,6 +764,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"パッケージベリファイアのリクエストを所有者に許可します。通常のアプリでは不要です。"</string>
<string name="permlab_serialPort" msgid="546083327654631076">"シリアルポートへのアクセス"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"SerialManager APIを使用してシリアルポートにアクセスすることを所有者に許可します。"</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"このパスワードをブラウザで保存しますか?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"今は保存しない"</string>
<string name="save_password_remember" msgid="6491879678996749466">"保存"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wi-Fiに接続できませんでした"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" はインターネット接続に問題があります。"</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Wi-Fi Directを開始します。これによりWi-Fiクライアント/アクセスポイントがOFFになります。"</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Wi-Fi Directを開始できませんでした。"</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi DirectはONです"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"設定を表示するにはタップしてください"</string>
<string name="accept" msgid="1645267259272829559">"同意する"</string>
<string name="decline" msgid="2112225451706137894">"同意しない"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"招待状を送信しました"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index f97cbdc..aeca1ed 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -764,6 +764,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"권한을 가진 프로그램이 패키지 인증을 요청할 수 있도록 허용합니다. 일반 앱에는 필요하지 않습니다."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"직렬 포트에 액세스"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"SerialManager API를 사용하여 권한을 가진 프로그램이 직렬 포트에 액세스할 수 있도록 합니다."</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"브라우저에 이 비밀번호를 저장하시겠습니까?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"나중에"</string>
<string name="save_password_remember" msgid="6491879678996749466">"저장"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wi-Fi에 연결할 수 없습니다"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" 인터넷 연결 상태가 좋지 않습니다."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Wi-Fi Direct 작업을 시작합니다. 이 작업을 하면 Wi-Fi 클라이언트/핫스팟 작업이 중지됩니다."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Wi-Fi Direct를 시작하지 못했습니다."</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct 켜짐"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"설정으로 이동하려면 터치하세요."</string>
<string name="accept" msgid="1645267259272829559">"동의"</string>
<string name="decline" msgid="2112225451706137894">"거부"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"초대장을 보냈습니다."</string>
diff --git a/core/res/res/values-large/themes.xml b/core/res/res/values-large/themes.xml
index 871a131..448e7c8 100644
--- a/core/res/res/values-large/themes.xml
+++ b/core/res/res/values-large/themes.xml
@@ -33,17 +33,17 @@
-->
<resources>
<style name="Theme.Holo.DialogWhenLarge"
- parent="@android:style/Theme.Holo.Dialog.MinWidth">
+ parent="@android:style/Theme.Holo.Dialog.FixedSize">
<item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
</style>
<style name="Theme.Holo.DialogWhenLarge.NoActionBar"
- parent="@android:style/Theme.Holo.Dialog.NoActionBar.MinWidth">
+ parent="@android:style/Theme.Holo.Dialog.NoActionBar.FixedSize">
<item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
</style>
<style name="Theme.Holo.Light.DialogWhenLarge"
- parent="@android:style/Theme.Holo.Light.Dialog.MinWidth">
+ parent="@android:style/Theme.Holo.Light.Dialog.FixedSize">
</style>
<style name="Theme.Holo.Light.DialogWhenLarge.NoActionBar"
- parent="@android:style/Theme.Holo.Light.Dialog.NoActionBar.MinWidth">
+ parent="@android:style/Theme.Holo.Light.Dialog.NoActionBar.FixedSize">
</style>
</resources>
diff --git a/core/res/res/values-large/themes_device_defaults.xml b/core/res/res/values-large/themes_device_defaults.xml
index 52fff5c..d57e827 100644
--- a/core/res/res/values-large/themes_device_defaults.xml
+++ b/core/res/res/values-large/themes_device_defaults.xml
@@ -32,17 +32,17 @@
-->
<resources>
<style name="Theme.DeviceDefault.DialogWhenLarge"
- parent="@android:style/Theme.DeviceDefault.Dialog.MinWidth">
+ parent="@android:style/Theme.DeviceDefault.Dialog.FixedSize">
<item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
</style>
<style name="Theme.DeviceDefault.DialogWhenLarge.NoActionBar"
- parent="@android:style/Theme.DeviceDefault.Dialog.NoActionBar.MinWidth">
+ parent="@android:style/Theme.DeviceDefault.Dialog.NoActionBar.FixedSize">
<item name="preferencePanelStyle">@style/PreferencePanel.Dialog</item>
</style>
<style name="Theme.DeviceDefault.Light.DialogWhenLarge"
- parent="@android:style/Theme.DeviceDefault.Light.Dialog.MinWidth">
+ parent="@android:style/Theme.DeviceDefault.Light.Dialog.FixedSize">
</style>
<style name="Theme.DeviceDefault.Light.DialogWhenLarge.NoActionBar"
- parent="@android:style/Theme.DeviceDefault.Light.Dialog.NoActionBar.MinWidth">
+ parent="@android:style/Theme.DeviceDefault.Light.Dialog.NoActionBar.FixedSize">
</style>
</resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index a1694af..739dca8 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -764,6 +764,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Savininkui leidžiama teikti užklausas patikrinti paketą. Įprastoms programoms to neturėtų prireikti."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"pasiekti nuosekliuosius prievadus"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"Leidžiama savininkui pasiekti nuosekliuosius prievadus naudojant „SerialManager“ API."</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"Ar norite, kad naršyklė atsimintų šį slaptažodį?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Ne dabar"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Atsiminti"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Nepavyko prisijungti prie „Wi-Fi“"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" turi prastą interneto ryšį."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Tiesioginis „Wi-Fi“ ryšys"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Paleiskite „Wi-Fi Direct“. Bus išjungta „Wi-Fi“ programa / viešosios interneto prieigos taškas."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Nepavyko paleisti „Wi-Fi Direct“."</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"„Wi-Fi Direct“ įjungta"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Jei norite peržiūrėti nustatymus, palieskite"</string>
<string name="accept" msgid="1645267259272829559">"Sutikti"</string>
<string name="decline" msgid="2112225451706137894">"Atmesti"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Pakvietimas išsiųstas"</string>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index aeec70b..c36434c 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -764,6 +764,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Ļauj īpašniekam sūtīt pakotņu verificētāju pieprasījumus. Parastajām lietotnēm tas nekad nav nepieciešams."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"piekļuve seriālajiem portiem"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"Ļauj īpašniekam piekļūt seriālajiem portiem, izmantojot SerialManager API."</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"Vai vēlaties, lai pārlūkprogrammā tiktu saglabāta šī parole?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Ne tagad"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Atcerēties"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Nevarēja izveidot savienojumu ar Wi-Fi."</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" ir slikts interneta savienojums."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Palaist programmu Wi-Fi Direct. Tādējādi tiks izslēgta Wi-Fi klienta/tīklāja darbība."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Nevarēja palaist programmu Wi-Fi Direct."</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct ir ieslēgts"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Pieskarieties, lai piekļūtu iestatījumiem."</string>
<string name="accept" msgid="1645267259272829559">"Piekrist"</string>
<string name="decline" msgid="2112225451706137894">"Noraidīt"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Ielūgums ir nosūtīts."</string>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index 0610e88..6d0f5fd 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -764,6 +764,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Membenarkan pemegang membuat permintaan pengesah pakej. Tidak sekali-kali diperlukan untuk apl normal."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"akses port bersiri"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"Membenarkan pemegang mengakses port bersiri menggunakan API SerialManager."</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"Adakah anda mahu penyemak imbas mengingati kata laluan ini?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Bukan sekarang"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Ingat"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Tidak boleh menyambung kepada Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" mempunyai sambungan internet yang kurang baik."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Langsung"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Mulakan Wi-Fi Langsung. Hal ini akan mematikan pengendalian klien/liputan Wi-Fi."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Tidak dapat memulakan Wi-Fi Langsung."</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct dihidupkan"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Sentuh untuk tetapan"</string>
<string name="accept" msgid="1645267259272829559">"Terima"</string>
<string name="decline" msgid="2112225451706137894">"Tolak"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Jemputan dihantar"</string>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index e82718e..41ff046 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -764,6 +764,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Lar innehaveren sende forespørsler om pakkeverifikatorer. Skal aldri være nødvendig for normale apper."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"tilgang til serielle porter"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"Gir innehaveren tilgang til serielle porter ved hjelp av SerialManager API."</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"Ønsker du at nettleseren skal huske dette passordet?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Ikke nå"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Husk"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Kan ikke koble til Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" har en dårlig Internett-tilkobling."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Start Wi-Fi Direct. Dette deaktiverer Wi-Fi-klienten/-sonen."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Kunne ikke starte Wi-Fi Direct."</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct er slått på"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Berør for å se innstillinger"</string>
<string name="accept" msgid="1645267259272829559">"Godta"</string>
<string name="decline" msgid="2112225451706137894">"Avslå"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Invitasjonen er sendt"</string>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index ef4dd6a..8e5e8bc 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -764,6 +764,8 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Hiermee kan de houder verzoeken indienen voor pakketcontroles. Nooit vereist voor normale apps."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"toegang krijgen tot seriële poorten"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"De houder toestaan toegang tot seriële poorten te krijgen met de SerialManager API."</string>
+ <string name="permlab_accessContentProvidersExternally" msgid="5077774297943409285">"externe toegang tot inhoudsproviders"</string>
+ <string name="permdesc_accessContentProvidersExternally" msgid="4544346486697853685">"Hiermee kan de houder toegang krijgen tot inhoudsproviders via de shell. Nooit vereist voor normale apps."</string>
<string name="save_password_message" msgid="767344687139195790">"Wilt u dat de browser dit wachtwoord onthoudt?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Niet nu"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Onthouden"</string>
@@ -973,6 +975,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Kan geen verbinding maken met Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" heeft een slechte internetverbinding."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Wifi Direct starten. Hierdoor wordt de wifi-client/hotspot uitgeschakeld."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Kan Wifi Direct niet starten."</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct is actief"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Aanraken voor instellingen"</string>
<string name="accept" msgid="1645267259272829559">"Accepteren"</string>
<string name="decline" msgid="2112225451706137894">"Weigeren"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Uitnodiging verzonden"</string>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index f231d89..694ed75 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -216,7 +216,7 @@
<string name="permlab_removeTasks" msgid="6821513401870377403">"zatrzymywanie uruchomionych aplikacji"</string>
<string name="permdesc_removeTasks" msgid="1394714352062635493">"Umożliwia aplikacji usuwanie zadań i kończenie powiązanych z nimi aplikacji. Złośliwe aplikacje mogą zakłócić działanie innych aplikacji."</string>
<string name="permlab_setScreenCompatibility" msgid="6975387118861842061">"ustaw zgodność ekranu"</string>
- <string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Pozwala aplikacji na sterowanie trybem zgodności ekranu innych aplikacji. Złośliwe aplikacje mogą zmienić zachowanie innych aplikacji."</string>
+ <string name="permdesc_setScreenCompatibility" msgid="692043618693917374">"Pozwala aplikacji na sterowanie trybem zgodności ekranu innych aplikacji. Złośliwe aplikacje mogą zmienić zachowanie innych programów."</string>
<string name="permlab_setDebugApp" msgid="3022107198686584052">"włączenie debugowania aplikacji"</string>
<string name="permdesc_setDebugApp" msgid="4474512416299013256">"Pozwala aplikacji na włączenie debugowania innej aplikacji. Złośliwe aplikacje mogą to wykorzystać do kończenia pracy innych programów."</string>
<string name="permlab_changeConfiguration" msgid="8214475779521218295">"zmienianie ustawień interfejsu użytkownika"</string>
@@ -764,6 +764,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Pozwala na wysyłanie żądań weryfikacji pakietu. To uprawnienie nie powinno być potrzebne zwykłym aplikacjom."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"dostęp do portów szeregowych"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"Umożliwia posiadaczowi dostęp do portów szeregowych przy użyciu interfejsu API narzędzia SerialManager."</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"Czy chcesz, aby zapamiętać to hasło w przeglądarce?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Nie teraz"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Zapamiętaj"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Nie można połączyć się z siecią Wi-Fi."</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" ma powolne połączenie internetowe."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Uruchom Wi-Fi Direct. Spowoduje to wyłączenie klienta lub punktu dostępu Wi-Fi."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Nie można uruchomić Wi-Fi Direct."</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct włączone"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Dotknij, aby zmienić ustawienia"</string>
<string name="accept" msgid="1645267259272829559">"Akceptuj"</string>
<string name="decline" msgid="2112225451706137894">"Odrzuć"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Wysłano zaproszenie"</string>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index f3f060090..3fa89d3 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -764,6 +764,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Permite ao titular solicitar verificadores de pacotes. Nunca deverá ser necessário para aplicações normais."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"aceder a portas série"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"Permite ao titular aceder a portas de série através da API SerialManager."</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"Quer que o browser memorize esta palavra-passe?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Agora não"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Lembrar"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Não foi possível ligar a Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" tem uma ligação à internet fraca."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Iniciar o Wi-Fi Direct. Esta opção desativará o cliente/zona Wi-Fi."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Não foi possível iniciar o Wi-Fi Direct."</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"O Wi-Fi Direct está ativado"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Toque para aceder às definições"</string>
<string name="accept" msgid="1645267259272829559">"Aceitar"</string>
<string name="decline" msgid="2112225451706137894">"Recusar"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Convite enviado"</string>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index b49c36b..d99bc60 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -764,6 +764,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Permite que o titular solicite verificadores de pacote. Nunca deve ser necessário para aplicativos normais."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"acessar portas seriais"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"Permite que o detentor tenha acesso a portas seriais usando a API SerialManager."</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"Deseja que o navegador lembre desta senha?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Agora não"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Lembrar"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Não foi possível se conectar a redes Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" tem uma conexão de baixa qualidade com a Internet."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Iniciar o Wi-Fi Direct. Isso desativará o ponto de acesso/cliente Wi-Fi."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Não foi possível iniciar o Wi-Fi Direct."</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct ativado"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Tocar para acessar configurações"</string>
<string name="accept" msgid="1645267259272829559">"Aceitar"</string>
<string name="decline" msgid="2112225451706137894">"Recusar"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Convite enviado"</string>
diff --git a/core/res/res/values-rm/strings.xml b/core/res/res/values-rm/strings.xml
index 1447c0e..5b8efa6 100644
--- a/core/res/res/values-rm/strings.xml
+++ b/core/res/res/values-rm/strings.xml
@@ -1155,6 +1155,10 @@
<skip />
<!-- no translation found for permdesc_serialPort (2991639985224598193) -->
<skip />
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"Vulais Vus ch\'il navigatur memorisescha quest pled-clav?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Betg ussa"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Memorisar"</string>
@@ -1418,6 +1422,16 @@
<skip />
<!-- no translation found for wifi_watchdog_network_disabled_detailed (5548780776418332675) -->
<skip />
+ <!-- no translation found for wifi_p2p_dialog_title (97611782659324517) -->
+ <skip />
+ <!-- no translation found for wifi_p2p_turnon_message (2909250942299627244) -->
+ <skip />
+ <!-- no translation found for wifi_p2p_failed_message (3763669677935623084) -->
+ <skip />
+ <!-- no translation found for wifi_p2p_enabled_notification_title (2068321881673734886) -->
+ <skip />
+ <!-- no translation found for wifi_p2p_enabled_notification_message (1638949953993894335) -->
+ <skip />
<!-- no translation found for accept (1645267259272829559) -->
<skip />
<!-- no translation found for decline (2112225451706137894) -->
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index f241e8e..d870d58 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -764,6 +764,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Permite proprietarului să efectueze solicitări pentru verificatori de pachete. Nu ar trebui să fie niciodată necesară pentru aplicaţiile obişnuite."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"acces la porturi seriale"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"Permite posesorului accesul la porturile serial utilizând API-ul SerialManager."</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"Doriţi ca browserul să reţină această parolă?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Nu acum"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Reţineţi"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Nu se poate conecta la Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" are o conexiune la internet slabă."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Porniţi Wi-Fi Direct. Acest lucru va dezactiva clientul/hotspotul Wi-Fi."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Wi-Fi Direct nu a putut porni."</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct este activat"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Atingeţi pentru setări"</string>
<string name="accept" msgid="1645267259272829559">"Acceptaţi"</string>
<string name="decline" msgid="2112225451706137894">"Refuzaţi"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Invitaţia a fost trimisă."</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 809da83..0b63de1 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -764,6 +764,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Приложение сможет запрашивать проверку пакетов. Это разрешение не используется обычными приложениями."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"доступ к последовательным портам"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"Открыть владельцу доступ к последовательным портам с помощью SerialManager API."</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"Вы хотите, чтобы браузер запомнил этот пароль?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Не сейчас"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Запомнить"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Не удалось подключиться к сети Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" – плохое интернет-соединение."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Начать соединение через Wi-Fi Direct. Модуль Wi-Fi будет отключен."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Не удалось запустить Wi-Fi Direct."</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct включен"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Нажмите, чтобы открыть настройки"</string>
<string name="accept" msgid="1645267259272829559">"Принять"</string>
<string name="decline" msgid="2112225451706137894">"Отклонить"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Приглашение отправлено"</string>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 7d75949..df25ac7 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -764,6 +764,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Umožňuje držiteľovi podávať žiadosti o overenie balíkov. Bežné aplikácie by toto nastavenie nemali nikdy potrebovať."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"prístup k sériovým portom"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"Držiteľa oprávňuje na prístup k sériovým portom pomocou rozhrania API SerialManager."</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"Chcete, aby si prehliadač zapamätal toto heslo?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Teraz nie"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Zapamätať"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Nepodarilo sa pripojiť k sieti Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" má nekvalitné internetové pripojenie."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Priame pripojenie Wi-Fi"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Spustiť priame pripojenie siete Wi-Fi. Táto možnosť vypne sieť Wi-Fi v režime klient alebo hotspot."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Priame pripojenie siete Wi-Fi sa nepodarilo spustiť"</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Priame pripojenie siete Wi-Fi je zapnuté"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Nastavenia otvoríte dotykom"</string>
<string name="accept" msgid="1645267259272829559">"Prijať"</string>
<string name="decline" msgid="2112225451706137894">"Odmietnuť"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Pozvánka bola odoslaná"</string>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index e152a2f..88d02ab 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -764,6 +764,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Imetniku omogoča zahtevanje preverjanja paketov. Tega nikoli ni treba uporabiti za navadne programe."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"dostop do serijskih vrat"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"Imetniku omogoča, da z API-jem za SerialManager dostopa do serijskih vrat."</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"Ali želite, da si brskalnik zapomni to geslo?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Ne zdaj"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Zapomni si"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Z omrežjem Wi-Fi se ni mogoče povezati"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" ima slabo internetno povezavo."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Zaženite Wi-Fi Direct. S tem boste izklopili odjemalca/dostopno točko Wi-Fi."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Wi-Fi Direct ni bilo mogoče zagnati."</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct je vklopljen"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Dotaknite se za nastavitve"</string>
<string name="accept" msgid="1645267259272829559">"Sprejmi"</string>
<string name="decline" msgid="2112225451706137894">"Zavrni"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Povabilo je poslano"</string>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 7f1dbcd..7d0b9f5 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -764,6 +764,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Омогућава да власник упућује захтеве верификаторима пакета. Уобичајене апликације никада не би требало да је користе."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"приступ серијским портовима"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"Омогућава власнику да приступи серијским портовима помоћу SerialManager API-ја."</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"Желите ли да прегледач запамти ову лозинку?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Не сада"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Запамти"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Није било могуће повезати са Wi-Fi мрежом"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" има лошу интернет везу."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Покрените Wi-Fi Direct. Тиме ћете искључити клијента/хотспот за Wi-Fi."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Није могуће покренути Wi-Fi Direct."</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct је укључен"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Додирните за подешавања"</string>
<string name="accept" msgid="1645267259272829559">"Прихвати"</string>
<string name="decline" msgid="2112225451706137894">"Одбиј"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Позивница је послата"</string>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 10ecffc..ee6295f 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -764,6 +764,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Tillåter att innehavaren skickar förfrågningar till paketverifierare. Det ska inte behövas för vanliga appar."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"åtkomst till serieportar"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"Innebär att innehavaren får åtkomst till serieportar med programmeringsgränssnittet för SerialManager."</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"Vill du att webbläsaren ska komma ihåg lösenordet?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Inte nu"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Kom ihåg"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Det gick inte att ansluta till Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" har en dålig Internetanslutning."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi direkt"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Starta direkt Wi-Fi-användning. Detta inaktiverar Wi-Fi-användning med klient/trådlös surfzon."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Det gick inte att starta Wi-Fi direkt."</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct är aktiverat"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Tryck om du vill visa inställningar"</string>
<string name="accept" msgid="1645267259272829559">"Godkänn"</string>
<string name="decline" msgid="2112225451706137894">"Avvisa"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Inbjudan har skickats"</string>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index d245685..70b7c2e 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -764,6 +764,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Inaruhusu mmiliki kutuma maombi ya vibainishi furushi. Kamwe hazitahitajika kwa programu za kawaida."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"kituo tambulishi cha ufikivu"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"Inaruhusu mmiliki kufikia vituo tambulishi kwa kutumia KisimamiziTambulishi cha API."</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"Unataka kuvinjari ili ukumbuke nenosiri hili?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Si Sasa"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Kumbuka"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Haikuweza kuunganisha kwa Mtandao-Hewa"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" ina muunganisho duni wa Mtandao."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Mtandao hewa Moja kwa moja"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Anzisha Wi-Fi Moja kwa Moja. Hii itazima mteja/mtandao-hewa wa Wi-Fi."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Haikuweza kuanzisha Wi-Fi Moja kwa Moja."</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi ya Moja kwa Moja imewashwa"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Gusa kwa ajili ya mipangilio"</string>
<string name="accept" msgid="1645267259272829559">"Kubali"</string>
<string name="decline" msgid="2112225451706137894">"Kataa"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Mwaliko umetumwa"</string>
diff --git a/core/res/res/values-sw600dp/dimens.xml b/core/res/res/values-sw600dp/dimens.xml
index 431a502..13acdd6 100644
--- a/core/res/res/values-sw600dp/dimens.xml
+++ b/core/res/res/values-sw600dp/dimens.xml
@@ -68,5 +68,19 @@
<!-- Minimum width for an action button in the menu area of an action bar -->
<dimen name="action_button_min_width">64dip</dimen>
+
+ <!-- The platform's desired fixed width for a dialog along the major axis
+ (the screen is in landscape). This may be either a fraction or a dimension.-->
+ <item type="dimen" name="dialog_fixed_width_major">50%</item>
+ <!-- The platform's desired fixed width for a dialog along the minor axis
+ (the screen is in portrait). This may be either a fraction or a dimension.-->
+ <item type="dimen" name="dialog_fixed_width_minor">70%</item>
+ <!-- The platform's desired fixed height for a dialog along the major axis
+ (the screen is in portrait). This may be either a fraction or a dimension.-->
+ <item type="dimen" name="dialog_fixed_height_major">60%</item>
+ <!-- The platform's desired fixed height for a dialog along the minor axis
+ (the screen is in landscape). This may be either a fraction or a dimension.-->
+ <item type="dimen" name="dialog_fixed_height_minor">90%</item>
+
</resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 97f1c70..0acd104 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -764,6 +764,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"อนุญาตให้ผู้ใช้ส่งคำขอให้มีการยืนยันแพคเกจ ไม่ควรต้องใช้สำหรับแอปพลิเคชันทั่วไป"</string>
<string name="permlab_serialPort" msgid="546083327654631076">"เข้าถึงพอร์ตอนุกรม"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"อนุญาตให้ผู้ถือสามารถเข้าถึงพอร์ตอนุกรมโดยใช้ SerialManager API"</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"คุณต้องการให้เบราว์เซอร์จำรหัสผ่านนี้หรือไม่"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"ยังไม่ใช้งานขณะนี้"</string>
<string name="save_password_remember" msgid="6491879678996749466">"จำไว้"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"ไม่สามารถเชื่อมต่อ Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" มีสัญญาณอินเทอร์เน็ตไม่ดี"</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"เริ่มการทำงาน WiFi Direct ซึ่งจะเป็นการปิดการทำงาน WiFi ไคลเอ็นต์/ฮอตสปอต"</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"ไม่สามารถเริ่ม WiFi Direct ได้"</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"เปิด Wi-Fi Direct อยู่"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"แตะเพื่อตั้งค่า"</string>
<string name="accept" msgid="1645267259272829559">"ยอมรับ"</string>
<string name="decline" msgid="2112225451706137894">"ปฏิเสธ"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"ส่งข้อความเชิญแล้ว"</string>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index f59cde4..3bde5c8 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -764,6 +764,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Pinapayagan ang may-ari na gumawa ng mga kahilingan ng mga taga-verify ng package. Hindi kailanman dapat na kailanganin para sa normal na apps."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"mag-access sa mga serial port"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"Binibigyang-daan ang may-ari na mag-access ng mga serial port gamit ang SerialManager API."</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"Gusto mo bang tandaan ng browser ang password na ito?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Hindi ngayon"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Tandaan"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Hindi makakonekta sa Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" ay mayroong mahinang koneksyon sa Internet."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Simulan ang Wi-Fi Direct. I-o-off nito ang client/hotspot ng Wi-Fi."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Hindi masimulan ang Wi-Fi Direct"</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Ang Wi-Fi Direct ay naka-on"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Pindutin para sa mga setting"</string>
<string name="accept" msgid="1645267259272829559">"Tanggapin"</string>
<string name="decline" msgid="2112225451706137894">"Tanggihan"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Naipadala ang imbitasyon"</string>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index bcaa9a8..1b27dbd 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -764,6 +764,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Cihazın sahibine, paket doğrulayıcıları için istek yapma izni verir. Normal uygulamalar için gerekli olmaz."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"seri bağlantı noktalarına eriş"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"İzin sahibinin, SerialManager API\'sını kullanarak seri bağlantı noktalarına erişmesine olanak sağlar."</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"Tarayıcının bu şifreyi anımsamasını istiyor musunuz?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Şimdi değil"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Anımsa"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Kablosuz bağlantısı kurulamadı"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" İnternet bağlantısı zayıf."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Kablosuz Doğrudan Bağlantı"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Kablosuz Doğrudan Bağlantıyı başlat. Bu işlem, Kablosuz istemci/hotspot kullanımını kapatacak."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Kablosuz Doğrudan bağlantı başlatılamadı."</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Kablosuz Doğrudan özelliği açık"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Ayarlar için dokunun"</string>
<string name="accept" msgid="1645267259272829559">"Kabul et"</string>
<string name="decline" msgid="2112225451706137894">"Reddet"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Davetiye gönderildi"</string>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 6288aa1..eb22ec8 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -764,6 +764,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Дозволяє власникові робити запити на програми перевірки пакетів. Ніколи не застосовується для звичайних програм."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"отримувати доступ до послідовних портів"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"Дозволяє власнику отримувати доступ до послідовних портів за допомогою API SerialManager."</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"Хочете, щоб переглядач запам\'ятав цей пароль?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Не зараз"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Запам\'ятати"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Не вдалося під’єднатися до мережі Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" має погане з’єднання з Інтернетом."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Запустити Wi-Fi Direct. Це вимкне з’єднання Wi-Fi клієнт/точка доступу."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Не вдалося запустити Wi-Fi Direct."</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct увімкнено"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Торкніться, щоб побачити налаштування"</string>
<string name="accept" msgid="1645267259272829559">"Прийняти"</string>
<string name="decline" msgid="2112225451706137894">"Відхилити"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Запрошення надіслано"</string>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index ba81838..583d216 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -764,6 +764,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Cho phép chủ sở hữu yêu cầu trình xác minh gói. Không cần thiết cho các ứng dụng thông thường."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"truy cập cổng nối tiếp"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"Cho phép chủ sở hữu truy cập cổng nối tiếp sử dụng API SerialManager."</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"Bạn có muốn trình duyệt nhớ mật khẩu này không?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Không phải bây giờ"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Nhớ"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Không thể kết nối với Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" có kết nối Internet không tốt."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Khởi động Wi-Fi Direct. Việc này sẽ tắt hoạt động của ứng dụng khách/điểm phát sóng Wi-Fi."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Không thể khởi động Wi-Fi Direct."</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct được bật"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Chạm để cài đặt"</string>
<string name="accept" msgid="1645267259272829559">"Đồng ý"</string>
<string name="decline" msgid="2112225451706137894">"Từ chối"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Đã gửi thư mời"</string>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index cbfc222..ca3c65c 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -764,6 +764,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"允许用户请求使用程序包验证程序。普通应用程序绝不需要此权限。"</string>
<string name="permlab_serialPort" msgid="546083327654631076">"访问串行端口"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"允许持有人使用 SerialManager API 访问串行端口。"</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"是否希望浏览器记住此密码?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"暂不保存"</string>
<string name="save_password_remember" msgid="6491879678996749466">"记住"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"无法连接到 Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" 互联网连接状况不佳。"</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"启动 Wi-Fi Direct。此操作将会关闭 Wi-Fi 客户端/热点。"</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"无法启动 Wi-Fi Direct。"</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"已启用 Wi-Fi Direct"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"通过触摸进行设置"</string>
<string name="accept" msgid="1645267259272829559">"接受"</string>
<string name="decline" msgid="2112225451706137894">"拒绝"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"邀请已发送"</string>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 4d6042c..9b11c43 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -764,6 +764,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"允許應用程式要求驗證套件 (一般應用程式不需使用)。"</string>
<string name="permlab_serialPort" msgid="546083327654631076">"存取序列埠"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"允許應用程式使用 SerialManager API 存取序列埠。"</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"是否記住此密碼?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"現在不要"</string>
<string name="save_password_remember" msgid="6491879678996749466">"記住"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"無法連線至 Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" 的網際網路連線狀況不佳。"</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi Direct"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"啟動 WiFi Direct 作業,這會關閉 WiFi 用戶端/無線基地台作業。"</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"無法啟動 WiFi Direct。"</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi Direct 已開啟"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"輕觸即可設定"</string>
<string name="accept" msgid="1645267259272829559">"接受"</string>
<string name="decline" msgid="2112225451706137894">"拒絕"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"邀請函已傳送"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index c90fe76..8d02eff 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -764,6 +764,10 @@
<string name="permdesc_bindPackageVerifier" msgid="3180741773233862126">"Ivumela umnikazi ukuthi enze izicelo zezinsiza eziqinisekisa iphakheji. Akumele kudingeke ekusetshenzisweni okujwayelekile."</string>
<string name="permlab_serialPort" msgid="546083327654631076">"finyelela kuma- serial port"</string>
<string name="permdesc_serialPort" msgid="2991639985224598193">"Ivumela umnikai ukuthi athole inombolo ye-serial ukue angene kwiindawo ze-serial esebenzisa i-SerialManager API."</string>
+ <!-- no translation found for permlab_accessContentProvidersExternally (5077774297943409285) -->
+ <skip />
+ <!-- no translation found for permdesc_accessContentProvidersExternally (4544346486697853685) -->
+ <skip />
<string name="save_password_message" msgid="767344687139195790">"Ingabe ufuna ukuba isiphequluli sikhumbule lephasiwedi?"</string>
<string name="save_password_notnow" msgid="6389675316706699758">"Hha yi manje"</string>
<string name="save_password_remember" msgid="6491879678996749466">"Khumbula"</string>
@@ -973,6 +977,11 @@
<skip />
<string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Ayikwazanga ukuxhuma kwi-Wi-Fi"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" inoxhumano oluphansi lwe-inthanethi."</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"I-WiFi Eqondile"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Qala ukusebenza kwe-WiFi Okuqondile. Lokhu kuzocima ikhasimende le-WiFi/Ukusebenza okwe-hotspot"</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Yehlulekile ukuqala i-Wi-Fi Ngqo"</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"I-Wi-Fi Direct ivulekile"</string>
+ <string name="wifi_p2p_enabled_notification_message" msgid="1638949953993894335">"Thinta ukuze uthole izilungiselelo"</string>
<string name="accept" msgid="1645267259272829559">"Yamukela"</string>
<string name="decline" msgid="2112225451706137894">"Nqaba"</string>
<string name="wifi_p2p_invitation_sent_title" msgid="1318975185112070734">"Isimemo sithunyelwe"</string>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 16b7ff3..c152b73 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -1556,6 +1556,24 @@
an absolute dimension or a fraction of the screen size in that
dimension. -->
<attr name="windowMinWidthMinor" format="dimension|fraction" />
+
+ <!-- A fixed width for the window along the major axis of the screen,
+ that is, when in landscape. Can be either an absolute dimension
+ or a fraction of the screen size in that dimension. -->
+ <attr name="windowFixedWidthMajor" format="dimension|fraction" />
+ <!-- A fixed height for the window along the minor axis of the screen,
+ that is, when in landscape. Can be either an absolute dimension
+ or a fraction of the screen size in that dimension. -->
+ <attr name="windowFixedHeightMinor" format="dimension|fraction" />
+
+ <!-- A fixed width for the window along the minor axis of the screen,
+ that is, when in portrait. Can be either an absolute dimension
+ or a fraction of the screen size in that dimension. -->
+ <attr name="windowFixedWidthMinor" format="dimension|fraction" />
+ <!-- A fixed height for the window along the major axis of the screen,
+ that is, when in portrait. Can be either an absolute dimension
+ or a fraction of the screen size in that dimension. -->
+ <attr name="windowFixedHeightMajor" format="dimension|fraction" />
</declare-styleable>
<!-- The set of attributes that describe a AlertDialog's theme. -->
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 82ef68a..6d6b86b 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -108,6 +108,20 @@
is along the major axis (that is the screen is landscape). This may
be either a fraction or a dimension. -->
<item type="dimen" name="dialog_min_width_major">65%</item>
+
+ <!-- The platform's desired fixed width for a dialog along the major axis
+ (the screen is in landscape). This may be either a fraction or a dimension.-->
+ <item type="dimen" name="dialog_fixed_width_major">320dp</item>
+ <!-- The platform's desired fixed width for a dialog along the minor axis
+ (the screen is in portrait). This may be either a fraction or a dimension.-->
+ <item type="dimen" name="dialog_fixed_width_minor">320dp</item>
+ <!-- The platform's desired fixed height for a dialog along the major axis
+ (the screen is in portrait). This may be either a fraction or a dimension.-->
+ <item type="dimen" name="dialog_fixed_height_major">80%</item>
+ <!-- The platform's desired fixed height for a dialog along the minor axis
+ (the screen is in landscape). This may be either a fraction or a dimension.-->
+ <item type="dimen" name="dialog_fixed_height_minor">100%</item>
+
<!-- Preference activity, vertical padding for the header list -->
<dimen name="preference_screen_header_vertical_padding">0dp</dimen>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index f347a4e..2a6cef3 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -212,6 +212,10 @@
<java-symbol type="attr" name="textAppearanceMisspelledSuggestion" />
<java-symbol type="attr" name="textColorSearchUrl" />
<java-symbol type="attr" name="timePickerStyle" />
+ <java-symbol type="attr" name="windowFixedWidthMajor" />
+ <java-symbol type="attr" name="windowFixedWidthMinor" />
+ <java-symbol type="attr" name="windowFixedHeightMajor" />
+ <java-symbol type="attr" name="windowFixedHeightMinor" />
<java-symbol type="bool" name="action_bar_embed_tabs" />
<java-symbol type="bool" name="action_bar_expanded_action_views_exclusive" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 7111d00..3c1f50d 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -2248,6 +2248,14 @@
<!-- Description of an application permission which allows the application access serial ports via the SerialManager. [CHAR LIMIT=NONE] -->
<string name="permdesc_serialPort">Allows the holder to access serial ports using the SerialManager API.</string>
+ <!-- Title of an application permission which allows the holder to access content
+ providers from outside an ApplicationThread. [CHAR LIMIT=40] -->
+ <string name="permlab_accessContentProvidersExternally">access content providers externally</string>
+ <!-- Description of an application permission which allows the holder to access
+ content providers from outside an ApplicationThread. [CHAR LIMIT=NONE] -->
+ <string name="permdesc_accessContentProvidersExternally">Allows the holder to access content
+ providers from the shell. Should never be needed for normal apps.</string>
+
<!-- If the user enters a password in a form on a website, a dialog will come up asking if they want to save the password. Text in the save password dialog, asking if the browser should remember a password. -->
<string name="save_password_message">Do you want the browser to remember this password?</string>
<!-- If the user enters a password in a form on a website, a dialog will come up asking if they want to save the password. Button in the save password dialog, saying not to remember this password. -->
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index 7046fc5..55438b2 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -1580,6 +1580,22 @@
<item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item>
</style>
+ <!-- Variant of Theme.Holo.Dialog that has a fixed size. -->
+ <style name="Theme.Holo.Dialog.FixedSize">
+ <item name="windowFixedWidthMajor">@android:dimen/dialog_fixed_width_major</item>
+ <item name="windowFixedWidthMinor">@android:dimen/dialog_fixed_width_minor</item>
+ <item name="windowFixedHeightMajor">@android:dimen/dialog_fixed_height_major</item>
+ <item name="windowFixedHeightMinor">@android:dimen/dialog_fixed_height_minor</item>
+ </style>
+
+ <!-- Variant of Theme.Holo.Dialog.NoActionBar that has a fixed size. -->
+ <style name="Theme.Holo.Dialog.NoActionBar.FixedSize">
+ <item name="windowFixedWidthMajor">@android:dimen/dialog_fixed_width_major</item>
+ <item name="windowFixedWidthMinor">@android:dimen/dialog_fixed_width_minor</item>
+ <item name="windowFixedHeightMajor">@android:dimen/dialog_fixed_height_major</item>
+ <item name="windowFixedHeightMinor">@android:dimen/dialog_fixed_height_minor</item>
+ </style>
+
<!-- Variant of Theme.Holo.Dialog that does not include a frame (or background).
The view hierarchy of the dialog is responsible for drawing all of
its pixels. -->
@@ -1672,6 +1688,22 @@
<item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item>
</style>
+ <!-- Variant of Theme.Holo.Light.Dialog that has a fixed size. -->
+ <style name="Theme.Holo.Light.Dialog.FixedSize">
+ <item name="windowFixedWidthMajor">@android:dimen/dialog_fixed_width_major</item>
+ <item name="windowFixedWidthMinor">@android:dimen/dialog_fixed_width_minor</item>
+ <item name="windowFixedHeightMajor">@android:dimen/dialog_fixed_height_major</item>
+ <item name="windowFixedHeightMinor">@android:dimen/dialog_fixed_height_minor</item>
+ </style>
+
+ <!-- Variant of Theme.Holo.Light.Dialog.NoActionBar that has a fixed size. -->
+ <style name="Theme.Holo.Light.Dialog.NoActionBar.FixedSize">
+ <item name="windowFixedWidthMajor">@android:dimen/dialog_fixed_width_major</item>
+ <item name="windowFixedWidthMinor">@android:dimen/dialog_fixed_width_minor</item>
+ <item name="windowFixedHeightMajor">@android:dimen/dialog_fixed_height_major</item>
+ <item name="windowFixedHeightMinor">@android:dimen/dialog_fixed_height_minor</item>
+ </style>
+
<!-- Theme for a window that will be displayed either full-screen on
smaller screens (small, normal) or as a dialog on larger screens
(large, xlarge). -->
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index abe4aad..7fd981c 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -379,6 +379,23 @@
<style name="Theme.DeviceDefault.Dialog.NoActionBar.MinWidth" parent="Theme.Holo.Dialog.NoActionBar.MinWidth" >
</style>
+
+ <!-- Variant of Theme.DeviceDefault.Dialog that has a fixed size. -->
+ <style name="Theme.DeviceDefault.Dialog.FixedSize">
+ <item name="windowFixedWidthMajor">@android:dimen/dialog_fixed_width_major</item>
+ <item name="windowFixedWidthMinor">@android:dimen/dialog_fixed_width_minor</item>
+ <item name="windowFixedHeightMajor">@android:dimen/dialog_fixed_height_major</item>
+ <item name="windowFixedHeightMinor">@android:dimen/dialog_fixed_height_minor</item>
+ </style>
+
+ <!-- Variant of Theme.DeviceDefault.Dialog.NoActionBar that has a fixed size. -->
+ <style name="Theme.DeviceDefault.Dialog.NoActionBar.FixedSize">
+ <item name="windowFixedWidthMajor">@android:dimen/dialog_fixed_width_major</item>
+ <item name="windowFixedWidthMinor">@android:dimen/dialog_fixed_width_minor</item>
+ <item name="windowFixedHeightMajor">@android:dimen/dialog_fixed_height_major</item>
+ <item name="windowFixedHeightMinor">@android:dimen/dialog_fixed_height_minor</item>
+ </style>
+
<!-- DeviceDefault light theme for dialog windows and activities. This changes the window to be
floating (not fill the entire screen), and puts a frame around its contents. You can set this
theme on an activity if you would like to make an activity that looks like a Dialog.-->
@@ -406,6 +423,23 @@
<style name="Theme.DeviceDefault.Light.Dialog.NoActionBar.MinWidth" parent="Theme.Holo.Light.Dialog.NoActionBar.MinWidth" >
</style>
+
+ <!-- Variant of Theme.DeviceDefault.Dialog that has a fixed size. -->
+ <style name="Theme.DeviceDefault.Light.Dialog.FixedSize">
+ <item name="windowFixedWidthMajor">@android:dimen/dialog_fixed_width_major</item>
+ <item name="windowFixedWidthMinor">@android:dimen/dialog_fixed_width_minor</item>
+ <item name="windowFixedHeightMajor">@android:dimen/dialog_fixed_height_major</item>
+ <item name="windowFixedHeightMinor">@android:dimen/dialog_fixed_height_minor</item>
+ </style>
+
+ <!-- Variant of Theme.DeviceDefault.Dialog.NoActionBar that has a fixed size. -->
+ <style name="Theme.DeviceDefault.Light.Dialog.NoActionBar.FixedSize">
+ <item name="windowFixedWidthMajor">@android:dimen/dialog_fixed_width_major</item>
+ <item name="windowFixedWidthMinor">@android:dimen/dialog_fixed_width_minor</item>
+ <item name="windowFixedHeightMajor">@android:dimen/dialog_fixed_height_major</item>
+ <item name="windowFixedHeightMinor">@android:dimen/dialog_fixed_height_minor</item>
+ </style>
+
<!-- DeviceDefault theme for a window that will be displayed either full-screen on smaller
screens (small, normal) or as a dialog on larger screens (large, xlarge). -->
<style name="Theme.DeviceDefault.DialogWhenLarge" parent="Theme.Holo.DialogWhenLarge" >
diff --git a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestRunner.java b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestRunner.java
index 9819c54..9c1922f 100644
--- a/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestRunner.java
+++ b/core/tests/ConnectivityManagerTest/src/com/android/connectivitymanagertest/ConnectivityManagerTestRunner.java
@@ -46,8 +46,7 @@
// create a new test suite
suite.setName("ConnectivityManagerWifiOnlyFunctionalTests");
String[] methodNames = {"testConnectToWifi", "testConnectToWifWithKnownAP",
- "testDisconnectWifi", "testDataConnectionOverAMWithWifi",
- "testDataConnectionWithWifiToAMToWifi", "testWifiStateChange"};
+ "testDisconnectWifi", "testWifiStateChange"};
Class<ConnectivityManagerMobileTest> testClass = ConnectivityManagerMobileTest.class;
for (String method: methodNames) {
suite.addTest(TestSuite.createTest(testClass, method));
diff --git a/core/tests/coretests/src/android/accessibilityservice/InterrogationActivityTest.java b/core/tests/coretests/src/android/accessibilityservice/InterrogationActivityTest.java
index 2fb4237..3dc140b 100644
--- a/core/tests/coretests/src/android/accessibilityservice/InterrogationActivityTest.java
+++ b/core/tests/coretests/src/android/accessibilityservice/InterrogationActivityTest.java
@@ -50,6 +50,12 @@
// Timeout for the accessibility state of an Activity to be fully initialized.
private static final int TIMEOUT_PROPAGATE_ACCESSIBILITY_EVENT_MILLIS = 5000;
+ // Timeout for which non getting accessibility events considers the app idle.
+ private static final long IDLE_EVENT_TIME_DELTA_MILLIS = 200;
+
+ // Timeout in which to wait for idle device.
+ private static final long GLOBAL_IDLE_DETECTION_TIMEOUT_MILLIS = 1000;
+
// Handle to a connection to the AccessibilityManagerService
private UiTestAutomationBridge mUiTestAutomationBridge;
@@ -62,6 +68,8 @@
super.setUp();
mUiTestAutomationBridge = new UiTestAutomationBridge();
mUiTestAutomationBridge.connect();
+ mUiTestAutomationBridge.waitForIdle(IDLE_EVENT_TIME_DELTA_MILLIS,
+ GLOBAL_IDLE_DETECTION_TIMEOUT_MILLIS);
mUiTestAutomationBridge.executeCommandAndWaitForAccessibilityEvent(new Runnable() {
// wait for the first accessibility event
@Override
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index 6cd07a3..8be1db2 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -158,6 +158,7 @@
<assign-permission name="android.permission.BACKUP" uid="shell" />
<assign-permission name="android.permission.FORCE_STOP_PACKAGES" uid="shell" />
<assign-permission name="android.permission.STOP_APP_SWITCHES" uid="shell" />
+ <assign-permission name="android.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY" uid="shell" />
<assign-permission name="android.permission.MODIFY_AUDIO_SETTINGS" uid="media" />
<assign-permission name="android.permission.ACCESS_DRM" uid="media" />
diff --git a/data/fonts/DroidNaskh-Bold.ttf b/data/fonts/DroidNaskh-Bold.ttf
index 6b7d4f0..692b796 100644
--- a/data/fonts/DroidNaskh-Bold.ttf
+++ b/data/fonts/DroidNaskh-Bold.ttf
Binary files differ
diff --git a/data/fonts/DroidNaskh-Regular.ttf b/data/fonts/DroidNaskh-Regular.ttf
index d11e1ae..da9a45f 100644
--- a/data/fonts/DroidNaskh-Regular.ttf
+++ b/data/fonts/DroidNaskh-Regular.ttf
Binary files differ
diff --git a/data/fonts/DroidSansFallback.ttf b/data/fonts/DroidSansFallback.ttf
index 2379b2d..cfbc66a 100644
--- a/data/fonts/DroidSansFallback.ttf
+++ b/data/fonts/DroidSansFallback.ttf
Binary files differ
diff --git a/data/fonts/DroidSansFallbackFull.ttf b/data/fonts/DroidSansFallbackFull.ttf
index 41b015d..0cacabe 100644
--- a/data/fonts/DroidSansFallbackFull.ttf
+++ b/data/fonts/DroidSansFallbackFull.ttf
Binary files differ
diff --git a/drm/java/android/drm/DrmInfo.java b/drm/java/android/drm/DrmInfo.java
index 8812bfe..22d06c7 100755
--- a/drm/java/android/drm/DrmInfo.java
+++ b/drm/java/android/drm/DrmInfo.java
@@ -49,6 +49,13 @@
mInfoType = infoType;
mMimeType = mimeType;
mData = data;
+ if (!isValid()) {
+ final String msg = "infoType: " + infoType + "," +
+ "mimeType: " + mimeType + "," +
+ "data: " + data;
+
+ throw new IllegalArgumentException(msg);
+ }
}
/**
@@ -69,6 +76,13 @@
// call would fail with IllegalArgumentException because of mData = null
mData = null;
}
+ if (!isValid()) {
+ final String msg = "infoType: " + infoType + "," +
+ "mimeType: " + mimeType + "," +
+ "data: " + mData;
+
+ throw new IllegalArgumentException();
+ }
}
/**
diff --git a/drm/java/android/drm/DrmInfoRequest.java b/drm/java/android/drm/DrmInfoRequest.java
index 1429fa5..621da41 100755
--- a/drm/java/android/drm/DrmInfoRequest.java
+++ b/drm/java/android/drm/DrmInfoRequest.java
@@ -67,6 +67,11 @@
public DrmInfoRequest(int infoType, String mimeType) {
mInfoType = infoType;
mMimeType = mimeType;
+ if (!isValid()) {
+ final String msg = "infoType: " + infoType + "," +
+ "mimeType: " + mimeType;
+ throw new IllegalArgumentException(msg);
+ }
}
/**
diff --git a/drm/java/android/drm/DrmInfoStatus.java b/drm/java/android/drm/DrmInfoStatus.java
index 5c12ae3..2fe0a78 100755
--- a/drm/java/android/drm/DrmInfoStatus.java
+++ b/drm/java/android/drm/DrmInfoStatus.java
@@ -56,6 +56,10 @@
* @param _mimeType The MIME type.
*/
public DrmInfoStatus(int _statusCode, int _infoType, ProcessedData _data, String _mimeType) {
+ if (!DrmInfoRequest.isValidType(_infoType)) {
+ throw new IllegalArgumentException("infoType: " + _infoType);
+ }
+
statusCode = _statusCode;
infoType = _infoType;
data = _data;
diff --git a/drm/java/android/drm/DrmRights.java b/drm/java/android/drm/DrmRights.java
index ef9c21d..d4afed1 100755
--- a/drm/java/android/drm/DrmRights.java
+++ b/drm/java/android/drm/DrmRights.java
@@ -103,6 +103,11 @@
}
mMimeType = mimeType;
+ if (!isValid()) {
+ final String msg = "mimeType: " + mMimeType + "," +
+ "data: " + mData;
+ throw new IllegalArgumentException(msg);
+ }
}
/**
@@ -117,17 +122,25 @@
mData = data.getData();
String accountId = data.getAccountId();
- if (null != accountId && !accountId.equals("")) {
- mAccountId = accountId;
+ if (null == accountId || !accountId.equals("")) {
+ throw new IllegalArgumentException("accountId: " + accountId);
}
+ mAccountId = accountId;
String subscriptionId = data.getSubscriptionId();
- if (null != subscriptionId && !subscriptionId.equals("")) {
- mSubscriptionId = subscriptionId;
+ if (null == subscriptionId || !subscriptionId.equals("")) {
+ throw new IllegalArgumentException(
+ "subscriptionId: " + subscriptionId);
}
+ mSubscriptionId = subscriptionId;
}
mMimeType = mimeType;
+ if (!isValid()) {
+ final String msg = "mimeType: " + mMimeType + "," +
+ "data: " + mData;
+ throw new IllegalArgumentException(msg);
+ }
}
/**
diff --git a/graphics/jni/Android.mk b/graphics/jni/Android.mk
index 652189f..ca69e1e 100644
--- a/graphics/jni/Android.mk
+++ b/graphics/jni/Android.mk
@@ -6,6 +6,7 @@
LOCAL_SHARED_LIBRARIES := \
libandroid_runtime \
+ libandroidfw \
libnativehelper \
libRS \
libcutils \
diff --git a/graphics/jni/android_renderscript_RenderScript.cpp b/graphics/jni/android_renderscript_RenderScript.cpp
index 2d8c416..27ea8f6 100644
--- a/graphics/jni/android_renderscript_RenderScript.cpp
+++ b/graphics/jni/android_renderscript_RenderScript.cpp
@@ -31,9 +31,9 @@
#include <core/SkTemplates.h>
#include <images/SkImageDecoder.h>
-#include <utils/Asset.h>
-#include <utils/AssetManager.h>
-#include <utils/ResourceTypes.h>
+#include <androidfw/Asset.h>
+#include <androidfw/AssetManager.h>
+#include <androidfw/ResourceTypes.h>
#include "jni.h"
#include "JNIHelp.h"
@@ -41,8 +41,8 @@
#include "android_runtime/android_view_Surface.h"
#include "android_runtime/android_util_AssetManager.h"
-#include <RenderScript.h>
-#include <RenderScriptEnv.h>
+#include <rs.h>
+#include <rsEnv.h>
#include <gui/SurfaceTexture.h>
#include <gui/SurfaceTextureClient.h>
#include <android_runtime/android_graphics_SurfaceTexture.h>
diff --git a/include/android_runtime/android_app_NativeActivity.h b/include/android_runtime/android_app_NativeActivity.h
index 93fcf69..a59677a 100644
--- a/include/android_runtime/android_app_NativeActivity.h
+++ b/include/android_runtime/android_app_NativeActivity.h
@@ -17,7 +17,7 @@
#ifndef _ANDROID_APP_NATIVEACTIVITY_H
#define _ANDROID_APP_NATIVEACTIVITY_H
-#include <ui/InputTransport.h>
+#include <androidfw/InputTransport.h>
#include <utils/Looper.h>
#include <android/native_activity.h>
diff --git a/include/android_runtime/android_content_res_Configuration.h b/include/android_runtime/android_content_res_Configuration.h
index 2f5a982..34c4439 100644
--- a/include/android_runtime/android_content_res_Configuration.h
+++ b/include/android_runtime/android_content_res_Configuration.h
@@ -17,7 +17,7 @@
#ifndef _ANDROID_CONTENT_RES_CONFIGURATION_H
#define _ANDROID_CONTENT_RES_CONFIGURATION_H
-#include <utils/ResourceTypes.h>
+#include <androidfw/ResourceTypes.h>
#include <android/configuration.h>
#include "jni.h"
diff --git a/include/android_runtime/android_util_AssetManager.h b/include/android_runtime/android_util_AssetManager.h
index b6dd9c9..8dd9337 100644
--- a/include/android_runtime/android_util_AssetManager.h
+++ b/include/android_runtime/android_util_AssetManager.h
@@ -17,7 +17,7 @@
#ifndef android_util_AssetManager_H
#define android_util_AssetManager_H
-#include <utils/AssetManager.h>
+#include <androidfw/AssetManager.h>
#include "jni.h"
diff --git a/include/utils/Asset.h b/include/androidfw/Asset.h
similarity index 100%
rename from include/utils/Asset.h
rename to include/androidfw/Asset.h
diff --git a/include/utils/AssetDir.h b/include/androidfw/AssetDir.h
similarity index 100%
rename from include/utils/AssetDir.h
rename to include/androidfw/AssetDir.h
diff --git a/include/utils/AssetManager.h b/include/androidfw/AssetManager.h
similarity index 98%
rename from include/utils/AssetManager.h
rename to include/androidfw/AssetManager.h
index a8c7ddb..d95b45e 100644
--- a/include/utils/AssetManager.h
+++ b/include/androidfw/AssetManager.h
@@ -20,14 +20,15 @@
#ifndef __LIBS_ASSETMANAGER_H
#define __LIBS_ASSETMANAGER_H
-#include <utils/Asset.h>
-#include <utils/AssetDir.h>
+#include <androidfw/Asset.h>
+#include <androidfw/AssetDir.h>
+#include <androidfw/ZipFileRO.h>
#include <utils/KeyedVector.h>
-#include <utils/String8.h>
-#include <utils/Vector.h>
+#include <utils/SortedVector.h>
#include <utils/String16.h>
-#include <utils/ZipFileRO.h>
+#include <utils/String8.h>
#include <utils/threads.h>
+#include <utils/Vector.h>
/*
* Native-app access is via the opaque typedef struct AAssetManager in the C namespace.
diff --git a/include/utils/BackupHelpers.h b/include/androidfw/BackupHelpers.h
similarity index 100%
rename from include/utils/BackupHelpers.h
rename to include/androidfw/BackupHelpers.h
diff --git a/include/ui/Input.h b/include/androidfw/Input.h
similarity index 99%
rename from include/ui/Input.h
rename to include/androidfw/Input.h
index c2cbe1d..f5db6e24 100644
--- a/include/ui/Input.h
+++ b/include/androidfw/Input.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef _UI_INPUT_H
-#define _UI_INPUT_H
+#ifndef _ANDROIDFW_INPUT_H
+#define _ANDROIDFW_INPUT_H
/**
* Native input event structures.
@@ -894,4 +894,4 @@
} // namespace android
-#endif // _UI_INPUT_H
+#endif // _ANDROIDFW_INPUT_H
diff --git a/include/ui/InputTransport.h b/include/androidfw/InputTransport.h
similarity index 98%
rename from include/ui/InputTransport.h
rename to include/androidfw/InputTransport.h
index 0facce3..a846e65 100644
--- a/include/ui/InputTransport.h
+++ b/include/androidfw/InputTransport.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef _UI_INPUT_TRANSPORT_H
-#define _UI_INPUT_TRANSPORT_H
+#ifndef _ANDROIDFW_INPUT_TRANSPORT_H
+#define _ANDROIDFW_INPUT_TRANSPORT_H
/**
* Native input transport.
@@ -27,11 +27,12 @@
* The InputConsumer is used by the application to receive events from the input dispatcher.
*/
-#include <ui/Input.h>
+#include <androidfw/Input.h>
#include <utils/Errors.h>
#include <utils/Timers.h>
#include <utils/RefBase.h>
#include <utils/String8.h>
+#include <utils/Vector.h>
namespace android {
@@ -332,4 +333,4 @@
} // namespace android
-#endif // _UI_INPUT_TRANSPORT_H
+#endif // _ANDROIDFW_INPUT_TRANSPORT_H
diff --git a/include/ui/KeyCharacterMap.h b/include/androidfw/KeyCharacterMap.h
similarity index 97%
rename from include/ui/KeyCharacterMap.h
rename to include/androidfw/KeyCharacterMap.h
index be14432..679dd2c 100644
--- a/include/ui/KeyCharacterMap.h
+++ b/include/androidfw/KeyCharacterMap.h
@@ -14,12 +14,12 @@
* limitations under the License.
*/
-#ifndef _UI_KEY_CHARACTER_MAP_H
-#define _UI_KEY_CHARACTER_MAP_H
+#ifndef _ANDROIDFW_KEY_CHARACTER_MAP_H
+#define _ANDROIDFW_KEY_CHARACTER_MAP_H
#include <stdint.h>
-#include <ui/Input.h>
+#include <androidfw/Input.h>
#include <utils/Errors.h>
#include <utils/KeyedVector.h>
#include <utils/Tokenizer.h>
@@ -196,4 +196,4 @@
} // namespace android
-#endif // _UI_KEY_CHARACTER_MAP_H
+#endif // _ANDROIDFW_KEY_CHARACTER_MAP_H
diff --git a/include/ui/KeyLayoutMap.h b/include/androidfw/KeyLayoutMap.h
similarity index 95%
rename from include/ui/KeyLayoutMap.h
rename to include/androidfw/KeyLayoutMap.h
index d82d0c8..5a6f550 100644
--- a/include/ui/KeyLayoutMap.h
+++ b/include/androidfw/KeyLayoutMap.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef _UI_KEY_LAYOUT_MAP_H
-#define _UI_KEY_LAYOUT_MAP_H
+#ifndef _ANDROIDFW_KEY_LAYOUT_MAP_H
+#define _ANDROIDFW_KEY_LAYOUT_MAP_H
#include <stdint.h>
#include <utils/Errors.h>
@@ -96,4 +96,4 @@
} // namespace android
-#endif // _UI_KEY_LAYOUT_MAP_H
+#endif // _ANDROIDFW_KEY_LAYOUT_MAP_H
diff --git a/include/ui/Keyboard.h b/include/androidfw/Keyboard.h
similarity index 96%
rename from include/ui/Keyboard.h
rename to include/androidfw/Keyboard.h
index 274f526..ae65198 100644
--- a/include/ui/Keyboard.h
+++ b/include/androidfw/Keyboard.h
@@ -14,10 +14,10 @@
* limitations under the License.
*/
-#ifndef _UI_KEYBOARD_H
-#define _UI_KEYBOARD_H
+#ifndef _ANDROIDFW_KEYBOARD_H
+#define _ANDROIDFW_KEYBOARD_H
-#include <ui/Input.h>
+#include <androidfw/Input.h>
#include <utils/Errors.h>
#include <utils/String8.h>
#include <utils/PropertyMap.h>
@@ -116,4 +116,4 @@
} // namespace android
-#endif // _UI_KEYBOARD_H
+#endif // _ANDROIDFW_KEYBOARD_H
diff --git a/include/ui/KeycodeLabels.h b/include/androidfw/KeycodeLabels.h
similarity index 98%
rename from include/ui/KeycodeLabels.h
rename to include/androidfw/KeycodeLabels.h
index c5bd0c5..9e4dfcb 100755
--- a/include/ui/KeycodeLabels.h
+++ b/include/androidfw/KeycodeLabels.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef _UI_KEYCODE_LABELS_H
-#define _UI_KEYCODE_LABELS_H
+#ifndef _ANDROIDFW_KEYCODE_LABELS_H
+#define _ANDROIDFW_KEYCODE_LABELS_H
#include <android/keycodes.h>
@@ -307,4 +307,4 @@
{ NULL, -1 }
};
-#endif // _UI_KEYCODE_LABELS_H
+#endif // _ANDROIDFW_KEYCODE_LABELS_H
diff --git a/include/utils/ObbFile.h b/include/androidfw/ObbFile.h
similarity index 100%
rename from include/utils/ObbFile.h
rename to include/androidfw/ObbFile.h
diff --git a/include/ui/PowerManager.h b/include/androidfw/PowerManager.h
similarity index 88%
rename from include/ui/PowerManager.h
rename to include/androidfw/PowerManager.h
index dd80318..59e993a 100644
--- a/include/ui/PowerManager.h
+++ b/include/androidfw/PowerManager.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef _UI_POWER_MANAGER_H
-#define _UI_POWER_MANAGER_H
+#ifndef _ANDROIDFW_POWER_MANAGER_H
+#define _ANDROIDFW_POWER_MANAGER_H
namespace android {
@@ -30,4 +30,4 @@
} // namespace android
-#endif // _UI_POWER_MANAGER_H
+#endif // _ANDROIDFW_POWER_MANAGER_H
diff --git a/include/utils/ResourceTypes.h b/include/androidfw/ResourceTypes.h
similarity index 99%
rename from include/utils/ResourceTypes.h
rename to include/androidfw/ResourceTypes.h
index c496da6..23bca3e 100644
--- a/include/utils/ResourceTypes.h
+++ b/include/androidfw/ResourceTypes.h
@@ -20,7 +20,7 @@
#ifndef _LIBS_UTILS_RESOURCE_TYPES_H
#define _LIBS_UTILS_RESOURCE_TYPES_H
-#include <utils/Asset.h>
+#include <androidfw/Asset.h>
#include <utils/ByteOrder.h>
#include <utils/Errors.h>
#include <utils/String16.h>
diff --git a/include/utils/StreamingZipInflater.h b/include/androidfw/StreamingZipInflater.h
similarity index 100%
rename from include/utils/StreamingZipInflater.h
rename to include/androidfw/StreamingZipInflater.h
diff --git a/include/ui/VirtualKeyMap.h b/include/androidfw/VirtualKeyMap.h
similarity index 92%
rename from include/ui/VirtualKeyMap.h
rename to include/androidfw/VirtualKeyMap.h
index 7813d9d..66340e3 100644
--- a/include/ui/VirtualKeyMap.h
+++ b/include/androidfw/VirtualKeyMap.h
@@ -14,12 +14,12 @@
* limitations under the License.
*/
-#ifndef _UI_VIRTUAL_KEY_MAP_H
-#define _UI_VIRTUAL_KEY_MAP_H
+#ifndef _ANDROIDFW_VIRTUAL_KEY_MAP_H
+#define _ANDROIDFW_VIRTUAL_KEY_MAP_H
#include <stdint.h>
-#include <ui/Input.h>
+#include <androidfw/Input.h>
#include <utils/Errors.h>
#include <utils/KeyedVector.h>
#include <utils/Tokenizer.h>
@@ -76,4 +76,4 @@
} // namespace android
-#endif // _UI_KEY_CHARACTER_MAP_H
+#endif // _ANDROIDFW_KEY_CHARACTER_MAP_H
diff --git a/include/utils/ZipFileCRO.h b/include/androidfw/ZipFileCRO.h
similarity index 100%
rename from include/utils/ZipFileCRO.h
rename to include/androidfw/ZipFileCRO.h
diff --git a/include/utils/ZipFileRO.h b/include/androidfw/ZipFileRO.h
similarity index 100%
rename from include/utils/ZipFileRO.h
rename to include/androidfw/ZipFileRO.h
diff --git a/include/utils/ZipUtils.h b/include/androidfw/ZipUtils.h
similarity index 100%
rename from include/utils/ZipUtils.h
rename to include/androidfw/ZipUtils.h
diff --git a/include/common_time/ICommonClock.h b/include/common_time/ICommonClock.h
new file mode 100644
index 0000000..d7073f1
--- /dev/null
+++ b/include/common_time/ICommonClock.h
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#ifndef ANDROID_ICOMMONCLOCK_H
+#define ANDROID_ICOMMONCLOCK_H
+
+#include <stdint.h>
+#include <linux/socket.h>
+
+#include <binder/IInterface.h>
+#include <binder/IServiceManager.h>
+
+namespace android {
+
+class ICommonClockListener : public IInterface {
+ public:
+ DECLARE_META_INTERFACE(CommonClockListener);
+
+ virtual void onTimelineChanged(uint64_t timelineID) = 0;
+};
+
+class BnCommonClockListener : public BnInterface<ICommonClockListener> {
+ public:
+ virtual status_t onTransact(uint32_t code, const Parcel& data,
+ Parcel* reply, uint32_t flags = 0);
+};
+
+class ICommonClock : public IInterface {
+ public:
+ DECLARE_META_INTERFACE(CommonClock);
+
+ // Name of the ICommonClock service registered with the service manager.
+ static const String16 kServiceName;
+
+ // a reserved invalid timeline ID
+ static const uint64_t kInvalidTimelineID;
+
+ // a reserved invalid error estimate
+ static const int32_t kErrorEstimateUnknown;
+
+ enum State {
+ // the device just came up and is trying to discover the master
+ STATE_INITIAL,
+
+ // the device is a client of a master
+ STATE_CLIENT,
+
+ // the device is acting as master
+ STATE_MASTER,
+
+ // the device has lost contact with its master and needs to participate
+ // in the election of a new master
+ STATE_RONIN,
+
+ // the device is waiting for announcement of the newly elected master
+ STATE_WAIT_FOR_ELECTION,
+ };
+
+ virtual status_t isCommonTimeValid(bool* valid, uint32_t* timelineID) = 0;
+ virtual status_t commonTimeToLocalTime(int64_t commonTime,
+ int64_t* localTime) = 0;
+ virtual status_t localTimeToCommonTime(int64_t localTime,
+ int64_t* commonTime) = 0;
+ virtual status_t getCommonTime(int64_t* commonTime) = 0;
+ virtual status_t getCommonFreq(uint64_t* freq) = 0;
+ virtual status_t getLocalTime(int64_t* localTime) = 0;
+ virtual status_t getLocalFreq(uint64_t* freq) = 0;
+ virtual status_t getEstimatedError(int32_t* estimate) = 0;
+ virtual status_t getTimelineID(uint64_t* id) = 0;
+ virtual status_t getState(State* state) = 0;
+ virtual status_t getMasterAddr(struct sockaddr_storage* addr) = 0;
+
+ virtual status_t registerListener(
+ const sp<ICommonClockListener>& listener) = 0;
+ virtual status_t unregisterListener(
+ const sp<ICommonClockListener>& listener) = 0;
+
+ // Simple helper to make it easier to connect to the CommonClock service.
+ static inline sp<ICommonClock> getInstance() {
+ sp<IBinder> binder = defaultServiceManager()->checkService(
+ ICommonClock::kServiceName);
+ sp<ICommonClock> clk = interface_cast<ICommonClock>(binder);
+ return clk;
+ }
+};
+
+class BnCommonClock : public BnInterface<ICommonClock> {
+ public:
+ virtual status_t onTransact(uint32_t code, const Parcel& data,
+ Parcel* reply, uint32_t flags = 0);
+};
+
+}; // namespace android
+
+#endif // ANDROID_ICOMMONCLOCK_H
diff --git a/include/common_time/ICommonTimeConfig.h b/include/common_time/ICommonTimeConfig.h
new file mode 100644
index 0000000..497b666
--- /dev/null
+++ b/include/common_time/ICommonTimeConfig.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#ifndef ANDROID_ICOMMONTIMECONFIG_H
+#define ANDROID_ICOMMONTIMECONFIG_H
+
+#include <stdint.h>
+#include <linux/socket.h>
+
+#include <binder/IInterface.h>
+#include <binder/IServiceManager.h>
+
+namespace android {
+
+class String16;
+
+class ICommonTimeConfig : public IInterface {
+ public:
+ DECLARE_META_INTERFACE(CommonTimeConfig);
+
+ // Name of the ICommonTimeConfig service registered with the service
+ // manager.
+ static const String16 kServiceName;
+
+ virtual status_t getMasterElectionPriority(uint8_t *priority) = 0;
+ virtual status_t setMasterElectionPriority(uint8_t priority) = 0;
+ virtual status_t getMasterElectionEndpoint(struct sockaddr_storage *addr) = 0;
+ virtual status_t setMasterElectionEndpoint(const struct sockaddr_storage *addr) = 0;
+ virtual status_t getMasterElectionGroupId(uint64_t *id) = 0;
+ virtual status_t setMasterElectionGroupId(uint64_t id) = 0;
+ virtual status_t getInterfaceBinding(String16& ifaceName) = 0;
+ virtual status_t setInterfaceBinding(const String16& ifaceName) = 0;
+ virtual status_t getMasterAnnounceInterval(int *interval) = 0;
+ virtual status_t setMasterAnnounceInterval(int interval) = 0;
+ virtual status_t getClientSyncInterval(int *interval) = 0;
+ virtual status_t setClientSyncInterval(int interval) = 0;
+ virtual status_t getPanicThreshold(int *threshold) = 0;
+ virtual status_t setPanicThreshold(int threshold) = 0;
+ virtual status_t getAutoDisable(bool *autoDisable) = 0;
+ virtual status_t setAutoDisable(bool autoDisable) = 0;
+ virtual status_t forceNetworklessMasterMode() = 0;
+
+ // Simple helper to make it easier to connect to the CommonTimeConfig service.
+ static inline sp<ICommonTimeConfig> getInstance() {
+ sp<IBinder> binder = defaultServiceManager()->checkService(
+ ICommonTimeConfig::kServiceName);
+ sp<ICommonTimeConfig> clk = interface_cast<ICommonTimeConfig>(binder);
+ return clk;
+ }
+};
+
+class BnCommonTimeConfig : public BnInterface<ICommonTimeConfig> {
+ public:
+ virtual status_t onTransact(uint32_t code, const Parcel& data,
+ Parcel* reply, uint32_t flags = 0);
+};
+
+}; // namespace android
+
+#endif // ANDROID_ICOMMONTIMECONFIG_H
diff --git a/include/common_time/cc_helper.h b/include/common_time/cc_helper.h
new file mode 100644
index 0000000..8c4d5c0
--- /dev/null
+++ b/include/common_time/cc_helper.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#ifndef __CC_HELPER_H__
+#define __CC_HELPER_H__
+
+#include <stdint.h>
+#include <common_time/ICommonClock.h>
+#include <utils/threads.h>
+
+namespace android {
+
+// CCHelper is a simple wrapper class to help with centralizing access to the
+// Common Clock service and implementing lifetime managment, as well as to
+// implement a simple policy of making a basic attempt to reconnect to the
+// common clock service when things go wrong.
+//
+// On platforms which run the native common_time service in auto-disable mode,
+// the service will go into networkless mode whenever it has no active clients.
+// It tracks active clients using registered CommonClockListeners (the callback
+// interface for onTimelineChanged) since this provides a convienent death
+// handler notification for when the service's clients die unexpectedly. This
+// means that users of the common time service should really always have a
+// CommonClockListener, unless they know that the time service is not running in
+// auto disabled mode, or that there is at least one other registered listener
+// active in the system. The CCHelper makes this a little easier by sharing a
+// ref counted ICommonClock interface across all clients and automatically
+// registering and unregistering a listener whenever there are CCHelper
+// instances active in the process.
+class CCHelper {
+ public:
+ CCHelper();
+ ~CCHelper();
+
+ status_t isCommonTimeValid(bool* valid, uint32_t* timelineID);
+ status_t commonTimeToLocalTime(int64_t commonTime, int64_t* localTime);
+ status_t localTimeToCommonTime(int64_t localTime, int64_t* commonTime);
+ status_t getCommonTime(int64_t* commonTime);
+ status_t getCommonFreq(uint64_t* freq);
+ status_t getLocalTime(int64_t* localTime);
+ status_t getLocalFreq(uint64_t* freq);
+
+ private:
+ class CommonClockListener : public BnCommonClockListener {
+ public:
+ void onTimelineChanged(uint64_t timelineID);
+ };
+
+ static bool verifyClock_l();
+
+ static Mutex lock_;
+ static sp<ICommonClock> common_clock_;
+ static sp<ICommonClockListener> common_clock_listener_;
+ static uint32_t ref_count_;
+};
+
+
+} // namespace android
+#endif // __CC_HELPER_H__
diff --git a/include/common_time/local_clock.h b/include/common_time/local_clock.h
new file mode 100644
index 0000000..845d1c21
--- /dev/null
+++ b/include/common_time/local_clock.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+
+#ifndef __LOCAL_CLOCK_H__
+#define __LOCAL_CLOCK_H__
+
+#include <stdint.h>
+
+#include <hardware/local_time_hal.h>
+#include <utils/Errors.h>
+#include <utils/threads.h>
+
+namespace android {
+
+class LocalClock {
+ public:
+ LocalClock();
+
+ bool initCheck();
+
+ int64_t getLocalTime();
+ uint64_t getLocalFreq();
+ status_t setLocalSlew(int16_t rate);
+ int32_t getDebugLog(struct local_time_debug_event* records,
+ int max_records);
+
+ private:
+ static Mutex dev_lock_;
+ static local_time_hw_device_t* dev_;
+};
+
+} // namespace android
+#endif // __LOCAL_CLOCK_H__
diff --git a/include/media/AudioTrack.h b/include/media/AudioTrack.h
index ac7f6cf..9f2bd3a 100644
--- a/include/media/AudioTrack.h
+++ b/include/media/AudioTrack.h
@@ -446,7 +446,7 @@
*/
status_t dump(int fd, const Vector<String16>& args) const;
-private:
+protected:
/* copying audio tracks is not allowed */
AudioTrack(const AudioTrack& other);
AudioTrack& operator = (const AudioTrack& other);
@@ -518,10 +518,33 @@
int mAuxEffectId;
mutable Mutex mLock;
status_t mRestoreStatus;
+ bool mIsTimed;
int mPreviousPriority; // before start()
int mPreviousSchedulingGroup;
};
+class TimedAudioTrack : public AudioTrack
+{
+public:
+ TimedAudioTrack();
+
+ /* allocate a shared memory buffer that can be passed to queueTimedBuffer */
+ status_t allocateTimedBuffer(size_t size, sp<IMemory>* buffer);
+
+ /* queue a buffer obtained via allocateTimedBuffer for playback at the
+ given timestamp. PTS units a microseconds on the media time timeline.
+ The media time transform (set with setMediaTimeTransform) set by the
+ audio producer will handle converting from media time to local time
+ (perhaps going through the common time timeline in the case of
+ synchronized multiroom audio case) */
+ status_t queueTimedBuffer(const sp<IMemory>& buffer, int64_t pts);
+
+ /* define a transform between media time and either common time or
+ local time */
+ enum TargetTimeline {LOCAL_TIME, COMMON_TIME};
+ status_t setMediaTimeTransform(const LinearTransform& xform,
+ TargetTimeline target);
+};
}; // namespace android
diff --git a/include/media/IAudioFlinger.h b/include/media/IAudioFlinger.h
index 433ce7c..7a2ada0 100644
--- a/include/media/IAudioFlinger.h
+++ b/include/media/IAudioFlinger.h
@@ -55,6 +55,7 @@
uint32_t flags,
const sp<IMemory>& sharedBuffer,
audio_io_handle_t output,
+ bool isTimed,
int *sessionId,
status_t *status) = 0;
diff --git a/include/media/IAudioTrack.h b/include/media/IAudioTrack.h
index e4772a1..77f3e21 100644
--- a/include/media/IAudioTrack.h
+++ b/include/media/IAudioTrack.h
@@ -24,7 +24,7 @@
#include <utils/Errors.h>
#include <binder/IInterface.h>
#include <binder/IMemory.h>
-
+#include <utils/LinearTransform.h>
namespace android {
@@ -71,6 +71,23 @@
*/
virtual status_t attachAuxEffect(int effectId) = 0;
+
+ /* Allocate a shared memory buffer suitable for holding timed audio
+ samples */
+ virtual status_t allocateTimedBuffer(size_t size,
+ sp<IMemory>* buffer) = 0;
+
+ /* Queue a buffer obtained via allocateTimedBuffer for playback at the given
+ timestamp */
+ virtual status_t queueTimedBuffer(const sp<IMemory>& buffer,
+ int64_t pts) = 0;
+
+ /* Define the linear transform that will be applied to the timestamps
+ given to queueTimedBuffer (which are expressed in media time).
+ Target specifies whether this transform converts media time to local time
+ or Tungsten time. The values for target are defined in AudioTrack.h */
+ virtual status_t setMediaTimeTransform(const LinearTransform& xform,
+ int target) = 0;
};
// ----------------------------------------------------------------------------
diff --git a/include/media/MediaPlayerInterface.h b/include/media/MediaPlayerInterface.h
index 77c82b2..23a3e49 100644
--- a/include/media/MediaPlayerInterface.h
+++ b/include/media/MediaPlayerInterface.h
@@ -46,6 +46,9 @@
// The shared library with the test player is passed passed as an
// argument to the 'test:' url in the setDataSource call.
TEST_PLAYER = 5,
+
+ AAH_RX_PLAYER = 100,
+ AAH_TX_PLAYER = 101,
};
diff --git a/include/media/stagefright/AudioSource.h b/include/media/stagefright/AudioSource.h
index 79437bf..f5466e8 100644
--- a/include/media/stagefright/AudioSource.h
+++ b/include/media/stagefright/AudioSource.h
@@ -95,6 +95,7 @@
int32_t startFrame, int32_t rampDurationFrames,
uint8_t *data, size_t bytes);
+ void queueInputBuffer_l(MediaBuffer *buffer, int64_t timeUs);
void releaseQueuedFrames_l();
void waitOutstandingEncodingFrames_l();
status_t reset();
diff --git a/include/ui/PixelFormat.h b/include/ui/PixelFormat.h
index 848c5a1..fc260c4 100644
--- a/include/ui/PixelFormat.h
+++ b/include/ui/PixelFormat.h
@@ -21,7 +21,6 @@
// skia or SurfaceFlinger are not required to support all of these formats
// (either as source or destination)
-// XXX: we should consolidate these formats and skia's
#ifndef UI_PIXELFORMAT_H
#define UI_PIXELFORMAT_H
@@ -29,7 +28,6 @@
#include <stdint.h>
#include <sys/types.h>
#include <utils/Errors.h>
-#include <pixelflinger/format.h>
#include <hardware/hardware.h>
namespace android {
@@ -65,10 +63,7 @@
PIXEL_FORMAT_BGRA_8888 = HAL_PIXEL_FORMAT_BGRA_8888, // 4x8-bit BGRA
PIXEL_FORMAT_RGBA_5551 = HAL_PIXEL_FORMAT_RGBA_5551, // 16-bit ARGB
PIXEL_FORMAT_RGBA_4444 = HAL_PIXEL_FORMAT_RGBA_4444, // 16-bit ARGB
- PIXEL_FORMAT_A_8 = GGL_PIXEL_FORMAT_A_8, // 8-bit A
- PIXEL_FORMAT_L_8 = GGL_PIXEL_FORMAT_L_8, // 8-bit L (R=G=B=L)
- PIXEL_FORMAT_LA_88 = GGL_PIXEL_FORMAT_LA_88, // 16-bit LA
- PIXEL_FORMAT_RGB_332 = GGL_PIXEL_FORMAT_RGB_332, // 8-bit RGB
+ PIXEL_FORMAT_A_8 = 8, // 8-bit A
// New formats can be added if they're also defined in
// pixelflinger/format.h
@@ -76,8 +71,7 @@
typedef int32_t PixelFormat;
-struct PixelFormatInfo
-{
+struct PixelFormatInfo {
enum {
INDEX_ALPHA = 0,
INDEX_RED = 1,
@@ -89,8 +83,6 @@
ALPHA = 1,
RGB = 2,
RGBA = 3,
- LUMINANCE = 4,
- LUMINANCE_ALPHA = 5,
OTHER = 0xFF
};
diff --git a/keystore/java/android/security/KeyChain.java b/keystore/java/android/security/KeyChain.java
index db6388a..0fe7bd8 100644
--- a/keystore/java/android/security/KeyChain.java
+++ b/keystore/java/android/security/KeyChain.java
@@ -124,7 +124,7 @@
public static final String EXTRA_SENDER = "sender";
/**
- * Action to bring up the CertInstaller
+ * Action to bring up the CertInstaller.
*/
private static final String ACTION_INSTALL = "android.credentials.INSTALL";
@@ -167,6 +167,22 @@
// Compatible with old android.security.Credentials.PKCS12
public static final String EXTRA_PKCS12 = "PKCS12";
+
+ /**
+ * @hide TODO This is temporary and will be removed
+ * Broadcast Action: Indicates the trusted storage has changed. Sent when
+ * one of this happens:
+ *
+ * <ul>
+ * <li>a new CA is added,
+ * <li>an existing CA is removed or disabled,
+ * <li>a disabled CA is enabled,
+ * <li>trusted storage is reset (all user certs are cleared),
+ * <li>when permission to access a private key is changed.
+ * </ul>
+ */
+ public static final String ACTION_STORAGE_CHANGED = "android.security.STORAGE_CHANGED";
+
/**
* Returns an {@code Intent} that can be used for credential
* installation. The intent may be used without any extras, in
diff --git a/libs/androidfw/Android.mk b/libs/androidfw/Android.mk
new file mode 100644
index 0000000..c5f8a87
--- /dev/null
+++ b/libs/androidfw/Android.mk
@@ -0,0 +1,113 @@
+# Copyright (C) 2010 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)
+
+# libandroidfw is partially built for the host (used by build time keymap validation tool)
+# These files are common to host and target builds.
+
+# formerly in libutils
+commonUtilsSources:= \
+ Asset.cpp \
+ AssetDir.cpp \
+ AssetManager.cpp \
+ ObbFile.cpp \
+ ResourceTypes.cpp \
+ StreamingZipInflater.cpp \
+ ZipFileCRO.cpp \
+ ZipFileRO.cpp \
+ ZipUtils.cpp
+
+# formerly in libui
+commonUiSources:= \
+ Input.cpp \
+ Keyboard.cpp \
+ KeyCharacterMap.cpp \
+ KeyLayoutMap.cpp \
+ VirtualKeyMap.cpp
+
+commonSources:= \
+ $(commonUtilsSources) \
+ $(commonUiSources)
+
+# For the host
+# =====================================================
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= $(commonSources)
+
+LOCAL_MODULE:= libandroidfw
+
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_C_INCLUDES := \
+ external/zlib
+
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+
+# For the device
+# =====================================================
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+ $(commonSources) \
+ BackupData.cpp \
+ BackupHelpers.cpp \
+ InputTransport.cpp
+
+LOCAL_SHARED_LIBRARIES := \
+ liblog \
+ libcutils \
+ libutils \
+ libbinder \
+ libskia \
+ libz
+
+LOCAL_C_INCLUDES := \
+ external/skia/include/core \
+ external/icu4c/common \
+ external/zlib
+
+LOCAL_MODULE:= libandroidfw
+
+LOCAL_MODULE_TAGS := optional
+
+include $(BUILD_SHARED_LIBRARY)
+
+
+ifeq ($(TARGET_OS),linux)
+include $(CLEAR_VARS)
+LOCAL_C_INCLUDES += \
+ external/skia/include/core \
+ external/zlib \
+ external/icu4c/common \
+ bionic/libc/private
+LOCAL_LDLIBS := -lrt -ldl -lpthread
+LOCAL_MODULE := libandroidfw
+LOCAL_SRC_FILES := $(commonUtilsSources) BackupData.cpp BackupHelpers.cpp
+include $(BUILD_STATIC_LIBRARY)
+endif
+
+
+# Include subdirectory makefiles
+# ============================================================
+
+# If we're building with ONE_SHOT_MAKEFILE (mm, mmm), then what the framework
+# team really wants is to build the stuff defined by this makefile.
+ifeq (,$(ONE_SHOT_MAKEFILE))
+include $(call first-makefiles-under,$(LOCAL_PATH))
+endif
diff --git a/libs/utils/Asset.cpp b/libs/androidfw/Asset.cpp
similarity index 98%
rename from libs/utils/Asset.cpp
rename to libs/androidfw/Asset.cpp
index 50e701a..cb7628d 100644
--- a/libs/utils/Asset.cpp
+++ b/libs/androidfw/Asset.cpp
@@ -21,23 +21,23 @@
#define LOG_TAG "asset"
//#define NDEBUG 0
-#include <utils/Asset.h>
+#include <androidfw/Asset.h>
+#include <androidfw/StreamingZipInflater.h>
+#include <androidfw/ZipFileRO.h>
+#include <androidfw/ZipUtils.h>
#include <utils/Atomic.h>
#include <utils/FileMap.h>
-#include <utils/StreamingZipInflater.h>
-#include <utils/ZipUtils.h>
-#include <utils/ZipFileRO.h>
#include <utils/Log.h>
#include <utils/threads.h>
-#include <string.h>
-#include <memory.h>
-#include <fcntl.h>
-#include <errno.h>
#include <assert.h>
-#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <memory.h>
+#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
+#include <unistd.h>
using namespace android;
diff --git a/libs/utils/AssetDir.cpp b/libs/androidfw/AssetDir.cpp
similarity index 97%
rename from libs/utils/AssetDir.cpp
rename to libs/androidfw/AssetDir.cpp
index c5f664e..475f521 100644
--- a/libs/utils/AssetDir.cpp
+++ b/libs/androidfw/AssetDir.cpp
@@ -19,7 +19,7 @@
// implementation is in the header file or in friend functions in
// AssetManager.
//
-#include <utils/AssetDir.h>
+#include <androidfw/AssetDir.h>
using namespace android;
diff --git a/libs/utils/AssetManager.cpp b/libs/androidfw/AssetManager.cpp
similarity index 99%
rename from libs/utils/AssetManager.cpp
rename to libs/androidfw/AssetManager.cpp
index 47a2b99..4829add 100644
--- a/libs/utils/AssetManager.cpp
+++ b/libs/androidfw/AssetManager.cpp
@@ -21,23 +21,23 @@
#define LOG_TAG "asset"
//#define LOG_NDEBUG 0
-#include <utils/AssetManager.h>
-#include <utils/AssetDir.h>
-#include <utils/Asset.h>
+#include <androidfw/Asset.h>
+#include <androidfw/AssetDir.h>
+#include <androidfw/AssetManager.h>
+#include <androidfw/ResourceTypes.h>
+#include <androidfw/ZipFileRO.h>
#include <utils/Atomic.h>
-#include <utils/String8.h>
-#include <utils/ResourceTypes.h>
-#include <utils/String8.h>
-#include <utils/ZipFileRO.h>
#include <utils/Log.h>
-#include <utils/Timers.h>
+#include <utils/String8.h>
+#include <utils/String8.h>
#include <utils/threads.h>
+#include <utils/Timers.h>
+#include <assert.h>
#include <dirent.h>
#include <errno.h>
-#include <assert.h>
-#include <strings.h>
#include <fcntl.h>
+#include <strings.h>
#include <sys/stat.h>
#include <unistd.h>
diff --git a/libs/utils/BackupData.cpp b/libs/androidfw/BackupData.cpp
similarity index 99%
rename from libs/utils/BackupData.cpp
rename to libs/androidfw/BackupData.cpp
index f956306..7b1bcba 100644
--- a/libs/utils/BackupData.cpp
+++ b/libs/androidfw/BackupData.cpp
@@ -16,7 +16,7 @@
#define LOG_TAG "backup_data"
-#include <utils/BackupHelpers.h>
+#include <androidfw/BackupHelpers.h>
#include <utils/ByteOrder.h>
#include <stdio.h>
diff --git a/libs/utils/BackupHelpers.cpp b/libs/androidfw/BackupHelpers.cpp
similarity index 99%
rename from libs/utils/BackupHelpers.cpp
rename to libs/androidfw/BackupHelpers.cpp
index f77a891..7a817a7 100644
--- a/libs/utils/BackupHelpers.cpp
+++ b/libs/androidfw/BackupHelpers.cpp
@@ -16,7 +16,7 @@
#define LOG_TAG "file_backup_helper"
-#include <utils/BackupHelpers.h>
+#include <androidfw/BackupHelpers.h>
#include <utils/KeyedVector.h>
#include <utils/ByteOrder.h>
@@ -546,7 +546,7 @@
// read/write up to this much at a time.
const size_t BUFSIZE = 32 * 1024;
- char* buf = new char[BUFSIZE];
+ char* buf = (char *)calloc(1,BUFSIZE);
char* paxHeader = buf + 512; // use a different chunk of it as separate scratch
char* paxData = buf + 1024;
@@ -556,9 +556,6 @@
goto cleanup;
}
- // Good to go -- first construct the standard tar header at the start of the buffer
- memset(buf, 0, BUFSIZE);
-
// Magic fields for the ustar file format
strcat(buf + 257, "ustar");
strcat(buf + 263, "00");
diff --git a/libs/ui/Input.cpp b/libs/androidfw/Input.cpp
similarity index 99%
rename from libs/ui/Input.cpp
rename to libs/androidfw/Input.cpp
index 263c8d9..ca09caf 100644
--- a/libs/ui/Input.cpp
+++ b/libs/androidfw/Input.cpp
@@ -24,7 +24,7 @@
#include <unistd.h>
#include <ctype.h>
-#include <ui/Input.h>
+#include <androidfw/Input.h>
#include <math.h>
#include <limits.h>
diff --git a/libs/ui/InputTransport.cpp b/libs/androidfw/InputTransport.cpp
similarity index 99%
rename from libs/ui/InputTransport.cpp
rename to libs/androidfw/InputTransport.cpp
index ecb3fb5..1ebd75c 100644
--- a/libs/ui/InputTransport.cpp
+++ b/libs/androidfw/InputTransport.cpp
@@ -20,7 +20,7 @@
#include <cutils/log.h>
#include <errno.h>
#include <fcntl.h>
-#include <ui/InputTransport.h>
+#include <androidfw/InputTransport.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
diff --git a/libs/ui/KeyCharacterMap.cpp b/libs/androidfw/KeyCharacterMap.cpp
similarity index 99%
rename from libs/ui/KeyCharacterMap.cpp
rename to libs/androidfw/KeyCharacterMap.cpp
index 485234c..6984084 100644
--- a/libs/ui/KeyCharacterMap.cpp
+++ b/libs/androidfw/KeyCharacterMap.cpp
@@ -19,8 +19,8 @@
#include <stdlib.h>
#include <string.h>
#include <android/keycodes.h>
-#include <ui/Keyboard.h>
-#include <ui/KeyCharacterMap.h>
+#include <androidfw/Keyboard.h>
+#include <androidfw/KeyCharacterMap.h>
#include <utils/Log.h>
#include <utils/Errors.h>
#include <utils/Tokenizer.h>
diff --git a/libs/ui/KeyLayoutMap.cpp b/libs/androidfw/KeyLayoutMap.cpp
similarity index 98%
rename from libs/ui/KeyLayoutMap.cpp
rename to libs/androidfw/KeyLayoutMap.cpp
index 44a9420..15d81ee 100644
--- a/libs/ui/KeyLayoutMap.cpp
+++ b/libs/androidfw/KeyLayoutMap.cpp
@@ -18,8 +18,8 @@
#include <stdlib.h>
#include <android/keycodes.h>
-#include <ui/Keyboard.h>
-#include <ui/KeyLayoutMap.h>
+#include <androidfw/Keyboard.h>
+#include <androidfw/KeyLayoutMap.h>
#include <utils/Log.h>
#include <utils/Errors.h>
#include <utils/Tokenizer.h>
diff --git a/libs/ui/Keyboard.cpp b/libs/androidfw/Keyboard.cpp
similarity index 98%
rename from libs/ui/Keyboard.cpp
rename to libs/androidfw/Keyboard.cpp
index e4611f7..e97a5eb 100644
--- a/libs/ui/Keyboard.cpp
+++ b/libs/androidfw/Keyboard.cpp
@@ -20,10 +20,10 @@
#include <unistd.h>
#include <limits.h>
-#include <ui/Keyboard.h>
-#include <ui/KeycodeLabels.h>
-#include <ui/KeyLayoutMap.h>
-#include <ui/KeyCharacterMap.h>
+#include <androidfw/Keyboard.h>
+#include <androidfw/KeycodeLabels.h>
+#include <androidfw/KeyLayoutMap.h>
+#include <androidfw/KeyCharacterMap.h>
#include <utils/Errors.h>
#include <utils/Log.h>
#include <cutils/properties.h>
diff --git a/libs/androidfw/MODULE_LICENSE_APACHE2 b/libs/androidfw/MODULE_LICENSE_APACHE2
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libs/androidfw/MODULE_LICENSE_APACHE2
diff --git a/libs/androidfw/NOTICE b/libs/androidfw/NOTICE
new file mode 100644
index 0000000..c5b1efa
--- /dev/null
+++ b/libs/androidfw/NOTICE
@@ -0,0 +1,190 @@
+
+ Copyright (c) 2005-2008, 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.
+
+ 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.
+
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
diff --git a/libs/utils/ObbFile.cpp b/libs/androidfw/ObbFile.cpp
similarity index 99%
rename from libs/utils/ObbFile.cpp
rename to libs/androidfw/ObbFile.cpp
index ddf5991..21e06c8 100644
--- a/libs/utils/ObbFile.cpp
+++ b/libs/androidfw/ObbFile.cpp
@@ -23,9 +23,9 @@
#define LOG_TAG "ObbFile"
+#include <androidfw/ObbFile.h>
#include <utils/Compat.h>
#include <utils/Log.h>
-#include <utils/ObbFile.h>
//#define DEBUG 1
diff --git a/libs/utils/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
similarity index 99%
rename from libs/utils/ResourceTypes.cpp
rename to libs/androidfw/ResourceTypes.cpp
index 3fa562e..07f3b16 100644
--- a/libs/utils/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -17,14 +17,14 @@
#define LOG_TAG "ResourceType"
//#define LOG_NDEBUG 0
+#include <androidfw/ResourceTypes.h>
#include <utils/Atomic.h>
#include <utils/ByteOrder.h>
#include <utils/Debug.h>
-#include <utils/ResourceTypes.h>
+#include <utils/Log.h>
#include <utils/String16.h>
#include <utils/String8.h>
#include <utils/TextOutput.h>
-#include <utils/Log.h>
#include <stdlib.h>
#include <string.h>
@@ -379,8 +379,7 @@
size_t charSize;
if (mHeader->flags&ResStringPool_header::UTF8_FLAG) {
charSize = sizeof(uint8_t);
- mCache = (char16_t**)malloc(sizeof(char16_t**)*mHeader->stringCount);
- memset(mCache, 0, sizeof(char16_t**)*mHeader->stringCount);
+ mCache = (char16_t**)calloc(mHeader->stringCount, sizeof(char16_t**));
} else {
charSize = sizeof(char16_t);
}
@@ -3252,16 +3251,14 @@
// Bag not found, we need to compute it!
if (!grp->bags) {
- grp->bags = (bag_set***)malloc(sizeof(bag_set*)*grp->typeCount);
+ grp->bags = (bag_set***)calloc(grp->typeCount, sizeof(bag_set*));
if (!grp->bags) return NO_MEMORY;
- memset(grp->bags, 0, sizeof(bag_set*)*grp->typeCount);
}
bag_set** typeSet = grp->bags[t];
if (!typeSet) {
- typeSet = (bag_set**)malloc(sizeof(bag_set*)*NENTRY);
+ typeSet = (bag_set**)calloc(NENTRY, sizeof(bag_set*));
if (!typeSet) return NO_MEMORY;
- memset(typeSet, 0, sizeof(bag_set*)*NENTRY);
grp->bags[t] = typeSet;
}
diff --git a/libs/utils/StreamingZipInflater.cpp b/libs/androidfw/StreamingZipInflater.cpp
similarity index 99%
rename from libs/utils/StreamingZipInflater.cpp
rename to libs/androidfw/StreamingZipInflater.cpp
index 8512170a..d3fb98d 100644
--- a/libs/utils/StreamingZipInflater.cpp
+++ b/libs/androidfw/StreamingZipInflater.cpp
@@ -18,8 +18,8 @@
#define LOG_TAG "szipinf"
#include <utils/Log.h>
+#include <androidfw/StreamingZipInflater.h>
#include <utils/FileMap.h>
-#include <utils/StreamingZipInflater.h>
#include <string.h>
#include <stddef.h>
#include <assert.h>
diff --git a/libs/ui/VirtualKeyMap.cpp b/libs/androidfw/VirtualKeyMap.cpp
similarity index 98%
rename from libs/ui/VirtualKeyMap.cpp
rename to libs/androidfw/VirtualKeyMap.cpp
index 62d5b59..2ba1673 100644
--- a/libs/ui/VirtualKeyMap.cpp
+++ b/libs/androidfw/VirtualKeyMap.cpp
@@ -18,7 +18,7 @@
#include <stdlib.h>
#include <string.h>
-#include <ui/VirtualKeyMap.h>
+#include <androidfw/VirtualKeyMap.h>
#include <utils/Log.h>
#include <utils/Errors.h>
#include <utils/Tokenizer.h>
diff --git a/libs/utils/ZipFileCRO.cpp b/libs/androidfw/ZipFileCRO.cpp
similarity index 95%
rename from libs/utils/ZipFileCRO.cpp
rename to libs/androidfw/ZipFileCRO.cpp
index 55dfd9f..c8df845 100644
--- a/libs/utils/ZipFileCRO.cpp
+++ b/libs/androidfw/ZipFileCRO.cpp
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#include <utils/ZipFileCRO.h>
-#include <utils/ZipFileRO.h>
+#include <androidfw/ZipFileCRO.h>
+#include <androidfw/ZipFileRO.h>
using namespace android;
diff --git a/libs/utils/ZipFileRO.cpp b/libs/androidfw/ZipFileRO.cpp
similarity index 99%
rename from libs/utils/ZipFileRO.cpp
rename to libs/androidfw/ZipFileRO.cpp
index 1498aac..4b7f1e7 100644
--- a/libs/utils/ZipFileRO.cpp
+++ b/libs/androidfw/ZipFileRO.cpp
@@ -19,7 +19,7 @@
//
#define LOG_TAG "zipro"
//#define LOG_NDEBUG 0
-#include <utils/ZipFileRO.h>
+#include <androidfw/ZipFileRO.h>
#include <utils/Log.h>
#include <utils/misc.h>
#include <utils/threads.h>
diff --git a/libs/utils/ZipUtils.cpp b/libs/androidfw/ZipUtils.cpp
similarity index 98%
rename from libs/utils/ZipUtils.cpp
rename to libs/androidfw/ZipUtils.cpp
index 2dbdc1d..db3479d 100644
--- a/libs/utils/ZipUtils.cpp
+++ b/libs/androidfw/ZipUtils.cpp
@@ -20,8 +20,8 @@
#define LOG_TAG "ziputil"
-#include <utils/ZipUtils.h>
-#include <utils/ZipFileRO.h>
+#include <androidfw/ZipUtils.h>
+#include <androidfw/ZipFileRO.h>
#include <utils/Log.h>
#include <stdlib.h>
diff --git a/libs/androidfw/tests/Android.mk b/libs/androidfw/tests/Android.mk
new file mode 100644
index 0000000..d85009b
--- /dev/null
+++ b/libs/androidfw/tests/Android.mk
@@ -0,0 +1,47 @@
+# Build the unit tests.
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# Build the unit tests.
+test_src_files := \
+ InputChannel_test.cpp \
+ InputEvent_test.cpp \
+ InputPublisherAndConsumer_test.cpp \
+ ObbFile_test.cpp \
+ ZipFileRO_test.cpp
+
+shared_libraries := \
+ libandroidfw \
+ libcutils \
+ libutils \
+ libbinder \
+ libui \
+ libstlport \
+ libskia
+
+static_libraries := \
+ libgtest \
+ libgtest_main
+
+c_includes := \
+ bionic \
+ bionic/libstdc++/include \
+ external/gtest/include \
+ external/stlport/stlport \
+ external/skia/include/core
+
+module_tags := eng tests
+
+$(foreach file,$(test_src_files), \
+ $(eval include $(CLEAR_VARS)) \
+ $(eval LOCAL_SHARED_LIBRARIES := $(shared_libraries)) \
+ $(eval LOCAL_STATIC_LIBRARIES := $(static_libraries)) \
+ $(eval LOCAL_C_INCLUDES := $(c_includes)) \
+ $(eval LOCAL_SRC_FILES := $(file)) \
+ $(eval LOCAL_MODULE := $(notdir $(file:%.cpp=%))) \
+ $(eval LOCAL_MODULE_TAGS := $(module_tags)) \
+ $(eval include $(BUILD_EXECUTABLE)) \
+)
+
+# Build the manual test programs.
+include $(call all-makefiles-under, $(LOCAL_PATH))
diff --git a/libs/ui/tests/InputChannel_test.cpp b/libs/androidfw/tests/InputChannel_test.cpp
similarity index 98%
rename from libs/ui/tests/InputChannel_test.cpp
rename to libs/androidfw/tests/InputChannel_test.cpp
index ee422fe..0e5d19d 100644
--- a/libs/ui/tests/InputChannel_test.cpp
+++ b/libs/androidfw/tests/InputChannel_test.cpp
@@ -14,9 +14,10 @@
* limitations under the License.
*/
-#include <ui/InputTransport.h>
+#include <androidfw/InputTransport.h>
#include <utils/Timers.h>
#include <utils/StopWatch.h>
+#include <utils/StrongPointer.h>
#include <gtest/gtest.h>
#include <unistd.h>
#include <time.h>
diff --git a/libs/ui/tests/InputEvent_test.cpp b/libs/androidfw/tests/InputEvent_test.cpp
similarity index 99%
rename from libs/ui/tests/InputEvent_test.cpp
rename to libs/androidfw/tests/InputEvent_test.cpp
index e21c464..ac5549c 100644
--- a/libs/ui/tests/InputEvent_test.cpp
+++ b/libs/androidfw/tests/InputEvent_test.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include <ui/Input.h>
+#include <androidfw/Input.h>
#include <gtest/gtest.h>
#include <binder/Parcel.h>
diff --git a/libs/ui/tests/InputPublisherAndConsumer_test.cpp b/libs/androidfw/tests/InputPublisherAndConsumer_test.cpp
similarity index 99%
rename from libs/ui/tests/InputPublisherAndConsumer_test.cpp
rename to libs/androidfw/tests/InputPublisherAndConsumer_test.cpp
index 3303053..bb45247 100644
--- a/libs/ui/tests/InputPublisherAndConsumer_test.cpp
+++ b/libs/androidfw/tests/InputPublisherAndConsumer_test.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include <ui/InputTransport.h>
+#include <androidfw/InputTransport.h>
#include <utils/Timers.h>
#include <utils/StopWatch.h>
#include <gtest/gtest.h>
diff --git a/libs/utils/tests/ObbFile_test.cpp b/libs/androidfw/tests/ObbFile_test.cpp
similarity index 98%
rename from libs/utils/tests/ObbFile_test.cpp
rename to libs/androidfw/tests/ObbFile_test.cpp
index 46b30c2..09d4d7d 100644
--- a/libs/utils/tests/ObbFile_test.cpp
+++ b/libs/androidfw/tests/ObbFile_test.cpp
@@ -15,8 +15,8 @@
*/
#define LOG_TAG "ObbFile_test"
+#include <androidfw/ObbFile.h>
#include <utils/Log.h>
-#include <utils/ObbFile.h>
#include <utils/RefBase.h>
#include <utils/String8.h>
diff --git a/libs/utils/tests/ZipFileRO_test.cpp b/libs/androidfw/tests/ZipFileRO_test.cpp
similarity index 97%
rename from libs/utils/tests/ZipFileRO_test.cpp
rename to libs/androidfw/tests/ZipFileRO_test.cpp
index 7a1d0bd..344f974 100644
--- a/libs/utils/tests/ZipFileRO_test.cpp
+++ b/libs/androidfw/tests/ZipFileRO_test.cpp
@@ -15,8 +15,8 @@
*/
#define LOG_TAG "ZipFileRO_test"
+#include <androidfw/ZipFileRO.h>
#include <utils/Log.h>
-#include <utils/ZipFileRO.h>
#include <gtest/gtest.h>
diff --git a/libs/common_time/Android.mk b/libs/common_time/Android.mk
new file mode 100644
index 0000000..526f17b
--- /dev/null
+++ b/libs/common_time/Android.mk
@@ -0,0 +1,21 @@
+LOCAL_PATH:= $(call my-dir)
+#
+# libcommon_time_client
+# (binder marshalers for ICommonClock as well as common clock and local clock
+# helper code)
+#
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libcommon_time_client
+LOCAL_MODULE_TAGS := optional
+LOCAL_SRC_FILES := cc_helper.cpp \
+ local_clock.cpp \
+ ICommonClock.cpp \
+ ICommonTimeConfig.cpp \
+ utils.cpp
+LOCAL_SHARED_LIBRARIES := libbinder \
+ libhardware \
+ libutils
+
+include $(BUILD_SHARED_LIBRARY)
diff --git a/libs/common_time/ICommonClock.cpp b/libs/common_time/ICommonClock.cpp
new file mode 100644
index 0000000..28b43ac
--- /dev/null
+++ b/libs/common_time/ICommonClock.cpp
@@ -0,0 +1,432 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+#include <linux/socket.h>
+
+#include <common_time/ICommonClock.h>
+#include <binder/Parcel.h>
+
+#include "utils.h"
+
+namespace android {
+
+/***** ICommonClock *****/
+
+enum {
+ IS_COMMON_TIME_VALID = IBinder::FIRST_CALL_TRANSACTION,
+ COMMON_TIME_TO_LOCAL_TIME,
+ LOCAL_TIME_TO_COMMON_TIME,
+ GET_COMMON_TIME,
+ GET_COMMON_FREQ,
+ GET_LOCAL_TIME,
+ GET_LOCAL_FREQ,
+ GET_ESTIMATED_ERROR,
+ GET_TIMELINE_ID,
+ GET_STATE,
+ GET_MASTER_ADDRESS,
+ REGISTER_LISTENER,
+ UNREGISTER_LISTENER,
+};
+
+const String16 ICommonClock::kServiceName("common_time.clock");
+const uint64_t ICommonClock::kInvalidTimelineID = 0;
+const int32_t ICommonClock::kErrorEstimateUnknown = 0x7FFFFFFF;
+
+class BpCommonClock : public BpInterface<ICommonClock>
+{
+ public:
+ BpCommonClock(const sp<IBinder>& impl)
+ : BpInterface<ICommonClock>(impl) {}
+
+ virtual status_t isCommonTimeValid(bool* valid, uint32_t* timelineID) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
+ status_t status = remote()->transact(IS_COMMON_TIME_VALID,
+ data,
+ &reply);
+ if (status == OK) {
+ status = reply.readInt32();
+ if (status == OK) {
+ *valid = reply.readInt32();
+ *timelineID = reply.readInt32();
+ }
+ }
+ return status;
+ }
+
+ virtual status_t commonTimeToLocalTime(int64_t commonTime,
+ int64_t* localTime) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
+ data.writeInt64(commonTime);
+ status_t status = remote()->transact(COMMON_TIME_TO_LOCAL_TIME,
+ data, &reply);
+ if (status == OK) {
+ status = reply.readInt32();
+ if (status == OK) {
+ *localTime = reply.readInt64();
+ }
+ }
+ return status;
+ }
+
+ virtual status_t localTimeToCommonTime(int64_t localTime,
+ int64_t* commonTime) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
+ data.writeInt64(localTime);
+ status_t status = remote()->transact(LOCAL_TIME_TO_COMMON_TIME,
+ data, &reply);
+ if (status == OK) {
+ status = reply.readInt32();
+ if (status == OK) {
+ *commonTime = reply.readInt64();
+ }
+ }
+ return status;
+ }
+
+ virtual status_t getCommonTime(int64_t* commonTime) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
+ status_t status = remote()->transact(GET_COMMON_TIME, data, &reply);
+ if (status == OK) {
+ status = reply.readInt32();
+ if (status == OK) {
+ *commonTime = reply.readInt64();
+ }
+ }
+ return status;
+ }
+
+ virtual status_t getCommonFreq(uint64_t* freq) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
+ status_t status = remote()->transact(GET_COMMON_FREQ, data, &reply);
+ if (status == OK) {
+ status = reply.readInt32();
+ if (status == OK) {
+ *freq = reply.readInt64();
+ }
+ }
+ return status;
+ }
+
+ virtual status_t getLocalTime(int64_t* localTime) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
+ status_t status = remote()->transact(GET_LOCAL_TIME, data, &reply);
+ if (status == OK) {
+ status = reply.readInt32();
+ if (status == OK) {
+ *localTime = reply.readInt64();
+ }
+ }
+ return status;
+ }
+
+ virtual status_t getLocalFreq(uint64_t* freq) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
+ status_t status = remote()->transact(GET_LOCAL_FREQ, data, &reply);
+ if (status == OK) {
+ status = reply.readInt32();
+ if (status == OK) {
+ *freq = reply.readInt64();
+ }
+ }
+ return status;
+ }
+
+ virtual status_t getEstimatedError(int32_t* estimate) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
+ status_t status = remote()->transact(GET_ESTIMATED_ERROR, data, &reply);
+ if (status == OK) {
+ status = reply.readInt32();
+ if (status == OK) {
+ *estimate = reply.readInt32();
+ }
+ }
+ return status;
+ }
+
+ virtual status_t getTimelineID(uint64_t* id) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
+ status_t status = remote()->transact(GET_TIMELINE_ID, data, &reply);
+ if (status == OK) {
+ status = reply.readInt32();
+ if (status == OK) {
+ *id = static_cast<uint64_t>(reply.readInt64());
+ }
+ }
+ return status;
+ }
+
+ virtual status_t getState(State* state) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
+ status_t status = remote()->transact(GET_STATE, data, &reply);
+ if (status == OK) {
+ status = reply.readInt32();
+ if (status == OK) {
+ *state = static_cast<State>(reply.readInt32());
+ }
+ }
+ return status;
+ }
+
+ virtual status_t getMasterAddr(struct sockaddr_storage* addr) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
+ status_t status = remote()->transact(GET_MASTER_ADDRESS, data, &reply);
+ if (status == OK) {
+ status = reply.readInt32();
+ if (status == OK)
+ deserializeSockaddr(&reply, addr);
+ }
+ return status;
+ }
+
+ virtual status_t registerListener(
+ const sp<ICommonClockListener>& listener) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
+ data.writeStrongBinder(listener->asBinder());
+
+ status_t status = remote()->transact(REGISTER_LISTENER, data, &reply);
+
+ if (status == OK) {
+ status = reply.readInt32();
+ }
+
+ return status;
+ }
+
+ virtual status_t unregisterListener(
+ const sp<ICommonClockListener>& listener) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ICommonClock::getInterfaceDescriptor());
+ data.writeStrongBinder(listener->asBinder());
+ status_t status = remote()->transact(UNREGISTER_LISTENER, data, &reply);
+
+ if (status == OK) {
+ status = reply.readInt32();
+ }
+
+ return status;
+ }
+};
+
+IMPLEMENT_META_INTERFACE(CommonClock, "android.os.ICommonClock");
+
+status_t BnCommonClock::onTransact(uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags) {
+ switch(code) {
+ case IS_COMMON_TIME_VALID: {
+ CHECK_INTERFACE(ICommonClock, data, reply);
+ bool valid;
+ uint32_t timelineID;
+ status_t status = isCommonTimeValid(&valid, &timelineID);
+ reply->writeInt32(status);
+ if (status == OK) {
+ reply->writeInt32(valid);
+ reply->writeInt32(timelineID);
+ }
+ return OK;
+ } break;
+
+ case COMMON_TIME_TO_LOCAL_TIME: {
+ CHECK_INTERFACE(ICommonClock, data, reply);
+ int64_t commonTime = data.readInt64();
+ int64_t localTime;
+ status_t status = commonTimeToLocalTime(commonTime, &localTime);
+ reply->writeInt32(status);
+ if (status == OK) {
+ reply->writeInt64(localTime);
+ }
+ return OK;
+ } break;
+
+ case LOCAL_TIME_TO_COMMON_TIME: {
+ CHECK_INTERFACE(ICommonClock, data, reply);
+ int64_t localTime = data.readInt64();
+ int64_t commonTime;
+ status_t status = localTimeToCommonTime(localTime, &commonTime);
+ reply->writeInt32(status);
+ if (status == OK) {
+ reply->writeInt64(commonTime);
+ }
+ return OK;
+ } break;
+
+ case GET_COMMON_TIME: {
+ CHECK_INTERFACE(ICommonClock, data, reply);
+ int64_t commonTime;
+ status_t status = getCommonTime(&commonTime);
+ reply->writeInt32(status);
+ if (status == OK) {
+ reply->writeInt64(commonTime);
+ }
+ return OK;
+ } break;
+
+ case GET_COMMON_FREQ: {
+ CHECK_INTERFACE(ICommonClock, data, reply);
+ uint64_t freq;
+ status_t status = getCommonFreq(&freq);
+ reply->writeInt32(status);
+ if (status == OK) {
+ reply->writeInt64(freq);
+ }
+ return OK;
+ } break;
+
+ case GET_LOCAL_TIME: {
+ CHECK_INTERFACE(ICommonClock, data, reply);
+ int64_t localTime;
+ status_t status = getLocalTime(&localTime);
+ reply->writeInt32(status);
+ if (status == OK) {
+ reply->writeInt64(localTime);
+ }
+ return OK;
+ } break;
+
+ case GET_LOCAL_FREQ: {
+ CHECK_INTERFACE(ICommonClock, data, reply);
+ uint64_t freq;
+ status_t status = getLocalFreq(&freq);
+ reply->writeInt32(status);
+ if (status == OK) {
+ reply->writeInt64(freq);
+ }
+ return OK;
+ } break;
+
+ case GET_ESTIMATED_ERROR: {
+ CHECK_INTERFACE(ICommonClock, data, reply);
+ int32_t error;
+ status_t status = getEstimatedError(&error);
+ reply->writeInt32(status);
+ if (status == OK) {
+ reply->writeInt32(error);
+ }
+ return OK;
+ } break;
+
+ case GET_TIMELINE_ID: {
+ CHECK_INTERFACE(ICommonClock, data, reply);
+ uint64_t id;
+ status_t status = getTimelineID(&id);
+ reply->writeInt32(status);
+ if (status == OK) {
+ reply->writeInt64(static_cast<int64_t>(id));
+ }
+ return OK;
+ } break;
+
+ case GET_STATE: {
+ CHECK_INTERFACE(ICommonClock, data, reply);
+ State state;
+ status_t status = getState(&state);
+ reply->writeInt32(status);
+ if (status == OK) {
+ reply->writeInt32(static_cast<int32_t>(state));
+ }
+ return OK;
+ } break;
+
+ case GET_MASTER_ADDRESS: {
+ CHECK_INTERFACE(ICommonClock, data, reply);
+ struct sockaddr_storage addr;
+ status_t status = getMasterAddr(&addr);
+
+ if ((status == OK) && !canSerializeSockaddr(&addr)) {
+ status = UNKNOWN_ERROR;
+ }
+
+ reply->writeInt32(status);
+
+ if (status == OK) {
+ serializeSockaddr(reply, &addr);
+ }
+
+ return OK;
+ } break;
+
+ case REGISTER_LISTENER: {
+ CHECK_INTERFACE(ICommonClock, data, reply);
+ sp<ICommonClockListener> listener =
+ interface_cast<ICommonClockListener>(data.readStrongBinder());
+ status_t status = registerListener(listener);
+ reply->writeInt32(status);
+ return OK;
+ } break;
+
+ case UNREGISTER_LISTENER: {
+ CHECK_INTERFACE(ICommonClock, data, reply);
+ sp<ICommonClockListener> listener =
+ interface_cast<ICommonClockListener>(data.readStrongBinder());
+ status_t status = unregisterListener(listener);
+ reply->writeInt32(status);
+ return OK;
+ } break;
+ }
+ return BBinder::onTransact(code, data, reply, flags);
+}
+
+/***** ICommonClockListener *****/
+
+enum {
+ ON_TIMELINE_CHANGED = IBinder::FIRST_CALL_TRANSACTION,
+};
+
+class BpCommonClockListener : public BpInterface<ICommonClockListener>
+{
+ public:
+ BpCommonClockListener(const sp<IBinder>& impl)
+ : BpInterface<ICommonClockListener>(impl) {}
+
+ virtual void onTimelineChanged(uint64_t timelineID) {
+ Parcel data, reply;
+ data.writeInterfaceToken(
+ ICommonClockListener::getInterfaceDescriptor());
+ data.writeInt64(timelineID);
+ remote()->transact(ON_TIMELINE_CHANGED, data, &reply);
+ }
+};
+
+IMPLEMENT_META_INTERFACE(CommonClockListener,
+ "android.os.ICommonClockListener");
+
+status_t BnCommonClockListener::onTransact(
+ uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) {
+ switch(code) {
+ case ON_TIMELINE_CHANGED: {
+ CHECK_INTERFACE(ICommonClockListener, data, reply);
+ uint32_t timelineID = data.readInt64();
+ onTimelineChanged(timelineID);
+ return NO_ERROR;
+ } break;
+ }
+
+ return BBinder::onTransact(code, data, reply, flags);
+}
+
+}; // namespace android
diff --git a/libs/common_time/ICommonTimeConfig.cpp b/libs/common_time/ICommonTimeConfig.cpp
new file mode 100644
index 0000000..8eb37cb
--- /dev/null
+++ b/libs/common_time/ICommonTimeConfig.cpp
@@ -0,0 +1,508 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+#include <linux/socket.h>
+
+#include <common_time/ICommonTimeConfig.h>
+#include <binder/Parcel.h>
+
+#include "utils.h"
+
+namespace android {
+
+/***** ICommonTimeConfig *****/
+
+enum {
+ GET_MASTER_ELECTION_PRIORITY = IBinder::FIRST_CALL_TRANSACTION,
+ SET_MASTER_ELECTION_PRIORITY,
+ GET_MASTER_ELECTION_ENDPOINT,
+ SET_MASTER_ELECTION_ENDPOINT,
+ GET_MASTER_ELECTION_GROUP_ID,
+ SET_MASTER_ELECTION_GROUP_ID,
+ GET_INTERFACE_BINDING,
+ SET_INTERFACE_BINDING,
+ GET_MASTER_ANNOUNCE_INTERVAL,
+ SET_MASTER_ANNOUNCE_INTERVAL,
+ GET_CLIENT_SYNC_INTERVAL,
+ SET_CLIENT_SYNC_INTERVAL,
+ GET_PANIC_THRESHOLD,
+ SET_PANIC_THRESHOLD,
+ GET_AUTO_DISABLE,
+ SET_AUTO_DISABLE,
+ FORCE_NETWORKLESS_MASTER_MODE,
+};
+
+const String16 ICommonTimeConfig::kServiceName("common_time.config");
+
+class BpCommonTimeConfig : public BpInterface<ICommonTimeConfig>
+{
+ public:
+ BpCommonTimeConfig(const sp<IBinder>& impl)
+ : BpInterface<ICommonTimeConfig>(impl) {}
+
+ virtual status_t getMasterElectionPriority(uint8_t *priority) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
+ status_t status = remote()->transact(GET_MASTER_ELECTION_PRIORITY,
+ data,
+ &reply);
+ if (status == OK) {
+ status = reply.readInt32();
+ if (status == OK) {
+ *priority = static_cast<uint8_t>(reply.readInt32());
+ }
+ }
+
+ return status;
+ }
+
+ virtual status_t setMasterElectionPriority(uint8_t priority) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
+ data.writeInt32(static_cast<int32_t>(priority));
+ status_t status = remote()->transact(SET_MASTER_ELECTION_PRIORITY,
+ data,
+ &reply);
+ if (status == OK) {
+ status = reply.readInt32();
+ }
+
+ return status;
+ }
+
+ virtual status_t getMasterElectionEndpoint(struct sockaddr_storage *addr) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
+ status_t status = remote()->transact(GET_MASTER_ELECTION_ENDPOINT,
+ data,
+ &reply);
+ if (status == OK) {
+ status = reply.readInt32();
+ if (status == OK) {
+ deserializeSockaddr(&reply, addr);
+ }
+ }
+
+ return status;
+ }
+
+ virtual status_t setMasterElectionEndpoint(
+ const struct sockaddr_storage *addr) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
+ if (!canSerializeSockaddr(addr))
+ return BAD_VALUE;
+ if (NULL == addr) {
+ data.writeInt32(0);
+ } else {
+ data.writeInt32(1);
+ serializeSockaddr(&data, addr);
+ }
+ status_t status = remote()->transact(SET_MASTER_ELECTION_ENDPOINT,
+ data,
+ &reply);
+ if (status == OK) {
+ status = reply.readInt32();
+ }
+
+ return status;
+ }
+
+ virtual status_t getMasterElectionGroupId(uint64_t *id) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
+ status_t status = remote()->transact(GET_MASTER_ELECTION_GROUP_ID,
+ data,
+ &reply);
+
+ if (status == OK) {
+ status = reply.readInt32();
+ if (status == OK) {
+ *id = static_cast<uint64_t>(reply.readInt64());
+ }
+ }
+
+ return status;
+ }
+
+ virtual status_t setMasterElectionGroupId(uint64_t id) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
+ data.writeInt64(id);
+ status_t status = remote()->transact(SET_MASTER_ELECTION_GROUP_ID,
+ data,
+ &reply);
+
+ if (status == OK) {
+ status = reply.readInt32();
+ }
+
+ return status;
+ }
+
+ virtual status_t getInterfaceBinding(String16& ifaceName) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
+ status_t status = remote()->transact(GET_INTERFACE_BINDING,
+ data,
+ &reply);
+ if (status == OK) {
+ status = reply.readInt32();
+ if (status == OK) {
+ ifaceName = reply.readString16();
+ }
+ }
+
+ return status;
+ }
+
+ virtual status_t setInterfaceBinding(const String16& ifaceName) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
+ data.writeString16(ifaceName);
+ status_t status = remote()->transact(SET_INTERFACE_BINDING,
+ data,
+ &reply);
+ if (status == OK) {
+ status = reply.readInt32();
+ }
+
+ return status;
+ }
+
+ virtual status_t getMasterAnnounceInterval(int *interval) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
+ status_t status = remote()->transact(GET_MASTER_ANNOUNCE_INTERVAL,
+ data,
+ &reply);
+ if (status == OK) {
+ status = reply.readInt32();
+ if (status == OK) {
+ *interval = reply.readInt32();
+ }
+ }
+
+ return status;
+ }
+
+ virtual status_t setMasterAnnounceInterval(int interval) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
+ data.writeInt32(interval);
+ status_t status = remote()->transact(SET_MASTER_ANNOUNCE_INTERVAL,
+ data,
+ &reply);
+ if (status == OK) {
+ status = reply.readInt32();
+ }
+
+ return status;
+ }
+
+ virtual status_t getClientSyncInterval(int *interval) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
+ status_t status = remote()->transact(GET_CLIENT_SYNC_INTERVAL,
+ data,
+ &reply);
+ if (status == OK) {
+ status = reply.readInt32();
+ if (status == OK) {
+ *interval = reply.readInt32();
+ }
+ }
+
+ return status;
+ }
+
+ virtual status_t setClientSyncInterval(int interval) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
+ data.writeInt32(interval);
+ status_t status = remote()->transact(SET_CLIENT_SYNC_INTERVAL,
+ data,
+ &reply);
+ if (status == OK) {
+ status = reply.readInt32();
+ }
+
+ return status;
+ }
+
+ virtual status_t getPanicThreshold(int *threshold) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
+ status_t status = remote()->transact(GET_PANIC_THRESHOLD,
+ data,
+ &reply);
+ if (status == OK) {
+ status = reply.readInt32();
+ if (status == OK) {
+ *threshold = reply.readInt32();
+ }
+ }
+
+ return status;
+ }
+
+ virtual status_t setPanicThreshold(int threshold) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
+ data.writeInt32(threshold);
+ status_t status = remote()->transact(SET_PANIC_THRESHOLD,
+ data,
+ &reply);
+ if (status == OK) {
+ status = reply.readInt32();
+ }
+
+ return status;
+ }
+
+ virtual status_t getAutoDisable(bool *autoDisable) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
+ status_t status = remote()->transact(GET_AUTO_DISABLE,
+ data,
+ &reply);
+ if (status == OK) {
+ status = reply.readInt32();
+ if (status == OK) {
+ *autoDisable = (0 != reply.readInt32());
+ }
+ }
+
+ return status;
+ }
+
+ virtual status_t setAutoDisable(bool autoDisable) {
+ Parcel data, reply;
+ data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
+ data.writeInt32(autoDisable ? 1 : 0);
+ status_t status = remote()->transact(SET_AUTO_DISABLE,
+ data,
+ &reply);
+
+ if (status == OK) {
+ status = reply.readInt32();
+ }
+
+ return status;
+ }
+
+ virtual status_t forceNetworklessMasterMode() {
+ Parcel data, reply;
+ data.writeInterfaceToken(ICommonTimeConfig::getInterfaceDescriptor());
+ status_t status = remote()->transact(FORCE_NETWORKLESS_MASTER_MODE,
+ data,
+ &reply);
+
+ if (status == OK) {
+ status = reply.readInt32();
+ }
+
+ return status;
+ }
+};
+
+IMPLEMENT_META_INTERFACE(CommonTimeConfig, "android.os.ICommonTimeConfig");
+
+status_t BnCommonTimeConfig::onTransact(uint32_t code,
+ const Parcel& data,
+ Parcel* reply,
+ uint32_t flags) {
+ switch(code) {
+ case GET_MASTER_ELECTION_PRIORITY: {
+ CHECK_INTERFACE(ICommonTimeConfig, data, reply);
+ uint8_t priority;
+ status_t status = getMasterElectionPriority(&priority);
+ reply->writeInt32(status);
+ if (status == OK) {
+ reply->writeInt32(static_cast<int32_t>(priority));
+ }
+ return OK;
+ } break;
+
+ case SET_MASTER_ELECTION_PRIORITY: {
+ CHECK_INTERFACE(ICommonTimeConfig, data, reply);
+ uint8_t priority = static_cast<uint8_t>(data.readInt32());
+ status_t status = setMasterElectionPriority(priority);
+ reply->writeInt32(status);
+ return OK;
+ } break;
+
+ case GET_MASTER_ELECTION_ENDPOINT: {
+ CHECK_INTERFACE(ICommonTimeConfig, data, reply);
+ struct sockaddr_storage addr;
+ status_t status = getMasterElectionEndpoint(&addr);
+
+ if ((status == OK) && !canSerializeSockaddr(&addr)) {
+ status = UNKNOWN_ERROR;
+ }
+
+ reply->writeInt32(status);
+
+ if (status == OK) {
+ serializeSockaddr(reply, &addr);
+ }
+
+ return OK;
+ } break;
+
+ case SET_MASTER_ELECTION_ENDPOINT: {
+ CHECK_INTERFACE(ICommonTimeConfig, data, reply);
+ struct sockaddr_storage addr;
+ int hasAddr = data.readInt32();
+
+ status_t status;
+ if (hasAddr) {
+ deserializeSockaddr(&data, &addr);
+ status = setMasterElectionEndpoint(&addr);
+ } else {
+ status = setMasterElectionEndpoint(&addr);
+ }
+
+ reply->writeInt32(status);
+ return OK;
+ } break;
+
+ case GET_MASTER_ELECTION_GROUP_ID: {
+ CHECK_INTERFACE(ICommonTimeConfig, data, reply);
+ uint64_t id;
+ status_t status = getMasterElectionGroupId(&id);
+ reply->writeInt32(status);
+ if (status == OK) {
+ reply->writeInt64(id);
+ }
+ return OK;
+ } break;
+
+ case SET_MASTER_ELECTION_GROUP_ID: {
+ CHECK_INTERFACE(ICommonTimeConfig, data, reply);
+ uint64_t id = static_cast<uint64_t>(data.readInt64());
+ status_t status = setMasterElectionGroupId(id);
+ reply->writeInt32(status);
+ return OK;
+ } break;
+
+ case GET_INTERFACE_BINDING: {
+ CHECK_INTERFACE(ICommonTimeConfig, data, reply);
+ String16 ret;
+ status_t status = getInterfaceBinding(ret);
+ reply->writeInt32(status);
+ if (status == OK) {
+ reply->writeString16(ret);
+ }
+ return OK;
+ } break;
+
+ case SET_INTERFACE_BINDING: {
+ CHECK_INTERFACE(ICommonTimeConfig, data, reply);
+ String16 ifaceName;
+ ifaceName = data.readString16();
+ status_t status = setInterfaceBinding(ifaceName);
+ reply->writeInt32(status);
+ return OK;
+ } break;
+
+ case GET_MASTER_ANNOUNCE_INTERVAL: {
+ CHECK_INTERFACE(ICommonTimeConfig, data, reply);
+ int interval;
+ status_t status = getMasterAnnounceInterval(&interval);
+ reply->writeInt32(status);
+ if (status == OK) {
+ reply->writeInt32(interval);
+ }
+ return OK;
+ } break;
+
+ case SET_MASTER_ANNOUNCE_INTERVAL: {
+ CHECK_INTERFACE(ICommonTimeConfig, data, reply);
+ int interval = data.readInt32();
+ status_t status = setMasterAnnounceInterval(interval);
+ reply->writeInt32(status);
+ return OK;
+ } break;
+
+ case GET_CLIENT_SYNC_INTERVAL: {
+ CHECK_INTERFACE(ICommonTimeConfig, data, reply);
+ int interval;
+ status_t status = getClientSyncInterval(&interval);
+ reply->writeInt32(status);
+ if (status == OK) {
+ reply->writeInt32(interval);
+ }
+ return OK;
+ } break;
+
+ case SET_CLIENT_SYNC_INTERVAL: {
+ CHECK_INTERFACE(ICommonTimeConfig, data, reply);
+ int interval = data.readInt32();
+ status_t status = setClientSyncInterval(interval);
+ reply->writeInt32(status);
+ return OK;
+ } break;
+
+ case GET_PANIC_THRESHOLD: {
+ CHECK_INTERFACE(ICommonTimeConfig, data, reply);
+ int threshold;
+ status_t status = getPanicThreshold(&threshold);
+ reply->writeInt32(status);
+ if (status == OK) {
+ reply->writeInt32(threshold);
+ }
+ return OK;
+ } break;
+
+ case SET_PANIC_THRESHOLD: {
+ CHECK_INTERFACE(ICommonTimeConfig, data, reply);
+ int threshold = data.readInt32();
+ status_t status = setPanicThreshold(threshold);
+ reply->writeInt32(status);
+ return OK;
+ } break;
+
+ case GET_AUTO_DISABLE: {
+ CHECK_INTERFACE(ICommonTimeConfig, data, reply);
+ bool autoDisable;
+ status_t status = getAutoDisable(&autoDisable);
+ reply->writeInt32(status);
+ if (status == OK) {
+ reply->writeInt32(autoDisable ? 1 : 0);
+ }
+ return OK;
+ } break;
+
+ case SET_AUTO_DISABLE: {
+ CHECK_INTERFACE(ICommonTimeConfig, data, reply);
+ bool autoDisable = (0 != data.readInt32());
+ status_t status = setAutoDisable(autoDisable);
+ reply->writeInt32(status);
+ return OK;
+ } break;
+
+ case FORCE_NETWORKLESS_MASTER_MODE: {
+ CHECK_INTERFACE(ICommonTimeConfig, data, reply);
+ status_t status = forceNetworklessMasterMode();
+ reply->writeInt32(status);
+ return OK;
+ } break;
+ }
+ return BBinder::onTransact(code, data, reply, flags);
+}
+
+}; // namespace android
+
diff --git a/libs/common_time/cc_helper.cpp b/libs/common_time/cc_helper.cpp
new file mode 100644
index 0000000..8d8556c
--- /dev/null
+++ b/libs/common_time/cc_helper.cpp
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#include <stdint.h>
+
+#include <common_time/cc_helper.h>
+#include <common_time/ICommonClock.h>
+#include <utils/threads.h>
+
+namespace android {
+
+Mutex CCHelper::lock_;
+sp<ICommonClock> CCHelper::common_clock_;
+sp<ICommonClockListener> CCHelper::common_clock_listener_;
+uint32_t CCHelper::ref_count_ = 0;
+
+bool CCHelper::verifyClock_l() {
+ bool ret = false;
+
+ if (common_clock_ == NULL) {
+ common_clock_ = ICommonClock::getInstance();
+ if (common_clock_ == NULL)
+ goto bailout;
+ }
+
+ if (ref_count_ > 0) {
+ if (common_clock_listener_ == NULL) {
+ common_clock_listener_ = new CommonClockListener();
+ if (common_clock_listener_ == NULL)
+ goto bailout;
+
+ if (OK != common_clock_->registerListener(common_clock_listener_))
+ goto bailout;
+ }
+ }
+
+ ret = true;
+
+bailout:
+ if (!ret) {
+ common_clock_listener_ = NULL;
+ common_clock_ = NULL;
+ }
+ return ret;
+}
+
+CCHelper::CCHelper() {
+ Mutex::Autolock lock(&lock_);
+ ref_count_++;
+ verifyClock_l();
+}
+
+CCHelper::~CCHelper() {
+ Mutex::Autolock lock(&lock_);
+
+ assert(ref_count_ > 0);
+ ref_count_--;
+
+ // If we were the last CCHelper instance in the system, and we had
+ // previously register a listener, unregister it now so that the common time
+ // service has the chance to go into auto-disabled mode.
+ if (!ref_count_ &&
+ (common_clock_ != NULL) &&
+ (common_clock_listener_ != NULL)) {
+ common_clock_->unregisterListener(common_clock_listener_);
+ common_clock_listener_ = NULL;
+ }
+}
+
+void CCHelper::CommonClockListener::onTimelineChanged(uint64_t timelineID) {
+ // do nothing; listener is only really used as a token so the server can
+ // find out when clients die.
+}
+
+// Helper methods which attempts to make calls to the common time binder
+// service. If the first attempt fails with DEAD_OBJECT, the helpers will
+// attempt to make a connection to the service again (assuming that the process
+// hosting the service had crashed and the client proxy we are holding is dead)
+// If the second attempt fails, or no connection can be made, the we let the
+// error propagate up the stack and let the caller deal with the situation as
+// best they can.
+#define CCHELPER_METHOD(decl, call) \
+ status_t CCHelper::decl { \
+ Mutex::Autolock lock(&lock_); \
+ \
+ if (!verifyClock_l()) \
+ return DEAD_OBJECT; \
+ \
+ status_t status = common_clock_->call; \
+ if (DEAD_OBJECT == status) { \
+ if (!verifyClock_l()) \
+ return DEAD_OBJECT; \
+ status = common_clock_->call; \
+ } \
+ \
+ return status; \
+ }
+
+#define VERIFY_CLOCK()
+
+CCHELPER_METHOD(isCommonTimeValid(bool* valid, uint32_t* timelineID),
+ isCommonTimeValid(valid, timelineID))
+CCHELPER_METHOD(commonTimeToLocalTime(int64_t commonTime, int64_t* localTime),
+ commonTimeToLocalTime(commonTime, localTime))
+CCHELPER_METHOD(localTimeToCommonTime(int64_t localTime, int64_t* commonTime),
+ localTimeToCommonTime(localTime, commonTime))
+CCHELPER_METHOD(getCommonTime(int64_t* commonTime),
+ getCommonTime(commonTime))
+CCHELPER_METHOD(getCommonFreq(uint64_t* freq),
+ getCommonFreq(freq))
+CCHELPER_METHOD(getLocalTime(int64_t* localTime),
+ getLocalTime(localTime))
+CCHELPER_METHOD(getLocalFreq(uint64_t* freq),
+ getLocalFreq(freq))
+
+} // namespace android
diff --git a/libs/common_time/local_clock.cpp b/libs/common_time/local_clock.cpp
new file mode 100644
index 0000000..a7c61fc
--- /dev/null
+++ b/libs/common_time/local_clock.cpp
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#define LOG_TAG "common_time"
+#include <utils/Log.h>
+
+#include <assert.h>
+#include <stdint.h>
+
+#include <common_time/local_clock.h>
+#include <hardware/hardware.h>
+#include <hardware/local_time_hal.h>
+#include <utils/Errors.h>
+#include <utils/threads.h>
+
+namespace android {
+
+Mutex LocalClock::dev_lock_;
+local_time_hw_device_t* LocalClock::dev_ = NULL;
+
+LocalClock::LocalClock() {
+ int res;
+ const hw_module_t* mod;
+
+ AutoMutex lock(&dev_lock_);
+
+ if (dev_ != NULL)
+ return;
+
+ res = hw_get_module_by_class(LOCAL_TIME_HARDWARE_MODULE_ID, NULL, &mod);
+ if (res) {
+ ALOGE("Failed to open local time HAL module (res = %d)", res);
+ } else {
+ res = local_time_hw_device_open(mod, &dev_);
+ if (res) {
+ ALOGE("Failed to open local time HAL device (res = %d)", res);
+ dev_ = NULL;
+ }
+ }
+}
+
+bool LocalClock::initCheck() {
+ return (NULL != dev_);
+}
+
+int64_t LocalClock::getLocalTime() {
+ assert(NULL != dev_);
+ assert(NULL != dev_->get_local_time);
+
+ return dev_->get_local_time(dev_);
+}
+
+uint64_t LocalClock::getLocalFreq() {
+ assert(NULL != dev_);
+ assert(NULL != dev_->get_local_freq);
+
+ return dev_->get_local_freq(dev_);
+}
+
+status_t LocalClock::setLocalSlew(int16_t rate) {
+ assert(NULL != dev_);
+
+ if (!dev_->set_local_slew)
+ return INVALID_OPERATION;
+
+ return static_cast<status_t>(dev_->set_local_slew(dev_, rate));
+}
+
+int32_t LocalClock::getDebugLog(struct local_time_debug_event* records,
+ int max_records) {
+ assert(NULL != dev_);
+
+ if (!dev_->get_debug_log)
+ return INVALID_OPERATION;
+
+ return dev_->get_debug_log(dev_, records, max_records);
+}
+
+} // namespace android
diff --git a/libs/common_time/utils.cpp b/libs/common_time/utils.cpp
new file mode 100644
index 0000000..6539171
--- /dev/null
+++ b/libs/common_time/utils.cpp
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#include <arpa/inet.h>
+#include <linux/socket.h>
+
+#include <binder/Parcel.h>
+
+namespace android {
+
+bool canSerializeSockaddr(const struct sockaddr_storage* addr) {
+ switch (addr->ss_family) {
+ case AF_INET:
+ case AF_INET6:
+ return true;
+ default:
+ return false;
+ }
+}
+
+void serializeSockaddr(Parcel* p, const struct sockaddr_storage* addr) {
+ switch (addr->ss_family) {
+ case AF_INET: {
+ const struct sockaddr_in* s =
+ reinterpret_cast<const struct sockaddr_in*>(addr);
+ p->writeInt32(AF_INET);
+ p->writeInt32(ntohl(s->sin_addr.s_addr));
+ p->writeInt32(static_cast<int32_t>(ntohs(s->sin_port)));
+ } break;
+
+ case AF_INET6: {
+ const struct sockaddr_in6* s =
+ reinterpret_cast<const struct sockaddr_in6*>(addr);
+ const int32_t* a =
+ reinterpret_cast<const int32_t*>(s->sin6_addr.s6_addr);
+ p->writeInt32(AF_INET6);
+ p->writeInt32(ntohl(a[0]));
+ p->writeInt32(ntohl(a[1]));
+ p->writeInt32(ntohl(a[2]));
+ p->writeInt32(ntohl(a[3]));
+ p->writeInt32(static_cast<int32_t>(ntohs(s->sin6_port)));
+ p->writeInt32(ntohl(s->sin6_flowinfo));
+ p->writeInt32(ntohl(s->sin6_scope_id));
+ } break;
+ }
+}
+
+void deserializeSockaddr(const Parcel* p, struct sockaddr_storage* addr) {
+ memset(addr, 0, sizeof(addr));
+
+ addr->ss_family = p->readInt32();
+ switch(addr->ss_family) {
+ case AF_INET: {
+ struct sockaddr_in* s =
+ reinterpret_cast<struct sockaddr_in*>(addr);
+ s->sin_addr.s_addr = htonl(p->readInt32());
+ s->sin_port = htons(static_cast<uint16_t>(p->readInt32()));
+ } break;
+
+ case AF_INET6: {
+ struct sockaddr_in6* s =
+ reinterpret_cast<struct sockaddr_in6*>(addr);
+ int32_t* a = reinterpret_cast<int32_t*>(s->sin6_addr.s6_addr);
+
+ a[0] = htonl(p->readInt32());
+ a[1] = htonl(p->readInt32());
+ a[2] = htonl(p->readInt32());
+ a[3] = htonl(p->readInt32());
+ s->sin6_port = htons(static_cast<uint16_t>(p->readInt32()));
+ s->sin6_flowinfo = htonl(p->readInt32());
+ s->sin6_scope_id = htonl(p->readInt32());
+ } break;
+ }
+}
+
+} // namespace android
diff --git a/libs/common_time/utils.h b/libs/common_time/utils.h
new file mode 100644
index 0000000..ce79d0d
--- /dev/null
+++ b/libs/common_time/utils.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#ifndef ANDROID_LIBCOMMONCLOCK_UTILS_H
+#define ANDROID_LIBCOMMONCLOCK_UTILS_H
+
+#include <linux/socket.h>
+
+#include <binder/Parcel.h>
+#include <utils/Errors.h>
+
+namespace android {
+
+extern bool canSerializeSockaddr(const struct sockaddr_storage* addr);
+extern void serializeSockaddr(Parcel* p, const struct sockaddr_storage* addr);
+extern status_t deserializeSockaddr(const Parcel* p,
+ struct sockaddr_storage* addr);
+
+}; // namespace android
+
+#endif // ANDROID_LIBCOMMONCLOCK_UTILS_H
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index 1a11fbc..f9088ac 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -226,6 +226,11 @@
while (!mReader.eof()) {
int op = mReader.readInt();
+ if (op & OP_MAY_BE_SKIPPED_MASK) {
+ int skip = mReader.readInt();
+ ALOGD("%sSkip %d", (char*) indent, skip);
+ op &= ~OP_MAY_BE_SKIPPED_MASK;
+ }
switch (op) {
case DrawGLFunction: {
@@ -316,8 +321,9 @@
DisplayList* displayList = getDisplayList();
uint32_t width = getUInt();
uint32_t height = getUInt();
- ALOGD("%s%s %p, %dx%d, %d", (char*) indent, OP_NAMES[op],
- displayList, width, height, level + 1);
+ int32_t flags = getInt();
+ ALOGD("%s%s %p, %dx%d, 0x%x %d", (char*) indent, OP_NAMES[op],
+ displayList, width, height, flags, level + 1);
renderer.outputDisplayList(displayList, level + 1);
}
break;
@@ -551,7 +557,7 @@
* in the output() function, since that function processes the same list of opcodes for the
* purposes of logging display list info for a given view.
*/
-bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level) {
+bool DisplayList::replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, uint32_t level) {
bool needsInvalidate = false;
TextContainer text;
mReader.rewind();
@@ -572,6 +578,18 @@
int saveCount = renderer.getSaveCount() - 1;
while (!mReader.eof()) {
int op = mReader.readInt();
+ if (op & OP_MAY_BE_SKIPPED_MASK) {
+ int32_t skip = mReader.readInt() * 4;
+ if (CC_LIKELY(flags & kReplayFlag_ClipChildren)) {
+ mReader.skip(skip);
+ DISPLAY_LIST_LOGD("%s%s skipping %d bytes", (char*) indent,
+ OP_NAMES[op & ~OP_MAY_BE_SKIPPED_MASK], skip);
+ continue;
+ } else {
+ op &= ~OP_MAY_BE_SKIPPED_MASK;
+ ALOGD("%s", OP_NAMES[op]);
+ }
+ }
logBuffer.writeCommand(level, op);
switch (op) {
@@ -584,7 +602,7 @@
}
break;
case Save: {
- int rendererNum = getInt();
+ int32_t rendererNum = getInt();
DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, OP_NAMES[op], rendererNum);
renderer.save(rendererNum);
}
@@ -595,7 +613,7 @@
}
break;
case RestoreToCount: {
- int restoreCount = saveCount + getInt();
+ int32_t restoreCount = saveCount + getInt();
DISPLAY_LIST_LOGD("%s%s %d", (char*) indent, OP_NAMES[op], restoreCount);
renderer.restoreToCount(restoreCount);
}
@@ -606,7 +624,7 @@
float f3 = getFloat();
float f4 = getFloat();
SkPaint* paint = getPaint(renderer);
- int flags = getInt();
+ int32_t flags = getInt();
DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %p, 0x%x", (char*) indent,
OP_NAMES[op], f1, f2, f3, f4, paint, flags);
renderer.saveLayer(f1, f2, f3, f4, paint, flags);
@@ -617,8 +635,8 @@
float f2 = getFloat();
float f3 = getFloat();
float f4 = getFloat();
- int alpha = getInt();
- int flags = getInt();
+ int32_t alpha = getInt();
+ int32_t flags = getInt();
DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d, 0x%x", (char*) indent,
OP_NAMES[op], f1, f2, f3, f4, alpha, flags);
renderer.saveLayerAlpha(f1, f2, f3, f4, alpha, flags);
@@ -668,7 +686,7 @@
float f2 = getFloat();
float f3 = getFloat();
float f4 = getFloat();
- int regionOp = getInt();
+ int32_t regionOp = getInt();
DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %d", (char*) indent, OP_NAMES[op],
f1, f2, f3, f4, regionOp);
renderer.clipRect(f1, f2, f3, f4, (SkRegion::Op) regionOp);
@@ -678,10 +696,11 @@
DisplayList* displayList = getDisplayList();
uint32_t width = getUInt();
uint32_t height = getUInt();
- DISPLAY_LIST_LOGD("%s%s %p, %dx%d, %d", (char*) indent, OP_NAMES[op],
- displayList, width, height, level + 1);
+ int32_t flags = getInt();
+ DISPLAY_LIST_LOGD("%s%s %p, %dx%d, 0x%x %d", (char*) indent, OP_NAMES[op],
+ displayList, width, height, flags, level + 1);
needsInvalidate |= renderer.drawDisplayList(displayList, width, height,
- dirty, level + 1);
+ dirty, flags, level + 1);
}
break;
case DrawLayer: {
@@ -730,7 +749,7 @@
}
break;
case DrawBitmapMesh: {
- int verticesCount = 0;
+ int32_t verticesCount = 0;
uint32_t colorsCount = 0;
SkBitmap* bitmap = getBitmap();
@@ -738,7 +757,7 @@
uint32_t meshHeight = getInt();
float* vertices = getFloats(verticesCount);
bool hasColors = getInt();
- int* colors = hasColors ? getInts(colorsCount) : NULL;
+ int32_t* colors = hasColors ? getInts(colorsCount) : NULL;
SkPaint* paint = getPaint(renderer);
DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
@@ -771,8 +790,8 @@
}
break;
case DrawColor: {
- int color = getInt();
- int xferMode = getInt();
+ int32_t color = getInt();
+ int32_t xferMode = getInt();
DISPLAY_LIST_LOGD("%s%s 0x%x %d", (char*) indent, OP_NAMES[op], color, xferMode);
renderer.drawColor(color, (SkXfermode::Mode) xferMode);
}
@@ -829,7 +848,7 @@
float f4 = getFloat();
float f5 = getFloat();
float f6 = getFloat();
- int i1 = getInt();
+ int32_t i1 = getInt();
SkPaint* paint = getPaint(renderer);
DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %d, %p",
(char*) indent, OP_NAMES[op], f1, f2, f3, f4, f5, f6, i1, paint);
@@ -844,7 +863,7 @@
}
break;
case DrawLines: {
- int count = 0;
+ int32_t count = 0;
float* points = getFloats(count);
SkPaint* paint = getPaint(renderer);
DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
@@ -852,7 +871,7 @@
}
break;
case DrawPoints: {
- int count = 0;
+ int32_t count = 0;
float* points = getFloats(count);
SkPaint* paint = getPaint(renderer);
DISPLAY_LIST_LOGD("%s%s", (char*) indent, OP_NAMES[op]);
@@ -861,7 +880,7 @@
break;
case DrawText: {
getText(&text);
- int count = getInt();
+ int32_t count = getInt();
float x = getFloat();
float y = getFloat();
SkPaint* paint = getPaint(renderer);
@@ -873,8 +892,8 @@
break;
case DrawPosText: {
getText(&text);
- int count = getInt();
- int positionsCount = 0;
+ int32_t count = getInt();
+ int32_t positionsCount = 0;
float* positions = getFloats(positionsCount);
SkPaint* paint = getPaint(renderer);
DISPLAY_LIST_LOGD("%s%s %s, %d, %d, %p", (char*) indent,
@@ -913,7 +932,7 @@
float radius = getFloat();
float dx = getFloat();
float dy = getFloat();
- int color = getInt();
+ int32_t color = getInt();
DISPLAY_LIST_LOGD("%s%s %.2f, %.2f, %.2f, 0x%x", (char*) indent, OP_NAMES[op],
radius, dx, dy, color);
renderer.setupShadow(radius, dx, dy, color);
@@ -925,8 +944,8 @@
}
break;
case SetupPaintFilter: {
- int clearBits = getInt();
- int setBits = getInt();
+ int32_t clearBits = getInt();
+ int32_t setBits = getInt();
DISPLAY_LIST_LOGD("%s%s 0x%x, 0x%x", (char*) indent, OP_NAMES[op],
clearBits, setBits);
renderer.setupPaintFilter(clearBits, setBits);
@@ -949,7 +968,8 @@
// Base structure
///////////////////////////////////////////////////////////////////////////////
-DisplayListRenderer::DisplayListRenderer(): mWriter(MIN_WRITER_SIZE), mHasDrawOps(false) {
+DisplayListRenderer::DisplayListRenderer(): mWriter(MIN_WRITER_SIZE),
+ mTranslateX(0.0f), mTranslateY(0.0f), mHasTranslate(false), mHasDrawOps(false) {
}
DisplayListRenderer::~DisplayListRenderer() {
@@ -1019,6 +1039,7 @@
void DisplayListRenderer::finish() {
insertRestoreToCount();
+ insertTranlate();
OpenGLRenderer::finish();
}
@@ -1043,15 +1064,18 @@
void DisplayListRenderer::restore() {
if (mRestoreSaveCount < 0) {
- addOp(DisplayList::Restore);
- } else {
- mRestoreSaveCount--;
+ restoreToCount(getSaveCount() - 1);
+ return;
}
+
+ mRestoreSaveCount--;
+ insertTranlate();
OpenGLRenderer::restore();
}
void DisplayListRenderer::restoreToCount(int saveCount) {
mRestoreSaveCount = saveCount;
+ insertTranlate();
OpenGLRenderer::restoreToCount(saveCount);
}
@@ -1074,8 +1098,10 @@
}
void DisplayListRenderer::translate(float dx, float dy) {
- addOp(DisplayList::Translate);
- addPoint(dx, dy);
+ mHasTranslate = true;
+ mTranslateX += dx;
+ mTranslateY += dy;
+ insertRestoreToCount();
OpenGLRenderer::translate(dx, dy);
}
@@ -1118,12 +1144,15 @@
}
bool DisplayListRenderer::drawDisplayList(DisplayList* displayList,
- uint32_t width, uint32_t height, Rect& dirty, uint32_t level) {
+ uint32_t width, uint32_t height, Rect& dirty, int32_t flags, uint32_t level) {
// dirty is an out parameter and should not be recorded,
// it matters only when replaying the display list
- addOp(DisplayList::DrawDisplayList);
+ const bool reject = quickReject(0.0f, 0.0f, width, height);
+ uint32_t* location = addOp(DisplayList::DrawDisplayList, reject);
addDisplayList(displayList);
addSize(width, height);
+ addInt(flags);
+ addSkip(location);
return false;
}
@@ -1134,30 +1163,38 @@
addPaint(paint);
}
-void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top,
- SkPaint* paint) {
- addOp(DisplayList::DrawBitmap);
+void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint) {
+ const bool reject = quickReject(left, top, left + bitmap->width(), top + bitmap->height());
+ uint32_t* location = addOp(DisplayList::DrawBitmap, reject);
addBitmap(bitmap);
addPoint(left, top);
addPaint(paint);
+ addSkip(location);
}
-void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix,
- SkPaint* paint) {
- addOp(DisplayList::DrawBitmapMatrix);
+void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint) {
+ Rect r(0.0f, 0.0f, bitmap->width(), bitmap->height());
+ const mat4 transform(*matrix);
+ transform.mapRect(r);
+
+ const bool reject = quickReject(r.left, r.top, r.right, r.bottom);
+ uint32_t* location = addOp(DisplayList::DrawBitmapMatrix, reject);
addBitmap(bitmap);
addMatrix(matrix);
addPaint(paint);
+ addSkip(location);
}
void DisplayListRenderer::drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
float srcRight, float srcBottom, float dstLeft, float dstTop,
float dstRight, float dstBottom, SkPaint* paint) {
- addOp(DisplayList::DrawBitmapRect);
+ const bool reject = quickReject(dstLeft, dstTop, dstRight, dstBottom);
+ uint32_t* location = addOp(DisplayList::DrawBitmapRect, reject);
addBitmap(bitmap);
addBounds(srcLeft, srcTop, srcRight, srcBottom);
addBounds(dstLeft, dstTop, dstRight, dstBottom);
addPaint(paint);
+ addSkip(location);
}
void DisplayListRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
@@ -1179,13 +1216,15 @@
void DisplayListRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
float left, float top, float right, float bottom, SkPaint* paint) {
- addOp(DisplayList::DrawPatch);
+ const bool reject = quickReject(left, top, right, bottom);
+ uint32_t* location = addOp(DisplayList::DrawPatch, reject);
addBitmap(bitmap);
addInts(xDivs, width);
addInts(yDivs, height);
addUInts(colors, numColors);
addBounds(left, top, right, bottom);
addPaint(paint);
+ addSkip(location);
}
void DisplayListRenderer::drawColor(int color, SkXfermode::Mode mode) {
@@ -1196,17 +1235,23 @@
void DisplayListRenderer::drawRect(float left, float top, float right, float bottom,
SkPaint* paint) {
- addOp(DisplayList::DrawRect);
+ const bool reject = paint->getStyle() == SkPaint::kFill_Style &&
+ quickReject(left, top, right, bottom);
+ uint32_t* location = addOp(DisplayList::DrawRect, reject);
addBounds(left, top, right, bottom);
addPaint(paint);
+ addSkip(location);
}
void DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom,
float rx, float ry, SkPaint* paint) {
- addOp(DisplayList::DrawRoundRect);
+ const bool reject = paint->getStyle() == SkPaint::kFill_Style &&
+ quickReject(left, top, right, bottom);
+ uint32_t* location = addOp(DisplayList::DrawRoundRect, reject);
addBounds(left, top, right, bottom);
addPoint(rx, ry);
addPaint(paint);
+ addSkip(location);
}
void DisplayListRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) {
@@ -1233,9 +1278,15 @@
}
void DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) {
- addOp(DisplayList::DrawPath);
+ float left, top, offset;
+ uint32_t width, height;
+ computePathBounds(path, paint, left, top, offset, width, height);
+
+ const bool reject = quickReject(left - offset, top - offset, width, height);
+ uint32_t* location = addOp(DisplayList::DrawPath, reject);
addPath(path);
addPaint(paint);
+ addSkip(location);
}
void DisplayListRenderer::drawLines(float* points, int count, SkPaint* paint) {
@@ -1252,11 +1303,8 @@
void DisplayListRenderer::drawText(const char* text, int bytesCount, int count,
float x, float y, SkPaint* paint, float length) {
- if (count <= 0) return;
- addOp(DisplayList::DrawText);
- addText(text, bytesCount);
- addInt(count);
- addPoint(x, y);
+ if (!text || count <= 0) return;
+
// TODO: We should probably make a copy of the paint instead of modifying
// it; modifying the paint will change its generationID the first
// time, which might impact caches. More investigation needed to
@@ -1265,13 +1313,27 @@
// its own copy as it does right now.
// Beware: this needs Glyph encoding (already done on the Paint constructor)
paint->setAntiAlias(true);
+ if (length < 0.0f) length = paint->measureText(text, bytesCount);
+
+ bool reject = false;
+ if (CC_LIKELY(paint->getTextAlign() == SkPaint::kLeft_Align)) {
+ SkPaint::FontMetrics metrics;
+ paint->getFontMetrics(&metrics, 0.0f);
+ reject = quickReject(x, y + metrics.fTop, x + length, y + metrics.fBottom);
+ }
+
+ uint32_t* location = addOp(DisplayList::DrawText, reject);
+ addText(text, bytesCount);
+ addInt(count);
+ addPoint(x, y);
addPaint(paint);
- addFloat(length < 0.0f ? paint->measureText(text, bytesCount) : length);
+ addFloat(length);
+ addSkip(location);
}
void DisplayListRenderer::drawPosText(const char* text, int bytesCount, int count,
const float* positions, SkPaint* paint) {
- if (count <= 0) return;
+ if (!text || count <= 0) return;
addOp(DisplayList::DrawPosText);
addText(text, bytesCount);
addInt(count);
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 46506e4..90a7145 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -42,6 +42,7 @@
///////////////////////////////////////////////////////////////////////////////
#define MIN_WRITER_SIZE 4096
+#define OP_MAY_BE_SKIPPED_MASK 0xff000000
// Debug
#if DEBUG_DISPLAY_LIST
@@ -110,13 +111,18 @@
DrawGLFunction,
};
+ // See flags defined in DisplayList.java
+ enum ReplayFlag {
+ kReplayFlag_ClipChildren = 0x1
+ };
+
static const char* OP_NAMES[];
void initFromDisplayListRenderer(const DisplayListRenderer& recorder, bool reusing = false);
ANDROID_API size_t getSize();
- bool replay(OpenGLRenderer& renderer, Rect& dirty, uint32_t level = 0);
+ bool replay(OpenGLRenderer& renderer, Rect& dirty, int32_t flags, uint32_t level = 0);
void output(OpenGLRenderer& renderer, uint32_t level = 0);
@@ -167,11 +173,11 @@
return (SkiaColorFilter*) getInt();
}
- inline int getIndex() {
+ inline int32_t getIndex() {
return mReader.readInt();
}
- inline int getInt() {
+ inline int32_t getInt() {
return mReader.readInt();
}
@@ -209,7 +215,7 @@
return (uint32_t*) mReader.skip(count * sizeof(uint32_t));
}
- float* getFloats(int& count) {
+ float* getFloats(int32_t& count) {
count = getInt();
return (float*) mReader.skip(count * sizeof(float));
}
@@ -279,7 +285,7 @@
virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
virtual bool drawDisplayList(DisplayList* displayList, uint32_t width, uint32_t height,
- Rect& dirty, uint32_t level = 0);
+ Rect& dirty, int32_t flags, uint32_t level = 0);
virtual void drawLayer(Layer* layer, float x, float y, SkPaint* paint);
virtual void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
virtual void drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* paint);
@@ -358,13 +364,45 @@
}
}
- inline void addOp(DisplayList::Op drawOp) {
+ void insertTranlate() {
+ if (mHasTranslate) {
+ if (mTranslateX != 0.0f || mTranslateY != 0.0f) {
+ mWriter.writeInt(DisplayList::Translate);
+ addPoint(mTranslateX, mTranslateY);
+ mTranslateX = mTranslateY = 0.0f;
+ }
+ mHasTranslate = false;
+ }
+ }
+
+ inline void addOp(const DisplayList::Op drawOp) {
insertRestoreToCount();
+ insertTranlate();
mWriter.writeInt(drawOp);
mHasDrawOps = mHasDrawOps || drawOp >= DisplayList::DrawDisplayList;
}
- inline void addInt(int value) {
+ uint32_t* addOp(const DisplayList::Op drawOp, const bool reject) {
+ insertRestoreToCount();
+ insertTranlate();
+ mHasDrawOps = mHasDrawOps || drawOp >= DisplayList::DrawDisplayList;
+ if (reject) {
+ mWriter.writeInt(OP_MAY_BE_SKIPPED_MASK | drawOp);
+ mWriter.writeInt(0);
+ uint32_t* location = reject ? mWriter.peek32(mWriter.size() - 4) : NULL;
+ return location;
+ }
+ mWriter.writeInt(drawOp);
+ return NULL;
+ }
+
+ inline void addSkip(uint32_t* location) {
+ if (location) {
+ *location = (int32_t) (mWriter.peek32(mWriter.size() - 4) - location);
+ }
+ }
+
+ inline void addInt(int32_t value) {
mWriter.writeInt(value);
}
@@ -391,9 +429,9 @@
mWriter.writeScalar(value);
}
- void addFloats(const float* values, int count) {
+ void addFloats(const float* values, int32_t count) {
mWriter.writeInt(count);
- for (int i = 0; i < count; i++) {
+ for (int32_t i = 0; i < count; i++) {
mWriter.writeScalar(values[i]);
}
}
@@ -424,7 +462,8 @@
SkPath* pathCopy = mPathMap.valueFor(path);
if (pathCopy == NULL || pathCopy->getGenerationID() != path->getGenerationID()) {
pathCopy = new SkPath(*path);
- mPathMap.add(path, pathCopy);
+ // replaceValueFor() performs an add if the entry doesn't exist
+ mPathMap.replaceValueFor(path, pathCopy);
mPaths.add(pathCopy);
}
@@ -440,7 +479,8 @@
SkPaint* paintCopy = mPaintMap.valueFor(paint);
if (paintCopy == NULL || paintCopy->getGenerationID() != paint->getGenerationID()) {
paintCopy = new SkPaint(*paint);
- mPaintMap.add(paint, paintCopy);
+ // replaceValueFor() performs an add if the entry doesn't exist
+ mPaintMap.replaceValueFor(paint, paintCopy);
mPaints.add(paintCopy);
}
@@ -482,7 +522,8 @@
// TODO: We also need to handle generation ID changes in compose shaders
if (shaderCopy == NULL || shaderCopy->getGenerationId() != shader->getGenerationId()) {
shaderCopy = shader->copy();
- mShaderMap.add(shader, shaderCopy);
+ // replaceValueFor() performs an add if the entry doesn't exist
+ mShaderMap.replaceValueFor(shader, shaderCopy);
mShaders.add(shaderCopy);
Caches::getInstance().resourceCache.incrementRefcount(shaderCopy);
}
@@ -513,6 +554,11 @@
SkWriter32 mWriter;
int mRestoreSaveCount;
+
+ float mTranslateX;
+ float mTranslateY;
+ bool mHasTranslate;
+
bool mHasDrawOps;
friend class DisplayList;
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index afae70f..55e2ca5 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -1321,7 +1321,7 @@
///////////////////////////////////////////////////////////////////////////////
bool OpenGLRenderer::drawDisplayList(DisplayList* displayList, uint32_t width, uint32_t height,
- Rect& dirty, uint32_t level) {
+ Rect& dirty, int32_t flags, uint32_t level) {
if (quickReject(0.0f, 0.0f, width, height)) {
return false;
}
@@ -1329,7 +1329,7 @@
// All the usual checks and setup operations (quickReject, setupDraw, etc.)
// will be performed by the display list itself
if (displayList && displayList->isRenderable()) {
- return displayList->replay(*this, dirty, level);
+ return displayList->replay(*this, dirty, flags, level);
}
return false;
@@ -2189,8 +2189,7 @@
SkPaint::FontMetrics metrics;
paint->getFontMetrics(&metrics, 0.0f);
// If no length was specified, just perform the hit test on the Y axis
- if (quickReject(x, y + metrics.fTop,
- x + (length >= 0.0f ? length : INT_MAX / 2), y + metrics.fBottom)) {
+ if (quickReject(x, y + metrics.fTop, x + length, y + metrics.fBottom)) {
return;
}
@@ -2298,6 +2297,7 @@
mCaches.activeTexture(0);
+ // TODO: Perform early clip test before we rasterize the path
const PathTexture* texture = mCaches.pathCache.get(path, paint);
if (!texture) return;
const AutoTexture autoCleanup(texture);
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 3c2d09e..3f63c3fe 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -98,7 +98,7 @@
virtual bool clipRect(float left, float top, float right, float bottom, SkRegion::Op op);
virtual bool drawDisplayList(DisplayList* displayList, uint32_t width, uint32_t height,
- Rect& dirty, uint32_t level = 0);
+ Rect& dirty, int32_t flags, uint32_t level = 0);
virtual void outputDisplayList(DisplayList* displayList, uint32_t level = 0);
virtual void drawLayer(Layer* layer, float x, float y, SkPaint* paint);
virtual void drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint* paint);
diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp
index e893f7a..e09c243 100644
--- a/libs/hwui/PathCache.cpp
+++ b/libs/hwui/PathCache.cpp
@@ -24,6 +24,23 @@
namespace android {
namespace uirenderer {
+// Defined in ShapeCache.h
+void computePathBounds(const SkPath *path, const SkPaint* paint,
+ float& left, float& top, float& offset, uint32_t& width, uint32_t& height) {
+ const SkRect& bounds = path->getBounds();
+
+ const float pathWidth = fmax(bounds.width(), 1.0f);
+ const float pathHeight = fmax(bounds.height(), 1.0f);
+
+ left = bounds.fLeft;
+ top = bounds.fTop;
+
+ offset = (int) floorf(fmax(paint->getStrokeWidth(), 1.0f) * 1.5f + 0.5f);
+
+ width = uint32_t(pathWidth + offset * 2.0 + 0.5);
+ height = uint32_t(pathHeight + offset * 2.0 + 0.5);
+}
+
///////////////////////////////////////////////////////////////////////////////
// Path cache
///////////////////////////////////////////////////////////////////////////////
@@ -69,6 +86,9 @@
PathCacheEntry entry(path, paint);
PathTexture* texture = mCache.get(entry);
+ float left, top, offset;
+ uint32_t width, height;
+
if (!texture) {
texture = addTexture(entry, path, paint);
} else if (path->getGenerationID() != texture->generation) {
diff --git a/libs/hwui/ShapeCache.h b/libs/hwui/ShapeCache.h
index 30ce690..f180e94 100644
--- a/libs/hwui/ShapeCache.h
+++ b/libs/hwui/ShapeCache.h
@@ -489,18 +489,16 @@
}
}
+void computePathBounds(const SkPath *path, const SkPaint* paint,
+ float& left, float& top, float& offset, uint32_t& width, uint32_t& height);
+
template<class Entry>
PathTexture* ShapeCache<Entry>::addTexture(const Entry& entry, const SkPath *path,
const SkPaint* paint) {
- const SkRect& bounds = path->getBounds();
- const float pathWidth = fmax(bounds.width(), 1.0f);
- const float pathHeight = fmax(bounds.height(), 1.0f);
-
- const float offset = (int) floorf(fmax(paint->getStrokeWidth(), 1.0f) * 1.5f + 0.5f);
-
- const uint32_t width = uint32_t(pathWidth + offset * 2.0 + 0.5);
- const uint32_t height = uint32_t(pathHeight + offset * 2.0 + 0.5);
+ float left, top, offset;
+ uint32_t width, height;
+ computePathBounds(path, paint, left, top, offset, width, height);
if (width > mMaxTextureSize || height > mMaxTextureSize) {
ALOGW("Shape %s too large to be rendered into a texture (%dx%d, max=%dx%d)",
@@ -517,8 +515,8 @@
}
PathTexture* texture = new PathTexture;
- texture->left = bounds.fLeft;
- texture->top = bounds.fTop;
+ texture->left = left;
+ texture->top = top;
texture->offset = offset;
texture->width = width;
texture->height = height;
@@ -542,7 +540,7 @@
SkSafeUnref(pathPaint.setXfermode(mode));
SkCanvas canvas(bitmap);
- canvas.translate(-bounds.fLeft + offset, -bounds.fTop + offset);
+ canvas.translate(-left + offset, -top + offset);
canvas.drawPath(*path, pathPaint);
generateTexture(bitmap, texture);
diff --git a/libs/rs/RenderScript.h b/libs/rs/rs.h
similarity index 98%
rename from libs/rs/RenderScript.h
rename to libs/rs/rs.h
index 6d54268..fbcaf4a 100644
--- a/libs/rs/RenderScript.h
+++ b/libs/rs/rs.h
@@ -24,7 +24,7 @@
extern "C" {
#endif
-#include "RenderScriptDefines.h"
+#include "rsDefines.h"
//
// A3D loading and object update code.
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index adaefc6..95ac76e 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -263,6 +263,10 @@
rsc->timerSet(RS_TIMER_IDLE);
#ifndef ANDROID_RS_SERIALIZE
+ if (!rsc->mRootScript.get() || !rsc->mHasSurface || rsc->mPaused) {
+ targetRate = 0;
+ }
+
if (vsyncRate != targetRate) {
displayEvent.setVsyncRate(targetRate);
vsyncRate = targetRate;
diff --git a/libs/rs/RenderScriptDefines.h b/libs/rs/rsDefines.h
similarity index 100%
rename from libs/rs/RenderScriptDefines.h
rename to libs/rs/rsDefines.h
diff --git a/libs/rs/RenderScriptEnv.h b/libs/rs/rsEnv.h
similarity index 100%
rename from libs/rs/RenderScriptEnv.h
rename to libs/rs/rsEnv.h
diff --git a/libs/rs/rsFileA3D.h b/libs/rs/rsFileA3D.h
index 056b5af..baf81de5 100644
--- a/libs/rs/rsFileA3D.h
+++ b/libs/rs/rsFileA3D.h
@@ -17,11 +17,11 @@
#ifndef ANDROID_RS_FILE_A3D_H
#define ANDROID_RS_FILE_A3D_H
-#include "RenderScript.h"
+#include "rs.h"
#include "rsMesh.h"
+#include <androidfw/Asset.h>
#include <utils/String8.h>
-#include <utils/Asset.h>
#include "rsStream.h"
#include <stdio.h>
diff --git a/libs/rs/rsFont.h b/libs/rs/rsFont.h
index 4ca794d..88c4795 100644
--- a/libs/rs/rsFont.h
+++ b/libs/rs/rsFont.h
@@ -17,7 +17,7 @@
#ifndef ANDROID_RS_FONT_H
#define ANDROID_RS_FONT_H
-#include "RenderScript.h"
+#include "rs.h"
#include "rsStream.h"
#include <utils/String8.h>
#include <utils/Vector.h>
diff --git a/libs/rs/rsMesh.h b/libs/rs/rsMesh.h
index 166b5d3..8eea427 100644
--- a/libs/rs/rsMesh.h
+++ b/libs/rs/rsMesh.h
@@ -18,7 +18,7 @@
#define ANDROID_RS_MESH_H
-#include "RenderScript.h"
+#include "rs.h"
// ---------------------------------------------------------------------------
namespace android {
diff --git a/libs/rs/rsPath.h b/libs/rs/rsPath.h
index dac795e..7c05503 100644
--- a/libs/rs/rsPath.h
+++ b/libs/rs/rsPath.h
@@ -18,7 +18,7 @@
#define ANDROID_RS_PATH_H
-#include "RenderScript.h"
+#include "rs.h"
// ---------------------------------------------------------------------------
namespace android {
diff --git a/libs/rs/rsSampler.h b/libs/rs/rsSampler.h
index 654cd9c..013e4ca 100644
--- a/libs/rs/rsSampler.h
+++ b/libs/rs/rsSampler.h
@@ -18,7 +18,7 @@
#define ANDROID_RS_SAMPLER_H
#include "rsAllocation.h"
-#include "RenderScript.h"
+#include "rs.h"
// ---------------------------------------------------------------------------
namespace android {
diff --git a/libs/rs/rsScriptC.h b/libs/rs/rsScriptC.h
index c65a5bf..fc4df51 100644
--- a/libs/rs/rsScriptC.h
+++ b/libs/rs/rsScriptC.h
@@ -19,7 +19,7 @@
#include "rsScript.h"
-#include "RenderScriptEnv.h"
+#include "rsEnv.h"
#ifndef ANDROID_RS_SERIALIZE
#include "bcinfo/BitcodeTranslator.h"
diff --git a/libs/rs/rsThreadIO.cpp b/libs/rs/rsThreadIO.cpp
index 4f30573..7182f53 100644
--- a/libs/rs/rsThreadIO.cpp
+++ b/libs/rs/rsThreadIO.cpp
@@ -31,6 +31,8 @@
ThreadIO::ThreadIO() {
mRunning = true;
+ mPureFifo = false;
+ mMaxInlineSize = 1024;
}
ThreadIO::~ThreadIO() {
@@ -65,6 +67,16 @@
mToClient.shutdown();
}
+void ThreadIO::coreWrite(const void *data, size_t len) {
+ //ALOGV("core write %p %i", data, (int)len);
+ mToCore.writeAsync(data, len, true);
+}
+
+void ThreadIO::coreRead(void *data, size_t len) {
+ //ALOGV("core read %p %i", data, (int)len);
+ mToCore.read(data, len);
+}
+
void ThreadIO::coreSetReturn(const void *data, size_t dataLen) {
uint32_t buf;
if (data == NULL) {
@@ -91,6 +103,7 @@
bool ThreadIO::playCoreCommands(Context *con, int waitFd) {
bool ret = false;
+ const bool isLocal = !isPureFifo();
uint8_t buf[2 * 1024];
const CoreCmdHeader *cmd = (const CoreCmdHeader *)&buf[0];
@@ -120,14 +133,19 @@
}
if (p[0].revents) {
- size_t r = mToCore.read(&buf[0], sizeof(CoreCmdHeader));
- mToCore.read(&buf[sizeof(CoreCmdHeader)], cmd->bytes);
-
- if (r != sizeof(CoreCmdHeader)) {
- // exception or timeout occurred.
- break;
+ size_t r = 0;
+ if (isLocal) {
+ r = mToCore.read(&buf[0], sizeof(CoreCmdHeader));
+ mToCore.read(&buf[sizeof(CoreCmdHeader)], cmd->bytes);
+ if (r != sizeof(CoreCmdHeader)) {
+ // exception or timeout occurred.
+ break;
+ }
+ } else {
+ r = mToCore.read((void *)&cmd->cmdID, sizeof(cmd->cmdID));
}
+
ret = true;
if (con->props.mLogTimes) {
con->timerSet(Context::RS_TIMER_INTERNAL);
@@ -138,7 +156,12 @@
rsAssert(cmd->cmdID < (sizeof(gPlaybackFuncs) / sizeof(void *)));
ALOGE("playCoreCommands error con %p, cmd %i", con, cmd->cmdID);
}
- gPlaybackFuncs[cmd->cmdID](con, data, cmd->bytes);
+
+ if (isLocal) {
+ gPlaybackFuncs[cmd->cmdID](con, data, cmd->bytes);
+ } else {
+ gPlaybackRemoteFuncs[cmd->cmdID](con, this);
+ }
if (con->props.mLogTimes) {
con->timerSet(Context::RS_TIMER_IDLE);
diff --git a/libs/rs/rsThreadIO.h b/libs/rs/rsThreadIO.h
index 62e3e33..cb7d4ab 100644
--- a/libs/rs/rsThreadIO.h
+++ b/libs/rs/rsThreadIO.h
@@ -34,6 +34,13 @@
void init();
void shutdown();
+ size_t getMaxInlineSize() {
+ return mMaxInlineSize;
+ }
+ bool isPureFifo() {
+ return mPureFifo;
+ }
+
// Plays back commands from the client.
// Returns true if any commands were processed.
bool playCoreCommands(Context *con, int waitFd);
@@ -42,8 +49,16 @@
void * coreHeader(uint32_t, size_t dataLen);
void coreCommit();
+
void coreSetReturn(const void *data, size_t dataLen);
void coreGetReturn(void *data, size_t dataLen);
+ void coreWrite(const void *data, size_t len);
+ void coreRead(void *data, size_t len);
+
+ void asyncSetReturn(const void *data, size_t dataLen);
+ void asyncGetReturn(void *data, size_t dataLen);
+ void asyncWrite(const void *data, size_t len);
+ void asyncRead(void *data, size_t len);
RsMessageToClientType getClientHeader(size_t *receiveLen, uint32_t *usrID);
@@ -65,6 +80,8 @@
ClientCmdHeader mLastClientHeader;
bool mRunning;
+ bool mPureFifo;
+ size_t mMaxInlineSize;
FifoSocket mToClient;
FifoSocket mToCore;
diff --git a/libs/rs/rsUtils.h b/libs/rs/rsUtils.h
index db6f5920..a9a992a 100644
--- a/libs/rs/rsUtils.h
+++ b/libs/rs/rsUtils.h
@@ -34,7 +34,7 @@
#include <math.h>
-#include "RenderScript.h"
+#include "rs.h"
namespace android {
namespace renderscript {
diff --git a/libs/rs/rs_hal.h b/libs/rs/rs_hal.h
index 1201128..e4bf17f 100644
--- a/libs/rs/rs_hal.h
+++ b/libs/rs/rs_hal.h
@@ -17,7 +17,7 @@
#ifndef RS_HAL_H
#define RS_HAL_H
-#include <RenderScriptDefines.h>
+#include <rsDefines.h>
struct ANativeWindow;
diff --git a/libs/rs/rsg_generator.c b/libs/rs/rsg_generator.c
index 385c8b5..99c305e 100644
--- a/libs/rs/rsg_generator.c
+++ b/libs/rs/rsg_generator.c
@@ -238,7 +238,7 @@
//fprintf(f, " ALOGE(\"add command %s\\n\");\n", api->name);
if (hasInlineDataPointers(api)) {
fprintf(f, " RS_CMD_%s *cmd = NULL;\n", api->name);
- fprintf(f, " if (dataSize < 1024) {;\n");
+ fprintf(f, " if (dataSize < io->getMaxInlineSize()) {;\n");
fprintf(f, " cmd = static_cast<RS_CMD_%s *>(io->coreHeader(RS_CMD_ID_%s, dataSize + size));\n", api->name, api->name);
fprintf(f, " } else {\n");
fprintf(f, " cmd = static_cast<RS_CMD_%s *>(io->coreHeader(RS_CMD_ID_%s, size));\n", api->name, api->name);
@@ -252,7 +252,7 @@
const VarType *vt = &api->params[ct2];
needFlush += vt->ptrLevel;
if (vt->ptrLevel && hasInlineDataPointers(api)) {
- fprintf(f, " if (dataSize < 1024) {\n");
+ fprintf(f, " if (dataSize < io->getMaxInlineSize()) {\n");
fprintf(f, " memcpy(payload, %s, %s_length);\n", vt->name, vt->name);
fprintf(f, " cmd->%s = (", vt->name);
printVarType(f, vt);
@@ -272,7 +272,7 @@
fprintf(f, " io->coreCommit();\n");
if (hasInlineDataPointers(api)) {
- fprintf(f, " if (dataSize >= 1024) {\n");
+ fprintf(f, " if (dataSize >= io->getMaxInlineSize()) {\n");
fprintf(f, " io->coreGetReturn(NULL, 0);\n");
fprintf(f, " }\n");
} else if (api->ret.typeName[0]) {
@@ -288,81 +288,71 @@
fprintf(f, "};\n\n");
+ // Generate a remote sender function
+ const char * str = "core";
+ if (api->direct) {
+ str = "async";
+ }
+
fprintf(f, "static ");
printFuncDecl(f, api, "RF_", 0, 0);
fprintf(f, "\n{\n");
- fprintf(f, " Fifo *f = NULL;\n");
- fprintf(f, " RS_CMD_%s cmd;\n", api->name);
- fprintf(f, " const uint32_t cmdSize = sizeof(cmd);\n");
+ fprintf(f, " ThreadIO *io = &((Context *)rsc)->mIO;\n");
fprintf(f, " const uint32_t cmdID = RS_CMD_ID_%s;\n", api->name);
- fprintf(f, " f->writeAsync(&cmdID, sizeof(cmdID));\n");
- fprintf(f, " intptr_t offset = cmdSize;\n");
- fprintf(f, " uint32_t dataSize = 0;\n");
+ fprintf(f, " io->%sWrite(&cmdID, sizeof(cmdID));\n\n", str);
+
for (ct2=0; ct2 < api->paramCount; ct2++) {
const VarType *vt = &api->params[ct2];
- if (vt->isConst && vt->ptrLevel) {
- switch(vt->ptrLevel) {
- case 1:
- fprintf(f, " dataSize += %s_length;\n", vt->name);
- break;
- case 2:
- fprintf(f, " for (size_t ct = 0; ct < (%s_length_length / sizeof(%s_length)); ct++) {\n", vt->name, vt->name);
- fprintf(f, " dataSize += %s_length[ct];\n", vt->name);
- fprintf(f, " }\n");
- break;
- default:
- printf("pointer level not handled!!");
- }
+ if (vt->ptrLevel == 0) {
+ fprintf(f, " io->%sWrite(& %s, sizeof(%s));\n", str, vt->name, vt->name);
}
}
fprintf(f, "\n");
for (ct2=0; ct2 < api->paramCount; ct2++) {
const VarType *vt = &api->params[ct2];
- switch(vt->ptrLevel) {
- case 0:
- fprintf(f, " cmd.%s = %s;\n", vt->name, vt->name);
- break;
- case 1:
- fprintf(f, " cmd.%s = (", vt->name);
- printVarType(f, vt);
- fprintf(f, ")offset;\n");
- fprintf(f, " offset += %s_length;\n", vt->name);
- break;
- case 2:
- fprintf(f, " cmd.%s = (", vt->name);
- printVarType(f, vt);
- fprintf(f, ")offset;\n");
- fprintf(f, " for (size_t ct = 0; ct < (%s_length_length / sizeof(%s_length)); ct++) {\n", vt->name, vt->name);
- fprintf(f, " offset += %s_length[ct];\n", vt->name);
- fprintf(f, " }\n");
- break;
- default:
- fprintf(stderr, "pointer level not handled!!");
+ if ((vt->ptrLevel == 1) && (vt->isConst)) {
+ fprintf(f, " io->%sWrite(%s, %s_length);\n", str, vt->name, vt->name);
}
}
fprintf(f, "\n");
- fprintf(f, " f->writeAsync(&cmd, cmdSize);\n");
for (ct2=0; ct2 < api->paramCount; ct2++) {
const VarType *vt = &api->params[ct2];
- if (vt->ptrLevel == 1) {
- fprintf(f, " f->writeAsync(%s, %s_length);\n", vt->name, vt->name);
- }
- if (vt->ptrLevel == 2) {
+ if ((vt->ptrLevel == 2) && (vt->isConst)) {
fprintf(f, " for (size_t ct = 0; ct < (%s_length_length / sizeof(%s_length)); ct++) {\n", vt->name, vt->name);
- fprintf(f, " f->writeAsync(%s, %s_length[ct]);\n", vt->name, vt->name);
- fprintf(f, " offset += %s_length[ct];\n", vt->name);
+ fprintf(f, " io->%sWrite(%s[ct], %s_length[ct]);\n", str, vt->name, vt->name);
fprintf(f, " }\n");
}
}
+ fprintf(f, "\n");
+
+ for (ct2=0; ct2 < api->paramCount; ct2++) {
+ const VarType *vt = &api->params[ct2];
+ if ((vt->ptrLevel == 1) && (!vt->isConst)) {
+ fprintf(f, " io->%sGetReturn(%s, %s_length);\n", str, vt->name, vt->name);
+ }
+ }
+ fprintf(f, "\n");
+
+ for (ct2=0; ct2 < api->paramCount; ct2++) {
+ const VarType *vt = &api->params[ct2];
+ if ((vt->ptrLevel == 2) && (!vt->isConst)) {
+ fprintf(f, " for (size_t ct = 0; ct < (%s_length_length / sizeof(%s_length)); ct++) {\n", vt->name, vt->name);
+ fprintf(f, " io->%sGetReturn(%s[ct], %s_length[ct]);\n", str, vt->name, vt->name);
+ fprintf(f, " }\n");
+ }
+ }
+ fprintf(f, "\n");
if (api->ret.typeName[0]) {
fprintf(f, " ");
printVarType(f, &api->ret);
fprintf(f, " retValue;\n");
- fprintf(f, " f->writeWaitReturn(&retValue, sizeof(retValue));\n");
+ fprintf(f, " io->%sGetReturn(&retValue, sizeof(retValue));\n", str);
fprintf(f, " return retValue;\n");
+ } else /*if (api->sync)*/ {
+ fprintf(f, " io->%sGetReturn(NULL, 0);\n", str);
}
fprintf(f, "}\n\n");
}
@@ -418,7 +408,6 @@
fprintf(f, "#include \"rsDevice.h\"\n");
fprintf(f, "#include \"rsContext.h\"\n");
fprintf(f, "#include \"rsThreadIO.h\"\n");
- //fprintf(f, "#include \"rsgApiStructs.h\"\n");
fprintf(f, "#include \"rsgApiFuncDecl.h\"\n");
fprintf(f, "\n");
fprintf(f, "namespace android {\n");
@@ -434,8 +423,6 @@
}
fprintf(f, "void rsp_%s(Context *con, const void *vp, size_t cmdSizeBytes) {\n", api->name);
-
- //fprintf(f, " ALOGE(\"play command %s\\n\");\n", api->name);
fprintf(f, " const RS_CMD_%s *cmd = static_cast<const RS_CMD_%s *>(vp);\n", api->name, api->name);
if (hasInlineDataPointers(api)) {
@@ -488,30 +475,40 @@
const ApiEntry * api = &apis[ct];
int needFlush = 0;
- fprintf(f, "void rspr_%s(Context *con, Fifo *f, uint8_t *scratch, size_t scratchSize) {\n", api->name);
-
- //fprintf(f, " ALOGE(\"play command %s\\n\");\n", api->name);
+ fprintf(f, "void rspr_%s(Context *con, ThreadIO *io) {\n", api->name);
fprintf(f, " RS_CMD_%s cmd;\n", api->name);
- fprintf(f, " f->read(&cmd, sizeof(cmd));\n");
for (ct2=0; ct2 < api->paramCount; ct2++) {
const VarType *vt = &api->params[ct2];
- needFlush += vt->ptrLevel;
+ if (vt->ptrLevel == 0) {
+ fprintf(f, " io->coreRead(&cmd.%s, sizeof(cmd.%s));\n", vt->name, vt->name);
+ }
+ }
+ fprintf(f, "\n");
+
+ for (ct2=0; ct2 < api->paramCount; ct2++) {
+ const VarType *vt = &api->params[ct2];
if (vt->ptrLevel == 1) {
fprintf(f, " cmd.%s = (", vt->name);
printVarType(f, vt);
- fprintf(f, ")scratch;\n");
- fprintf(f, " f->read(scratch, cmd.%s_length);\n", vt->name);
- fprintf(f, " scratch += cmd.%s_length;\n", vt->name);
+ fprintf(f, ")malloc(cmd.%s_length);\n", vt->name);
+
+ if (vt->isConst) {
+ fprintf(f, " if (cmd.%s_length) io->coreRead((void *)cmd.%s, cmd.%s_length);\n", vt->name, vt->name, vt->name);
+ }
}
+ }
+ fprintf(f, "\n");
+
+ for (ct2=0; ct2 < api->paramCount; ct2++) {
+ const VarType *vt = &api->params[ct2];
if (vt->ptrLevel == 2) {
- fprintf(f, " size_t sum_%s = 0;\n", vt->name);
fprintf(f, " for (size_t ct = 0; ct < (cmd.%s_length_length / sizeof(cmd.%s_length)); ct++) {\n", vt->name, vt->name);
- fprintf(f, " ((size_t *)scratch)[ct] = cmd.%s_length[ct];\n", vt->name);
- fprintf(f, " sum_%s += cmd.%s_length[ct];\n", vt->name, vt->name);
+ fprintf(f, " cmd.%s = (", vt->name);
+ printVarType(f, vt);
+ fprintf(f, ")malloc(cmd.%s_length[ct]);\n", vt->name);
+ fprintf(f, " io->coreRead(& cmd.%s, cmd.%s_length[ct]);\n", vt->name, vt->name);
fprintf(f, " }\n");
- fprintf(f, " f->read(scratch, sum_%s);\n", vt->name);
- fprintf(f, " scratch += sum_%s;\n", vt->name);
}
}
fprintf(f, "\n");
@@ -535,10 +532,42 @@
}
fprintf(f, ");\n");
+ for (ct2=0; ct2 < api->paramCount; ct2++) {
+ const VarType *vt = &api->params[ct2];
+ if ((vt->ptrLevel == 1) && (!vt->isConst)) {
+ fprintf(f, " io->coreSetReturn((void *)cmd.%s, cmd.%s_length);\n", vt->name, vt->name);
+ }
+ }
+
+ for (ct2=0; ct2 < api->paramCount; ct2++) {
+ const VarType *vt = &api->params[ct2];
+ if ((vt->ptrLevel == 2) && (!vt->isConst)) {
+ fprintf(f, " for (size_t ct = 0; ct < (cmd.%s_length_length / sizeof(cmd.%s_length)); ct++) {\n", vt->name, vt->name);
+ fprintf(f, " io->coreSetReturn((void *)cmd.%s[ct], cmd.%s_length[ct]);\n", vt->name, vt->name);
+ fprintf(f, " }\n");
+ }
+ }
+ fprintf(f, "\n");
+
if (api->ret.typeName[0]) {
- fprintf(f, " f->readReturn(&ret, sizeof(ret));\n");
- } else if (needFlush) {
- fprintf(f, " f->readReturn(NULL, 0);\n");
+ fprintf(f, " io->coreSetReturn(&ret, sizeof(ret));\n");
+ } else /*if (needFlush)*/ {
+ fprintf(f, " io->coreSetReturn(NULL, 0);\n");
+ }
+
+ for (ct2=0; ct2 < api->paramCount; ct2++) {
+ const VarType *vt = &api->params[ct2];
+ if (vt->ptrLevel == 1) {
+ fprintf(f, " free((void *)cmd.%s);\n", vt->name);
+ }
+ }
+ for (ct2=0; ct2 < api->paramCount; ct2++) {
+ const VarType *vt = &api->params[ct2];
+ if (vt->ptrLevel == 2) {
+ fprintf(f, " for (size_t ct = 0; ct < (cmd.%s_length_length / sizeof(cmd.%s_length)); ct++) {\n", vt->name, vt->name);
+ fprintf(f, " free((void *)cmd.%s);\n", vt->name);
+ fprintf(f, " }\n");
+ }
}
fprintf(f, "};\n\n");
@@ -608,7 +637,7 @@
fprintf(f, " uint32_t size;\n");
fprintf(f, "} RsPlaybackRemoteHeader;\n\n");
fprintf(f, "typedef void (*RsPlaybackLocalFunc)(Context *, const void *, size_t sizeBytes);\n");
- fprintf(f, "typedef void (*RsPlaybackRemoteFunc)(Context *, Fifo *, uint8_t *scratch, size_t scratchSize);\n");
+ fprintf(f, "typedef void (*RsPlaybackRemoteFunc)(Context *, ThreadIO *);\n");
fprintf(f, "extern RsPlaybackLocalFunc gPlaybackFuncs[%i];\n", apiCount + 1);
fprintf(f, "extern RsPlaybackRemoteFunc gPlaybackRemoteFuncs[%i];\n", apiCount + 1);
diff --git a/libs/ui/Android.mk b/libs/ui/Android.mk
index f8b4452..f0d7b02 100644
--- a/libs/ui/Android.mk
+++ b/libs/ui/Android.mk
@@ -13,41 +13,14 @@
# limitations under the License.
LOCAL_PATH:= $(call my-dir)
-
-# libui is partially built for the host (used by build time keymap validation tool)
-# These files are common to host and target builds.
-commonSources:= \
- Input.cpp \
- Keyboard.cpp \
- KeyLayoutMap.cpp \
- KeyCharacterMap.cpp \
- VirtualKeyMap.cpp
-
-# For the host
-# =====================================================
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES:= $(commonSources)
-
-LOCAL_MODULE:= libui
-
-include $(BUILD_HOST_STATIC_LIBRARY)
-
-
-# For the device
-# =====================================================
-
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
- $(commonSources) \
EGLUtils.cpp \
FramebufferNativeWindow.cpp \
GraphicBuffer.cpp \
GraphicBufferAllocator.cpp \
GraphicBufferMapper.cpp \
- InputTransport.cpp \
PixelFormat.cpp \
Rect.cpp \
Region.cpp
@@ -56,14 +29,7 @@
libcutils \
libutils \
libEGL \
- libpixelflinger \
- libhardware \
- libhardware_legacy \
- libskia \
- libbinder
-
-LOCAL_C_INCLUDES := \
- external/skia/include/core
+ libhardware
LOCAL_MODULE:= libui
diff --git a/libs/ui/PixelFormat.cpp b/libs/ui/PixelFormat.cpp
index ee186c8..6993dac 100644
--- a/libs/ui/PixelFormat.cpp
+++ b/libs/ui/PixelFormat.cpp
@@ -15,13 +15,51 @@
*/
#include <ui/PixelFormat.h>
-#include <pixelflinger/format.h>
#include <hardware/hardware.h>
+// ----------------------------------------------------------------------------
namespace android {
+// ----------------------------------------------------------------------------
static const int COMPONENT_YUV = 0xFF;
+struct Info {
+ size_t size;
+ size_t bitsPerPixel;
+ struct {
+ uint8_t ah;
+ uint8_t al;
+ uint8_t rh;
+ uint8_t rl;
+ uint8_t gh;
+ uint8_t gl;
+ uint8_t bh;
+ uint8_t bl;
+ };
+ uint8_t components;
+};
+
+static Info const sPixelFormatInfos[] = {
+ { 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 }, 0 },
+ { 4, 32, {32,24, 8, 0, 16, 8, 24,16 }, PixelFormatInfo::RGBA },
+ { 4, 24, { 0, 0, 8, 0, 16, 8, 24,16 }, PixelFormatInfo::RGB },
+ { 3, 24, { 0, 0, 8, 0, 16, 8, 24,16 }, PixelFormatInfo::RGB },
+ { 2, 16, { 0, 0, 16,11, 11, 5, 5, 0 }, PixelFormatInfo::RGB },
+ { 4, 32, {32,24, 24,16, 16, 8, 8, 0 }, PixelFormatInfo::RGBA },
+ { 2, 16, { 1, 0, 16,11, 11, 6, 6, 1 }, PixelFormatInfo::RGBA },
+ { 2, 16, { 4, 0, 16,12, 12, 8, 8, 4 }, PixelFormatInfo::RGBA },
+ { 1, 8, { 8, 0, 0, 0, 0, 0, 0, 0 }, PixelFormatInfo::ALPHA}
+};
+
+static const Info* gGetPixelFormatTable(size_t* numEntries) {
+ if (numEntries) {
+ *numEntries = sizeof(sPixelFormatInfos)/sizeof(Info);
+ }
+ return sPixelFormatInfos;
+}
+
+// ----------------------------------------------------------------------------
+
size_t PixelFormatInfo::getScanlineSize(unsigned int width) const
{
size_t size;
@@ -77,27 +115,12 @@
}
size_t numEntries;
- const GGLFormat *i = gglGetPixelFormatTable(&numEntries) + format;
+ const Info *i = gGetPixelFormatTable(&numEntries) + format;
bool valid = uint32_t(format) < numEntries;
if (!valid) {
return BAD_INDEX;
}
- #define COMPONENT(name) \
- case GGL_##name: info->components = PixelFormatInfo::name; break;
-
- switch (i->components) {
- COMPONENT(ALPHA)
- COMPONENT(RGB)
- COMPONENT(RGBA)
- COMPONENT(LUMINANCE)
- COMPONENT(LUMINANCE_ALPHA)
- default:
- return BAD_INDEX;
- }
-
- #undef COMPONENT
-
info->format = format;
info->bytesPerPixel = i->size;
info->bitsPerPixel = i->bitsPerPixel;
@@ -109,9 +132,12 @@
info->l_green = i->gl;
info->h_blue = i->bh;
info->l_blue = i->bl;
+ info->components = i->components;
return NO_ERROR;
}
+// ----------------------------------------------------------------------------
}; // namespace android
+// ----------------------------------------------------------------------------
diff --git a/libs/ui/tests/Android.mk b/libs/ui/tests/Android.mk
index 700b604..50cad36 100644
--- a/libs/ui/tests/Android.mk
+++ b/libs/ui/tests/Android.mk
@@ -2,47 +2,5 @@
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
-# Build the unit tests.
-test_src_files := \
- InputChannel_test.cpp \
- InputEvent_test.cpp \
- InputPublisherAndConsumer_test.cpp
-
-shared_libraries := \
- libcutils \
- libutils \
- libEGL \
- libbinder \
- libpixelflinger \
- libhardware \
- libhardware_legacy \
- libui \
- libstlport \
- libskia
-
-static_libraries := \
- libgtest \
- libgtest_main
-
-c_includes := \
- bionic \
- bionic/libstdc++/include \
- external/gtest/include \
- external/stlport/stlport \
- external/skia/include/core
-
-module_tags := eng tests
-
-$(foreach file,$(test_src_files), \
- $(eval include $(CLEAR_VARS)) \
- $(eval LOCAL_SHARED_LIBRARIES := $(shared_libraries)) \
- $(eval LOCAL_STATIC_LIBRARIES := $(static_libraries)) \
- $(eval LOCAL_C_INCLUDES := $(c_includes)) \
- $(eval LOCAL_SRC_FILES := $(file)) \
- $(eval LOCAL_MODULE := $(notdir $(file:%.cpp=%))) \
- $(eval LOCAL_MODULE_TAGS := $(module_tags)) \
- $(eval include $(BUILD_EXECUTABLE)) \
-)
-
# Build the manual test programs.
include $(call all-makefiles-under, $(LOCAL_PATH))
diff --git a/libs/utils/Android.mk b/libs/utils/Android.mk
index 24cf504..a96c8e6 100644
--- a/libs/utils/Android.mk
+++ b/libs/utils/Android.mk
@@ -18,9 +18,6 @@
# and once for the device.
commonSources:= \
- Asset.cpp \
- AssetDir.cpp \
- AssetManager.cpp \
BasicHashtable.cpp \
BlobCache.cpp \
BufferedTextOutput.cpp \
@@ -29,14 +26,11 @@
FileMap.cpp \
Flattenable.cpp \
LinearTransform.cpp \
- ObbFile.cpp \
PropertyMap.cpp \
RefBase.cpp \
- ResourceTypes.cpp \
SharedBuffer.cpp \
Static.cpp \
StopWatch.cpp \
- StreamingZipInflater.cpp \
String8.cpp \
String16.cpp \
StringArray.cpp \
@@ -47,9 +41,6 @@
Tokenizer.cpp \
Unicode.cpp \
VectorImpl.cpp \
- ZipFileCRO.cpp \
- ZipFileRO.cpp \
- ZipUtils.cpp \
misc.cpp
@@ -63,7 +54,6 @@
LOCAL_MODULE:= libutils
LOCAL_CFLAGS += -DLIBUTILS_NATIVE=1 $(TOOL_CFLAGS)
-LOCAL_C_INCLUDES += external/zlib
ifeq ($(HOST_OS),windows)
ifeq ($(strip $(USE_CYGWIN),),)
@@ -79,7 +69,6 @@
include $(BUILD_HOST_STATIC_LIBRARY)
-
# For the device
# =====================================================
include $(CLEAR_VARS)
@@ -88,8 +77,6 @@
# we have the common sources, plus some device-specific stuff
LOCAL_SRC_FILES:= \
$(commonSources) \
- BackupData.cpp \
- BackupHelpers.cpp \
Looper.cpp
ifeq ($(TARGET_OS),linux)
@@ -97,14 +84,11 @@
endif
LOCAL_C_INCLUDES += \
- external/zlib \
- external/icu4c/common \
bionic/libc/private
LOCAL_LDLIBS += -lpthread
LOCAL_SHARED_LIBRARIES := \
- libz \
liblog \
libcutils \
libdl \
@@ -113,19 +97,6 @@
LOCAL_MODULE:= libutils
include $(BUILD_SHARED_LIBRARY)
-ifeq ($(TARGET_OS),linux)
-include $(CLEAR_VARS)
-LOCAL_C_INCLUDES += \
- external/zlib \
- external/icu4c/common \
- bionic/libc/private
-LOCAL_LDLIBS := -lrt -ldl -lpthread
-LOCAL_MODULE := libutils
-LOCAL_SRC_FILES := $(commonSources) BackupData.cpp BackupHelpers.cpp
-include $(BUILD_STATIC_LIBRARY)
-endif
-
-
# Include subdirectory makefiles
# ============================================================
diff --git a/libs/utils/tests/Android.mk b/libs/utils/tests/Android.mk
index 58230f4..a6811fc 100644
--- a/libs/utils/tests/Android.mk
+++ b/libs/utils/tests/Android.mk
@@ -7,10 +7,8 @@
BasicHashtable_test.cpp \
BlobCache_test.cpp \
Looper_test.cpp \
- ObbFile_test.cpp \
String8_test.cpp \
Unicode_test.cpp \
- ZipFileRO_test.cpp \
shared_libraries := \
libz \
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index eae03be..1c7f577 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -591,7 +591,7 @@
// Post a persist volume msg
sendMsg(mAudioHandler,
MSG_PERSIST_VOLUME,
- SENDMSG_REPLACE,
+ SENDMSG_QUEUE,
PERSIST_LAST_AUDIBLE,
device,
s,
@@ -606,7 +606,7 @@
// to persist). Do not change volume if stream is muted.
sendMsg(mAudioHandler,
MSG_SET_DEVICE_VOLUME,
- SENDMSG_NOOP,
+ SENDMSG_QUEUE,
device,
0,
streamState,
@@ -746,7 +746,7 @@
// Post a persist volume msg
sendMsg(mAudioHandler,
MSG_PERSIST_VOLUME,
- SENDMSG_REPLACE,
+ SENDMSG_QUEUE,
PERSIST_LAST_AUDIBLE,
device,
streamState,
@@ -758,7 +758,7 @@
// to persist).
sendMsg(mAudioHandler,
MSG_SET_DEVICE_VOLUME,
- SENDMSG_NOOP,
+ SENDMSG_QUEUE,
device,
0,
streamState,
@@ -2208,7 +2208,7 @@
}
sendMsg(mAudioHandler,
MSG_SET_ALL_VOLUMES,
- SENDMSG_NOOP,
+ SENDMSG_QUEUE,
0,
0,
VolumeStreamState.this, 0);
@@ -2252,7 +2252,7 @@
}
sendMsg(mAudioHandler,
MSG_SET_ALL_VOLUMES,
- SENDMSG_NOOP,
+ SENDMSG_QUEUE,
0,
0,
VolumeStreamState.this, 0);
@@ -2350,7 +2350,7 @@
// Post a persist volume msg
sendMsg(mAudioHandler,
MSG_PERSIST_VOLUME,
- SENDMSG_REPLACE,
+ SENDMSG_QUEUE,
PERSIST_CURRENT|PERSIST_LAST_AUDIBLE,
device,
streamState,
diff --git a/media/java/android/media/audiofx/Visualizer.java b/media/java/android/media/audiofx/Visualizer.java
index bcf7b89..91d0addd 100755
--- a/media/java/android/media/audiofx/Visualizer.java
+++ b/media/java/android/media/audiofx/Visualizer.java
@@ -84,6 +84,7 @@
// to keep in sync with frameworks/base/media/jni/audioeffect/android_media_Visualizer.cpp
private static final int NATIVE_EVENT_PCM_CAPTURE = 0;
private static final int NATIVE_EVENT_FFT_CAPTURE = 1;
+ private static final int NATIVE_EVENT_SERVER_DIED = 2;
// Error codes:
/**
@@ -147,6 +148,10 @@
* PCM and FFT capture listener registered by client
*/
private OnDataCaptureListener mCaptureListener = null;
+ /**
+ * Server Died listener registered by client
+ */
+ private OnServerDiedListener mServerDiedListener = null;
// accessed by native methods
private int mNativeVisualizer;
@@ -396,6 +401,9 @@
public interface OnDataCaptureListener {
/**
* Method called when a new waveform capture is available.
+ * <p>Data in the waveform buffer is valid only within the scope of the callback.
+ * Applications which needs access to the waveform data after returning from the callback
+ * should make a copy of the data instead of holding a reference.
* @param visualizer Visualizer object on which the listener is registered.
* @param waveform array of bytes containing the waveform representation.
* @param samplingRate sampling rate of the audio visualized.
@@ -404,6 +412,9 @@
/**
* Method called when a new frequency capture is available.
+ * <p>Data in the fft buffer is valid only within the scope of the callback.
+ * Applications which needs access to the fft data after returning from the callback
+ * should make a copy of the data instead of holding a reference.
* @param visualizer Visualizer object on which the listener is registered.
* @param fft array of bytes containing the frequency representation.
* @param samplingRate sampling rate of the audio visualized.
@@ -452,6 +463,43 @@
}
/**
+ * @hide
+ *
+ * The OnServerDiedListener interface defines a method called by the Visualizer to indicate that
+ * the connection to the native media server has been broken and that the Visualizer object will
+ * need to be released and re-created.
+ * The client application can implement this interface and register the listener with the
+ * {@link #setServerDiedListener(OnServerDiedListener)} method.
+ */
+ public interface OnServerDiedListener {
+ /**
+ * @hide
+ *
+ * Method called when the native media server has died.
+ * <p>If the native media server encounters a fatal error and needs to restart, the binder
+ * connection from the {@link #Visualizer} to the media server will be broken. Data capture
+ * callbacks will stop happening, and client initiated calls to the {@link #Visualizer}
+ * instance will fail with the error code {@link #DEAD_OBJECT}. To restore functionality,
+ * clients should {@link #release()} their old visualizer and create a new instance.
+ */
+ void onServerDied();
+ }
+
+ /**
+ * @hide
+ *
+ * Registers an OnServerDiedListener interface.
+ * <p>Call this method with a null listener to stop receiving server death notifications.
+ * @return {@link #SUCCESS} in case of success,
+ */
+ public int setServerDiedListener(OnServerDiedListener listener) {
+ synchronized (mListenerLock) {
+ mServerDiedListener = listener;
+ }
+ return SUCCESS;
+ }
+
+ /**
* Helper class to handle the forwarding of native events to the appropriate listeners
*/
private class NativeEventHandler extends Handler
@@ -463,11 +511,7 @@
mVisualizer = v;
}
- @Override
- public void handleMessage(Message msg) {
- if (mVisualizer == null) {
- return;
- }
+ private void handleCaptureMessage(Message msg) {
OnDataCaptureListener l = null;
synchronized (mListenerLock) {
l = mVisualizer.mCaptureListener;
@@ -476,6 +520,7 @@
if (l != null) {
byte[] data = (byte[])msg.obj;
int samplingRate = msg.arg1;
+
switch(msg.what) {
case NATIVE_EVENT_PCM_CAPTURE:
l.onWaveFormDataCapture(mVisualizer, data, samplingRate);
@@ -484,11 +529,41 @@
l.onFftDataCapture(mVisualizer, data, samplingRate);
break;
default:
- Log.e(TAG,"Unknown native event: "+msg.what);
+ Log.e(TAG,"Unknown native event in handleCaptureMessge: "+msg.what);
break;
}
}
}
+
+ private void handleServerDiedMessage(Message msg) {
+ OnServerDiedListener l = null;
+ synchronized (mListenerLock) {
+ l = mVisualizer.mServerDiedListener;
+ }
+
+ if (l != null)
+ l.onServerDied();
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ if (mVisualizer == null) {
+ return;
+ }
+
+ switch(msg.what) {
+ case NATIVE_EVENT_PCM_CAPTURE:
+ case NATIVE_EVENT_FFT_CAPTURE:
+ handleCaptureMessage(msg);
+ break;
+ case NATIVE_EVENT_SERVER_DIED:
+ handleServerDiedMessage(msg);
+ break;
+ default:
+ Log.e(TAG,"Unknown native event: "+msg.what);
+ break;
+ }
+ }
}
//---------------------------------------------------------
diff --git a/media/jni/audioeffect/android_media_Visualizer.cpp b/media/jni/audioeffect/android_media_Visualizer.cpp
index ecd4d07..f015afb 100644
--- a/media/jni/audioeffect/android_media_Visualizer.cpp
+++ b/media/jni/audioeffect/android_media_Visualizer.cpp
@@ -23,6 +23,7 @@
#include <nativehelper/jni.h>
#include <nativehelper/JNIHelp.h>
#include <android_runtime/AndroidRuntime.h>
+#include <utils/threads.h>
#include "media/Visualizer.h"
using namespace android;
@@ -38,6 +39,7 @@
#define NATIVE_EVENT_PCM_CAPTURE 0
#define NATIVE_EVENT_FFT_CAPTURE 1
+#define NATIVE_EVENT_SERVER_DIED 2
// ----------------------------------------------------------------------------
static const char* const kClassPathName = "android/media/audiofx/Visualizer";
@@ -54,6 +56,43 @@
struct visualizer_callback_cookie {
jclass visualizer_class; // Visualizer class
jobject visualizer_ref; // Visualizer object instance
+
+ // Lazily allocated arrays used to hold callback data provided to java
+ // applications. These arrays are allocated during the first callback and
+ // reallocated when the size of the callback data changes. Allocating on
+ // demand and saving the arrays means that applications cannot safely hold a
+ // reference to the provided data (they need to make a copy if they want to
+ // hold onto outside of the callback scope), but it avoids GC thrash caused
+ // by constantly allocating and releasing arrays to hold callback data.
+ Mutex callback_data_lock;
+ jbyteArray waveform_data;
+ jbyteArray fft_data;
+
+ visualizer_callback_cookie() {
+ waveform_data = NULL;
+ fft_data = NULL;
+ }
+
+ ~visualizer_callback_cookie() {
+ cleanupBuffers();
+ }
+
+ void cleanupBuffers() {
+ AutoMutex lock(&callback_data_lock);
+ if (waveform_data || fft_data) {
+ JNIEnv *env = AndroidRuntime::getJNIEnv();
+
+ if (waveform_data) {
+ env->DeleteGlobalRef(waveform_data);
+ waveform_data = NULL;
+ }
+
+ if (fft_data) {
+ env->DeleteGlobalRef(fft_data);
+ fft_data = NULL;
+ }
+ }
+ }
};
// ----------------------------------------------------------------------------
@@ -66,7 +105,6 @@
~visualizerJniStorage() {
}
-
};
@@ -93,6 +131,26 @@
// ----------------------------------------------------------------------------
+static void ensureArraySize(JNIEnv *env, jbyteArray *array, uint32_t size) {
+ if (NULL != *array) {
+ uint32_t len = env->GetArrayLength(*array);
+ if (len == size)
+ return;
+
+ env->DeleteGlobalRef(*array);
+ *array = NULL;
+ }
+
+ jbyteArray localRef = env->NewByteArray(size);
+ if (NULL != localRef) {
+ // Promote to global ref.
+ *array = (jbyteArray)env->NewGlobalRef(localRef);
+
+ // Release our (now pointless) local ref.
+ env->DeleteLocalRef(localRef);
+ }
+}
+
static void captureCallback(void* user,
uint32_t waveformSize,
uint8_t *waveform,
@@ -106,6 +164,7 @@
visualizer_callback_cookie *callbackInfo = (visualizer_callback_cookie *)user;
JNIEnv *env = AndroidRuntime::getJNIEnv();
+ AutoMutex lock(&callbackInfo->callback_data_lock);
ALOGV("captureCallback: callbackInfo %p, visualizer_ref %p visualizer_class %p",
callbackInfo,
@@ -118,7 +177,11 @@
}
if (waveformSize != 0 && waveform != NULL) {
- jbyteArray jArray = env->NewByteArray(waveformSize);
+ jbyteArray jArray;
+
+ ensureArraySize(env, &callbackInfo->waveform_data, waveformSize);
+ jArray = callbackInfo->waveform_data;
+
if (jArray != NULL) {
jbyte *nArray = env->GetByteArrayElements(jArray, NULL);
memcpy(nArray, waveform, waveformSize);
@@ -131,12 +194,15 @@
samplingrate,
0,
jArray);
- env->DeleteLocalRef(jArray);
}
}
if (fftSize != 0 && fft != NULL) {
- jbyteArray jArray = env->NewByteArray(fftSize);
+ jbyteArray jArray;
+
+ ensureArraySize(env, &callbackInfo->fft_data, fftSize);
+ jArray = callbackInfo->fft_data;
+
if (jArray != NULL) {
jbyte *nArray = env->GetByteArrayElements(jArray, NULL);
memcpy(nArray, fft, fftSize);
@@ -149,7 +215,6 @@
samplingrate,
0,
jArray);
- env->DeleteLocalRef(jArray);
}
}
@@ -220,6 +285,23 @@
}
+static void android_media_visualizer_effect_callback(int32_t event,
+ void *user,
+ void *info) {
+ if ((event == AudioEffect::EVENT_ERROR) &&
+ (*((status_t*)info) == DEAD_OBJECT)) {
+ visualizerJniStorage* lpJniStorage = (visualizerJniStorage*)user;
+ visualizer_callback_cookie* callbackInfo = &lpJniStorage->mCallbackData;
+ JNIEnv *env = AndroidRuntime::getJNIEnv();
+
+ env->CallStaticVoidMethod(
+ callbackInfo->visualizer_class,
+ fields.midPostNativeEvent,
+ callbackInfo->visualizer_ref,
+ NATIVE_EVENT_SERVER_DIED,
+ 0, 0, 0);
+ }
+}
static jint
android_media_visualizer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this,
@@ -255,8 +337,8 @@
// create the native Visualizer object
lpVisualizer = new Visualizer(0,
- NULL,
- NULL,
+ android_media_visualizer_effect_callback,
+ lpJniStorage,
sessionId);
if (lpVisualizer == NULL) {
ALOGE("Error creating Visualizer");
@@ -345,7 +427,17 @@
return VISUALIZER_ERROR_NO_INIT;
}
- return translateError(lpVisualizer->setEnabled(enabled));
+ jint retVal = translateError(lpVisualizer->setEnabled(enabled));
+
+ if (!enabled) {
+ visualizerJniStorage* lpJniStorage = (visualizerJniStorage *)env->GetIntField(
+ thiz, fields.fidJniData);
+
+ if (NULL != lpJniStorage)
+ lpJniStorage->mCallbackData.cleanupBuffers();
+ }
+
+ return retVal;
}
static jboolean
diff --git a/media/libaah_rtp/Android.mk b/media/libaah_rtp/Android.mk
new file mode 100644
index 0000000..54fd9ec
--- /dev/null
+++ b/media/libaah_rtp/Android.mk
@@ -0,0 +1,40 @@
+LOCAL_PATH:= $(call my-dir)
+#
+# libaah_rtp
+#
+
+include $(CLEAR_VARS)
+
+LOCAL_MODULE := libaah_rtp
+LOCAL_MODULE_TAGS := optional
+
+LOCAL_SRC_FILES := \
+ aah_decoder_pump.cpp \
+ aah_rx_player.cpp \
+ aah_rx_player_core.cpp \
+ aah_rx_player_ring_buffer.cpp \
+ aah_rx_player_substream.cpp \
+ aah_tx_packet.cpp \
+ aah_tx_player.cpp \
+ aah_tx_sender.cpp \
+ pipe_event.cpp
+
+LOCAL_C_INCLUDES := \
+ frameworks/base/include \
+ frameworks/base/include/media/stagefright/openmax \
+ frameworks/base/media \
+ frameworks/base/media/libstagefright
+
+LOCAL_SHARED_LIBRARIES := \
+ libcommon_time_client \
+ libbinder \
+ libmedia \
+ libstagefright \
+ libstagefright_foundation \
+ libutils
+
+LOCAL_LDLIBS := \
+ -lpthread
+
+include $(BUILD_SHARED_LIBRARY)
+
diff --git a/media/libaah_rtp/aah_decoder_pump.cpp b/media/libaah_rtp/aah_decoder_pump.cpp
new file mode 100644
index 0000000..72fe43b
--- /dev/null
+++ b/media/libaah_rtp/aah_decoder_pump.cpp
@@ -0,0 +1,520 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#define LOG_TAG "LibAAH_RTP"
+//#define LOG_NDEBUG 0
+#include <utils/Log.h>
+
+#include <poll.h>
+#include <pthread.h>
+
+#include <common_time/cc_helper.h>
+#include <media/AudioSystem.h>
+#include <media/AudioTrack.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/OMXClient.h>
+#include <media/stagefright/OMXCodec.h>
+#include <media/stagefright/Utils.h>
+#include <utils/Timers.h>
+#include <utils/threads.h>
+
+#include "aah_decoder_pump.h"
+
+namespace android {
+
+static const long long kLongDecodeErrorThreshold = 1000000ll;
+static const uint32_t kMaxLongErrorsBeforeFatal = 3;
+static const uint32_t kMaxErrorsBeforeFatal = 60;
+
+AAH_DecoderPump::AAH_DecoderPump(OMXClient& omx)
+ : omx_(omx)
+ , thread_status_(OK)
+ , renderer_(NULL)
+ , last_queued_pts_valid_(false)
+ , last_queued_pts_(0)
+ , last_ts_transform_valid_(false)
+ , last_volume_(0xFF) {
+ thread_ = new ThreadWrapper(this);
+}
+
+AAH_DecoderPump::~AAH_DecoderPump() {
+ shutdown();
+}
+
+status_t AAH_DecoderPump::initCheck() {
+ if (thread_ == NULL) {
+ ALOGE("Failed to allocate thread");
+ return NO_MEMORY;
+ }
+
+ return OK;
+}
+
+status_t AAH_DecoderPump::queueForDecode(MediaBuffer* buf) {
+ if (NULL == buf) {
+ return BAD_VALUE;
+ }
+
+ if (OK != thread_status_) {
+ return thread_status_;
+ }
+
+ { // Explicit scope for AutoMutex pattern.
+ AutoMutex lock(&thread_lock_);
+ in_queue_.push_back(buf);
+ }
+
+ thread_cond_.signal();
+
+ return OK;
+}
+
+void AAH_DecoderPump::queueToRenderer(MediaBuffer* decoded_sample) {
+ Mutex::Autolock lock(&render_lock_);
+ sp<MetaData> meta;
+ int64_t ts;
+ status_t res;
+
+ // Fetch the metadata and make sure the sample has a timestamp. We
+ // cannot render samples which are missing PTSs.
+ meta = decoded_sample->meta_data();
+ if ((meta == NULL) || (!meta->findInt64(kKeyTime, &ts))) {
+ ALOGV("Decoded sample missing timestamp, cannot render.");
+ CHECK(false);
+ } else {
+ // If we currently are not holding on to a renderer, go ahead and
+ // make one now.
+ if (NULL == renderer_) {
+ renderer_ = new TimedAudioTrack();
+ if (NULL != renderer_) {
+ int frameCount;
+ AudioTrack::getMinFrameCount(&frameCount,
+ AUDIO_STREAM_DEFAULT,
+ static_cast<int>(format_sample_rate_));
+ int ch_format = (format_channels_ == 1)
+ ? AUDIO_CHANNEL_OUT_MONO
+ : AUDIO_CHANNEL_OUT_STEREO;
+
+ res = renderer_->set(AUDIO_STREAM_DEFAULT,
+ format_sample_rate_,
+ AUDIO_FORMAT_PCM_16_BIT,
+ ch_format,
+ frameCount);
+ if (res != OK) {
+ ALOGE("Failed to setup audio renderer. (res = %d)", res);
+ delete renderer_;
+ renderer_ = NULL;
+ } else {
+ CHECK(last_ts_transform_valid_);
+
+ res = renderer_->setMediaTimeTransform(
+ last_ts_transform_, TimedAudioTrack::COMMON_TIME);
+ if (res != NO_ERROR) {
+ ALOGE("Failed to set media time transform on AudioTrack"
+ " (res = %d)", res);
+ delete renderer_;
+ renderer_ = NULL;
+ } else {
+ float volume = static_cast<float>(last_volume_)
+ / 255.0f;
+ if (renderer_->setVolume(volume, volume) != OK) {
+ ALOGW("%s: setVolume failed", __FUNCTION__);
+ }
+
+ renderer_->start();
+ }
+ }
+ } else {
+ ALOGE("Failed to allocate AudioTrack to use as a renderer.");
+ }
+ }
+
+ if (NULL != renderer_) {
+ uint8_t* decoded_data =
+ reinterpret_cast<uint8_t*>(decoded_sample->data());
+ uint32_t decoded_amt = decoded_sample->range_length();
+ decoded_data += decoded_sample->range_offset();
+
+ sp<IMemory> pcm_payload;
+ res = renderer_->allocateTimedBuffer(decoded_amt, &pcm_payload);
+ if (res != OK) {
+ ALOGE("Failed to allocate %d byte audio track buffer."
+ " (res = %d)", decoded_amt, res);
+ } else {
+ memcpy(pcm_payload->pointer(), decoded_data, decoded_amt);
+
+ res = renderer_->queueTimedBuffer(pcm_payload, ts);
+ if (res != OK) {
+ ALOGE("Failed to queue %d byte audio track buffer with media"
+ " PTS %lld. (res = %d)", decoded_amt, ts, res);
+ } else {
+ last_queued_pts_valid_ = true;
+ last_queued_pts_ = ts;
+ }
+ }
+
+ } else {
+ ALOGE("No renderer, dropping audio payload.");
+ }
+ }
+}
+
+void AAH_DecoderPump::stopAndCleanupRenderer() {
+ if (NULL == renderer_) {
+ return;
+ }
+
+ renderer_->stop();
+ delete renderer_;
+ renderer_ = NULL;
+}
+
+void AAH_DecoderPump::setRenderTSTransform(const LinearTransform& trans) {
+ Mutex::Autolock lock(&render_lock_);
+
+ if (last_ts_transform_valid_ && !memcmp(&trans,
+ &last_ts_transform_,
+ sizeof(trans))) {
+ return;
+ }
+
+ last_ts_transform_ = trans;
+ last_ts_transform_valid_ = true;
+
+ if (NULL != renderer_) {
+ status_t res = renderer_->setMediaTimeTransform(
+ last_ts_transform_, TimedAudioTrack::COMMON_TIME);
+ if (res != NO_ERROR) {
+ ALOGE("Failed to set media time transform on AudioTrack"
+ " (res = %d)", res);
+ }
+ }
+}
+
+void AAH_DecoderPump::setRenderVolume(uint8_t volume) {
+ Mutex::Autolock lock(&render_lock_);
+
+ if (volume == last_volume_) {
+ return;
+ }
+
+ last_volume_ = volume;
+ if (renderer_ != NULL) {
+ float volume = static_cast<float>(last_volume_) / 255.0f;
+ if (renderer_->setVolume(volume, volume) != OK) {
+ ALOGW("%s: setVolume failed", __FUNCTION__);
+ }
+ }
+}
+
+// isAboutToUnderflow is something of a hack used to figure out when it might be
+// time to give up on trying to fill in a gap in the RTP sequence and simply
+// move on with a discontinuity. If we had perfect knowledge of when we were
+// going to underflow, it would not be a hack, but unfortunately we do not.
+// Right now, we just take the PTS of the last sample queued, and check to see
+// if its presentation time is within kAboutToUnderflowThreshold from now. If
+// it is, then we say that we are about to underflow. This decision is based on
+// two (possibly invalid) assumptions.
+//
+// 1) The transmitter is leading the clock by more than
+// kAboutToUnderflowThreshold.
+// 2) The delta between the PTS of the last sample queued and the next sample
+// is less than the transmitter's clock lead amount.
+//
+// Right now, the default transmitter lead time is 1 second, which is a pretty
+// large number and greater than the 50mSec that kAboutToUnderflowThreshold is
+// currently set to. This should satisfy assumption #1 for now, but changes to
+// the transmitter clock lead time could effect this.
+//
+// For non-sparse streams with a homogeneous sample rate (the vast majority of
+// streams in the world), the delta between any two adjacent PTSs will always be
+// the homogeneous sample period. It is very uncommon to see a sample period
+// greater than the 1 second clock lead we are currently using, and you
+// certainly will not see it in an MP3 file which should satisfy assumption #2.
+// Sparse audio streams (where no audio is transmitted for long periods of
+// silence) and extremely low framerate video stream (like an MPEG-2 slideshow
+// or the video stream for a pay TV audio channel) are examples of streams which
+// might violate assumption #2.
+bool AAH_DecoderPump::isAboutToUnderflow(int64_t threshold) {
+ Mutex::Autolock lock(&render_lock_);
+
+ // If we have never queued anything to the decoder, we really don't know if
+ // we are going to underflow or not.
+ if (!last_queued_pts_valid_ || !last_ts_transform_valid_) {
+ return false;
+ }
+
+ // Don't have access to Common Time? If so, then things are Very Bad
+ // elsewhere in the system; it pretty much does not matter what we do here.
+ // Since we cannot really tell if we are about to underflow or not, its
+ // probably best to assume that we are not and proceed accordingly.
+ int64_t tt_now;
+ if (OK != cc_helper_.getCommonTime(&tt_now)) {
+ return false;
+ }
+
+ // Transform from media time to common time.
+ int64_t last_queued_pts_tt;
+ if (!last_ts_transform_.doForwardTransform(last_queued_pts_,
+ &last_queued_pts_tt)) {
+ return false;
+ }
+
+ // Check to see if we are underflowing.
+ return ((tt_now + threshold - last_queued_pts_tt) > 0);
+}
+
+void* AAH_DecoderPump::workThread() {
+ // No need to lock when accessing decoder_ from the thread. The
+ // implementation of init and shutdown ensure that other threads never touch
+ // decoder_ while the work thread is running.
+ CHECK(decoder_ != NULL);
+ CHECK(format_ != NULL);
+
+ // Start the decoder and note its result code. If something goes horribly
+ // wrong, callers of queueForDecode and getOutput will be able to detect
+ // that the thread encountered a fatal error and shut down by examining
+ // thread_status_.
+ thread_status_ = decoder_->start(format_.get());
+ if (OK != thread_status_) {
+ ALOGE("AAH_DecoderPump's work thread failed to start decoder (res = %d)",
+ thread_status_);
+ return NULL;
+ }
+
+ DurationTimer decode_timer;
+ uint32_t consecutive_long_errors = 0;
+ uint32_t consecutive_errors = 0;
+
+ while (!thread_->exitPending()) {
+ status_t res;
+ MediaBuffer* bufOut = NULL;
+
+ decode_timer.start();
+ res = decoder_->read(&bufOut);
+ decode_timer.stop();
+
+ if (res == INFO_FORMAT_CHANGED) {
+ // Format has changed. Destroy our current renderer so that a new
+ // one can be created during queueToRenderer with the proper format.
+ //
+ // TODO : In order to transition seamlessly, we should change this
+ // to put the old renderer in a queue to play out completely before
+ // we destroy it. We can still create a new renderer, the timed
+ // nature of the renderer should ensure a seamless splice.
+ stopAndCleanupRenderer();
+ res = OK;
+ }
+
+ // Try to be a little nuanced in our handling of actual decode errors.
+ // Errors could happen because of minor stream corruption or because of
+ // transient resource limitations. In these cases, we would rather drop
+ // a little bit of output and ride out the unpleasantness then throw up
+ // our hands and abort everything.
+ //
+ // OTOH - When things are really bad (like we have a non-transient
+ // resource or bookkeeping issue, or the stream being fed to us is just
+ // complete and total garbage) we really want to terminate playback and
+ // raise an error condition all the way up to the application level so
+ // they can deal with it.
+ //
+ // Unfortunately, the error codes returned by the decoder can be a
+ // little non-specific. For example, if an OMXCodec times out
+ // attempting to obtain an output buffer, the error we get back is a
+ // generic -1. Try to distinguish between this resource timeout error
+ // and ES corruption error by timing how long the decode operation
+ // takes. Maintain accounting for both errors and "long errors". If we
+ // get more than a certain number consecutive errors of either type,
+ // consider it fatal and shutdown (which will cause the error to
+ // propagate all of the way up to the application level). The threshold
+ // for "long errors" is deliberately much lower than that of normal
+ // decode errors, both because of how long they take to happen and
+ // because they generally indicate resource limitation errors which are
+ // unlikely to go away in pathologically bad cases (in contrast to
+ // stream corruption errors which might happen 20 times in a row and
+ // then be suddenly OK again)
+ if (res != OK) {
+ consecutive_errors++;
+ if (decode_timer.durationUsecs() >= kLongDecodeErrorThreshold)
+ consecutive_long_errors++;
+
+ CHECK(NULL == bufOut);
+
+ ALOGW("%s: Failed to decode data (res = %d)",
+ __PRETTY_FUNCTION__, res);
+
+ if ((consecutive_errors >= kMaxErrorsBeforeFatal) ||
+ (consecutive_long_errors >= kMaxLongErrorsBeforeFatal)) {
+ ALOGE("%s: Maximum decode error threshold has been reached."
+ " There have been %d consecutive decode errors, and %d"
+ " consecutive decode operations which resulted in errors"
+ " and took more than %lld uSec to process. The last"
+ " decode operation took %lld uSec.",
+ __PRETTY_FUNCTION__,
+ consecutive_errors, consecutive_long_errors,
+ kLongDecodeErrorThreshold, decode_timer.durationUsecs());
+ thread_status_ = res;
+ break;
+ }
+
+ continue;
+ }
+
+ if (NULL == bufOut) {
+ ALOGW("%s: Successful decode, but no buffer produced",
+ __PRETTY_FUNCTION__);
+ continue;
+ }
+
+ // Successful decode (with actual output produced). Clear the error
+ // counters.
+ consecutive_errors = 0;
+ consecutive_long_errors = 0;
+
+ queueToRenderer(bufOut);
+ bufOut->release();
+ }
+
+ decoder_->stop();
+ stopAndCleanupRenderer();
+
+ return NULL;
+}
+
+status_t AAH_DecoderPump::init(const sp<MetaData>& params) {
+ Mutex::Autolock lock(&init_lock_);
+
+ if (decoder_ != NULL) {
+ // already inited
+ return OK;
+ }
+
+ if (params == NULL) {
+ return BAD_VALUE;
+ }
+
+ if (!params->findInt32(kKeyChannelCount, &format_channels_)) {
+ return BAD_VALUE;
+ }
+
+ if (!params->findInt32(kKeySampleRate, &format_sample_rate_)) {
+ return BAD_VALUE;
+ }
+
+ CHECK(OK == thread_status_);
+ CHECK(decoder_ == NULL);
+
+ status_t ret_val = UNKNOWN_ERROR;
+
+ // Cache the format and attempt to create the decoder.
+ format_ = params;
+ decoder_ = OMXCodec::Create(
+ omx_.interface(), // IOMX Handle
+ format_, // Metadata for substream (indicates codec)
+ false, // Make a decoder, not an encoder
+ sp<MediaSource>(this)); // We will be the source for this codec.
+
+ if (decoder_ == NULL) {
+ ALOGE("Failed to allocate decoder in %s", __PRETTY_FUNCTION__);
+ goto bailout;
+ }
+
+ // Fire up the pump thread. It will take care of starting and stopping the
+ // decoder.
+ ret_val = thread_->run("aah_decode_pump", ANDROID_PRIORITY_AUDIO);
+ if (OK != ret_val) {
+ ALOGE("Failed to start work thread in %s (res = %d)",
+ __PRETTY_FUNCTION__, ret_val);
+ goto bailout;
+ }
+
+bailout:
+ if (OK != ret_val) {
+ decoder_ = NULL;
+ format_ = NULL;
+ }
+
+ return OK;
+}
+
+status_t AAH_DecoderPump::shutdown() {
+ Mutex::Autolock lock(&init_lock_);
+ return shutdown_l();
+}
+
+status_t AAH_DecoderPump::shutdown_l() {
+ thread_->requestExit();
+ thread_cond_.signal();
+ thread_->requestExitAndWait();
+
+ for (MBQueue::iterator iter = in_queue_.begin();
+ iter != in_queue_.end();
+ ++iter) {
+ (*iter)->release();
+ }
+ in_queue_.clear();
+
+ last_queued_pts_valid_ = false;
+ last_ts_transform_valid_ = false;
+ last_volume_ = 0xFF;
+ thread_status_ = OK;
+
+ decoder_ = NULL;
+ format_ = NULL;
+
+ return OK;
+}
+
+status_t AAH_DecoderPump::read(MediaBuffer **buffer,
+ const ReadOptions *options) {
+ if (!buffer) {
+ return BAD_VALUE;
+ }
+
+ *buffer = NULL;
+
+ // While its not time to shut down, and we have no data to process, wait.
+ AutoMutex lock(&thread_lock_);
+ while (!thread_->exitPending() && in_queue_.empty())
+ thread_cond_.wait(thread_lock_);
+
+ // At this point, if its not time to shutdown then we must have something to
+ // process. Go ahead and pop the front of the queue for processing.
+ if (!thread_->exitPending()) {
+ CHECK(!in_queue_.empty());
+
+ *buffer = *(in_queue_.begin());
+ in_queue_.erase(in_queue_.begin());
+ }
+
+ // If we managed to get a buffer, then everything must be OK. If not, then
+ // we must be shutting down.
+ return (NULL == *buffer) ? INVALID_OPERATION : OK;
+}
+
+AAH_DecoderPump::ThreadWrapper::ThreadWrapper(AAH_DecoderPump* owner)
+ : Thread(false /* canCallJava*/ )
+ , owner_(owner) {
+}
+
+bool AAH_DecoderPump::ThreadWrapper::threadLoop() {
+ CHECK(NULL != owner_);
+ owner_->workThread();
+ return false;
+}
+
+} // namespace android
diff --git a/media/libaah_rtp/aah_decoder_pump.h b/media/libaah_rtp/aah_decoder_pump.h
new file mode 100644
index 0000000..f5a6529
--- /dev/null
+++ b/media/libaah_rtp/aah_decoder_pump.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#ifndef __DECODER_PUMP_H__
+#define __DECODER_PUMP_H__
+
+#include <pthread.h>
+
+#include <common_time/cc_helper.h>
+#include <media/stagefright/MediaSource.h>
+#include <utils/LinearTransform.h>
+#include <utils/List.h>
+#include <utils/threads.h>
+
+namespace android {
+
+class MetaData;
+class OMXClient;
+class TimedAudioTrack;
+
+class AAH_DecoderPump : public MediaSource {
+ public:
+ explicit AAH_DecoderPump(OMXClient& omx);
+ status_t initCheck();
+
+ status_t queueForDecode(MediaBuffer* buf);
+
+ status_t init(const sp<MetaData>& params);
+ status_t shutdown();
+
+ void setRenderTSTransform(const LinearTransform& trans);
+ void setRenderVolume(uint8_t volume);
+ bool isAboutToUnderflow(int64_t threshold);
+ bool getStatus() const { return thread_status_; }
+
+ // MediaSource methods
+ virtual status_t start(MetaData *params) { return OK; }
+ virtual sp<MetaData> getFormat() { return format_; }
+ virtual status_t stop() { return OK; }
+ virtual status_t read(MediaBuffer **buffer,
+ const ReadOptions *options);
+
+ protected:
+ virtual ~AAH_DecoderPump();
+
+ private:
+ class ThreadWrapper : public Thread {
+ public:
+ friend class AAH_DecoderPump;
+ explicit ThreadWrapper(AAH_DecoderPump* owner);
+
+ private:
+ virtual bool threadLoop();
+ AAH_DecoderPump* owner_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(ThreadWrapper);
+ };
+
+ void* workThread();
+ virtual status_t shutdown_l();
+ void queueToRenderer(MediaBuffer* decoded_sample);
+ void stopAndCleanupRenderer();
+
+ sp<MetaData> format_;
+ int32_t format_channels_;
+ int32_t format_sample_rate_;
+
+ sp<MediaSource> decoder_;
+ OMXClient& omx_;
+ Mutex init_lock_;
+
+ sp<ThreadWrapper> thread_;
+ Condition thread_cond_;
+ Mutex thread_lock_;
+ status_t thread_status_;
+
+ Mutex render_lock_;
+ TimedAudioTrack* renderer_;
+ bool last_queued_pts_valid_;
+ int64_t last_queued_pts_;
+ bool last_ts_transform_valid_;
+ LinearTransform last_ts_transform_;
+ uint8_t last_volume_;
+ CCHelper cc_helper_;
+
+ // protected by the thread_lock_
+ typedef List<MediaBuffer*> MBQueue;
+ MBQueue in_queue_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(AAH_DecoderPump);
+};
+
+} // namespace android
+#endif // __DECODER_PUMP_H__
diff --git a/media/libaah_rtp/aah_rx_player.cpp b/media/libaah_rtp/aah_rx_player.cpp
new file mode 100644
index 0000000..9dd79fd
--- /dev/null
+++ b/media/libaah_rtp/aah_rx_player.cpp
@@ -0,0 +1,288 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#define LOG_TAG "LibAAH_RTP"
+//#define LOG_NDEBUG 0
+
+#include <binder/IServiceManager.h>
+#include <media/MediaPlayerInterface.h>
+#include <utils/Log.h>
+
+#include "aah_rx_player.h"
+
+namespace android {
+
+const uint32_t AAH_RXPlayer::kRTPRingBufferSize = 1 << 10;
+
+sp<MediaPlayerBase> createAAH_RXPlayer() {
+ sp<MediaPlayerBase> ret = new AAH_RXPlayer();
+ return ret;
+}
+
+AAH_RXPlayer::AAH_RXPlayer()
+ : ring_buffer_(kRTPRingBufferSize)
+ , substreams_(NULL) {
+ thread_wrapper_ = new ThreadWrapper(*this);
+
+ is_playing_ = false;
+ multicast_joined_ = false;
+ transmitter_known_ = false;
+ current_epoch_known_ = false;
+ data_source_set_ = false;
+ sock_fd_ = -1;
+
+ substreams_.setCapacity(4);
+
+ memset(&listen_addr_, 0, sizeof(listen_addr_));
+ memset(&transmitter_addr_, 0, sizeof(transmitter_addr_));
+
+ fetchAudioFlinger();
+}
+
+AAH_RXPlayer::~AAH_RXPlayer() {
+ reset_l();
+ CHECK(substreams_.size() == 0);
+ omx_.disconnect();
+}
+
+status_t AAH_RXPlayer::initCheck() {
+ if (thread_wrapper_ == NULL) {
+ ALOGE("Failed to allocate thread wrapper!");
+ return NO_MEMORY;
+ }
+
+ if (!ring_buffer_.initCheck()) {
+ ALOGE("Failed to allocate reassembly ring buffer!");
+ return NO_MEMORY;
+ }
+
+ // Check for the presense of the common time service by attempting to query
+ // for CommonTime's frequency. If we get an error back, we cannot talk to
+ // the service at all and should abort now.
+ status_t res;
+ uint64_t freq;
+ res = cc_helper_.getCommonFreq(&freq);
+ if (OK != res) {
+ ALOGE("Failed to connect to common time service!");
+ return res;
+ }
+
+ return omx_.connect();
+}
+
+status_t AAH_RXPlayer::setDataSource(
+ const char *url,
+ const KeyedVector<String8, String8> *headers) {
+ AutoMutex api_lock(&api_lock_);
+ uint32_t a, b, c, d;
+ uint16_t port;
+
+ if (data_source_set_) {
+ return INVALID_OPERATION;
+ }
+
+ if (NULL == url) {
+ return BAD_VALUE;
+ }
+
+ if (5 != sscanf(url, "%*[^:/]://%u.%u.%u.%u:%hu", &a, &b, &c, &d, &port)) {
+ ALOGE("Failed to parse URL \"%s\"", url);
+ return BAD_VALUE;
+ }
+
+ if ((a > 255) || (b > 255) || (c > 255) || (d > 255) || (port == 0)) {
+ ALOGE("Bad multicast address \"%s\"", url);
+ return BAD_VALUE;
+ }
+
+ ALOGI("setDataSource :: %u.%u.%u.%u:%hu", a, b, c, d, port);
+
+ a = (a << 24) | (b << 16) | (c << 8) | d;
+
+ memset(&listen_addr_, 0, sizeof(listen_addr_));
+ listen_addr_.sin_family = AF_INET;
+ listen_addr_.sin_port = htons(port);
+ listen_addr_.sin_addr.s_addr = htonl(a);
+ data_source_set_ = true;
+
+ return OK;
+}
+
+status_t AAH_RXPlayer::setDataSource(int fd, int64_t offset, int64_t length) {
+ return INVALID_OPERATION;
+}
+
+status_t AAH_RXPlayer::setVideoSurface(const sp<Surface>& surface) {
+ return OK;
+}
+
+status_t AAH_RXPlayer::setVideoSurfaceTexture(
+ const sp<ISurfaceTexture>& surfaceTexture) {
+ return OK;
+}
+
+status_t AAH_RXPlayer::prepare() {
+ return OK;
+}
+
+status_t AAH_RXPlayer::prepareAsync() {
+ sendEvent(MEDIA_PREPARED);
+ return OK;
+}
+
+status_t AAH_RXPlayer::start() {
+ AutoMutex api_lock(&api_lock_);
+
+ if (is_playing_) {
+ return OK;
+ }
+
+ status_t res = startWorkThread();
+ is_playing_ = (res == OK);
+ return res;
+}
+
+status_t AAH_RXPlayer::stop() {
+ return pause();
+}
+
+status_t AAH_RXPlayer::pause() {
+ AutoMutex api_lock(&api_lock_);
+ stopWorkThread();
+ CHECK(sock_fd_ < 0);
+ is_playing_ = false;
+ return OK;
+}
+
+bool AAH_RXPlayer::isPlaying() {
+ AutoMutex api_lock(&api_lock_);
+ return is_playing_;
+}
+
+status_t AAH_RXPlayer::seekTo(int msec) {
+ sendEvent(MEDIA_SEEK_COMPLETE);
+ return OK;
+}
+
+status_t AAH_RXPlayer::getCurrentPosition(int *msec) {
+ if (NULL != msec) {
+ *msec = 0;
+ }
+ return OK;
+}
+
+status_t AAH_RXPlayer::getDuration(int *msec) {
+ if (NULL != msec) {
+ *msec = 1;
+ }
+ return OK;
+}
+
+status_t AAH_RXPlayer::reset() {
+ AutoMutex api_lock(&api_lock_);
+ reset_l();
+ return OK;
+}
+
+void AAH_RXPlayer::reset_l() {
+ stopWorkThread();
+ CHECK(sock_fd_ < 0);
+ CHECK(!multicast_joined_);
+ is_playing_ = false;
+ data_source_set_ = false;
+ transmitter_known_ = false;
+ memset(&listen_addr_, 0, sizeof(listen_addr_));
+}
+
+status_t AAH_RXPlayer::setLooping(int loop) {
+ return OK;
+}
+
+player_type AAH_RXPlayer::playerType() {
+ return AAH_RX_PLAYER;
+}
+
+status_t AAH_RXPlayer::setParameter(int key, const Parcel &request) {
+ return ERROR_UNSUPPORTED;
+}
+
+status_t AAH_RXPlayer::getParameter(int key, Parcel *reply) {
+ return ERROR_UNSUPPORTED;
+}
+
+status_t AAH_RXPlayer::invoke(const Parcel& request, Parcel *reply) {
+ if (!reply) {
+ return BAD_VALUE;
+ }
+
+ int32_t magic;
+ status_t err = request.readInt32(&magic);
+ if (err != OK) {
+ reply->writeInt32(err);
+ return OK;
+ }
+
+ if (magic != 0x12345) {
+ reply->writeInt32(BAD_VALUE);
+ return OK;
+ }
+
+ int32_t methodID;
+ err = request.readInt32(&methodID);
+ if (err != OK) {
+ reply->writeInt32(err);
+ return OK;
+ }
+
+ switch (methodID) {
+ // Get Volume
+ case INVOKE_GET_MASTER_VOLUME: {
+ if (audio_flinger_ != NULL) {
+ reply->writeInt32(OK);
+ reply->writeFloat(audio_flinger_->masterVolume());
+ } else {
+ reply->writeInt32(UNKNOWN_ERROR);
+ }
+ } break;
+
+ // Set Volume
+ case INVOKE_SET_MASTER_VOLUME: {
+ float targetVol = request.readFloat();
+ reply->writeInt32(audio_flinger_->setMasterVolume(targetVol));
+ } break;
+
+ default: return BAD_VALUE;
+ }
+
+ return OK;
+}
+
+void AAH_RXPlayer::fetchAudioFlinger() {
+ if (audio_flinger_ == NULL) {
+ sp<IServiceManager> sm = defaultServiceManager();
+ sp<IBinder> binder;
+ binder = sm->getService(String16("media.audio_flinger"));
+
+ if (binder == NULL) {
+ ALOGW("AAH_RXPlayer failed to fetch handle to audio flinger."
+ " Master volume control will not be possible.");
+ }
+
+ audio_flinger_ = interface_cast<IAudioFlinger>(binder);
+ }
+}
+
+} // namespace android
diff --git a/media/libaah_rtp/aah_rx_player.h b/media/libaah_rtp/aah_rx_player.h
new file mode 100644
index 0000000..7a1b6e3
--- /dev/null
+++ b/media/libaah_rtp/aah_rx_player.h
@@ -0,0 +1,313 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#ifndef __AAH_RX_PLAYER_H__
+#define __AAH_RX_PLAYER_H__
+
+#include <common_time/cc_helper.h>
+#include <media/MediaPlayerInterface.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/MediaBuffer.h>
+#include <media/stagefright/MediaSource.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/OMXClient.h>
+#include <netinet/in.h>
+#include <utils/KeyedVector.h>
+#include <utils/LinearTransform.h>
+#include <utils/threads.h>
+
+#include "aah_decoder_pump.h"
+#include "pipe_event.h"
+
+namespace android {
+
+class AAH_RXPlayer : public MediaPlayerInterface {
+ public:
+ AAH_RXPlayer();
+
+ virtual status_t initCheck();
+ virtual status_t setDataSource(const char *url,
+ const KeyedVector<String8, String8>*
+ headers);
+ virtual status_t setDataSource(int fd, int64_t offset, int64_t length);
+ virtual status_t setVideoSurface(const sp<Surface>& surface);
+ virtual status_t setVideoSurfaceTexture(const sp<ISurfaceTexture>&
+ surfaceTexture);
+ virtual status_t prepare();
+ virtual status_t prepareAsync();
+ virtual status_t start();
+ virtual status_t stop();
+ virtual status_t pause();
+ virtual bool isPlaying();
+ virtual status_t seekTo(int msec);
+ virtual status_t getCurrentPosition(int *msec);
+ virtual status_t getDuration(int *msec);
+ virtual status_t reset();
+ virtual status_t setLooping(int loop);
+ virtual player_type playerType();
+ virtual status_t setParameter(int key, const Parcel &request);
+ virtual status_t getParameter(int key, Parcel *reply);
+ virtual status_t invoke(const Parcel& request, Parcel *reply);
+
+ protected:
+ virtual ~AAH_RXPlayer();
+
+ private:
+ class ThreadWrapper : public Thread {
+ public:
+ friend class AAH_RXPlayer;
+ explicit ThreadWrapper(AAH_RXPlayer& player)
+ : Thread(false /* canCallJava */ )
+ , player_(player) { }
+
+ virtual bool threadLoop() { return player_.threadLoop(); }
+
+ private:
+ AAH_RXPlayer& player_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(ThreadWrapper);
+ };
+
+#pragma pack(push, 1)
+ // PacketBuffers are structures used by the RX ring buffer. The ring buffer
+ // is a ring of pointers to PacketBuffer structures which act as variable
+ // length byte arrays and hold the contents of received UDP packets. Rather
+ // than make this a structure which hold a length and a pointer to another
+ // allocated structure (which would require two allocations), this struct
+ // uses a structure overlay pattern where allocation for the byte array
+ // consists of allocating (arrayLen + sizeof(ssize_t)) bytes of data from
+ // whatever pool/heap the packet buffer pulls from, and then overlaying the
+ // packed PacketBuffer structure on top of the allocation. The one-byte
+ // array at the end of the structure serves as an offset to the the data
+ // portion of the allocation; packet buffers are never allocated on the
+ // stack or using the new operator. Instead, the static allocate-byte-array
+ // and destroy methods handle the allocate and overlay pattern. They also
+ // allow for a potential future optimization where instead of just
+ // allocating blocks from the process global heap and overlaying, the
+ // allocator is replaced with a different implementation (private heap,
+ // free-list, circular buffer, etc) which reduces potential heap
+ // fragmentation issues which might arise from the frequent allocation and
+ // destruction of the received UDP traffic.
+ struct PacketBuffer {
+ ssize_t length_;
+ uint8_t data_[1];
+
+ // TODO : consider changing this to be some form of ring buffer or free
+ // pool system instead of just using the heap in order to avoid heap
+ // fragmentation.
+ static PacketBuffer* allocate(ssize_t length);
+ static void destroy(PacketBuffer* pb);
+
+ private:
+ // Force people to use allocate/destroy instead of new/delete.
+ PacketBuffer() { }
+ ~PacketBuffer() { }
+ };
+
+ struct RetransRequest {
+ uint32_t magic_;
+ uint32_t mcast_ip_;
+ uint16_t mcast_port_;
+ uint16_t start_seq_;
+ uint16_t end_seq_;
+ };
+#pragma pack(pop)
+
+ enum GapStatus {
+ kGS_NoGap = 0,
+ kGS_NormalGap,
+ kGS_FastStartGap,
+ };
+
+ struct SeqNoGap {
+ uint16_t start_seq_;
+ uint16_t end_seq_;
+ };
+
+ class RXRingBuffer {
+ public:
+ explicit RXRingBuffer(uint32_t capacity);
+ ~RXRingBuffer();
+
+ bool initCheck() const { return (ring_ != NULL); }
+ void reset();
+
+ // Push a packet buffer with a given sequence number into the ring
+ // buffer. pushBuffer will always consume the buffer pushed to it,
+ // either destroying it because it was a duplicate or overflow, or
+ // holding on to it in the ring. Callers should not hold any references
+ // to PacketBuffers after they have been pushed to the ring. Returns
+ // false in the case of a serious error (such as ring overflow).
+ // Callers should consider resetting the pipeline entirely in the event
+ // of a serious error.
+ bool pushBuffer(PacketBuffer* buf, uint16_t seq);
+
+ // Fetch the next buffer in the RTP sequence. Returns NULL if there is
+ // no buffer to fetch. If a non-NULL PacketBuffer is returned,
+ // is_discon will be set to indicate whether or not this PacketBuffer is
+ // discontiuous with any previously returned packet buffers. Packet
+ // buffers returned by fetchBuffer are the caller's responsibility; they
+ // must be certain to destroy the buffers when they are done.
+ PacketBuffer* fetchBuffer(bool* is_discon);
+
+ // Returns true and fills out the gap structure if the read pointer of
+ // the ring buffer is currently pointing to a gap which would stall a
+ // fetchBuffer operation. Returns false if the read pointer is not
+ // pointing to a gap in the sequence currently.
+ GapStatus fetchCurrentGap(SeqNoGap* gap);
+
+ // Causes the read pointer to skip over any portion of a gap indicated
+ // by nak. If nak is NULL, any gap currently blocking the read pointer
+ // will be completely skipped. If any portion of a gap is skipped, the
+ // next successful read from fetch buffer will indicate a discontinuity.
+ void processNAK(const SeqNoGap* nak = NULL);
+
+ // Compute the number of milliseconds until the inactivity timer for
+ // this RTP stream. Returns -1 if there is no active timeout, or 0 if
+ // the system has already timed out.
+ int computeInactivityTimeout();
+
+ private:
+ Mutex lock_;
+ PacketBuffer** ring_;
+ uint32_t capacity_;
+ uint32_t rd_;
+ uint32_t wr_;
+
+ uint16_t rd_seq_;
+ bool rd_seq_known_;
+ bool waiting_for_fast_start_;
+ bool fetched_first_packet_;
+
+ uint64_t rtp_activity_timeout_;
+ bool rtp_activity_timeout_valid_;
+
+ DISALLOW_EVIL_CONSTRUCTORS(RXRingBuffer);
+ };
+
+ class Substream : public virtual RefBase {
+ public:
+ Substream(uint32_t ssrc, OMXClient& omx);
+
+ void cleanupBufferInProgress();
+ void shutdown();
+ void processPayloadStart(uint8_t* buf,
+ uint32_t amt,
+ int32_t ts_lower);
+ void processPayloadCont (uint8_t* buf,
+ uint32_t amt);
+ void processTSTransform(const LinearTransform& trans);
+
+ bool isAboutToUnderflow();
+ uint32_t getSSRC() const { return ssrc_; }
+ uint16_t getProgramID() const { return (ssrc_ >> 5) & 0x1F; }
+ status_t getStatus() const { return status_; }
+
+ protected:
+ virtual ~Substream() {
+ shutdown();
+ }
+
+ private:
+ void cleanupDecoder();
+ bool shouldAbort(const char* log_tag);
+ void processCompletedBuffer();
+ bool setupSubstreamType(uint8_t substream_type,
+ uint8_t codec_type);
+
+ uint32_t ssrc_;
+ bool waiting_for_rap_;
+ status_t status_;
+
+ bool substream_details_known_;
+ uint8_t substream_type_;
+ uint8_t codec_type_;
+ sp<MetaData> substream_meta_;
+
+ MediaBuffer* buffer_in_progress_;
+ uint32_t expected_buffer_size_;
+ uint32_t buffer_filled_;
+
+ sp<AAH_DecoderPump> decoder_;
+
+ static int64_t kAboutToUnderflowThreshold;
+
+ DISALLOW_EVIL_CONSTRUCTORS(Substream);
+ };
+
+ typedef DefaultKeyedVector< uint32_t, sp<Substream> > SubstreamVec;
+
+ status_t startWorkThread();
+ void stopWorkThread();
+ virtual bool threadLoop();
+ bool setupSocket();
+ void cleanupSocket();
+ void resetPipeline();
+ void reset_l();
+ bool processRX(PacketBuffer* pb);
+ void processRingBuffer();
+ void processCommandPacket(PacketBuffer* pb);
+ bool processGaps();
+ int computeNextGapRetransmitTimeout();
+ void fetchAudioFlinger();
+
+ PipeEvent wakeup_work_thread_evt_;
+ sp<ThreadWrapper> thread_wrapper_;
+ Mutex api_lock_;
+ bool is_playing_;
+ bool data_source_set_;
+
+ struct sockaddr_in listen_addr_;
+ int sock_fd_;
+ bool multicast_joined_;
+
+ struct sockaddr_in transmitter_addr_;
+ bool transmitter_known_;
+
+ uint32_t current_epoch_;
+ bool current_epoch_known_;
+
+ SeqNoGap current_gap_;
+ GapStatus current_gap_status_;
+ uint64_t next_retrans_req_time_;
+
+ RXRingBuffer ring_buffer_;
+ SubstreamVec substreams_;
+ OMXClient omx_;
+ CCHelper cc_helper_;
+
+ // Connection to audio flinger used to hack a path to setMasterVolume.
+ sp<IAudioFlinger> audio_flinger_;
+
+ static const uint32_t kRTPRingBufferSize;
+ static const uint32_t kRetransRequestMagic;
+ static const uint32_t kFastStartRequestMagic;
+ static const uint32_t kRetransNAKMagic;
+ static const uint32_t kGapRerequestTimeoutUSec;
+ static const uint32_t kFastStartTimeoutUSec;
+ static const uint32_t kRTPActivityTimeoutUSec;
+
+ static const uint32_t INVOKE_GET_MASTER_VOLUME = 3;
+ static const uint32_t INVOKE_SET_MASTER_VOLUME = 4;
+
+ static uint64_t monotonicUSecNow();
+
+ DISALLOW_EVIL_CONSTRUCTORS(AAH_RXPlayer);
+};
+
+} // namespace android
+
+#endif // __AAH_RX_PLAYER_H__
diff --git a/media/libaah_rtp/aah_rx_player_core.cpp b/media/libaah_rtp/aah_rx_player_core.cpp
new file mode 100644
index 0000000..d2b3386
--- /dev/null
+++ b/media/libaah_rtp/aah_rx_player_core.cpp
@@ -0,0 +1,807 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#define LOG_TAG "LibAAH_RTP"
+//#define LOG_NDEBUG 0
+#include <utils/Log.h>
+
+#include <fcntl.h>
+#include <poll.h>
+#include <sys/socket.h>
+#include <time.h>
+#include <utils/misc.h>
+
+#include <media/stagefright/Utils.h>
+
+#include "aah_rx_player.h"
+#include "aah_tx_packet.h"
+
+namespace android {
+
+const uint32_t AAH_RXPlayer::kRetransRequestMagic =
+ FOURCC('T','r','e','q');
+const uint32_t AAH_RXPlayer::kRetransNAKMagic =
+ FOURCC('T','n','a','k');
+const uint32_t AAH_RXPlayer::kFastStartRequestMagic =
+ FOURCC('T','f','s','t');
+const uint32_t AAH_RXPlayer::kGapRerequestTimeoutUSec = 75000;
+const uint32_t AAH_RXPlayer::kFastStartTimeoutUSec = 800000;
+const uint32_t AAH_RXPlayer::kRTPActivityTimeoutUSec = 10000000;
+
+static inline int16_t fetchInt16(uint8_t* data) {
+ return static_cast<int16_t>(U16_AT(data));
+}
+
+static inline int32_t fetchInt32(uint8_t* data) {
+ return static_cast<int32_t>(U32_AT(data));
+}
+
+static inline int64_t fetchInt64(uint8_t* data) {
+ return static_cast<int64_t>(U64_AT(data));
+}
+
+uint64_t AAH_RXPlayer::monotonicUSecNow() {
+ struct timespec now;
+ int res = clock_gettime(CLOCK_MONOTONIC, &now);
+ CHECK(res >= 0);
+
+ uint64_t ret = static_cast<uint64_t>(now.tv_sec) * 1000000;
+ ret += now.tv_nsec / 1000;
+
+ return ret;
+}
+
+status_t AAH_RXPlayer::startWorkThread() {
+ status_t res;
+ stopWorkThread();
+ res = thread_wrapper_->run("TRX_Player", PRIORITY_AUDIO);
+
+ if (res != OK) {
+ ALOGE("Failed to start work thread (res = %d)", res);
+ }
+
+ return res;
+}
+
+void AAH_RXPlayer::stopWorkThread() {
+ thread_wrapper_->requestExit(); // set the exit pending flag
+ wakeup_work_thread_evt_.setEvent();
+
+ status_t res;
+ res = thread_wrapper_->requestExitAndWait(); // block until thread exit.
+ if (res != OK) {
+ ALOGE("Failed to stop work thread (res = %d)", res);
+ }
+
+ wakeup_work_thread_evt_.clearPendingEvents();
+}
+
+void AAH_RXPlayer::cleanupSocket() {
+ if (sock_fd_ >= 0) {
+ if (multicast_joined_) {
+ int res;
+ struct ip_mreq mreq;
+ mreq.imr_multiaddr = listen_addr_.sin_addr;
+ mreq.imr_interface.s_addr = htonl(INADDR_ANY);
+ res = setsockopt(sock_fd_,
+ IPPROTO_IP,
+ IP_DROP_MEMBERSHIP,
+ &mreq, sizeof(mreq));
+ if (res < 0) {
+ ALOGW("Failed to leave multicast group. (%d, %d)", res, errno);
+ }
+ multicast_joined_ = false;
+ }
+
+ close(sock_fd_);
+ sock_fd_ = -1;
+ }
+
+ resetPipeline();
+}
+
+void AAH_RXPlayer::resetPipeline() {
+ ring_buffer_.reset();
+
+ // Explicitly shudown all of the active substreams, then call clear out the
+ // collection. Failure to clear out a substream can result in its decoder
+ // holding a reference to itself and therefor not going away when the
+ // collection is cleared.
+ for (size_t i = 0; i < substreams_.size(); ++i)
+ substreams_.valueAt(i)->shutdown();
+
+ substreams_.clear();
+
+ current_gap_status_ = kGS_NoGap;
+}
+
+bool AAH_RXPlayer::setupSocket() {
+ long flags;
+ int res, buf_size;
+ socklen_t opt_size;
+
+ cleanupSocket();
+ CHECK(sock_fd_ < 0);
+
+ // Make the socket
+ sock_fd_ = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (sock_fd_ < 0) {
+ ALOGE("Failed to create listen socket (errno %d)", errno);
+ goto bailout;
+ }
+
+ // Set non-blocking operation
+ flags = fcntl(sock_fd_, F_GETFL);
+ res = fcntl(sock_fd_, F_SETFL, flags | O_NONBLOCK);
+ if (res < 0) {
+ ALOGE("Failed to set socket (%d) to non-blocking mode (errno %d)",
+ sock_fd_, errno);
+ goto bailout;
+ }
+
+ // Bind to our port
+ struct sockaddr_in bind_addr;
+ memset(&bind_addr, 0, sizeof(bind_addr));
+ bind_addr.sin_family = AF_INET;
+ bind_addr.sin_addr.s_addr = INADDR_ANY;
+ bind_addr.sin_port = listen_addr_.sin_port;
+ res = bind(sock_fd_,
+ reinterpret_cast<const sockaddr*>(&bind_addr),
+ sizeof(bind_addr));
+ if (res < 0) {
+ uint32_t a = ntohl(bind_addr.sin_addr.s_addr);
+ uint16_t p = ntohs(bind_addr.sin_port);
+ ALOGE("Failed to bind socket (%d) to %d.%d.%d.%d:%hd. (errno %d)",
+ sock_fd_,
+ (a >> 24) & 0xFF,
+ (a >> 16) & 0xFF,
+ (a >> 8) & 0xFF,
+ (a ) & 0xFF,
+ p,
+ errno);
+
+ goto bailout;
+ }
+
+ buf_size = 1 << 16; // 64k
+ res = setsockopt(sock_fd_,
+ SOL_SOCKET, SO_RCVBUF,
+ &buf_size, sizeof(buf_size));
+ if (res < 0) {
+ ALOGW("Failed to increase socket buffer size to %d. (errno %d)",
+ buf_size, errno);
+ }
+
+ buf_size = 0;
+ opt_size = sizeof(buf_size);
+ res = getsockopt(sock_fd_,
+ SOL_SOCKET, SO_RCVBUF,
+ &buf_size, &opt_size);
+ if (res < 0) {
+ ALOGW("Failed to fetch socket buffer size. (errno %d)", errno);
+ } else {
+ ALOGI("RX socket buffer size is now %d bytes", buf_size);
+ }
+
+ if (listen_addr_.sin_addr.s_addr) {
+ // Join the multicast group and we should be good to go.
+ struct ip_mreq mreq;
+ mreq.imr_multiaddr = listen_addr_.sin_addr;
+ mreq.imr_interface.s_addr = htonl(INADDR_ANY);
+ res = setsockopt(sock_fd_,
+ IPPROTO_IP,
+ IP_ADD_MEMBERSHIP,
+ &mreq, sizeof(mreq));
+ if (res < 0) {
+ ALOGE("Failed to join multicast group. (errno %d)", errno);
+ goto bailout;
+ }
+ multicast_joined_ = true;
+ }
+
+ return true;
+
+bailout:
+ cleanupSocket();
+ return false;
+}
+
+bool AAH_RXPlayer::threadLoop() {
+ struct pollfd poll_fds[2];
+ bool process_more_right_now = false;
+
+ if (!setupSocket()) {
+ sendEvent(MEDIA_ERROR);
+ goto bailout;
+ }
+
+ while (!thread_wrapper_->exitPending()) {
+ // Step 1: Wait until there is something to do.
+ int gap_timeout = computeNextGapRetransmitTimeout();
+ int ring_timeout = ring_buffer_.computeInactivityTimeout();
+ int timeout = -1;
+
+ if (!ring_timeout) {
+ ALOGW("RTP inactivity timeout reached, resetting pipeline.");
+ resetPipeline();
+ timeout = gap_timeout;
+ } else {
+ if (gap_timeout < 0) {
+ timeout = ring_timeout;
+ } else if (ring_timeout < 0) {
+ timeout = gap_timeout;
+ } else {
+ timeout = (gap_timeout < ring_timeout) ? gap_timeout
+ : ring_timeout;
+ }
+ }
+
+ if ((0 != timeout) && (!process_more_right_now)) {
+ // Set up the events to wait on. Start with the wakeup pipe.
+ memset(&poll_fds, 0, sizeof(poll_fds));
+ poll_fds[0].fd = wakeup_work_thread_evt_.getWakeupHandle();
+ poll_fds[0].events = POLLIN;
+
+ // Add the RX socket.
+ poll_fds[1].fd = sock_fd_;
+ poll_fds[1].events = POLLIN;
+
+ // Wait for something interesing to happen.
+ int poll_res = poll(poll_fds, NELEM(poll_fds), timeout);
+ if (poll_res < 0) {
+ ALOGE("Fatal error (%d,%d) while waiting on events",
+ poll_res, errno);
+ sendEvent(MEDIA_ERROR);
+ goto bailout;
+ }
+ }
+
+ if (thread_wrapper_->exitPending()) {
+ break;
+ }
+
+ wakeup_work_thread_evt_.clearPendingEvents();
+ process_more_right_now = false;
+
+ // Step 2: Do we have data waiting in the socket? If so, drain the
+ // socket moving valid RTP information into the ring buffer to be
+ // processed.
+ if (poll_fds[1].revents) {
+ struct sockaddr_in from;
+ socklen_t from_len;
+
+ ssize_t res = 0;
+ while (!thread_wrapper_->exitPending()) {
+ // Check the size of any pending packet.
+ res = recv(sock_fd_, NULL, 0, MSG_PEEK | MSG_TRUNC);
+
+ // Error?
+ if (res < 0) {
+ // If the error is anything other than would block,
+ // something has gone very wrong.
+ if ((errno != EAGAIN) && (errno != EWOULDBLOCK)) {
+ ALOGE("Fatal socket error during recvfrom (%d, %d)",
+ (int)res, errno);
+ goto bailout;
+ }
+
+ // Socket is out of data, just break out of processing and
+ // wait for more.
+ break;
+ }
+
+ // Allocate a payload.
+ PacketBuffer* pb = PacketBuffer::allocate(res);
+ if (NULL == pb) {
+ ALOGE("Fatal error, failed to allocate packet buffer of"
+ " length %u", static_cast<uint32_t>(res));
+ goto bailout;
+ }
+
+ // Fetch the data.
+ from_len = sizeof(from);
+ res = recvfrom(sock_fd_, pb->data_, pb->length_, 0,
+ reinterpret_cast<struct sockaddr*>(&from),
+ &from_len);
+ if (res != pb->length_) {
+ ALOGE("Fatal error, fetched packet length (%d) does not"
+ " match peeked packet length (%u). This should never"
+ " happen. (errno = %d)",
+ static_cast<int>(res),
+ static_cast<uint32_t>(pb->length_),
+ errno);
+ }
+
+ bool drop_packet = false;
+ if (transmitter_known_) {
+ if (from.sin_addr.s_addr !=
+ transmitter_addr_.sin_addr.s_addr) {
+ uint32_t a = ntohl(from.sin_addr.s_addr);
+ uint16_t p = ntohs(from.sin_port);
+ ALOGV("Dropping packet from unknown transmitter"
+ " %u.%u.%u.%u:%hu",
+ ((a >> 24) & 0xFF),
+ ((a >> 16) & 0xFF),
+ ((a >> 8) & 0xFF),
+ ( a & 0xFF),
+ p);
+
+ drop_packet = true;
+ } else {
+ transmitter_addr_.sin_port = from.sin_port;
+ }
+ } else {
+ memcpy(&transmitter_addr_, &from, sizeof(from));
+ transmitter_known_ = true;
+ }
+
+ if (!drop_packet) {
+ bool serious_error = !processRX(pb);
+
+ if (serious_error) {
+ // Something went "seriously wrong". Currently, the
+ // only trigger for this should be a ring buffer
+ // overflow. The current failsafe behavior for when
+ // something goes seriously wrong is to just reset the
+ // pipeline. The system should behave as if this
+ // AAH_RXPlayer was just set up for the first time.
+ ALOGE("Something just went seriously wrong with the"
+ " pipeline. Resetting.");
+ resetPipeline();
+ }
+ } else {
+ PacketBuffer::destroy(pb);
+ }
+ }
+ }
+
+ // Step 3: Process any data we mave have accumulated in the ring buffer
+ // so far.
+ if (!thread_wrapper_->exitPending()) {
+ processRingBuffer();
+ }
+
+ // Step 4: At this point in time, the ring buffer should either be
+ // empty, or stalled in front of a gap caused by some dropped packets.
+ // Check on the current gap situation and deal with it in an appropriate
+ // fashion. If processGaps returns true, it means that it has given up
+ // on a gap and that we should try to process some more data
+ // immediately.
+ if (!thread_wrapper_->exitPending()) {
+ process_more_right_now = processGaps();
+ }
+
+ // Step 5: Check for fatal errors. If any of our substreams has
+ // encountered a fatal, unrecoverable, error, then propagate the error
+ // up to user level and shut down.
+ for (size_t i = 0; i < substreams_.size(); ++i) {
+ status_t status;
+ CHECK(substreams_.valueAt(i) != NULL);
+
+ status = substreams_.valueAt(i)->getStatus();
+ if (OK != status) {
+ ALOGE("Substream index %d has encountered an unrecoverable"
+ " error (%d). Signalling application level and shutting"
+ " down.", i, status);
+ sendEvent(MEDIA_ERROR);
+ goto bailout;
+ }
+ }
+ }
+
+bailout:
+ cleanupSocket();
+ return false;
+}
+
+bool AAH_RXPlayer::processRX(PacketBuffer* pb) {
+ CHECK(NULL != pb);
+
+ uint8_t* data = pb->data_;
+ ssize_t amt = pb->length_;
+ uint32_t nak_magic;
+ uint16_t seq_no;
+ uint32_t epoch;
+
+ // Every packet either starts with an RTP header which is at least 12 bytes
+ // long or is a retry NAK which is 14 bytes long. If there are fewer than
+ // 12 bytes here, this cannot be a proper RTP packet.
+ if (amt < 12) {
+ ALOGV("Dropping packet, too short to contain RTP header (%u bytes)",
+ static_cast<uint32_t>(amt));
+ goto drop_packet;
+ }
+
+ // Check to see if this is the special case of a NAK packet.
+ nak_magic = ntohl(*(reinterpret_cast<uint32_t*>(data)));
+ if (nak_magic == kRetransNAKMagic) {
+ // Looks like a NAK packet; make sure its long enough.
+
+ if (amt < static_cast<ssize_t>(sizeof(RetransRequest))) {
+ ALOGV("Dropping packet, too short to contain NAK payload (%u bytes)",
+ static_cast<uint32_t>(amt));
+ goto drop_packet;
+ }
+
+ SeqNoGap gap;
+ RetransRequest* rtr = reinterpret_cast<RetransRequest*>(data);
+ gap.start_seq_ = ntohs(rtr->start_seq_);
+ gap.end_seq_ = ntohs(rtr->end_seq_);
+
+ ALOGV("Process NAK for gap at [%hu, %hu]", gap.start_seq_, gap.end_seq_);
+ ring_buffer_.processNAK(&gap);
+
+ return true;
+ }
+
+ // According to the TRTP spec, version should be 2, padding should be 0,
+ // extension should be 0 and CSRCCnt should be 0. If any of these tests
+ // fail, we chuck the packet.
+ if (data[0] != 0x80) {
+ ALOGV("Dropping packet, bad V/P/X/CSRCCnt field (0x%02x)",
+ data[0]);
+ goto drop_packet;
+ }
+
+ // Check the payload type. For TRTP, it should always be 100.
+ if ((data[1] & 0x7F) != 100) {
+ ALOGV("Dropping packet, bad payload type. (%u)",
+ data[1] & 0x7F);
+ goto drop_packet;
+ }
+
+ // Check whether the transmitter has begun a new epoch.
+ epoch = (U32_AT(data + 8) >> 10) & 0x3FFFFF;
+ if (current_epoch_known_) {
+ if (epoch != current_epoch_) {
+ ALOGV("%s: new epoch %u", __PRETTY_FUNCTION__, epoch);
+ current_epoch_ = epoch;
+ resetPipeline();
+ }
+ } else {
+ current_epoch_ = epoch;
+ current_epoch_known_ = true;
+ }
+
+ // Extract the sequence number and hand the packet off to the ring buffer
+ // for dropped packet detection and later processing.
+ seq_no = U16_AT(data + 2);
+ return ring_buffer_.pushBuffer(pb, seq_no);
+
+drop_packet:
+ PacketBuffer::destroy(pb);
+ return true;
+}
+
+void AAH_RXPlayer::processRingBuffer() {
+ PacketBuffer* pb;
+ bool is_discon;
+ sp<Substream> substream;
+ LinearTransform trans;
+ bool foundTrans = false;
+
+ while (NULL != (pb = ring_buffer_.fetchBuffer(&is_discon))) {
+ if (is_discon) {
+ // Abort all partially assembled payloads.
+ for (size_t i = 0; i < substreams_.size(); ++i) {
+ CHECK(substreams_.valueAt(i) != NULL);
+ substreams_.valueAt(i)->cleanupBufferInProgress();
+ }
+ }
+
+ uint8_t* data = pb->data_;
+ ssize_t amt = pb->length_;
+
+ // Should not have any non-RTP packets in the ring buffer. RTP packets
+ // must be at least 12 bytes long.
+ CHECK(amt >= 12);
+
+ // Extract the marker bit and the SSRC field.
+ bool marker = (data[1] & 0x80) != 0;
+ uint32_t ssrc = U32_AT(data + 8);
+
+ // Is this the start of a new TRTP payload? If so, the marker bit
+ // should be set and there are some things we should be checking for.
+ if (marker) {
+ // TRTP headers need to have at least a byte for version, a byte for
+ // payload type and flags, and 4 bytes for length.
+ if (amt < 18) {
+ ALOGV("Dropping packet, too short to contain TRTP header"
+ " (%u bytes)", static_cast<uint32_t>(amt));
+ goto process_next_packet;
+ }
+
+ // Check the TRTP version and extract the payload type/flags.
+ uint8_t trtp_version = data[12];
+ uint8_t payload_type = (data[13] >> 4) & 0xF;
+ uint8_t trtp_flags = data[13] & 0xF;
+
+ if (1 != trtp_version) {
+ ALOGV("Dropping packet, bad trtp version %hhu", trtp_version);
+ goto process_next_packet;
+ }
+
+ // Is there a timestamp transformation present on this packet? If
+ // so, extract it and pass it to the appropriate substreams.
+ if (trtp_flags & 0x02) {
+ ssize_t offset = 18 + ((trtp_flags & 0x01) ? 4 : 0);
+ if (amt < (offset + 24)) {
+ ALOGV("Dropping packet, too short to contain TRTP Timestamp"
+ " Transformation (%u bytes)",
+ static_cast<uint32_t>(amt));
+ goto process_next_packet;
+ }
+
+ trans.a_zero = fetchInt64(data + offset);
+ trans.b_zero = fetchInt64(data + offset + 16);
+ trans.a_to_b_numer = static_cast<int32_t>(
+ fetchInt32 (data + offset + 8));
+ trans.a_to_b_denom = U32_AT(data + offset + 12);
+ foundTrans = true;
+
+ uint32_t program_id = (ssrc >> 5) & 0x1F;
+ for (size_t i = 0; i < substreams_.size(); ++i) {
+ sp<Substream> iter = substreams_.valueAt(i);
+ CHECK(iter != NULL);
+
+ if (iter->getProgramID() == program_id) {
+ iter->processTSTransform(trans);
+ }
+ }
+ }
+
+ // Is this a command packet? If so, its not necessarily associate
+ // with one particular substream. Just give it to the command
+ // packet handler and then move on.
+ if (4 == payload_type) {
+ processCommandPacket(pb);
+ goto process_next_packet;
+ }
+ }
+
+ // If we got to here, then we are a normal packet. Find (or allocate)
+ // the substream we belong to and send the packet off to be processed.
+ substream = substreams_.valueFor(ssrc);
+ if (substream == NULL) {
+ substream = new Substream(ssrc, omx_);
+ if (substream == NULL) {
+ ALOGE("Failed to allocate substream for SSRC 0x%08x", ssrc);
+ goto process_next_packet;
+ }
+ substreams_.add(ssrc, substream);
+
+ if (foundTrans) {
+ substream->processTSTransform(trans);
+ }
+ }
+
+ CHECK(substream != NULL);
+
+ if (marker) {
+ // Start of a new TRTP payload for this substream. Extract the
+ // lower 32 bits of the timestamp and hand the buffer to the
+ // substream for processing.
+ uint32_t ts_lower = U32_AT(data + 4);
+ substream->processPayloadStart(data + 12, amt - 12, ts_lower);
+ } else {
+ // Continuation of an existing TRTP payload. Just hand it off to
+ // the substream for processing.
+ substream->processPayloadCont(data + 12, amt - 12);
+ }
+
+process_next_packet:
+ PacketBuffer::destroy(pb);
+ } // end of main processing while loop.
+}
+
+void AAH_RXPlayer::processCommandPacket(PacketBuffer* pb) {
+ CHECK(NULL != pb);
+
+ uint8_t* data = pb->data_;
+ ssize_t amt = pb->length_;
+
+ // verify that this packet meets the minimum length of a command packet
+ if (amt < 20) {
+ return;
+ }
+
+ uint8_t trtp_version = data[12];
+ uint8_t trtp_flags = data[13] & 0xF;
+
+ if (1 != trtp_version) {
+ ALOGV("Dropping packet, bad trtp version %hhu", trtp_version);
+ return;
+ }
+
+ // calculate the start of the command payload
+ ssize_t offset = 18;
+ if (trtp_flags & 0x01) {
+ // timestamp is present (4 bytes)
+ offset += 4;
+ }
+ if (trtp_flags & 0x02) {
+ // transform is present (24 bytes)
+ offset += 24;
+ }
+
+ // the packet must contain 2 bytes of command payload beyond the TRTP header
+ if (amt < offset + 2) {
+ return;
+ }
+
+ uint16_t command_id = U16_AT(data + offset);
+
+ switch (command_id) {
+ case TRTPControlPacket::kCommandNop:
+ break;
+
+ case TRTPControlPacket::kCommandEOS:
+ case TRTPControlPacket::kCommandFlush: {
+ uint16_t program_id = (U32_AT(data + 8) >> 5) & 0x1F;
+ ALOGI("*** %s flushing program_id=%d",
+ __PRETTY_FUNCTION__, program_id);
+
+ Vector<uint32_t> substreams_to_remove;
+ for (size_t i = 0; i < substreams_.size(); ++i) {
+ sp<Substream> iter = substreams_.valueAt(i);
+ if (iter->getProgramID() == program_id) {
+ iter->shutdown();
+ substreams_to_remove.add(iter->getSSRC());
+ }
+ }
+
+ for (size_t i = 0; i < substreams_to_remove.size(); ++i) {
+ substreams_.removeItem(substreams_to_remove[i]);
+ }
+ } break;
+ }
+}
+
+bool AAH_RXPlayer::processGaps() {
+ // Deal with the current gap situation. Specifically...
+ //
+ // 1) If a new gap has shown up, send a retransmit request to the
+ // transmitter.
+ // 2) If a gap we were working on has had a packet in the middle or at
+ // the end filled in, send another retransmit request for the begining
+ // portion of the gap. TRTP was designed for LANs where packet
+ // re-ordering is very unlikely; so see the middle or end of a gap
+ // filled in before the begining is an almost certain indication that
+ // a retransmission packet was also dropped.
+ // 3) If we have been working on a gap for a while and it still has not
+ // been filled in, send another retransmit request.
+ // 4) If the are no more gaps in the ring, clear the current_gap_status_
+ // flag to indicate that all is well again.
+
+ // Start by fetching the active gap status.
+ SeqNoGap gap;
+ bool send_retransmit_request = false;
+ bool ret_val = false;
+ GapStatus gap_status;
+ if (kGS_NoGap != (gap_status = ring_buffer_.fetchCurrentGap(&gap))) {
+ // Note: checking for a change in the end sequence number should cover
+ // moving on to an entirely new gap for case #1 as well as resending the
+ // begining of a gap range for case #2.
+ send_retransmit_request = (kGS_NoGap == current_gap_status_) ||
+ (current_gap_.end_seq_ != gap.end_seq_);
+
+ // If this is the same gap we have been working on, and it has timed
+ // out, then check to see if our substreams are about to underflow. If
+ // so, instead of sending another retransmit request, just give up on
+ // this gap and move on.
+ if (!send_retransmit_request &&
+ (kGS_NoGap != current_gap_status_) &&
+ (0 == computeNextGapRetransmitTimeout())) {
+
+ // If out current gap is the fast-start gap, don't bother to skip it
+ // because substreams look like the are about to underflow.
+ if ((kGS_FastStartGap != gap_status) ||
+ (current_gap_.end_seq_ != gap.end_seq_)) {
+ for (size_t i = 0; i < substreams_.size(); ++i) {
+ if (substreams_.valueAt(i)->isAboutToUnderflow()) {
+ ALOGV("About to underflow, giving up on gap [%hu, %hu]",
+ gap.start_seq_, gap.end_seq_);
+ ring_buffer_.processNAK();
+ current_gap_status_ = kGS_NoGap;
+ return true;
+ }
+ }
+ }
+
+ // Looks like no one is about to underflow. Just go ahead and send
+ // the request.
+ send_retransmit_request = true;
+ }
+ } else {
+ current_gap_status_ = kGS_NoGap;
+ }
+
+ if (send_retransmit_request) {
+ // If we have been working on a fast start, and it is still not filled
+ // in, even after the extended retransmit time out, give up and skip it.
+ // The system should fall back into its normal slow-start behavior.
+ if ((kGS_FastStartGap == current_gap_status_) &&
+ (current_gap_.end_seq_ == gap.end_seq_)) {
+ ALOGV("Fast start is taking forever; giving up.");
+ ring_buffer_.processNAK();
+ current_gap_status_ = kGS_NoGap;
+ return true;
+ }
+
+ // Send the request.
+ RetransRequest req;
+ uint32_t magic = (kGS_FastStartGap == gap_status)
+ ? kFastStartRequestMagic
+ : kRetransRequestMagic;
+ req.magic_ = htonl(magic);
+ req.mcast_ip_ = listen_addr_.sin_addr.s_addr;
+ req.mcast_port_ = listen_addr_.sin_port;
+ req.start_seq_ = htons(gap.start_seq_);
+ req.end_seq_ = htons(gap.end_seq_);
+
+ {
+ uint32_t a = ntohl(transmitter_addr_.sin_addr.s_addr);
+ uint16_t p = ntohs(transmitter_addr_.sin_port);
+ ALOGV("Sending to transmitter %u.%u.%u.%u:%hu",
+ ((a >> 24) & 0xFF),
+ ((a >> 16) & 0xFF),
+ ((a >> 8) & 0xFF),
+ ( a & 0xFF),
+ p);
+ }
+
+ int res = sendto(sock_fd_, &req, sizeof(req), 0,
+ reinterpret_cast<struct sockaddr*>(&transmitter_addr_),
+ sizeof(transmitter_addr_));
+ if (res < 0) {
+ ALOGE("Error when sending retransmit request (%d)", errno);
+ } else {
+ ALOGV("%s request for range [%hu, %hu] sent",
+ (kGS_FastStartGap == gap_status) ? "Fast Start" : "Retransmit",
+ gap.start_seq_, gap.end_seq_);
+ }
+
+ // Update the current gap info.
+ current_gap_ = gap;
+ current_gap_status_ = gap_status;
+ next_retrans_req_time_ = monotonicUSecNow() +
+ ((kGS_FastStartGap == current_gap_status_)
+ ? kFastStartTimeoutUSec
+ : kGapRerequestTimeoutUSec);
+ }
+
+ return false;
+}
+
+// Compute when its time to send the next gap retransmission in milliseconds.
+// Returns < 0 for an infinite timeout (no gap) and 0 if its time to retransmit
+// right now.
+int AAH_RXPlayer::computeNextGapRetransmitTimeout() {
+ if (kGS_NoGap == current_gap_status_) {
+ return -1;
+ }
+
+ int64_t timeout_delta = next_retrans_req_time_ - monotonicUSecNow();
+
+ timeout_delta /= 1000;
+ if (timeout_delta <= 0) {
+ return 0;
+ }
+
+ return static_cast<uint32_t>(timeout_delta);
+}
+
+} // namespace android
diff --git a/media/libaah_rtp/aah_rx_player_ring_buffer.cpp b/media/libaah_rtp/aah_rx_player_ring_buffer.cpp
new file mode 100644
index 0000000..0d8b31f
--- /dev/null
+++ b/media/libaah_rtp/aah_rx_player_ring_buffer.cpp
@@ -0,0 +1,366 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#define LOG_TAG "LibAAH_RTP"
+//#define LOG_NDEBUG 0
+#include <utils/Log.h>
+
+#include "aah_rx_player.h"
+
+namespace android {
+
+AAH_RXPlayer::RXRingBuffer::RXRingBuffer(uint32_t capacity) {
+ capacity_ = capacity;
+ rd_ = wr_ = 0;
+ ring_ = new PacketBuffer*[capacity];
+ memset(ring_, 0, sizeof(PacketBuffer*) * capacity);
+ reset();
+}
+
+AAH_RXPlayer::RXRingBuffer::~RXRingBuffer() {
+ reset();
+ delete[] ring_;
+}
+
+void AAH_RXPlayer::RXRingBuffer::reset() {
+ AutoMutex lock(&lock_);
+
+ if (NULL != ring_) {
+ while (rd_ != wr_) {
+ CHECK(rd_ < capacity_);
+ if (NULL != ring_[rd_]) {
+ PacketBuffer::destroy(ring_[rd_]);
+ ring_[rd_] = NULL;
+ }
+ rd_ = (rd_ + 1) % capacity_;
+ }
+ }
+
+ rd_ = wr_ = 0;
+ rd_seq_known_ = false;
+ waiting_for_fast_start_ = true;
+ fetched_first_packet_ = false;
+ rtp_activity_timeout_valid_ = false;
+}
+
+bool AAH_RXPlayer::RXRingBuffer::pushBuffer(PacketBuffer* buf,
+ uint16_t seq) {
+ AutoMutex lock(&lock_);
+ CHECK(NULL != ring_);
+ CHECK(NULL != buf);
+
+ rtp_activity_timeout_valid_ = true;
+ rtp_activity_timeout_ = monotonicUSecNow() + kRTPActivityTimeoutUSec;
+
+ // If the ring buffer is totally reset (we have never received a single
+ // payload) then we don't know the rd sequence number and this should be
+ // simple. We just store the payload, advance the wr pointer and record the
+ // initial sequence number.
+ if (!rd_seq_known_) {
+ CHECK(rd_ == wr_);
+ CHECK(NULL == ring_[wr_]);
+ CHECK(wr_ < capacity_);
+
+ ring_[wr_] = buf;
+ wr_ = (wr_ + 1) % capacity_;
+ rd_seq_ = seq;
+ rd_seq_known_ = true;
+ return true;
+ }
+
+ // Compute the seqence number of this payload and of the write pointer,
+ // normalized around the read pointer. IOW - transform the payload seq no
+ // and the wr pointer seq no into a space where the rd pointer seq no is
+ // zero. This will define 4 cases we can consider...
+ //
+ // 1) norm_seq == norm_wr_seq
+ // This payload is contiguous with the last. All is good.
+ //
+ // 2) ((norm_seq < norm_wr_seq) && (norm_seq >= norm_rd_seq)
+ // aka ((norm_seq < norm_wr_seq) && (norm_seq >= 0)
+ // This payload is in the past, in the unprocessed region of the ring
+ // buffer. It is probably a retransmit intended to fill in a dropped
+ // payload; it may be a duplicate.
+ //
+ // 3) ((norm_seq - norm_wr_seq) & 0x8000) != 0
+ // This payload is in the past compared to the write pointer (or so very
+ // far in the future that it has wrapped the seq no space), but not in
+ // the unprocessed region of the ring buffer. This could be a duplicate
+ // retransmit; we just drop these payloads unless we are waiting for our
+ // first fast start packet. If we are waiting for fast start, than this
+ // packet is probably the first packet of the fast start retransmission.
+ // If it will fit in the buffer, back up the read pointer to its position
+ // and clear the fast start flag, otherwise just drop it.
+ //
+ // 4) ((norm_seq - norm_wr_seq) & 0x8000) == 0
+ // This payload which is ahead of the next write pointer. This indicates
+ // that we have missed some payloads and need to request a retransmit.
+ // If norm_seq >= (capacity - 1), then the gap is so large that it would
+ // overflow the ring buffer and we should probably start to panic.
+
+ uint16_t norm_wr_seq = ((wr_ + capacity_ - rd_) % capacity_);
+ uint16_t norm_seq = seq - rd_seq_;
+
+ // Check for overflow first.
+ if ((!(norm_seq & 0x8000)) && (norm_seq >= (capacity_ - 1))) {
+ ALOGW("Ring buffer overflow; cap = %u, [rd, wr] = [%hu, %hu], seq = %hu",
+ capacity_, rd_seq_, norm_wr_seq + rd_seq_, seq);
+ PacketBuffer::destroy(buf);
+ return false;
+ }
+
+ // Check for case #1
+ if (norm_seq == norm_wr_seq) {
+ CHECK(wr_ < capacity_);
+ CHECK(NULL == ring_[wr_]);
+
+ ring_[wr_] = buf;
+ wr_ = (wr_ + 1) % capacity_;
+
+ CHECK(wr_ != rd_);
+ return true;
+ }
+
+ // Check case #2
+ uint32_t ring_pos = (rd_ + norm_seq) % capacity_;
+ if ((norm_seq < norm_wr_seq) && (!(norm_seq & 0x8000))) {
+ // Do we already have a payload for this slot? If so, then this looks
+ // like a duplicate retransmit. Just ignore it.
+ if (NULL != ring_[ring_pos]) {
+ ALOGD("RXed duplicate retransmit, seq = %hu", seq);
+ PacketBuffer::destroy(buf);
+ } else {
+ // Looks like we were missing this payload. Go ahead and store it.
+ ring_[ring_pos] = buf;
+ }
+
+ return true;
+ }
+
+ // Check case #3
+ if ((norm_seq - norm_wr_seq) & 0x8000) {
+ if (!waiting_for_fast_start_) {
+ ALOGD("RXed duplicate retransmit from before rd pointer, seq = %hu",
+ seq);
+ PacketBuffer::destroy(buf);
+ } else {
+ // Looks like a fast start fill-in. Go ahead and store it, assuming
+ // that we can fit it in the buffer.
+ uint32_t implied_ring_size = static_cast<uint32_t>(norm_wr_seq)
+ + (rd_seq_ - seq);
+
+ if (implied_ring_size >= (capacity_ - 1)) {
+ ALOGD("RXed what looks like a fast start packet (seq = %hu),"
+ " but packet is too far in the past to fit into the ring"
+ " buffer. Dropping.", seq);
+ PacketBuffer::destroy(buf);
+ } else {
+ ring_pos = (rd_ + capacity_ + seq - rd_seq_) % capacity_;
+ rd_seq_ = seq;
+ rd_ = ring_pos;
+ waiting_for_fast_start_ = false;
+
+ CHECK(ring_pos < capacity_);
+ CHECK(NULL == ring_[ring_pos]);
+ ring_[ring_pos] = buf;
+ }
+
+ }
+ return true;
+ }
+
+ // Must be in case #4 with no overflow. This packet fits in the current
+ // ring buffer, but is discontiuguous. Advance the write pointer leaving a
+ // gap behind.
+ uint32_t gap_len = (ring_pos + capacity_ - wr_) % capacity_;
+ ALOGD("Drop detected; %u packets, seq_range [%hu, %hu]",
+ gap_len,
+ rd_seq_ + norm_wr_seq,
+ rd_seq_ + norm_wr_seq + gap_len - 1);
+
+ CHECK(NULL == ring_[ring_pos]);
+ ring_[ring_pos] = buf;
+ wr_ = (ring_pos + 1) % capacity_;
+ CHECK(wr_ != rd_);
+
+ return true;
+}
+
+AAH_RXPlayer::PacketBuffer*
+AAH_RXPlayer::RXRingBuffer::fetchBuffer(bool* is_discon) {
+ AutoMutex lock(&lock_);
+ CHECK(NULL != ring_);
+ CHECK(NULL != is_discon);
+
+ // If the read seqence number is not known, then this ring buffer has not
+ // received a packet since being reset and there cannot be any packets to
+ // return. If we are still waiting for the first fast start packet to show
+ // up, we don't want to let any buffer be consumed yet because we expect to
+ // see a packet before the initial read sequence number show up shortly.
+ if (!rd_seq_known_ || waiting_for_fast_start_) {
+ *is_discon = false;
+ return NULL;
+ }
+
+ PacketBuffer* ret = NULL;
+ *is_discon = !fetched_first_packet_;
+
+ while ((rd_ != wr_) && (NULL == ret)) {
+ CHECK(rd_ < capacity_);
+
+ // If we hit a gap, stall and do not advance the read pointer. Let the
+ // higher level code deal with requesting retries and/or deciding to
+ // skip the current gap.
+ ret = ring_[rd_];
+ if (NULL == ret) {
+ break;
+ }
+
+ ring_[rd_] = NULL;
+ rd_ = (rd_ + 1) % capacity_;
+ ++rd_seq_;
+ }
+
+ if (NULL != ret) {
+ fetched_first_packet_ = true;
+ }
+
+ return ret;
+}
+
+AAH_RXPlayer::GapStatus
+AAH_RXPlayer::RXRingBuffer::fetchCurrentGap(SeqNoGap* gap) {
+ AutoMutex lock(&lock_);
+ CHECK(NULL != ring_);
+ CHECK(NULL != gap);
+
+ // If the read seqence number is not known, then this ring buffer has not
+ // received a packet since being reset and there cannot be any gaps.
+ if (!rd_seq_known_) {
+ return kGS_NoGap;
+ }
+
+ // If we are waiting for fast start, then the current gap is a fast start
+ // gap and it includes all packets before the read sequence number.
+ if (waiting_for_fast_start_) {
+ gap->start_seq_ =
+ gap->end_seq_ = rd_seq_ - 1;
+ return kGS_FastStartGap;
+ }
+
+ // If rd == wr, then the buffer is empty and there cannot be any gaps.
+ if (rd_ == wr_) {
+ return kGS_NoGap;
+ }
+
+ // If rd_ is currently pointing at an unprocessed packet, then there is no
+ // current gap.
+ CHECK(rd_ < capacity_);
+ if (NULL != ring_[rd_]) {
+ return kGS_NoGap;
+ }
+
+ // Looks like there must be a gap here. The start of the gap is the current
+ // rd sequence number, all we need to do now is determine its length in
+ // order to compute the end sequence number.
+ gap->start_seq_ = rd_seq_;
+ uint16_t end = rd_seq_;
+ uint32_t tmp = (rd_ + 1) % capacity_;
+ while ((tmp != wr_) && (NULL == ring_[tmp])) {
+ ++end;
+ tmp = (tmp + 1) % capacity_;
+ }
+ gap->end_seq_ = end;
+
+ return kGS_NormalGap;
+}
+
+void AAH_RXPlayer::RXRingBuffer::processNAK(const SeqNoGap* nak) {
+ AutoMutex lock(&lock_);
+ CHECK(NULL != ring_);
+
+ // If we were waiting for our first fast start fill-in packet, and we
+ // received a NAK, then apparantly we are not getting our fast start. Just
+ // clear the waiting flag and go back to normal behavior.
+ if (waiting_for_fast_start_) {
+ waiting_for_fast_start_ = false;
+ }
+
+ // If we have not received a packet since last reset, or there is no data in
+ // the ring, then there is nothing to skip.
+ if ((!rd_seq_known_) || (rd_ == wr_)) {
+ return;
+ }
+
+ // If rd_ is currently pointing at an unprocessed packet, then there is no
+ // gap to skip.
+ CHECK(rd_ < capacity_);
+ if (NULL != ring_[rd_]) {
+ return;
+ }
+
+ // Looks like there must be a gap here. Advance rd until we have passed
+ // over the portion of it indicated by nak (or all of the gap if nak is
+ // NULL). Then reset fetched_first_packet_ so that the next read will show
+ // up as being discontiguous.
+ uint16_t seq_after_gap = (NULL == nak) ? 0 : nak->end_seq_ + 1;
+ while ((rd_ != wr_) &&
+ (NULL == ring_[rd_]) &&
+ ((NULL == nak) || (seq_after_gap != rd_seq_))) {
+ rd_ = (rd_ + 1) % capacity_;
+ ++rd_seq_;
+ }
+ fetched_first_packet_ = false;
+}
+
+int AAH_RXPlayer::RXRingBuffer::computeInactivityTimeout() {
+ AutoMutex lock(&lock_);
+
+ if (!rtp_activity_timeout_valid_) {
+ return -1;
+ }
+
+ uint64_t now = monotonicUSecNow();
+ if (rtp_activity_timeout_ <= now) {
+ return 0;
+ }
+
+ return (rtp_activity_timeout_ - now) / 1000;
+}
+
+AAH_RXPlayer::PacketBuffer*
+AAH_RXPlayer::PacketBuffer::allocate(ssize_t length) {
+ if (length <= 0) {
+ return NULL;
+ }
+
+ uint32_t alloc_len = sizeof(PacketBuffer) + length;
+ PacketBuffer* ret = reinterpret_cast<PacketBuffer*>(
+ new uint8_t[alloc_len]);
+
+ if (NULL != ret) {
+ ret->length_ = length;
+ }
+
+ return ret;
+}
+
+void AAH_RXPlayer::PacketBuffer::destroy(PacketBuffer* pb) {
+ uint8_t* kill_me = reinterpret_cast<uint8_t*>(pb);
+ delete[] kill_me;
+}
+
+} // namespace android
diff --git a/media/libaah_rtp/aah_rx_player_substream.cpp b/media/libaah_rtp/aah_rx_player_substream.cpp
new file mode 100644
index 0000000..1e4c784
--- /dev/null
+++ b/media/libaah_rtp/aah_rx_player_substream.cpp
@@ -0,0 +1,498 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#define LOG_TAG "LibAAH_RTP"
+//#define LOG_NDEBUG 0
+
+#include <utils/Log.h>
+
+#include <include/avc_utils.h>
+#include <media/stagefright/MediaBuffer.h>
+#include <media/stagefright/MediaDefs.h>
+#include <media/stagefright/MetaData.h>
+#include <media/stagefright/OMXCodec.h>
+#include <media/stagefright/Utils.h>
+
+#include "aah_rx_player.h"
+
+namespace android {
+
+int64_t AAH_RXPlayer::Substream::kAboutToUnderflowThreshold =
+ 50ull * 1000;
+
+AAH_RXPlayer::Substream::Substream(uint32_t ssrc, OMXClient& omx) {
+ ssrc_ = ssrc;
+ substream_details_known_ = false;
+ buffer_in_progress_ = NULL;
+ status_ = OK;
+
+ decoder_ = new AAH_DecoderPump(omx);
+ if (decoder_ == NULL) {
+ ALOGE("%s failed to allocate decoder pump!", __PRETTY_FUNCTION__);
+ }
+ if (OK != decoder_->initCheck()) {
+ ALOGE("%s failed to initialize decoder pump!", __PRETTY_FUNCTION__);
+ }
+
+ // cleanupBufferInProgress will reset most of the internal state variables.
+ // Just need to make sure that buffer_in_progress_ is NULL before calling.
+ cleanupBufferInProgress();
+}
+
+
+void AAH_RXPlayer::Substream::shutdown() {
+ substream_meta_ = NULL;
+ status_ = OK;
+ cleanupBufferInProgress();
+ cleanupDecoder();
+}
+
+void AAH_RXPlayer::Substream::cleanupBufferInProgress() {
+ if (NULL != buffer_in_progress_) {
+ buffer_in_progress_->release();
+ buffer_in_progress_ = NULL;
+ }
+
+ expected_buffer_size_ = 0;
+ buffer_filled_ = 0;
+ waiting_for_rap_ = true;
+}
+
+void AAH_RXPlayer::Substream::cleanupDecoder() {
+ if (decoder_ != NULL) {
+ decoder_->shutdown();
+ }
+}
+
+bool AAH_RXPlayer::Substream::shouldAbort(const char* log_tag) {
+ // If we have already encountered a fatal error, do nothing. We are just
+ // waiting for our owner to shut us down now.
+ if (OK != status_) {
+ ALOGV("Skipping %s, substream has encountered fatal error (%d).",
+ log_tag, status_);
+ return true;
+ }
+
+ return false;
+}
+
+void AAH_RXPlayer::Substream::processPayloadStart(uint8_t* buf,
+ uint32_t amt,
+ int32_t ts_lower) {
+ uint32_t min_length = 6;
+
+ if (shouldAbort(__PRETTY_FUNCTION__)) {
+ return;
+ }
+
+ // Do we have a buffer in progress already? If so, abort the buffer. In
+ // theory, this should never happen. If there were a discontinutity in the
+ // stream, the discon in the seq_nos at the RTP level should have already
+ // triggered a cleanup of the buffer in progress. To see a problem at this
+ // level is an indication either of a bug in the transmitter, or some form
+ // of terrible corruption/tampering on the wire.
+ if (NULL != buffer_in_progress_) {
+ ALOGE("processPayloadStart is aborting payload already in progress.");
+ cleanupBufferInProgress();
+ }
+
+ // Parse enough of the header to know where we stand. Since this is a
+ // payload start, it should begin with a TRTP header which has to be at
+ // least 6 bytes long.
+ if (amt < min_length) {
+ ALOGV("Discarding payload too short to contain TRTP header (len = %u)",
+ amt);
+ return;
+ }
+
+ // Check the TRTP version number.
+ if (0x01 != buf[0]) {
+ ALOGV("Unexpected TRTP version (%u) in header. Expected %u.",
+ buf[0], 1);
+ return;
+ }
+
+ // Extract the substream type field and make sure its one we understand (and
+ // one that does not conflict with any previously received substream type.
+ uint8_t header_type = (buf[1] >> 4) & 0xF;
+ switch (header_type) {
+ case 0x01:
+ // Audio, yay! Just break. We understand audio payloads.
+ break;
+ case 0x02:
+ ALOGV("RXed packet with unhandled TRTP header type (Video).");
+ return;
+ case 0x03:
+ ALOGV("RXed packet with unhandled TRTP header type (Subpicture).");
+ return;
+ case 0x04:
+ ALOGV("RXed packet with unhandled TRTP header type (Control).");
+ return;
+ default:
+ ALOGV("RXed packet with unhandled TRTP header type (%u).",
+ header_type);
+ return;
+ }
+
+ if (substream_details_known_ && (header_type != substream_type_)) {
+ ALOGV("RXed TRTP Payload for SSRC=0x%08x where header type (%u) does not"
+ " match previously received header type (%u)",
+ ssrc_, header_type, substream_type_);
+ return;
+ }
+
+ // Check the flags to see if there is another 32 bits of timestamp present.
+ uint32_t trtp_header_len = 6;
+ bool ts_valid = buf[1] & 0x1;
+ if (ts_valid) {
+ min_length += 4;
+ trtp_header_len += 4;
+ if (amt < min_length) {
+ ALOGV("Discarding payload too short to contain TRTP timestamp"
+ " (len = %u)", amt);
+ return;
+ }
+ }
+
+ // Extract the TRTP length field and sanity check it.
+ uint32_t trtp_len;
+ trtp_len = (static_cast<uint32_t>(buf[2]) << 24) |
+ (static_cast<uint32_t>(buf[3]) << 16) |
+ (static_cast<uint32_t>(buf[4]) << 8) |
+ static_cast<uint32_t>(buf[5]);
+ if (trtp_len < min_length) {
+ ALOGV("TRTP length (%u) is too short to be valid. Must be at least %u"
+ " bytes.", trtp_len, min_length);
+ return;
+ }
+
+ // Extract the rest of the timestamp field if valid.
+ int64_t ts = 0;
+ uint32_t parse_offset = 6;
+ if (ts_valid) {
+ ts = (static_cast<int64_t>(buf[parse_offset ]) << 56) |
+ (static_cast<int64_t>(buf[parse_offset + 1]) << 48) |
+ (static_cast<int64_t>(buf[parse_offset + 2]) << 40) |
+ (static_cast<int64_t>(buf[parse_offset + 3]) << 32);
+ ts |= ts_lower;
+ parse_offset += 4;
+ }
+
+ // Check the flags to see if there is another 24 bytes of timestamp
+ // transformation present.
+ if (buf[1] & 0x2) {
+ min_length += 24;
+ parse_offset += 24;
+ trtp_header_len += 24;
+ if (amt < min_length) {
+ ALOGV("Discarding payload too short to contain TRTP timestamp"
+ " transformation (len = %u)", amt);
+ return;
+ }
+ }
+
+ // TODO : break the parsing into individual parsers for the different
+ // payload types (audio, video, etc).
+ //
+ // At this point in time, we know that this is audio. Go ahead and parse
+ // the basic header, check the codec type, and find the payload portion of
+ // the packet.
+ min_length += 3;
+ if (trtp_len < min_length) {
+ ALOGV("TRTP length (%u) is too short to be a valid audio payload. Must"
+ " be at least %u bytes.", trtp_len, min_length);
+ return;
+ }
+
+ if (amt < min_length) {
+ ALOGV("TRTP porttion of RTP payload (%u bytes) too small to contain"
+ " entire TRTP header. TRTP does not currently support fragmenting"
+ " TRTP headers across RTP payloads", amt);
+ return;
+ }
+
+ uint8_t codec_type = buf[parse_offset ];
+ uint8_t flags = buf[parse_offset + 1];
+ uint8_t volume = buf[parse_offset + 2];
+ parse_offset += 3;
+ trtp_header_len += 3;
+
+ if (!setupSubstreamType(header_type, codec_type)) {
+ return;
+ }
+
+ if (decoder_ != NULL) {
+ decoder_->setRenderVolume(volume);
+ }
+
+ // TODO : move all of the constant flag and offset definitions for TRTP up
+ // into some sort of common header file.
+ if (waiting_for_rap_ && !(flags & 0x08)) {
+ ALOGV("Dropping non-RAP TRTP Audio Payload while waiting for RAP.");
+ return;
+ }
+
+ if (flags & 0x10) {
+ ALOGV("Dropping TRTP Audio Payload with aux codec data present (only"
+ " handle MP3 right now, and it has no aux data)");
+ return;
+ }
+
+ // OK - everything left is just payload. Compute the payload size, start
+ // the buffer in progress and pack as much payload as we can into it. If
+ // the payload is finished once we are done, go ahead and send the payload
+ // to the decoder.
+ expected_buffer_size_ = trtp_len - trtp_header_len;
+ if (!expected_buffer_size_) {
+ ALOGV("Dropping TRTP Audio Payload with 0 Access Unit length");
+ return;
+ }
+
+ CHECK(amt >= trtp_header_len);
+ uint32_t todo = amt - trtp_header_len;
+ if (expected_buffer_size_ < todo) {
+ ALOGV("Extra data (%u > %u) present in initial TRTP Audio Payload;"
+ " dropping payload.", todo, expected_buffer_size_);
+ return;
+ }
+
+ buffer_filled_ = 0;
+ buffer_in_progress_ = new MediaBuffer(expected_buffer_size_);
+ if ((NULL == buffer_in_progress_) ||
+ (NULL == buffer_in_progress_->data())) {
+ ALOGV("Failed to allocate MediaBuffer of length %u",
+ expected_buffer_size_);
+ cleanupBufferInProgress();
+ return;
+ }
+
+ sp<MetaData> meta = buffer_in_progress_->meta_data();
+ if (meta == NULL) {
+ ALOGV("Missing metadata structure in allocated MediaBuffer; dropping"
+ " payload");
+ cleanupBufferInProgress();
+ return;
+ }
+
+ // TODO : set this based on the codec type indicated in the TRTP stream.
+ // Right now, we only support MP3, so the choice is obvious.
+ meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG);
+ if (ts_valid) {
+ meta->setInt64(kKeyTime, ts);
+ }
+
+ if (amt > 0) {
+ uint8_t* tgt =
+ reinterpret_cast<uint8_t*>(buffer_in_progress_->data());
+ memcpy(tgt + buffer_filled_, buf + trtp_header_len, todo);
+ buffer_filled_ += amt;
+ }
+
+ if (buffer_filled_ >= expected_buffer_size_) {
+ processCompletedBuffer();
+ }
+}
+
+void AAH_RXPlayer::Substream::processPayloadCont(uint8_t* buf,
+ uint32_t amt) {
+ if (shouldAbort(__PRETTY_FUNCTION__)) {
+ return;
+ }
+
+ if (NULL == buffer_in_progress_) {
+ ALOGV("TRTP Receiver skipping payload continuation; no buffer currently"
+ " in progress.");
+ return;
+ }
+
+ CHECK(buffer_filled_ < expected_buffer_size_);
+ uint32_t buffer_left = expected_buffer_size_ - buffer_filled_;
+ if (amt > buffer_left) {
+ ALOGV("Extra data (%u > %u) present in continued TRTP Audio Payload;"
+ " dropping payload.", amt, buffer_left);
+ cleanupBufferInProgress();
+ return;
+ }
+
+ if (amt > 0) {
+ uint8_t* tgt =
+ reinterpret_cast<uint8_t*>(buffer_in_progress_->data());
+ memcpy(tgt + buffer_filled_, buf, amt);
+ buffer_filled_ += amt;
+ }
+
+ if (buffer_filled_ >= expected_buffer_size_) {
+ processCompletedBuffer();
+ }
+}
+
+void AAH_RXPlayer::Substream::processCompletedBuffer() {
+ const uint8_t* buffer_data = NULL;
+ int sample_rate;
+ int channel_count;
+ size_t frame_size;
+ status_t res;
+
+ CHECK(NULL != buffer_in_progress_);
+
+ if (decoder_ == NULL) {
+ ALOGV("Dropping complete buffer, no decoder pump allocated");
+ goto bailout;
+ }
+
+ buffer_data = reinterpret_cast<const uint8_t*>(buffer_in_progress_->data());
+ if (buffer_in_progress_->size() < 4) {
+ ALOGV("MP3 payload too short to contain header, dropping payload.");
+ goto bailout;
+ }
+
+ // Extract the channel count and the sample rate from the MP3 header. The
+ // stagefright MP3 requires that these be delivered before decoing can
+ // begin.
+ if (!GetMPEGAudioFrameSize(U32_AT(buffer_data),
+ &frame_size,
+ &sample_rate,
+ &channel_count,
+ NULL,
+ NULL)) {
+ ALOGV("Failed to parse MP3 header in payload, droping payload.");
+ goto bailout;
+ }
+
+
+ // Make sure that our substream metadata is set up properly. If there has
+ // been a format change, be sure to reset the underlying decoder. In
+ // stagefright, it seems like the only way to do this is to destroy and
+ // recreate the decoder.
+ if (substream_meta_ == NULL) {
+ substream_meta_ = new MetaData();
+
+ if (substream_meta_ == NULL) {
+ ALOGE("Failed to allocate MetaData structure for substream");
+ goto bailout;
+ }
+
+ substream_meta_->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MPEG);
+ substream_meta_->setInt32 (kKeyChannelCount, channel_count);
+ substream_meta_->setInt32 (kKeySampleRate, sample_rate);
+ } else {
+ int32_t prev_sample_rate;
+ int32_t prev_channel_count;
+ substream_meta_->findInt32(kKeySampleRate, &prev_sample_rate);
+ substream_meta_->findInt32(kKeyChannelCount, &prev_channel_count);
+
+ if ((prev_channel_count != channel_count) ||
+ (prev_sample_rate != sample_rate)) {
+ ALOGW("Format change detected, forcing decoder reset.");
+ cleanupDecoder();
+
+ substream_meta_->setInt32(kKeyChannelCount, channel_count);
+ substream_meta_->setInt32(kKeySampleRate, sample_rate);
+ }
+ }
+
+ // If our decoder has not be set up, do so now.
+ res = decoder_->init(substream_meta_);
+ if (OK != res) {
+ ALOGE("Failed to init decoder (res = %d)", res);
+ cleanupDecoder();
+ substream_meta_ = NULL;
+ goto bailout;
+ }
+
+ // Queue the payload for decode.
+ res = decoder_->queueForDecode(buffer_in_progress_);
+
+ if (res != OK) {
+ ALOGD("Failed to queue payload for decode, resetting decoder pump!"
+ " (res = %d)", res);
+ status_ = res;
+ cleanupDecoder();
+ cleanupBufferInProgress();
+ }
+
+ // NULL out buffer_in_progress before calling the cleanup helper.
+ //
+ // MediaBuffers use something of a hybrid ref-counting pattern which prevent
+ // the AAH_DecoderPump's input queue from adding their own reference to the
+ // MediaBuffer. MediaBuffers start life with a reference count of 0, as
+ // well as an observer which starts as NULL. Before being given an
+ // observer, the ref count cannot be allowed to become non-zero as it will
+ // cause calls to release() to assert. Basically, before a MediaBuffer has
+ // an observer, they behave like non-ref counted obects where release()
+ // serves the roll of delete. After a MediaBuffer has an observer, they
+ // become more like ref counted objects where add ref and release can be
+ // used, and when the ref count hits zero, the MediaBuffer is handed off to
+ // the observer.
+ //
+ // Given all of this, when we give the buffer to the decoder pump to wait in
+ // the to-be-processed queue, the decoder cannot add a ref to the buffer as
+ // it would in a traditional ref counting system. Instead it needs to
+ // "steal" the non-existent ref. In the case of queue failure, we need to
+ // make certain to release this non-existent reference so that the buffer is
+ // cleaned up during the cleanupBufferInProgress helper. In the case of a
+ // successful queue operation, we need to make certain that the
+ // cleanupBufferInProgress helper does not release the buffer since it needs
+ // to remain alive in the queue. We acomplish this by NULLing out the
+ // buffer pointer before calling the cleanup helper.
+ buffer_in_progress_ = NULL;
+
+bailout:
+ cleanupBufferInProgress();
+}
+
+
+void AAH_RXPlayer::Substream::processTSTransform(const LinearTransform& trans) {
+ if (decoder_ != NULL) {
+ decoder_->setRenderTSTransform(trans);
+ }
+}
+
+bool AAH_RXPlayer::Substream::isAboutToUnderflow() {
+ if (decoder_ == NULL) {
+ return false;
+ }
+
+ return decoder_->isAboutToUnderflow(kAboutToUnderflowThreshold);
+}
+
+bool AAH_RXPlayer::Substream::setupSubstreamType(uint8_t substream_type,
+ uint8_t codec_type) {
+ // Sanity check the codec type. Right now we only support MP3. Also check
+ // for conflicts with previously delivered codec types.
+ if (substream_details_known_ && (codec_type != codec_type_)) {
+ ALOGV("RXed TRTP Payload for SSRC=0x%08x where codec type (%u) does not"
+ " match previously received codec type (%u)",
+ ssrc_, codec_type, codec_type_);
+ return false;
+ }
+
+ if (codec_type != 0x03) {
+ ALOGV("RXed TRTP Audio Payload for SSRC=0x%08x with unsupported codec"
+ " type (%u)", ssrc_, codec_type);
+ return false;
+ }
+
+ if (!substream_details_known_) {
+ substream_type_ = substream_type;
+ codec_type_ = codec_type;
+ substream_details_known_ = true;
+ }
+
+ return true;
+}
+
+} // namespace android
diff --git a/media/libaah_rtp/aah_tx_packet.cpp b/media/libaah_rtp/aah_tx_packet.cpp
new file mode 100644
index 0000000..3f6e0e9
--- /dev/null
+++ b/media/libaah_rtp/aah_tx_packet.cpp
@@ -0,0 +1,331 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#define LOG_TAG "LibAAH_RTP"
+#include <utils/Log.h>
+
+#include <arpa/inet.h>
+#include <string.h>
+
+#include <media/stagefright/foundation/ADebug.h>
+
+#include "aah_tx_packet.h"
+
+namespace android {
+
+const int TRTPPacket::kRTPHeaderLen;
+const uint32_t TRTPPacket::kTRTPEpochMask;
+
+TRTPPacket::~TRTPPacket() {
+ delete mPacket;
+}
+
+/*** TRTP packet properties ***/
+
+void TRTPPacket::setSeqNumber(uint16_t val) {
+ mSeqNumber = val;
+
+ if (mIsPacked) {
+ const int kTRTPSeqNumberOffset = 2;
+ uint16_t* buf = reinterpret_cast<uint16_t*>(
+ mPacket + kTRTPSeqNumberOffset);
+ *buf = htons(mSeqNumber);
+ }
+}
+
+uint16_t TRTPPacket::getSeqNumber() const {
+ return mSeqNumber;
+}
+
+void TRTPPacket::setPTS(int64_t val) {
+ CHECK(!mIsPacked);
+ mPTS = val;
+ mPTSValid = true;
+}
+
+int64_t TRTPPacket::getPTS() const {
+ return mPTS;
+}
+
+void TRTPPacket::setEpoch(uint32_t val) {
+ mEpoch = val;
+
+ if (mIsPacked) {
+ const int kTRTPEpochOffset = 8;
+ uint32_t* buf = reinterpret_cast<uint32_t*>(
+ mPacket + kTRTPEpochOffset);
+ uint32_t val = ntohl(*buf);
+ val &= ~(kTRTPEpochMask << kTRTPEpochShift);
+ val |= (mEpoch & kTRTPEpochMask) << kTRTPEpochShift;
+ *buf = htonl(val);
+ }
+}
+
+void TRTPPacket::setProgramID(uint16_t val) {
+ CHECK(!mIsPacked);
+ mProgramID = val;
+}
+
+void TRTPPacket::setSubstreamID(uint16_t val) {
+ CHECK(!mIsPacked);
+ mSubstreamID = val;
+}
+
+
+void TRTPPacket::setClockTransform(const LinearTransform& trans) {
+ CHECK(!mIsPacked);
+ mClockTranform = trans;
+ mClockTranformValid = true;
+}
+
+uint8_t* TRTPPacket::getPacket() const {
+ CHECK(mIsPacked);
+ return mPacket;
+}
+
+int TRTPPacket::getPacketLen() const {
+ CHECK(mIsPacked);
+ return mPacketLen;
+}
+
+void TRTPPacket::setExpireTime(nsecs_t val) {
+ CHECK(!mIsPacked);
+ mExpireTime = val;
+}
+
+nsecs_t TRTPPacket::getExpireTime() const {
+ return mExpireTime;
+}
+
+/*** TRTP audio packet properties ***/
+
+void TRTPAudioPacket::setCodecType(TRTPAudioCodecType val) {
+ CHECK(!mIsPacked);
+ mCodecType = val;
+}
+
+void TRTPAudioPacket::setRandomAccessPoint(bool val) {
+ CHECK(!mIsPacked);
+ mRandomAccessPoint = val;
+}
+
+void TRTPAudioPacket::setDropable(bool val) {
+ CHECK(!mIsPacked);
+ mDropable = val;
+}
+
+void TRTPAudioPacket::setDiscontinuity(bool val) {
+ CHECK(!mIsPacked);
+ mDiscontinuity = val;
+}
+
+void TRTPAudioPacket::setEndOfStream(bool val) {
+ CHECK(!mIsPacked);
+ mEndOfStream = val;
+}
+
+void TRTPAudioPacket::setVolume(uint8_t val) {
+ CHECK(!mIsPacked);
+ mVolume = val;
+}
+
+void TRTPAudioPacket::setAccessUnitData(void* data, int len) {
+ CHECK(!mIsPacked);
+ mAccessUnitData = data;
+ mAccessUnitLen = len;
+}
+
+/*** TRTP control packet properties ***/
+
+void TRTPControlPacket::setCommandID(TRTPCommandID val) {
+ CHECK(!mIsPacked);
+ mCommandID = val;
+}
+
+/*** TRTP packet serializers ***/
+
+void TRTPPacket::writeU8(uint8_t*& buf, uint8_t val) {
+ *buf = val;
+ buf++;
+}
+
+void TRTPPacket::writeU16(uint8_t*& buf, uint16_t val) {
+ *reinterpret_cast<uint16_t*>(buf) = htons(val);
+ buf += 2;
+}
+
+void TRTPPacket::writeU32(uint8_t*& buf, uint32_t val) {
+ *reinterpret_cast<uint32_t*>(buf) = htonl(val);
+ buf += 4;
+}
+
+void TRTPPacket::writeU64(uint8_t*& buf, uint64_t val) {
+ buf[0] = static_cast<uint8_t>(val >> 56);
+ buf[1] = static_cast<uint8_t>(val >> 48);
+ buf[2] = static_cast<uint8_t>(val >> 40);
+ buf[3] = static_cast<uint8_t>(val >> 32);
+ buf[4] = static_cast<uint8_t>(val >> 24);
+ buf[5] = static_cast<uint8_t>(val >> 16);
+ buf[6] = static_cast<uint8_t>(val >> 8);
+ buf[7] = static_cast<uint8_t>(val);
+ buf += 8;
+}
+
+void TRTPPacket::writeTRTPHeader(uint8_t*& buf,
+ bool isFirstFragment,
+ int totalPacketLen) {
+ // RTP header
+ writeU8(buf,
+ ((mVersion & 0x03) << 6) |
+ (static_cast<int>(mPadding) << 5) |
+ (static_cast<int>(mExtension) << 4) |
+ (mCsrcCount & 0x0F));
+ writeU8(buf,
+ (static_cast<int>(isFirstFragment) << 7) |
+ (mPayloadType & 0x7F));
+ writeU16(buf, mSeqNumber);
+ if (isFirstFragment && mPTSValid) {
+ writeU32(buf, mPTS & 0xFFFFFFFF);
+ } else {
+ writeU32(buf, 0);
+ }
+ writeU32(buf,
+ ((mEpoch & kTRTPEpochMask) << kTRTPEpochShift) |
+ ((mProgramID & 0x1F) << 5) |
+ (mSubstreamID & 0x1F));
+
+ // TRTP header
+ writeU8(buf, mTRTPVersion);
+ writeU8(buf,
+ ((mTRTPHeaderType & 0x0F) << 4) |
+ (mClockTranformValid ? 0x02 : 0x00) |
+ (mPTSValid ? 0x01 : 0x00));
+ writeU32(buf, totalPacketLen - kRTPHeaderLen);
+ if (mPTSValid) {
+ writeU32(buf, mPTS >> 32);
+ }
+
+ if (mClockTranformValid) {
+ writeU64(buf, mClockTranform.a_zero);
+ writeU32(buf, mClockTranform.a_to_b_numer);
+ writeU32(buf, mClockTranform.a_to_b_denom);
+ writeU64(buf, mClockTranform.b_zero);
+ }
+}
+
+bool TRTPAudioPacket::pack() {
+ if (mIsPacked) {
+ return false;
+ }
+
+ int packetLen = kRTPHeaderLen +
+ mAccessUnitLen +
+ TRTPHeaderLen();
+
+ // TODO : support multiple fragments
+ const int kMaxUDPPayloadLen = 65507;
+ if (packetLen > kMaxUDPPayloadLen) {
+ return false;
+ }
+
+ mPacket = new uint8_t[packetLen];
+ if (!mPacket) {
+ return false;
+ }
+
+ mPacketLen = packetLen;
+
+ uint8_t* cur = mPacket;
+
+ writeTRTPHeader(cur, true, packetLen);
+ writeU8(cur, mCodecType);
+ writeU8(cur,
+ (static_cast<int>(mRandomAccessPoint) << 3) |
+ (static_cast<int>(mDropable) << 2) |
+ (static_cast<int>(mDiscontinuity) << 1) |
+ (static_cast<int>(mEndOfStream)));
+ writeU8(cur, mVolume);
+
+ memcpy(cur, mAccessUnitData, mAccessUnitLen);
+
+ mIsPacked = true;
+ return true;
+}
+
+int TRTPPacket::TRTPHeaderLen() const {
+ // 6 bytes for version, payload type, flags and length. An additional 4 if
+ // there are upper timestamp bits present and another 24 if there is a clock
+ // transformation present.
+ return 6 +
+ (mClockTranformValid ? 24 : 0) +
+ (mPTSValid ? 4 : 0);
+}
+
+int TRTPAudioPacket::TRTPHeaderLen() const {
+ // TRTPPacket::TRTPHeaderLen() for the base TRTPHeader. 3 bytes for audio's
+ // codec type, flags and volume field. Another 5 bytes if the codec type is
+ // PCM and we are sending sample rate/channel count. as well as however long
+ // the aux data (if present) is.
+
+ int pcmParamLength;
+ switch(mCodecType) {
+ case kCodecPCMBigEndian:
+ case kCodecPCMLittleEndian:
+ pcmParamLength = 5;
+ break;
+
+ default:
+ pcmParamLength = 0;
+ break;
+ }
+
+
+ // TODO : properly compute aux data length. Currently, nothing
+ // uses aux data, so its length is always 0.
+ int auxDataLength = 0;
+ return TRTPPacket::TRTPHeaderLen() +
+ 3 +
+ auxDataLength +
+ pcmParamLength;
+}
+
+bool TRTPControlPacket::pack() {
+ if (mIsPacked) {
+ return false;
+ }
+
+ // command packets contain a 2-byte command ID
+ int packetLen = kRTPHeaderLen +
+ TRTPHeaderLen() +
+ 2;
+
+ mPacket = new uint8_t[packetLen];
+ if (!mPacket) {
+ return false;
+ }
+
+ mPacketLen = packetLen;
+
+ uint8_t* cur = mPacket;
+
+ writeTRTPHeader(cur, true, packetLen);
+ writeU16(cur, mCommandID);
+
+ mIsPacked = true;
+ return true;
+}
+
+} // namespace android
diff --git a/media/libaah_rtp/aah_tx_packet.h b/media/libaah_rtp/aah_tx_packet.h
new file mode 100644
index 0000000..833803e
--- /dev/null
+++ b/media/libaah_rtp/aah_tx_packet.h
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#ifndef __AAH_TX_PACKET_H__
+#define __AAH_TX_PACKET_H__
+
+#include <media/stagefright/foundation/ABase.h>
+#include <utils/LinearTransform.h>
+#include <utils/RefBase.h>
+#include <utils/Timers.h>
+
+namespace android {
+
+class TRTPPacket : public RefBase {
+ protected:
+ enum TRTPHeaderType {
+ kHeaderTypeAudio = 1,
+ kHeaderTypeVideo = 2,
+ kHeaderTypeSubpicture = 3,
+ kHeaderTypeControl = 4,
+ };
+
+ TRTPPacket(TRTPHeaderType headerType)
+ : mIsPacked(false)
+ , mVersion(2)
+ , mPadding(false)
+ , mExtension(false)
+ , mCsrcCount(0)
+ , mPayloadType(100)
+ , mSeqNumber(0)
+ , mPTSValid(false)
+ , mPTS(0)
+ , mEpoch(0)
+ , mProgramID(0)
+ , mSubstreamID(0)
+ , mClockTranformValid(false)
+ , mTRTPVersion(1)
+ , mTRTPLength(0)
+ , mTRTPHeaderType(headerType)
+ , mPacket(NULL)
+ , mPacketLen(0) { }
+
+ public:
+ virtual ~TRTPPacket();
+
+ void setSeqNumber(uint16_t val);
+ uint16_t getSeqNumber() const;
+
+ void setPTS(int64_t val);
+ int64_t getPTS() const;
+
+ void setEpoch(uint32_t val);
+ void setProgramID(uint16_t val);
+ void setSubstreamID(uint16_t val);
+ void setClockTransform(const LinearTransform& trans);
+
+ uint8_t* getPacket() const;
+ int getPacketLen() const;
+
+ void setExpireTime(nsecs_t val);
+ nsecs_t getExpireTime() const;
+
+ virtual bool pack() = 0;
+
+ // mask for the number of bits in a TRTP epoch
+ static const uint32_t kTRTPEpochMask = (1 << 22) - 1;
+ static const int kTRTPEpochShift = 10;
+
+ protected:
+ static const int kRTPHeaderLen = 12;
+ virtual int TRTPHeaderLen() const;
+
+ void writeTRTPHeader(uint8_t*& buf,
+ bool isFirstFragment,
+ int totalPacketLen);
+
+ void writeU8(uint8_t*& buf, uint8_t val);
+ void writeU16(uint8_t*& buf, uint16_t val);
+ void writeU32(uint8_t*& buf, uint32_t val);
+ void writeU64(uint8_t*& buf, uint64_t val);
+
+ bool mIsPacked;
+
+ uint8_t mVersion;
+ bool mPadding;
+ bool mExtension;
+ uint8_t mCsrcCount;
+ uint8_t mPayloadType;
+ uint16_t mSeqNumber;
+ bool mPTSValid;
+ int64_t mPTS;
+ uint32_t mEpoch;
+ uint16_t mProgramID;
+ uint16_t mSubstreamID;
+ LinearTransform mClockTranform;
+ bool mClockTranformValid;
+ uint8_t mTRTPVersion;
+ uint32_t mTRTPLength;
+ TRTPHeaderType mTRTPHeaderType;
+
+ uint8_t* mPacket;
+ int mPacketLen;
+
+ nsecs_t mExpireTime;
+
+ DISALLOW_EVIL_CONSTRUCTORS(TRTPPacket);
+};
+
+class TRTPAudioPacket : public TRTPPacket {
+ public:
+ TRTPAudioPacket()
+ : TRTPPacket(kHeaderTypeAudio)
+ , mCodecType(kCodecInvalid)
+ , mRandomAccessPoint(false)
+ , mDropable(false)
+ , mDiscontinuity(false)
+ , mEndOfStream(false)
+ , mVolume(0)
+ , mAccessUnitData(NULL) { }
+
+ enum TRTPAudioCodecType {
+ kCodecInvalid = 0,
+ kCodecPCMBigEndian = 1,
+ kCodecPCMLittleEndian = 2,
+ kCodecMPEG1Audio = 3,
+ };
+
+ void setCodecType(TRTPAudioCodecType val);
+ void setRandomAccessPoint(bool val);
+ void setDropable(bool val);
+ void setDiscontinuity(bool val);
+ void setEndOfStream(bool val);
+ void setVolume(uint8_t val);
+ void setAccessUnitData(void* data, int len);
+
+ virtual bool pack();
+
+ protected:
+ virtual int TRTPHeaderLen() const;
+
+ private:
+ TRTPAudioCodecType mCodecType;
+ bool mRandomAccessPoint;
+ bool mDropable;
+ bool mDiscontinuity;
+ bool mEndOfStream;
+ uint8_t mVolume;
+ void* mAccessUnitData;
+ int mAccessUnitLen;
+
+ DISALLOW_EVIL_CONSTRUCTORS(TRTPAudioPacket);
+};
+
+class TRTPControlPacket : public TRTPPacket {
+ public:
+ TRTPControlPacket()
+ : TRTPPacket(kHeaderTypeControl)
+ , mCommandID(kCommandNop) {}
+
+ enum TRTPCommandID {
+ kCommandNop = 1,
+ kCommandFlush = 2,
+ kCommandEOS = 3,
+ };
+
+ void setCommandID(TRTPCommandID val);
+
+ virtual bool pack();
+
+ private:
+ TRTPCommandID mCommandID;
+
+ DISALLOW_EVIL_CONSTRUCTORS(TRTPControlPacket);
+};
+
+} // namespace android
+
+#endif // __AAH_TX_PLAYER_H__
diff --git a/media/libaah_rtp/aah_tx_player.cpp b/media/libaah_rtp/aah_tx_player.cpp
new file mode 100644
index 0000000..a79a989
--- /dev/null
+++ b/media/libaah_rtp/aah_tx_player.cpp
@@ -0,0 +1,1139 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#define LOG_TAG "LibAAH_RTP"
+#include <utils/Log.h>
+
+#define __STDC_FORMAT_MACROS
+#include <inttypes.h>
+#include <netdb.h>
+#include <netinet/ip.h>
+
+#include <common_time/cc_helper.h>
+#include <media/IMediaPlayer.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/FileSource.h>
+#include <media/stagefright/MediaBuffer.h>
+#include <media/stagefright/MetaData.h>
+#include <utils/Timers.h>
+
+#include "aah_tx_packet.h"
+#include "aah_tx_player.h"
+
+namespace android {
+
+static int64_t kLowWaterMarkUs = 2000000ll; // 2secs
+static int64_t kHighWaterMarkUs = 10000000ll; // 10secs
+static const size_t kLowWaterMarkBytes = 40000;
+static const size_t kHighWaterMarkBytes = 200000;
+
+// When we start up, how much lead time should we put on the first access unit?
+static const int64_t kAAHStartupLeadTimeUs = 300000LL;
+
+// How much time do we attempt to lead the clock by in steady state?
+static const int64_t kAAHBufferTimeUs = 1000000LL;
+
+// how long do we keep data in our retransmit buffer after sending it.
+const int64_t AAH_TXPlayer::kAAHRetryKeepAroundTimeNs =
+ kAAHBufferTimeUs * 1100;
+
+sp<MediaPlayerBase> createAAH_TXPlayer() {
+ sp<MediaPlayerBase> ret = new AAH_TXPlayer();
+ return ret;
+}
+
+template <typename T> static T clamp(T val, T min, T max) {
+ if (val < min) {
+ return min;
+ } else if (val > max) {
+ return max;
+ } else {
+ return val;
+ }
+}
+
+struct AAH_TXEvent : public TimedEventQueue::Event {
+ AAH_TXEvent(AAH_TXPlayer *player,
+ void (AAH_TXPlayer::*method)()) : mPlayer(player)
+ , mMethod(method) {}
+
+ protected:
+ virtual ~AAH_TXEvent() {}
+
+ virtual void fire(TimedEventQueue *queue, int64_t /* now_us */) {
+ (mPlayer->*mMethod)();
+ }
+
+ private:
+ AAH_TXPlayer *mPlayer;
+ void (AAH_TXPlayer::*mMethod)();
+
+ AAH_TXEvent(const AAH_TXEvent &);
+ AAH_TXEvent& operator=(const AAH_TXEvent &);
+};
+
+AAH_TXPlayer::AAH_TXPlayer()
+ : mQueueStarted(false)
+ , mFlags(0)
+ , mExtractorFlags(0) {
+ DataSource::RegisterDefaultSniffers();
+
+ mBufferingEvent = new AAH_TXEvent(this, &AAH_TXPlayer::onBufferingUpdate);
+ mBufferingEventPending = false;
+
+ mPumpAudioEvent = new AAH_TXEvent(this, &AAH_TXPlayer::onPumpAudio);
+ mPumpAudioEventPending = false;
+
+ reset_l();
+}
+
+AAH_TXPlayer::~AAH_TXPlayer() {
+ if (mQueueStarted) {
+ mQueue.stop();
+ }
+
+ reset_l();
+}
+
+void AAH_TXPlayer::cancelPlayerEvents(bool keepBufferingGoing) {
+ if (!keepBufferingGoing) {
+ mQueue.cancelEvent(mBufferingEvent->eventID());
+ mBufferingEventPending = false;
+
+ mQueue.cancelEvent(mPumpAudioEvent->eventID());
+ mPumpAudioEventPending = false;
+ }
+}
+
+status_t AAH_TXPlayer::initCheck() {
+ // Check for the presense of the common time service by attempting to query
+ // for CommonTime's frequency. If we get an error back, we cannot talk to
+ // the service at all and should abort now.
+ status_t res;
+ uint64_t freq;
+ res = mCCHelper.getCommonFreq(&freq);
+ if (OK != res) {
+ ALOGE("Failed to connect to common time service! (res %d)", res);
+ return res;
+ }
+
+ return OK;
+}
+
+status_t AAH_TXPlayer::setDataSource(
+ const char *url,
+ const KeyedVector<String8, String8> *headers) {
+ Mutex::Autolock autoLock(mLock);
+ return setDataSource_l(url, headers);
+}
+
+status_t AAH_TXPlayer::setDataSource_l(
+ const char *url,
+ const KeyedVector<String8, String8> *headers) {
+ reset_l();
+
+ // the URL must consist of "aahTX://" followed by the real URL of
+ // the data source
+ const char *kAAHPrefix = "aahTX://";
+ if (strncasecmp(url, kAAHPrefix, strlen(kAAHPrefix))) {
+ return INVALID_OPERATION;
+ }
+
+ mUri.setTo(url + strlen(kAAHPrefix));
+
+ if (headers) {
+ mUriHeaders = *headers;
+
+ ssize_t index = mUriHeaders.indexOfKey(String8("x-hide-urls-from-log"));
+ if (index >= 0) {
+ // Browser is in "incognito" mode, suppress logging URLs.
+
+ // This isn't something that should be passed to the server.
+ mUriHeaders.removeItemsAt(index);
+
+ mFlags |= INCOGNITO;
+ }
+ }
+
+ // The URL may optionally contain a "#" character followed by a Skyjam
+ // cookie. Ideally the cookie header should just be passed in the headers
+ // argument, but the Java API for supplying headers is apparently not yet
+ // exposed in the SDK used by application developers.
+ const char kSkyjamCookieDelimiter = '#';
+ char* skyjamCookie = strrchr(mUri.string(), kSkyjamCookieDelimiter);
+ if (skyjamCookie) {
+ skyjamCookie++;
+ mUriHeaders.add(String8("Cookie"), String8(skyjamCookie));
+ mUri = String8(mUri.string(), skyjamCookie - mUri.string());
+ }
+
+ return OK;
+}
+
+status_t AAH_TXPlayer::setDataSource(int fd, int64_t offset, int64_t length) {
+ Mutex::Autolock autoLock(mLock);
+
+ reset_l();
+
+ sp<DataSource> dataSource = new FileSource(dup(fd), offset, length);
+
+ status_t err = dataSource->initCheck();
+
+ if (err != OK) {
+ return err;
+ }
+
+ mFileSource = dataSource;
+
+ sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource);
+
+ if (extractor == NULL) {
+ return UNKNOWN_ERROR;
+ }
+
+ return setDataSource_l(extractor);
+}
+
+status_t AAH_TXPlayer::setVideoSurface(const sp<Surface>& surface) {
+ return OK;
+}
+
+status_t AAH_TXPlayer::setVideoSurfaceTexture(
+ const sp<ISurfaceTexture>& surfaceTexture) {
+ return OK;
+}
+
+status_t AAH_TXPlayer::prepare() {
+ return INVALID_OPERATION;
+}
+
+status_t AAH_TXPlayer::prepareAsync() {
+ Mutex::Autolock autoLock(mLock);
+
+ return prepareAsync_l();
+}
+
+status_t AAH_TXPlayer::prepareAsync_l() {
+ if (mFlags & PREPARING) {
+ return UNKNOWN_ERROR; // async prepare already pending
+ }
+
+ mAAH_Sender = AAH_TXSender::GetInstance();
+ if (mAAH_Sender == NULL) {
+ return NO_MEMORY;
+ }
+
+ if (!mQueueStarted) {
+ mQueue.start();
+ mQueueStarted = true;
+ }
+
+ mFlags |= PREPARING;
+ mAsyncPrepareEvent = new AAH_TXEvent(
+ this, &AAH_TXPlayer::onPrepareAsyncEvent);
+
+ mQueue.postEvent(mAsyncPrepareEvent);
+
+ return OK;
+}
+
+status_t AAH_TXPlayer::finishSetDataSource_l() {
+ sp<DataSource> dataSource;
+
+ if (!strncasecmp("http://", mUri.string(), 7) ||
+ !strncasecmp("https://", mUri.string(), 8)) {
+
+ mConnectingDataSource = HTTPBase::Create(
+ (mFlags & INCOGNITO)
+ ? HTTPBase::kFlagIncognito
+ : 0);
+
+ mLock.unlock();
+ status_t err = mConnectingDataSource->connect(mUri, &mUriHeaders);
+ mLock.lock();
+
+ if (err != OK) {
+ mConnectingDataSource.clear();
+
+ ALOGI("mConnectingDataSource->connect() returned %d", err);
+ return err;
+ }
+
+ mCachedSource = new NuCachedSource2(mConnectingDataSource);
+ mConnectingDataSource.clear();
+
+ dataSource = mCachedSource;
+
+ // We're going to prefill the cache before trying to instantiate
+ // the extractor below, as the latter is an operation that otherwise
+ // could block on the datasource for a significant amount of time.
+ // During that time we'd be unable to abort the preparation phase
+ // without this prefill.
+
+ mLock.unlock();
+
+ for (;;) {
+ status_t finalStatus;
+ size_t cachedDataRemaining =
+ mCachedSource->approxDataRemaining(&finalStatus);
+
+ if (finalStatus != OK ||
+ cachedDataRemaining >= kHighWaterMarkBytes ||
+ (mFlags & PREPARE_CANCELLED)) {
+ break;
+ }
+
+ usleep(200000);
+ }
+
+ mLock.lock();
+
+ if (mFlags & PREPARE_CANCELLED) {
+ ALOGI("Prepare cancelled while waiting for initial cache fill.");
+ return UNKNOWN_ERROR;
+ }
+ } else {
+ dataSource = DataSource::CreateFromURI(mUri.string(), &mUriHeaders);
+ }
+
+ if (dataSource == NULL) {
+ return UNKNOWN_ERROR;
+ }
+
+ sp<MediaExtractor> extractor = MediaExtractor::Create(dataSource);
+
+ if (extractor == NULL) {
+ return UNKNOWN_ERROR;
+ }
+
+ return setDataSource_l(extractor);
+}
+
+status_t AAH_TXPlayer::setDataSource_l(const sp<MediaExtractor> &extractor) {
+ // Attempt to approximate overall stream bitrate by summing all
+ // tracks' individual bitrates, if not all of them advertise bitrate,
+ // we have to fail.
+
+ int64_t totalBitRate = 0;
+
+ for (size_t i = 0; i < extractor->countTracks(); ++i) {
+ sp<MetaData> meta = extractor->getTrackMetaData(i);
+
+ int32_t bitrate;
+ if (!meta->findInt32(kKeyBitRate, &bitrate)) {
+ totalBitRate = -1;
+ break;
+ }
+
+ totalBitRate += bitrate;
+ }
+
+ mBitrate = totalBitRate;
+
+ ALOGV("mBitrate = %lld bits/sec", mBitrate);
+
+ bool haveAudio = false;
+ for (size_t i = 0; i < extractor->countTracks(); ++i) {
+ sp<MetaData> meta = extractor->getTrackMetaData(i);
+
+ const char *mime;
+ CHECK(meta->findCString(kKeyMIMEType, &mime));
+
+ if (!strncasecmp(mime, "audio/", 6)) {
+ mAudioSource = extractor->getTrack(i);
+ CHECK(mAudioSource != NULL);
+ haveAudio = true;
+ break;
+ }
+ }
+
+ if (!haveAudio) {
+ return UNKNOWN_ERROR;
+ }
+
+ mExtractorFlags = extractor->flags();
+
+ return OK;
+}
+
+void AAH_TXPlayer::abortPrepare(status_t err) {
+ CHECK(err != OK);
+
+ notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, err);
+
+ mPrepareResult = err;
+ mFlags &= ~(PREPARING|PREPARE_CANCELLED|PREPARING_CONNECTED);
+ mPreparedCondition.broadcast();
+}
+
+void AAH_TXPlayer::onPrepareAsyncEvent() {
+ Mutex::Autolock autoLock(mLock);
+
+ if (mFlags & PREPARE_CANCELLED) {
+ ALOGI("prepare was cancelled before doing anything");
+ abortPrepare(UNKNOWN_ERROR);
+ return;
+ }
+
+ if (mUri.size() > 0) {
+ status_t err = finishSetDataSource_l();
+
+ if (err != OK) {
+ abortPrepare(err);
+ return;
+ }
+ }
+
+ mAudioSource->getFormat()->findInt64(kKeyDuration, &mDurationUs);
+
+ status_t err = mAudioSource->start();
+ if (err != OK) {
+ ALOGI("failed to start audio source, err=%d", err);
+ abortPrepare(err);
+ return;
+ }
+
+ mFlags |= PREPARING_CONNECTED;
+
+ if (mCachedSource != NULL) {
+ postBufferingEvent_l();
+ } else {
+ finishAsyncPrepare_l();
+ }
+}
+
+void AAH_TXPlayer::finishAsyncPrepare_l() {
+ notifyListener_l(MEDIA_PREPARED);
+
+ mPrepareResult = OK;
+ mFlags &= ~(PREPARING|PREPARE_CANCELLED|PREPARING_CONNECTED);
+ mFlags |= PREPARED;
+ mPreparedCondition.broadcast();
+}
+
+status_t AAH_TXPlayer::start() {
+ Mutex::Autolock autoLock(mLock);
+
+ mFlags &= ~CACHE_UNDERRUN;
+
+ return play_l();
+}
+
+status_t AAH_TXPlayer::play_l() {
+ if (mFlags & PLAYING) {
+ return OK;
+ }
+
+ if (!(mFlags & PREPARED)) {
+ return INVALID_OPERATION;
+ }
+
+ {
+ Mutex::Autolock lock(mEndpointLock);
+ if (!mEndpointValid) {
+ return INVALID_OPERATION;
+ }
+ if (!mEndpointRegistered) {
+ mProgramID = mAAH_Sender->registerEndpoint(mEndpoint);
+ mEndpointRegistered = true;
+ }
+ }
+
+ mFlags |= PLAYING;
+
+ updateClockTransform_l(false);
+
+ postPumpAudioEvent_l(-1);
+
+ return OK;
+}
+
+status_t AAH_TXPlayer::stop() {
+ status_t ret = pause();
+ sendEOS_l();
+ return ret;
+}
+
+status_t AAH_TXPlayer::pause() {
+ Mutex::Autolock autoLock(mLock);
+
+ mFlags &= ~CACHE_UNDERRUN;
+
+ return pause_l();
+}
+
+status_t AAH_TXPlayer::pause_l(bool doClockUpdate) {
+ if (!(mFlags & PLAYING)) {
+ return OK;
+ }
+
+ cancelPlayerEvents(true /* keepBufferingGoing */);
+
+ mFlags &= ~PLAYING;
+
+ if (doClockUpdate) {
+ updateClockTransform_l(true);
+ }
+
+ return OK;
+}
+
+void AAH_TXPlayer::updateClockTransform_l(bool pause) {
+ // record the new pause status so that onPumpAudio knows what rate to apply
+ // when it initializes the transform
+ mPlayRateIsPaused = pause;
+
+ // if we haven't yet established a valid clock transform, then we can't
+ // do anything here
+ if (!mCurrentClockTransformValid) {
+ return;
+ }
+
+ // sample the current common time
+ int64_t commonTimeNow;
+ if (OK != mCCHelper.getCommonTime(&commonTimeNow)) {
+ ALOGE("updateClockTransform_l get common time failed");
+ mCurrentClockTransformValid = false;
+ return;
+ }
+
+ // convert the current common time to media time using the old
+ // transform
+ int64_t mediaTimeNow;
+ if (!mCurrentClockTransform.doReverseTransform(
+ commonTimeNow, &mediaTimeNow)) {
+ ALOGE("updateClockTransform_l reverse transform failed");
+ mCurrentClockTransformValid = false;
+ return;
+ }
+
+ // calculate a new transform that preserves the old transform's
+ // result for the current time
+ mCurrentClockTransform.a_zero = mediaTimeNow;
+ mCurrentClockTransform.b_zero = commonTimeNow;
+ mCurrentClockTransform.a_to_b_numer = 1;
+ mCurrentClockTransform.a_to_b_denom = pause ? 0 : 1;
+
+ // send a packet announcing the new transform
+ sp<TRTPControlPacket> packet = new TRTPControlPacket();
+ packet->setClockTransform(mCurrentClockTransform);
+ packet->setCommandID(TRTPControlPacket::kCommandNop);
+ queuePacketToSender_l(packet);
+}
+
+void AAH_TXPlayer::sendEOS_l() {
+ sp<TRTPControlPacket> packet = new TRTPControlPacket();
+ packet->setCommandID(TRTPControlPacket::kCommandEOS);
+ queuePacketToSender_l(packet);
+}
+
+bool AAH_TXPlayer::isPlaying() {
+ return (mFlags & PLAYING) || (mFlags & CACHE_UNDERRUN);
+}
+
+status_t AAH_TXPlayer::seekTo(int msec) {
+ if (mExtractorFlags & MediaExtractor::CAN_SEEK) {
+ Mutex::Autolock autoLock(mLock);
+ return seekTo_l(static_cast<int64_t>(msec) * 1000);
+ }
+
+ notifyListener_l(MEDIA_SEEK_COMPLETE);
+ return OK;
+}
+
+status_t AAH_TXPlayer::seekTo_l(int64_t timeUs) {
+ mIsSeeking = true;
+ mSeekTimeUs = timeUs;
+
+ mCurrentClockTransformValid = false;
+ mLastQueuedMediaTimePTSValid = false;
+
+ // send a flush command packet
+ sp<TRTPControlPacket> packet = new TRTPControlPacket();
+ packet->setCommandID(TRTPControlPacket::kCommandFlush);
+ queuePacketToSender_l(packet);
+
+ return OK;
+}
+
+status_t AAH_TXPlayer::getCurrentPosition(int *msec) {
+ if (!msec) {
+ return BAD_VALUE;
+ }
+
+ Mutex::Autolock lock(mLock);
+
+ int position;
+
+ if (mIsSeeking) {
+ position = mSeekTimeUs / 1000;
+ } else if (mCurrentClockTransformValid) {
+ // sample the current common time
+ int64_t commonTimeNow;
+ if (OK != mCCHelper.getCommonTime(&commonTimeNow)) {
+ ALOGE("getCurrentPosition get common time failed");
+ return INVALID_OPERATION;
+ }
+
+ int64_t mediaTimeNow;
+ if (!mCurrentClockTransform.doReverseTransform(commonTimeNow,
+ &mediaTimeNow)) {
+ ALOGE("getCurrentPosition reverse transform failed");
+ return INVALID_OPERATION;
+ }
+
+ position = static_cast<int>(mediaTimeNow / 1000);
+ } else {
+ position = 0;
+ }
+
+ int duration;
+ if (getDuration_l(&duration) == OK) {
+ *msec = clamp(position, 0, duration);
+ } else {
+ *msec = (position >= 0) ? position : 0;
+ }
+
+ return OK;
+}
+
+status_t AAH_TXPlayer::getDuration(int* msec) {
+ if (!msec) {
+ return BAD_VALUE;
+ }
+
+ Mutex::Autolock lock(mLock);
+
+ return getDuration_l(msec);
+}
+
+status_t AAH_TXPlayer::getDuration_l(int* msec) {
+ if (mDurationUs < 0) {
+ return UNKNOWN_ERROR;
+ }
+
+ *msec = (mDurationUs + 500) / 1000;
+
+ return OK;
+}
+
+status_t AAH_TXPlayer::reset() {
+ Mutex::Autolock autoLock(mLock);
+ reset_l();
+ return OK;
+}
+
+void AAH_TXPlayer::reset_l() {
+ if (mFlags & PREPARING) {
+ mFlags |= PREPARE_CANCELLED;
+ if (mConnectingDataSource != NULL) {
+ ALOGI("interrupting the connection process");
+ mConnectingDataSource->disconnect();
+ }
+
+ if (mFlags & PREPARING_CONNECTED) {
+ // We are basically done preparing, we're just buffering
+ // enough data to start playback, we can safely interrupt that.
+ finishAsyncPrepare_l();
+ }
+ }
+
+ while (mFlags & PREPARING) {
+ mPreparedCondition.wait(mLock);
+ }
+
+ cancelPlayerEvents();
+
+ sendEOS_l();
+
+ mCachedSource.clear();
+
+ if (mAudioSource != NULL) {
+ mAudioSource->stop();
+ }
+ mAudioSource.clear();
+
+ mFlags = 0;
+ mExtractorFlags = 0;
+
+ mDurationUs = -1;
+ mIsSeeking = false;
+ mSeekTimeUs = 0;
+
+ mUri.setTo("");
+ mUriHeaders.clear();
+
+ mFileSource.clear();
+
+ mBitrate = -1;
+
+ {
+ Mutex::Autolock lock(mEndpointLock);
+ if (mAAH_Sender != NULL && mEndpointRegistered) {
+ mAAH_Sender->unregisterEndpoint(mEndpoint);
+ }
+ mEndpointRegistered = false;
+ mEndpointValid = false;
+ }
+
+ mProgramID = 0;
+
+ mAAH_Sender.clear();
+ mLastQueuedMediaTimePTSValid = false;
+ mCurrentClockTransformValid = false;
+ mPlayRateIsPaused = false;
+
+ mTRTPVolume = 255;
+}
+
+status_t AAH_TXPlayer::setLooping(int loop) {
+ return OK;
+}
+
+player_type AAH_TXPlayer::playerType() {
+ return AAH_TX_PLAYER;
+}
+
+status_t AAH_TXPlayer::setParameter(int key, const Parcel &request) {
+ return ERROR_UNSUPPORTED;
+}
+
+status_t AAH_TXPlayer::getParameter(int key, Parcel *reply) {
+ return ERROR_UNSUPPORTED;
+}
+
+status_t AAH_TXPlayer::invoke(const Parcel& request, Parcel *reply) {
+ if (!reply) {
+ return BAD_VALUE;
+ }
+
+ int32_t methodID;
+ status_t err = request.readInt32(&methodID);
+ if (err != android::OK) {
+ return err;
+ }
+
+ switch (methodID) {
+ case kInvokeSetAAHDstIPPort:
+ case kInvokeSetAAHConfigBlob: {
+ if (mEndpointValid) {
+ return INVALID_OPERATION;
+ }
+
+ String8 addr;
+ uint16_t port;
+
+ if (methodID == kInvokeSetAAHDstIPPort) {
+ addr = String8(request.readString16());
+
+ int32_t port32;
+ err = request.readInt32(&port32);
+ if (err != android::OK) {
+ return err;
+ }
+ port = static_cast<uint16_t>(port32);
+ } else {
+ String8 blob(request.readString16());
+
+ char addr_buf[101];
+ if (sscanf(blob.string(), "V1:%100s %" SCNu16,
+ addr_buf, &port) != 2) {
+ return BAD_VALUE;
+ }
+ if (addr.setTo(addr_buf) != OK) {
+ return NO_MEMORY;
+ }
+ }
+
+ struct hostent* ent = gethostbyname(addr.string());
+ if (ent == NULL) {
+ return ERROR_UNKNOWN_HOST;
+ }
+ if (!(ent->h_addrtype == AF_INET && ent->h_length == 4)) {
+ return BAD_VALUE;
+ }
+
+ Mutex::Autolock lock(mEndpointLock);
+ mEndpoint = AAH_TXSender::Endpoint(
+ reinterpret_cast<struct in_addr*>(ent->h_addr)->s_addr,
+ port);
+ mEndpointValid = true;
+ return OK;
+ };
+
+ default:
+ return INVALID_OPERATION;
+ }
+}
+
+status_t AAH_TXPlayer::getMetadata(const media::Metadata::Filter& ids,
+ Parcel* records) {
+ using media::Metadata;
+
+ Metadata metadata(records);
+
+ metadata.appendBool(Metadata::kPauseAvailable, true);
+ metadata.appendBool(Metadata::kSeekBackwardAvailable, false);
+ metadata.appendBool(Metadata::kSeekForwardAvailable, false);
+ metadata.appendBool(Metadata::kSeekAvailable, false);
+
+ return OK;
+}
+
+status_t AAH_TXPlayer::setVolume(float leftVolume, float rightVolume) {
+ if (leftVolume != rightVolume) {
+ ALOGE("%s does not support per channel volume: %f, %f",
+ __PRETTY_FUNCTION__, leftVolume, rightVolume);
+ }
+
+ float volume = clamp(leftVolume, 0.0f, 1.0f);
+
+ Mutex::Autolock lock(mLock);
+ mTRTPVolume = static_cast<uint8_t>((leftVolume * 255.0) + 0.5);
+
+ return OK;
+}
+
+status_t AAH_TXPlayer::setAudioStreamType(audio_stream_type_t streamType) {
+ return OK;
+}
+
+void AAH_TXPlayer::notifyListener_l(int msg, int ext1, int ext2) {
+ sendEvent(msg, ext1, ext2);
+}
+
+bool AAH_TXPlayer::getBitrate_l(int64_t *bitrate) {
+ off64_t size;
+ if (mDurationUs >= 0 &&
+ mCachedSource != NULL &&
+ mCachedSource->getSize(&size) == OK) {
+ *bitrate = size * 8000000ll / mDurationUs; // in bits/sec
+ return true;
+ }
+
+ if (mBitrate >= 0) {
+ *bitrate = mBitrate;
+ return true;
+ }
+
+ *bitrate = 0;
+
+ return false;
+}
+
+// Returns true iff cached duration is available/applicable.
+bool AAH_TXPlayer::getCachedDuration_l(int64_t *durationUs, bool *eos) {
+ int64_t bitrate;
+
+ if (mCachedSource != NULL && getBitrate_l(&bitrate)) {
+ status_t finalStatus;
+ size_t cachedDataRemaining = mCachedSource->approxDataRemaining(
+ &finalStatus);
+ *durationUs = cachedDataRemaining * 8000000ll / bitrate;
+ *eos = (finalStatus != OK);
+ return true;
+ }
+
+ return false;
+}
+
+void AAH_TXPlayer::ensureCacheIsFetching_l() {
+ if (mCachedSource != NULL) {
+ mCachedSource->resumeFetchingIfNecessary();
+ }
+}
+
+void AAH_TXPlayer::postBufferingEvent_l() {
+ if (mBufferingEventPending) {
+ return;
+ }
+ mBufferingEventPending = true;
+ mQueue.postEventWithDelay(mBufferingEvent, 1000000ll);
+}
+
+void AAH_TXPlayer::postPumpAudioEvent_l(int64_t delayUs) {
+ if (mPumpAudioEventPending) {
+ return;
+ }
+ mPumpAudioEventPending = true;
+ mQueue.postEventWithDelay(mPumpAudioEvent, delayUs < 0 ? 10000 : delayUs);
+}
+
+void AAH_TXPlayer::onBufferingUpdate() {
+ Mutex::Autolock autoLock(mLock);
+ if (!mBufferingEventPending) {
+ return;
+ }
+ mBufferingEventPending = false;
+
+ if (mCachedSource != NULL) {
+ status_t finalStatus;
+ size_t cachedDataRemaining = mCachedSource->approxDataRemaining(
+ &finalStatus);
+ bool eos = (finalStatus != OK);
+
+ if (eos) {
+ if (finalStatus == ERROR_END_OF_STREAM) {
+ notifyListener_l(MEDIA_BUFFERING_UPDATE, 100);
+ }
+ if (mFlags & PREPARING) {
+ ALOGV("cache has reached EOS, prepare is done.");
+ finishAsyncPrepare_l();
+ }
+ } else {
+ int64_t bitrate;
+ if (getBitrate_l(&bitrate)) {
+ size_t cachedSize = mCachedSource->cachedSize();
+ int64_t cachedDurationUs = cachedSize * 8000000ll / bitrate;
+
+ int percentage = (100.0 * (double) cachedDurationUs)
+ / mDurationUs;
+ if (percentage > 100) {
+ percentage = 100;
+ }
+
+ notifyListener_l(MEDIA_BUFFERING_UPDATE, percentage);
+ } else {
+ // We don't know the bitrate of the stream, use absolute size
+ // limits to maintain the cache.
+
+ if ((mFlags & PLAYING) &&
+ !eos &&
+ (cachedDataRemaining < kLowWaterMarkBytes)) {
+ ALOGI("cache is running low (< %d) , pausing.",
+ kLowWaterMarkBytes);
+ mFlags |= CACHE_UNDERRUN;
+ pause_l();
+ ensureCacheIsFetching_l();
+ notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_START);
+ } else if (eos || cachedDataRemaining > kHighWaterMarkBytes) {
+ if (mFlags & CACHE_UNDERRUN) {
+ ALOGI("cache has filled up (> %d), resuming.",
+ kHighWaterMarkBytes);
+ mFlags &= ~CACHE_UNDERRUN;
+ play_l();
+ notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_END);
+ } else if (mFlags & PREPARING) {
+ ALOGV("cache has filled up (> %d), prepare is done",
+ kHighWaterMarkBytes);
+ finishAsyncPrepare_l();
+ }
+ }
+ }
+ }
+ }
+
+ int64_t cachedDurationUs;
+ bool eos;
+ if (getCachedDuration_l(&cachedDurationUs, &eos)) {
+ ALOGV("cachedDurationUs = %.2f secs, eos=%d",
+ cachedDurationUs / 1E6, eos);
+
+ if ((mFlags & PLAYING) &&
+ !eos &&
+ (cachedDurationUs < kLowWaterMarkUs)) {
+ ALOGI("cache is running low (%.2f secs) , pausing.",
+ cachedDurationUs / 1E6);
+ mFlags |= CACHE_UNDERRUN;
+ pause_l();
+ ensureCacheIsFetching_l();
+ notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_START);
+ } else if (eos || cachedDurationUs > kHighWaterMarkUs) {
+ if (mFlags & CACHE_UNDERRUN) {
+ ALOGI("cache has filled up (%.2f secs), resuming.",
+ cachedDurationUs / 1E6);
+ mFlags &= ~CACHE_UNDERRUN;
+ play_l();
+ notifyListener_l(MEDIA_INFO, MEDIA_INFO_BUFFERING_END);
+ } else if (mFlags & PREPARING) {
+ ALOGV("cache has filled up (%.2f secs), prepare is done",
+ cachedDurationUs / 1E6);
+ finishAsyncPrepare_l();
+ }
+ }
+ }
+
+ postBufferingEvent_l();
+}
+
+void AAH_TXPlayer::onPumpAudio() {
+ while (true) {
+ Mutex::Autolock autoLock(mLock);
+ // If this flag is clear, its because someone has externally canceled
+ // this pump operation (probably because we a resetting/shutting down).
+ // Get out immediately, do not reschedule ourselves.
+ if (!mPumpAudioEventPending) {
+ return;
+ }
+
+ // Start by checking if there is still work to be doing. If we have
+ // never queued a payload (so we don't know what the last queued PTS is)
+ // or we have never established a MediaTime->CommonTime transformation,
+ // then we have work to do (one time through this loop should establish
+ // both). Otherwise, we want to keep a fixed amt of presentation time
+ // worth of data buffered. If we cannot get common time (service is
+ // unavailable, or common time is undefined)) then we don't have a lot
+ // of good options here. For now, signal an error up to the app level
+ // and shut down the transmission pump.
+ int64_t commonTimeNow;
+ if (OK != mCCHelper.getCommonTime(&commonTimeNow)) {
+ // Failed to get common time; either the service is down or common
+ // time is not synced. Raise an error and shutdown the player.
+ ALOGE("*** Cannot pump audio, unable to fetch common time."
+ " Shutting down.");
+ notifyListener_l(MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, UNKNOWN_ERROR);
+ mPumpAudioEventPending = false;
+ break;
+ }
+
+ if (mCurrentClockTransformValid && mLastQueuedMediaTimePTSValid) {
+ int64_t mediaTimeNow;
+ bool conversionResult = mCurrentClockTransform.doReverseTransform(
+ commonTimeNow,
+ &mediaTimeNow);
+ CHECK(conversionResult);
+
+ if ((mediaTimeNow +
+ kAAHBufferTimeUs -
+ mLastQueuedMediaTimePTS) <= 0) {
+ break;
+ }
+ }
+
+ MediaSource::ReadOptions options;
+ if (mIsSeeking) {
+ options.setSeekTo(mSeekTimeUs);
+ }
+
+ MediaBuffer* mediaBuffer;
+ status_t err = mAudioSource->read(&mediaBuffer, &options);
+ if (err != NO_ERROR) {
+ if (err == ERROR_END_OF_STREAM) {
+ ALOGI("*** %s reached end of stream", __PRETTY_FUNCTION__);
+ notifyListener_l(MEDIA_BUFFERING_UPDATE, 100);
+ notifyListener_l(MEDIA_PLAYBACK_COMPLETE);
+ pause_l(false);
+ sendEOS_l();
+ } else {
+ ALOGE("*** %s read failed err=%d", __PRETTY_FUNCTION__, err);
+ }
+ return;
+ }
+
+ if (mIsSeeking) {
+ mIsSeeking = false;
+ notifyListener_l(MEDIA_SEEK_COMPLETE);
+ }
+
+ uint8_t* data = (static_cast<uint8_t*>(mediaBuffer->data()) +
+ mediaBuffer->range_offset());
+ ALOGV("*** %s got media buffer data=[%02hhx %02hhx %02hhx %02hhx]"
+ " offset=%d length=%d", __PRETTY_FUNCTION__,
+ data[0], data[1], data[2], data[3],
+ mediaBuffer->range_offset(), mediaBuffer->range_length());
+
+ int64_t mediaTimeUs;
+ CHECK(mediaBuffer->meta_data()->findInt64(kKeyTime, &mediaTimeUs));
+ ALOGV("*** timeUs=%lld", mediaTimeUs);
+
+ if (!mCurrentClockTransformValid) {
+ if (OK == mCCHelper.getCommonTime(&commonTimeNow)) {
+ mCurrentClockTransform.a_zero = mediaTimeUs;
+ mCurrentClockTransform.b_zero = commonTimeNow +
+ kAAHStartupLeadTimeUs;
+ mCurrentClockTransform.a_to_b_numer = 1;
+ mCurrentClockTransform.a_to_b_denom = mPlayRateIsPaused ? 0 : 1;
+ mCurrentClockTransformValid = true;
+ } else {
+ // Failed to get common time; either the service is down or
+ // common time is not synced. Raise an error and shutdown the
+ // player.
+ ALOGE("*** Cannot begin transmission, unable to fetch common"
+ " time. Dropping sample with pts=%lld", mediaTimeUs);
+ notifyListener_l(MEDIA_ERROR,
+ MEDIA_ERROR_UNKNOWN,
+ UNKNOWN_ERROR);
+ mPumpAudioEventPending = false;
+ break;
+ }
+ }
+
+ ALOGV("*** transmitting packet with pts=%lld", mediaTimeUs);
+
+ sp<TRTPAudioPacket> packet = new TRTPAudioPacket();
+ packet->setPTS(mediaTimeUs);
+ packet->setSubstreamID(1);
+
+ packet->setCodecType(TRTPAudioPacket::kCodecMPEG1Audio);
+ packet->setVolume(mTRTPVolume);
+ // TODO : introduce a throttle for this so we can control the
+ // frequency with which transforms get sent.
+ packet->setClockTransform(mCurrentClockTransform);
+ packet->setAccessUnitData(data, mediaBuffer->range_length());
+ packet->setRandomAccessPoint(true);
+
+ queuePacketToSender_l(packet);
+ mediaBuffer->release();
+
+ mLastQueuedMediaTimePTSValid = true;
+ mLastQueuedMediaTimePTS = mediaTimeUs;
+ }
+
+ { // Explicit scope for the autolock pattern.
+ Mutex::Autolock autoLock(mLock);
+
+ // If someone externally has cleared this flag, its because we should be
+ // shutting down. Do not reschedule ourselves.
+ if (!mPumpAudioEventPending) {
+ return;
+ }
+
+ // Looks like no one canceled us explicitly. Clear our flag and post a
+ // new event to ourselves.
+ mPumpAudioEventPending = false;
+ postPumpAudioEvent_l(10000);
+ }
+}
+
+void AAH_TXPlayer::queuePacketToSender_l(const sp<TRTPPacket>& packet) {
+ if (mAAH_Sender == NULL) {
+ return;
+ }
+
+ sp<AMessage> message = new AMessage(AAH_TXSender::kWhatSendPacket,
+ mAAH_Sender->handlerID());
+
+ {
+ Mutex::Autolock lock(mEndpointLock);
+ if (!mEndpointValid) {
+ return;
+ }
+
+ message->setInt32(AAH_TXSender::kSendPacketIPAddr, mEndpoint.addr);
+ message->setInt32(AAH_TXSender::kSendPacketPort, mEndpoint.port);
+ }
+
+ packet->setProgramID(mProgramID);
+ packet->setExpireTime(systemTime() + kAAHRetryKeepAroundTimeNs);
+ packet->pack();
+
+ message->setObject(AAH_TXSender::kSendPacketTRTPPacket, packet);
+
+ message->post();
+}
+
+} // namespace android
diff --git a/media/libaah_rtp/aah_tx_player.h b/media/libaah_rtp/aah_tx_player.h
new file mode 100644
index 0000000..64cf5dc1
--- /dev/null
+++ b/media/libaah_rtp/aah_tx_player.h
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#ifndef __AAH_TX_PLAYER_H__
+#define __AAH_TX_PLAYER_H__
+
+#include <common_time/cc_helper.h>
+#include <libstagefright/include/HTTPBase.h>
+#include <libstagefright/include/NuCachedSource2.h>
+#include <libstagefright/include/TimedEventQueue.h>
+#include <media/MediaPlayerInterface.h>
+#include <media/stagefright/MediaExtractor.h>
+#include <media/stagefright/MediaSource.h>
+#include <utils/LinearTransform.h>
+#include <utils/String8.h>
+#include <utils/threads.h>
+
+#include "aah_tx_sender.h"
+
+namespace android {
+
+class AAH_TXPlayer : public MediaPlayerHWInterface {
+ public:
+ AAH_TXPlayer();
+
+ virtual status_t initCheck();
+ virtual status_t setDataSource(const char *url,
+ const KeyedVector<String8, String8>*
+ headers);
+ virtual status_t setDataSource(int fd, int64_t offset, int64_t length);
+ virtual status_t setVideoSurface(const sp<Surface>& surface);
+ virtual status_t setVideoSurfaceTexture(const sp<ISurfaceTexture>&
+ surfaceTexture);
+ virtual status_t prepare();
+ virtual status_t prepareAsync();
+ virtual status_t start();
+ virtual status_t stop();
+ virtual status_t pause();
+ virtual bool isPlaying();
+ virtual status_t seekTo(int msec);
+ virtual status_t getCurrentPosition(int *msec);
+ virtual status_t getDuration(int *msec);
+ virtual status_t reset();
+ virtual status_t setLooping(int loop);
+ virtual player_type playerType();
+ virtual status_t setParameter(int key, const Parcel &request);
+ virtual status_t getParameter(int key, Parcel *reply);
+ virtual status_t invoke(const Parcel& request, Parcel *reply);
+ virtual status_t getMetadata(const media::Metadata::Filter& ids,
+ Parcel* records);
+ virtual status_t setVolume(float leftVolume, float rightVolume);
+ virtual status_t setAudioStreamType(audio_stream_type_t streamType);
+
+ // invoke method IDs
+ enum {
+ // set the IP address and port of the A@H receiver
+ kInvokeSetAAHDstIPPort = 1,
+
+ // set the destination IP address and port (and perhaps any additional
+ // parameters added in the future) packaged in one string
+ kInvokeSetAAHConfigBlob,
+ };
+
+ static const int64_t kAAHRetryKeepAroundTimeNs;
+
+ protected:
+ virtual ~AAH_TXPlayer();
+
+ private:
+ friend struct AwesomeEvent;
+
+ enum {
+ PLAYING = 1,
+ PREPARING = 8,
+ PREPARED = 16,
+ PREPARE_CANCELLED = 64,
+ CACHE_UNDERRUN = 128,
+
+ // We are basically done preparing but are currently buffering
+ // sufficient data to begin playback and finish the preparation
+ // phase for good.
+ PREPARING_CONNECTED = 2048,
+
+ INCOGNITO = 32768,
+ };
+
+ status_t setDataSource_l(const char *url,
+ const KeyedVector<String8, String8> *headers);
+ status_t setDataSource_l(const sp<MediaExtractor>& extractor);
+ status_t finishSetDataSource_l();
+ status_t prepareAsync_l();
+ void onPrepareAsyncEvent();
+ void finishAsyncPrepare_l();
+ void abortPrepare(status_t err);
+ status_t play_l();
+ status_t pause_l(bool doClockUpdate = true);
+ status_t seekTo_l(int64_t timeUs);
+ void updateClockTransform_l(bool pause);
+ void sendEOS_l();
+ void cancelPlayerEvents(bool keepBufferingGoing = false);
+ void reset_l();
+ void notifyListener_l(int msg, int ext1 = 0, int ext2 = 0);
+ bool getBitrate_l(int64_t* bitrate);
+ status_t getDuration_l(int* msec);
+ bool getCachedDuration_l(int64_t* durationUs, bool* eos);
+ void ensureCacheIsFetching_l();
+ void postBufferingEvent_l();
+ void postPumpAudioEvent_l(int64_t delayUs);
+ void onBufferingUpdate();
+ void onPumpAudio();
+ void queuePacketToSender_l(const sp<TRTPPacket>& packet);
+
+ Mutex mLock;
+
+ TimedEventQueue mQueue;
+ bool mQueueStarted;
+
+ sp<TimedEventQueue::Event> mBufferingEvent;
+ bool mBufferingEventPending;
+
+ uint32_t mFlags;
+ uint32_t mExtractorFlags;
+
+ String8 mUri;
+ KeyedVector<String8, String8> mUriHeaders;
+
+ sp<DataSource> mFileSource;
+
+ sp<TimedEventQueue::Event> mAsyncPrepareEvent;
+ Condition mPreparedCondition;
+ status_t mPrepareResult;
+
+ bool mIsSeeking;
+ int64_t mSeekTimeUs;
+
+ sp<TimedEventQueue::Event> mPumpAudioEvent;
+ bool mPumpAudioEventPending;
+
+ sp<HTTPBase> mConnectingDataSource;
+ sp<NuCachedSource2> mCachedSource;
+
+ sp<MediaSource> mAudioSource;
+ int64_t mDurationUs;
+ int64_t mBitrate;
+
+ sp<AAH_TXSender> mAAH_Sender;
+ LinearTransform mCurrentClockTransform;
+ bool mCurrentClockTransformValid;
+ int64_t mLastQueuedMediaTimePTS;
+ bool mLastQueuedMediaTimePTSValid;
+ bool mPlayRateIsPaused;
+ CCHelper mCCHelper;
+
+ Mutex mEndpointLock;
+ AAH_TXSender::Endpoint mEndpoint;
+ bool mEndpointValid;
+ bool mEndpointRegistered;
+ uint16_t mProgramID;
+ uint8_t mTRTPVolume;
+
+ DISALLOW_EVIL_CONSTRUCTORS(AAH_TXPlayer);
+};
+
+} // namespace android
+
+#endif // __AAH_TX_PLAYER_H__
diff --git a/media/libaah_rtp/aah_tx_sender.cpp b/media/libaah_rtp/aah_tx_sender.cpp
new file mode 100644
index 0000000..d991ea7
--- /dev/null
+++ b/media/libaah_rtp/aah_tx_sender.cpp
@@ -0,0 +1,602 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#define LOG_TAG "LibAAH_RTP"
+#include <media/stagefright/foundation/ADebug.h>
+
+#include <netinet/in.h>
+#include <poll.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+#include <media/stagefright/foundation/AMessage.h>
+#include <utils/misc.h>
+
+#include "aah_tx_player.h"
+#include "aah_tx_sender.h"
+
+namespace android {
+
+const char* AAH_TXSender::kSendPacketIPAddr = "ipaddr";
+const char* AAH_TXSender::kSendPacketPort = "port";
+const char* AAH_TXSender::kSendPacketTRTPPacket = "trtp";
+
+const int AAH_TXSender::kRetryTrimIntervalUs = 100000;
+const int AAH_TXSender::kHeartbeatIntervalUs = 1000000;
+const int AAH_TXSender::kRetryBufferCapacity = 100;
+const nsecs_t AAH_TXSender::kHeartbeatTimeout = 600ull * 1000000000ull;
+
+Mutex AAH_TXSender::sLock;
+wp<AAH_TXSender> AAH_TXSender::sInstance;
+uint32_t AAH_TXSender::sNextEpoch;
+bool AAH_TXSender::sNextEpochValid = false;
+
+AAH_TXSender::AAH_TXSender() : mSocket(-1) {
+ mLastSentPacketTime = systemTime();
+}
+
+sp<AAH_TXSender> AAH_TXSender::GetInstance() {
+ Mutex::Autolock autoLock(sLock);
+
+ sp<AAH_TXSender> sender = sInstance.promote();
+
+ if (sender == NULL) {
+ sender = new AAH_TXSender();
+ if (sender == NULL) {
+ return NULL;
+ }
+
+ sender->mLooper = new ALooper();
+ if (sender->mLooper == NULL) {
+ return NULL;
+ }
+
+ sender->mReflector = new AHandlerReflector<AAH_TXSender>(sender.get());
+ if (sender->mReflector == NULL) {
+ return NULL;
+ }
+
+ sender->mSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (sender->mSocket == -1) {
+ ALOGW("%s unable to create socket", __PRETTY_FUNCTION__);
+ return NULL;
+ }
+
+ struct sockaddr_in bind_addr;
+ memset(&bind_addr, 0, sizeof(bind_addr));
+ bind_addr.sin_family = AF_INET;
+ if (bind(sender->mSocket,
+ reinterpret_cast<const sockaddr*>(&bind_addr),
+ sizeof(bind_addr)) < 0) {
+ ALOGW("%s unable to bind socket (errno %d)",
+ __PRETTY_FUNCTION__, errno);
+ return NULL;
+ }
+
+ sender->mRetryReceiver = new RetryReceiver(sender.get());
+ if (sender->mRetryReceiver == NULL) {
+ return NULL;
+ }
+
+ sender->mLooper->setName("AAH_TXSender");
+ sender->mLooper->registerHandler(sender->mReflector);
+ sender->mLooper->start(false, false, PRIORITY_AUDIO);
+
+ if (sender->mRetryReceiver->run("AAH_TXSenderRetry", PRIORITY_AUDIO)
+ != OK) {
+ ALOGW("%s unable to start retry thread", __PRETTY_FUNCTION__);
+ return NULL;
+ }
+
+ sInstance = sender;
+ }
+
+ return sender;
+}
+
+AAH_TXSender::~AAH_TXSender() {
+ mLooper->stop();
+ mLooper->unregisterHandler(mReflector->id());
+
+ if (mRetryReceiver != NULL) {
+ mRetryReceiver->requestExit();
+ mRetryReceiver->mWakeupEvent.setEvent();
+ if (mRetryReceiver->requestExitAndWait() != OK) {
+ ALOGW("%s shutdown of retry receiver failed", __PRETTY_FUNCTION__);
+ }
+ mRetryReceiver->mSender = NULL;
+ mRetryReceiver.clear();
+ }
+
+ if (mSocket != -1) {
+ close(mSocket);
+ }
+}
+
+// Return the next epoch number usable for a newly instantiated endpoint.
+uint32_t AAH_TXSender::getNextEpoch() {
+ Mutex::Autolock autoLock(sLock);
+
+ if (sNextEpochValid) {
+ sNextEpoch = (sNextEpoch + 1) & TRTPPacket::kTRTPEpochMask;
+ } else {
+ sNextEpoch = ns2ms(systemTime()) & TRTPPacket::kTRTPEpochMask;
+ sNextEpochValid = true;
+ }
+
+ return sNextEpoch;
+}
+
+// Notify the sender that a player has started sending to this endpoint.
+// Returns a program ID for use by the calling player.
+uint16_t AAH_TXSender::registerEndpoint(const Endpoint& endpoint) {
+ Mutex::Autolock lock(mEndpointLock);
+
+ EndpointState* eps = mEndpointMap.valueFor(endpoint);
+ if (eps) {
+ eps->playerRefCount++;
+ } else {
+ eps = new EndpointState(getNextEpoch());
+ mEndpointMap.add(endpoint, eps);
+ }
+
+ // if this is the first registered endpoint, then send a message to start
+ // trimming retry buffers and a message to start sending heartbeats.
+ if (mEndpointMap.size() == 1) {
+ sp<AMessage> trimMessage = new AMessage(kWhatTrimRetryBuffers,
+ handlerID());
+ trimMessage->post(kRetryTrimIntervalUs);
+
+ sp<AMessage> heartbeatMessage = new AMessage(kWhatSendHeartbeats,
+ handlerID());
+ heartbeatMessage->post(kHeartbeatIntervalUs);
+ }
+
+ eps->nextProgramID++;
+ return eps->nextProgramID;
+}
+
+// Notify the sender that a player has ceased sending to this endpoint.
+// An endpoint's state can not be deleted until all of the endpoint's
+// registered players have called unregisterEndpoint.
+void AAH_TXSender::unregisterEndpoint(const Endpoint& endpoint) {
+ Mutex::Autolock lock(mEndpointLock);
+
+ EndpointState* eps = mEndpointMap.valueFor(endpoint);
+ if (eps) {
+ eps->playerRefCount--;
+ CHECK(eps->playerRefCount >= 0);
+ }
+}
+
+void AAH_TXSender::onMessageReceived(const sp<AMessage>& msg) {
+ switch (msg->what()) {
+ case kWhatSendPacket:
+ onSendPacket(msg);
+ break;
+
+ case kWhatTrimRetryBuffers:
+ trimRetryBuffers();
+ break;
+
+ case kWhatSendHeartbeats:
+ sendHeartbeats();
+ break;
+
+ default:
+ TRESPASS();
+ break;
+ }
+}
+
+void AAH_TXSender::onSendPacket(const sp<AMessage>& msg) {
+ sp<RefBase> obj;
+ CHECK(msg->findObject(kSendPacketTRTPPacket, &obj));
+ sp<TRTPPacket> packet = static_cast<TRTPPacket*>(obj.get());
+
+ uint32_t ipAddr;
+ CHECK(msg->findInt32(kSendPacketIPAddr,
+ reinterpret_cast<int32_t*>(&ipAddr)));
+
+ int32_t port32;
+ CHECK(msg->findInt32(kSendPacketPort, &port32));
+ uint16_t port = port32;
+
+ Mutex::Autolock lock(mEndpointLock);
+ doSendPacket_l(packet, Endpoint(ipAddr, port));
+ mLastSentPacketTime = systemTime();
+}
+
+void AAH_TXSender::doSendPacket_l(const sp<TRTPPacket>& packet,
+ const Endpoint& endpoint) {
+ EndpointState* eps = mEndpointMap.valueFor(endpoint);
+ if (!eps) {
+ // the endpoint state has disappeared, so the player that sent this
+ // packet must be dead.
+ return;
+ }
+
+ // assign the packet's sequence number
+ packet->setEpoch(eps->epoch);
+ packet->setSeqNumber(eps->trtpSeqNumber++);
+
+ // add the packet to the retry buffer
+ RetryBuffer& retry = eps->retry;
+ retry.push_back(packet);
+
+ // send the packet
+ struct sockaddr_in addr;
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = endpoint.addr;
+ addr.sin_port = htons(endpoint.port);
+
+ ssize_t result = sendto(mSocket,
+ packet->getPacket(),
+ packet->getPacketLen(),
+ 0,
+ (const struct sockaddr *) &addr,
+ sizeof(addr));
+ if (result == -1) {
+ ALOGW("%s sendto failed", __PRETTY_FUNCTION__);
+ }
+}
+
+void AAH_TXSender::trimRetryBuffers() {
+ Mutex::Autolock lock(mEndpointLock);
+
+ nsecs_t localTimeNow = systemTime();
+
+ Vector<Endpoint> endpointsToRemove;
+
+ for (size_t i = 0; i < mEndpointMap.size(); i++) {
+ EndpointState* eps = mEndpointMap.editValueAt(i);
+ RetryBuffer& retry = eps->retry;
+
+ while (!retry.isEmpty()) {
+ if (retry[0]->getExpireTime() < localTimeNow) {
+ retry.pop_front();
+ } else {
+ break;
+ }
+ }
+
+ if (retry.isEmpty() && eps->playerRefCount == 0) {
+ endpointsToRemove.add(mEndpointMap.keyAt(i));
+ }
+ }
+
+ // remove the state for any endpoints that are no longer in use
+ for (size_t i = 0; i < endpointsToRemove.size(); i++) {
+ Endpoint& e = endpointsToRemove.editItemAt(i);
+ ALOGD("*** %s removing endpoint addr=%08x", __PRETTY_FUNCTION__, e.addr);
+ size_t index = mEndpointMap.indexOfKey(e);
+ delete mEndpointMap.valueAt(index);
+ mEndpointMap.removeItemsAt(index);
+ }
+
+ // schedule the next trim
+ if (mEndpointMap.size()) {
+ sp<AMessage> trimMessage = new AMessage(kWhatTrimRetryBuffers,
+ handlerID());
+ trimMessage->post(kRetryTrimIntervalUs);
+ }
+}
+
+void AAH_TXSender::sendHeartbeats() {
+ Mutex::Autolock lock(mEndpointLock);
+
+ if (shouldSendHeartbeats_l()) {
+ for (size_t i = 0; i < mEndpointMap.size(); i++) {
+ EndpointState* eps = mEndpointMap.editValueAt(i);
+ const Endpoint& ep = mEndpointMap.keyAt(i);
+
+ sp<TRTPControlPacket> packet = new TRTPControlPacket();
+ packet->setCommandID(TRTPControlPacket::kCommandNop);
+
+ packet->setExpireTime(systemTime() +
+ AAH_TXPlayer::kAAHRetryKeepAroundTimeNs);
+ packet->pack();
+
+ doSendPacket_l(packet, ep);
+ }
+ }
+
+ // schedule the next heartbeat
+ if (mEndpointMap.size()) {
+ sp<AMessage> heartbeatMessage = new AMessage(kWhatSendHeartbeats,
+ handlerID());
+ heartbeatMessage->post(kHeartbeatIntervalUs);
+ }
+}
+
+bool AAH_TXSender::shouldSendHeartbeats_l() {
+ // assert(holding endpoint lock)
+ return (systemTime() < (mLastSentPacketTime + kHeartbeatTimeout));
+}
+
+// Receiver
+
+// initial 4-byte ID of a retry request packet
+const uint32_t AAH_TXSender::RetryReceiver::kRetryRequestID = 'Treq';
+
+// initial 4-byte ID of a retry NAK packet
+const uint32_t AAH_TXSender::RetryReceiver::kRetryNakID = 'Tnak';
+
+// initial 4-byte ID of a fast start request packet
+const uint32_t AAH_TXSender::RetryReceiver::kFastStartRequestID = 'Tfst';
+
+AAH_TXSender::RetryReceiver::RetryReceiver(AAH_TXSender* sender)
+ : Thread(false),
+ mSender(sender) {}
+
+ AAH_TXSender::RetryReceiver::~RetryReceiver() {
+ mWakeupEvent.clearPendingEvents();
+ }
+
+// Returns true if val is within the interval bounded inclusively by
+// start and end. Also handles the case where there is a rollover of the
+// range between start and end.
+template <typename T>
+static inline bool withinIntervalWithRollover(T val, T start, T end) {
+ return ((start <= end && val >= start && val <= end) ||
+ (start > end && (val >= start || val <= end)));
+}
+
+bool AAH_TXSender::RetryReceiver::threadLoop() {
+ struct pollfd pollFds[2];
+ pollFds[0].fd = mSender->mSocket;
+ pollFds[0].events = POLLIN;
+ pollFds[0].revents = 0;
+ pollFds[1].fd = mWakeupEvent.getWakeupHandle();
+ pollFds[1].events = POLLIN;
+ pollFds[1].revents = 0;
+
+ int pollResult = poll(pollFds, NELEM(pollFds), -1);
+ if (pollResult == -1) {
+ ALOGE("%s poll failed", __PRETTY_FUNCTION__);
+ return false;
+ }
+
+ if (exitPending()) {
+ ALOGI("*** %s exiting", __PRETTY_FUNCTION__);
+ return false;
+ }
+
+ if (pollFds[0].revents) {
+ handleRetryRequest();
+ }
+
+ return true;
+}
+
+void AAH_TXSender::RetryReceiver::handleRetryRequest() {
+ ALOGV("*** RX %s start", __PRETTY_FUNCTION__);
+
+ RetryPacket request;
+ struct sockaddr requestSrcAddr;
+ socklen_t requestSrcAddrLen = sizeof(requestSrcAddr);
+
+ ssize_t result = recvfrom(mSender->mSocket, &request, sizeof(request), 0,
+ &requestSrcAddr, &requestSrcAddrLen);
+ if (result == -1) {
+ ALOGE("%s recvfrom failed, errno=%d", __PRETTY_FUNCTION__, errno);
+ return;
+ }
+
+ if (static_cast<size_t>(result) < sizeof(RetryPacket)) {
+ ALOGW("%s short packet received", __PRETTY_FUNCTION__);
+ return;
+ }
+
+ uint32_t host_request_id = ntohl(request.id);
+ if ((host_request_id != kRetryRequestID) &&
+ (host_request_id != kFastStartRequestID)) {
+ ALOGW("%s received retry request with bogus ID (%08x)",
+ __PRETTY_FUNCTION__, host_request_id);
+ return;
+ }
+
+ Endpoint endpoint(request.endpointIP, ntohs(request.endpointPort));
+
+ Mutex::Autolock lock(mSender->mEndpointLock);
+
+ EndpointState* eps = mSender->mEndpointMap.valueFor(endpoint);
+
+ if (eps == NULL || eps->retry.isEmpty()) {
+ // we have no retry buffer or an empty retry buffer for this endpoint,
+ // so NAK the entire request
+ RetryPacket nak = request;
+ nak.id = htonl(kRetryNakID);
+ result = sendto(mSender->mSocket, &nak, sizeof(nak), 0,
+ &requestSrcAddr, requestSrcAddrLen);
+ if (result == -1) {
+ ALOGW("%s sendto failed", __PRETTY_FUNCTION__);
+ }
+ return;
+ }
+
+ RetryBuffer& retry = eps->retry;
+
+ uint16_t startSeq = ntohs(request.seqStart);
+ uint16_t endSeq = ntohs(request.seqEnd);
+
+ uint16_t retryFirstSeq = retry[0]->getSeqNumber();
+ uint16_t retryLastSeq = retry[retry.size() - 1]->getSeqNumber();
+
+ // If this is a fast start, then force the start of the retry to match the
+ // start of the retransmit ring buffer (unless the end of the retransmit
+ // ring buffer is already past the point of fast start)
+ if ((host_request_id == kFastStartRequestID) &&
+ !((startSeq - retryFirstSeq) & 0x8000)) {
+ startSeq = retryFirstSeq;
+ }
+
+ int startIndex;
+ if (withinIntervalWithRollover(startSeq, retryFirstSeq, retryLastSeq)) {
+ startIndex = static_cast<uint16_t>(startSeq - retryFirstSeq);
+ } else {
+ startIndex = -1;
+ }
+
+ int endIndex;
+ if (withinIntervalWithRollover(endSeq, retryFirstSeq, retryLastSeq)) {
+ endIndex = static_cast<uint16_t>(endSeq - retryFirstSeq);
+ } else {
+ endIndex = -1;
+ }
+
+ if (startIndex == -1 && endIndex == -1) {
+ // no part of the request range is found in the retry buffer
+ RetryPacket nak = request;
+ nak.id = htonl(kRetryNakID);
+ result = sendto(mSender->mSocket, &nak, sizeof(nak), 0,
+ &requestSrcAddr, requestSrcAddrLen);
+ if (result == -1) {
+ ALOGW("%s sendto failed", __PRETTY_FUNCTION__);
+ }
+ return;
+ }
+
+ if (startIndex == -1) {
+ // NAK a subrange at the front of the request range
+ RetryPacket nak = request;
+ nak.id = htonl(kRetryNakID);
+ nak.seqEnd = htons(retryFirstSeq - 1);
+ result = sendto(mSender->mSocket, &nak, sizeof(nak), 0,
+ &requestSrcAddr, requestSrcAddrLen);
+ if (result == -1) {
+ ALOGW("%s sendto failed", __PRETTY_FUNCTION__);
+ }
+
+ startIndex = 0;
+ } else if (endIndex == -1) {
+ // NAK a subrange at the back of the request range
+ RetryPacket nak = request;
+ nak.id = htonl(kRetryNakID);
+ nak.seqStart = htons(retryLastSeq + 1);
+ result = sendto(mSender->mSocket, &nak, sizeof(nak), 0,
+ &requestSrcAddr, requestSrcAddrLen);
+ if (result == -1) {
+ ALOGW("%s sendto failed", __PRETTY_FUNCTION__);
+ }
+
+ endIndex = retry.size() - 1;
+ }
+
+ // send the retry packets
+ for (int i = startIndex; i <= endIndex; i++) {
+ const sp<TRTPPacket>& replyPacket = retry[i];
+
+ result = sendto(mSender->mSocket,
+ replyPacket->getPacket(),
+ replyPacket->getPacketLen(),
+ 0,
+ &requestSrcAddr,
+ requestSrcAddrLen);
+
+ if (result == -1) {
+ ALOGW("%s sendto failed", __PRETTY_FUNCTION__);
+ }
+ }
+}
+
+// Endpoint
+
+AAH_TXSender::Endpoint::Endpoint()
+ : addr(0)
+ , port(0) { }
+
+AAH_TXSender::Endpoint::Endpoint(uint32_t a, uint16_t p)
+ : addr(a)
+ , port(p) {}
+
+bool AAH_TXSender::Endpoint::operator<(const Endpoint& other) const {
+ return ((addr < other.addr) ||
+ (addr == other.addr && port < other.port));
+}
+
+// EndpointState
+
+AAH_TXSender::EndpointState::EndpointState(uint32_t _epoch)
+ : retry(kRetryBufferCapacity)
+ , playerRefCount(1)
+ , trtpSeqNumber(0)
+ , nextProgramID(0)
+ , epoch(_epoch) { }
+
+// CircularBuffer
+
+template <typename T>
+CircularBuffer<T>::CircularBuffer(size_t capacity)
+ : mCapacity(capacity)
+ , mHead(0)
+ , mTail(0)
+ , mFillCount(0) {
+ mBuffer = new T[capacity];
+}
+
+template <typename T>
+CircularBuffer<T>::~CircularBuffer() {
+ delete [] mBuffer;
+}
+
+template <typename T>
+void CircularBuffer<T>::push_back(const T& item) {
+ if (this->isFull()) {
+ this->pop_front();
+ }
+ mBuffer[mHead] = item;
+ mHead = (mHead + 1) % mCapacity;
+ mFillCount++;
+}
+
+template <typename T>
+void CircularBuffer<T>::pop_front() {
+ CHECK(!isEmpty());
+ mBuffer[mTail] = T();
+ mTail = (mTail + 1) % mCapacity;
+ mFillCount--;
+}
+
+template <typename T>
+size_t CircularBuffer<T>::size() const {
+ return mFillCount;
+}
+
+template <typename T>
+bool CircularBuffer<T>::isFull() const {
+ return (mFillCount == mCapacity);
+}
+
+template <typename T>
+bool CircularBuffer<T>::isEmpty() const {
+ return (mFillCount == 0);
+}
+
+template <typename T>
+const T& CircularBuffer<T>::itemAt(size_t index) const {
+ CHECK(index < mFillCount);
+ return mBuffer[(mTail + index) % mCapacity];
+}
+
+template <typename T>
+const T& CircularBuffer<T>::operator[](size_t index) const {
+ return itemAt(index);
+}
+
+} // namespace android
diff --git a/media/libaah_rtp/aah_tx_sender.h b/media/libaah_rtp/aah_tx_sender.h
new file mode 100644
index 0000000..74206c4
--- /dev/null
+++ b/media/libaah_rtp/aah_tx_sender.h
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#ifndef __AAH_TX_SENDER_H__
+#define __AAH_TX_SENDER_H__
+
+#include <media/stagefright/foundation/ALooper.h>
+#include <media/stagefright/foundation/AHandlerReflector.h>
+#include <utils/RefBase.h>
+#include <utils/threads.h>
+
+#include "aah_tx_packet.h"
+#include "pipe_event.h"
+
+namespace android {
+
+template <typename T> class CircularBuffer {
+ public:
+ CircularBuffer(size_t capacity);
+ ~CircularBuffer();
+ void push_back(const T& item);;
+ void pop_front();
+ size_t size() const;
+ bool isFull() const;
+ bool isEmpty() const;
+ const T& itemAt(size_t index) const;
+ const T& operator[](size_t index) const;
+
+ private:
+ T* mBuffer;
+ size_t mCapacity;
+ size_t mHead;
+ size_t mTail;
+ size_t mFillCount;
+
+ DISALLOW_EVIL_CONSTRUCTORS(CircularBuffer);
+};
+
+class AAH_TXSender : public virtual RefBase {
+ public:
+ ~AAH_TXSender();
+
+ static sp<AAH_TXSender> GetInstance();
+
+ ALooper::handler_id handlerID() { return mReflector->id(); }
+
+ // an IP address and port
+ struct Endpoint {
+ Endpoint();
+ Endpoint(uint32_t a, uint16_t p);
+ bool operator<(const Endpoint& other) const;
+
+ uint32_t addr;
+ uint16_t port;
+ };
+
+ uint16_t registerEndpoint(const Endpoint& endpoint);
+ void unregisterEndpoint(const Endpoint& endpoint);
+
+ enum {
+ kWhatSendPacket,
+ kWhatTrimRetryBuffers,
+ kWhatSendHeartbeats,
+ };
+
+ // fields for SendPacket messages
+ static const char* kSendPacketIPAddr;
+ static const char* kSendPacketPort;
+ static const char* kSendPacketTRTPPacket;
+
+ private:
+ AAH_TXSender();
+
+ static Mutex sLock;
+ static wp<AAH_TXSender> sInstance;
+ static uint32_t sNextEpoch;
+ static bool sNextEpochValid;
+
+ static uint32_t getNextEpoch();
+
+ typedef CircularBuffer<sp<TRTPPacket> > RetryBuffer;
+
+ // state maintained on a per-endpoint basis
+ struct EndpointState {
+ EndpointState(uint32_t epoch);
+ RetryBuffer retry;
+ int playerRefCount;
+ uint16_t trtpSeqNumber;
+ uint16_t nextProgramID;
+ uint32_t epoch;
+ };
+
+ friend class AHandlerReflector<AAH_TXSender>;
+ void onMessageReceived(const sp<AMessage>& msg);
+ void onSendPacket(const sp<AMessage>& msg);
+ void doSendPacket_l(const sp<TRTPPacket>& packet,
+ const Endpoint& endpoint);
+ void trimRetryBuffers();
+ void sendHeartbeats();
+ bool shouldSendHeartbeats_l();
+
+ sp<ALooper> mLooper;
+ sp<AHandlerReflector<AAH_TXSender> > mReflector;
+
+ int mSocket;
+ nsecs_t mLastSentPacketTime;
+
+ DefaultKeyedVector<Endpoint, EndpointState*> mEndpointMap;
+ Mutex mEndpointLock;
+
+ static const int kRetryTrimIntervalUs;
+ static const int kHeartbeatIntervalUs;
+ static const int kRetryBufferCapacity;
+ static const nsecs_t kHeartbeatTimeout;
+
+ class RetryReceiver : public Thread {
+ private:
+ friend class AAH_TXSender;
+
+ RetryReceiver(AAH_TXSender* sender);
+ virtual ~RetryReceiver();
+ virtual bool threadLoop();
+ void handleRetryRequest();
+
+ static const int kMaxReceiverPacketLen;
+ static const uint32_t kRetryRequestID;
+ static const uint32_t kFastStartRequestID;
+ static const uint32_t kRetryNakID;
+
+ AAH_TXSender* mSender;
+ PipeEvent mWakeupEvent;
+ };
+
+ sp<RetryReceiver> mRetryReceiver;
+
+ DISALLOW_EVIL_CONSTRUCTORS(AAH_TXSender);
+};
+
+struct RetryPacket {
+ uint32_t id;
+ uint32_t endpointIP;
+ uint16_t endpointPort;
+ uint16_t seqStart;
+ uint16_t seqEnd;
+} __attribute__((packed));
+
+} // namespace android
+
+#endif // __AAH_TX_SENDER_H__
diff --git a/media/libaah_rtp/pipe_event.cpp b/media/libaah_rtp/pipe_event.cpp
new file mode 100644
index 0000000..b8e6960
--- /dev/null
+++ b/media/libaah_rtp/pipe_event.cpp
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#define LOG_TAG "LibAAH_RTP"
+#include <utils/Log.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <unistd.h>
+
+#include "pipe_event.h"
+
+namespace android {
+
+PipeEvent::PipeEvent() {
+ pipe_[0] = -1;
+ pipe_[1] = -1;
+
+ // Create the pipe.
+ if (pipe(pipe_) >= 0) {
+ // Set non-blocking mode on the read side of the pipe so we can
+ // easily drain it whenever we wakeup.
+ fcntl(pipe_[0], F_SETFL, O_NONBLOCK);
+ } else {
+ ALOGE("Failed to create pipe event %d %d %d",
+ pipe_[0], pipe_[1], errno);
+ pipe_[0] = -1;
+ pipe_[1] = -1;
+ }
+}
+
+PipeEvent::~PipeEvent() {
+ if (pipe_[0] >= 0) {
+ close(pipe_[0]);
+ }
+
+ if (pipe_[1] >= 0) {
+ close(pipe_[1]);
+ }
+}
+
+void PipeEvent::clearPendingEvents() {
+ char drain_buffer[16];
+ while (read(pipe_[0], drain_buffer, sizeof(drain_buffer)) > 0) {
+ // No body.
+ }
+}
+
+bool PipeEvent::wait(int timeout) {
+ struct pollfd wait_fd;
+
+ wait_fd.fd = getWakeupHandle();
+ wait_fd.events = POLLIN;
+ wait_fd.revents = 0;
+
+ int res = poll(&wait_fd, 1, timeout);
+
+ if (res < 0) {
+ ALOGE("Wait error in PipeEvent; sleeping to prevent overload!");
+ usleep(1000);
+ }
+
+ return (res > 0);
+}
+
+void PipeEvent::setEvent() {
+ char foo = 'q';
+ write(pipe_[1], &foo, 1);
+}
+
+} // namespace android
+
diff --git a/media/libaah_rtp/pipe_event.h b/media/libaah_rtp/pipe_event.h
new file mode 100644
index 0000000..e53b0fd
--- /dev/null
+++ b/media/libaah_rtp/pipe_event.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#ifndef __PIPE_EVENT_H__
+#define __PIPE_EVENT_H__
+
+#include <media/stagefright/foundation/ABase.h>
+
+namespace android {
+
+class PipeEvent {
+ public:
+ PipeEvent();
+ ~PipeEvent();
+
+ bool initCheck() const {
+ return ((pipe_[0] >= 0) && (pipe_[1] >= 0));
+ }
+
+ int getWakeupHandle() const { return pipe_[0]; }
+
+ // block until the event fires; returns true if the event fired and false if
+ // the wait timed out. Timeout is expressed in milliseconds; negative
+ // values mean wait forever.
+ bool wait(int timeout = -1);
+
+ void clearPendingEvents();
+ void setEvent();
+
+ private:
+ int pipe_[2];
+
+ DISALLOW_EVIL_CONSTRUCTORS(PipeEvent);
+};
+
+} // namespace android
+
+#endif // __PIPE_EVENT_H__
diff --git a/media/libmedia/AudioEffect.cpp b/media/libmedia/AudioEffect.cpp
index f9f997f..19b7e32 100644
--- a/media/libmedia/AudioEffect.cpp
+++ b/media/libmedia/AudioEffect.cpp
@@ -202,7 +202,7 @@
status_t AudioEffect::setEnabled(bool enabled)
{
if (mStatus != NO_ERROR) {
- return INVALID_OPERATION;
+ return (mStatus == ALREADY_EXISTS) ? INVALID_OPERATION : mStatus;
}
status_t status = NO_ERROR;
@@ -231,7 +231,7 @@
{
if (mStatus != NO_ERROR && mStatus != ALREADY_EXISTS) {
ALOGV("command() bad status %d", mStatus);
- return INVALID_OPERATION;
+ return mStatus;
}
if (cmdCode == EFFECT_CMD_ENABLE || cmdCode == EFFECT_CMD_DISABLE) {
@@ -263,7 +263,7 @@
status_t AudioEffect::setParameter(effect_param_t *param)
{
if (mStatus != NO_ERROR) {
- return INVALID_OPERATION;
+ return (mStatus == ALREADY_EXISTS) ? INVALID_OPERATION : mStatus;
}
if (param == NULL || param->psize == 0 || param->vsize == 0) {
@@ -281,7 +281,7 @@
status_t AudioEffect::setParameterDeferred(effect_param_t *param)
{
if (mStatus != NO_ERROR) {
- return INVALID_OPERATION;
+ return (mStatus == ALREADY_EXISTS) ? INVALID_OPERATION : mStatus;
}
if (param == NULL || param->psize == 0 || param->vsize == 0) {
@@ -307,7 +307,7 @@
status_t AudioEffect::setParameterCommit()
{
if (mStatus != NO_ERROR) {
- return INVALID_OPERATION;
+ return (mStatus == ALREADY_EXISTS) ? INVALID_OPERATION : mStatus;
}
Mutex::Autolock _l(mCblk->lock);
@@ -321,7 +321,7 @@
status_t AudioEffect::getParameter(effect_param_t *param)
{
if (mStatus != NO_ERROR && mStatus != ALREADY_EXISTS) {
- return INVALID_OPERATION;
+ return mStatus;
}
if (param == NULL || param->psize == 0 || param->vsize == 0) {
@@ -341,7 +341,7 @@
void AudioEffect::binderDied()
{
ALOGW("IEffect died");
- mStatus = NO_INIT;
+ mStatus = DEAD_OBJECT;
if (mCbf != NULL) {
status_t status = DEAD_OBJECT;
mCbf(EVENT_ERROR, mUserData, &status);
diff --git a/media/libmedia/AudioTrack.cpp b/media/libmedia/AudioTrack.cpp
index aead9a1..74c97ed 100644
--- a/media/libmedia/AudioTrack.cpp
+++ b/media/libmedia/AudioTrack.cpp
@@ -80,7 +80,9 @@
AudioTrack::AudioTrack()
: mStatus(NO_INIT),
- mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(ANDROID_TGROUP_DEFAULT)
+ mIsTimed(false),
+ mPreviousPriority(ANDROID_PRIORITY_NORMAL),
+ mPreviousSchedulingGroup(ANDROID_TGROUP_DEFAULT)
{
}
@@ -96,7 +98,9 @@
int notificationFrames,
int sessionId)
: mStatus(NO_INIT),
- mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(ANDROID_TGROUP_DEFAULT)
+ mIsTimed(false),
+ mPreviousPriority(ANDROID_PRIORITY_NORMAL),
+ mPreviousSchedulingGroup(ANDROID_TGROUP_DEFAULT)
{
mStatus = set(streamType, sampleRate, format, channelMask,
frameCount, flags, cbf, user, notificationFrames,
@@ -134,7 +138,9 @@
int notificationFrames,
int sessionId)
: mStatus(NO_INIT),
- mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(ANDROID_TGROUP_DEFAULT)
+ mIsTimed(false),
+ mPreviousPriority(ANDROID_PRIORITY_NORMAL),
+ mPreviousSchedulingGroup(ANDROID_TGROUP_DEFAULT)
{
mStatus = set(streamType, sampleRate, format, channelMask,
0, flags, cbf, user, notificationFrames,
@@ -540,6 +546,10 @@
{
int afSamplingRate;
+ if (mIsTimed) {
+ return INVALID_OPERATION;
+ }
+
if (AudioSystem::getOutputSamplingRate(&afSamplingRate, mStreamType) != NO_ERROR) {
return NO_INIT;
}
@@ -553,6 +563,10 @@
uint32_t AudioTrack::getSampleRate() const
{
+ if (mIsTimed) {
+ return INVALID_OPERATION;
+ }
+
AutoMutex lock(mLock);
return mCblk->sampleRate;
}
@@ -578,6 +592,10 @@
return NO_ERROR;
}
+ if (mIsTimed) {
+ return INVALID_OPERATION;
+ }
+
if (loopStart >= loopEnd ||
loopEnd - loopStart > cblk->frameCount ||
cblk->server > loopStart) {
@@ -641,6 +659,8 @@
status_t AudioTrack::setPosition(uint32_t position)
{
+ if (mIsTimed) return INVALID_OPERATION;
+
AutoMutex lock(mLock);
if (!stopped_l()) return INVALID_OPERATION;
@@ -791,6 +811,7 @@
((uint16_t)flags) << 16,
sharedBuffer,
output,
+ mIsTimed,
&mSessionId,
&status);
@@ -957,6 +978,7 @@
{
if (mSharedBuffer != 0) return INVALID_OPERATION;
+ if (mIsTimed) return INVALID_OPERATION;
if (ssize_t(userSize) < 0) {
// Sanity-check: user is most-likely passing an error code, and it would
@@ -1013,6 +1035,59 @@
// -------------------------------------------------------------------------
+TimedAudioTrack::TimedAudioTrack() {
+ mIsTimed = true;
+}
+
+status_t TimedAudioTrack::allocateTimedBuffer(size_t size, sp<IMemory>* buffer)
+{
+ status_t result = UNKNOWN_ERROR;
+
+ // If the track is not invalid already, try to allocate a buffer. alloc
+ // fails indicating that the server is dead, flag the track as invalid so
+ // we can attempt to restore in in just a bit.
+ if (!(mCblk->flags & CBLK_INVALID_MSK)) {
+ result = mAudioTrack->allocateTimedBuffer(size, buffer);
+ if (result == DEAD_OBJECT) {
+ android_atomic_or(CBLK_INVALID_ON, &mCblk->flags);
+ }
+ }
+
+ // If the track is invalid at this point, attempt to restore it. and try the
+ // allocation one more time.
+ if (mCblk->flags & CBLK_INVALID_MSK) {
+ mCblk->lock.lock();
+ result = restoreTrack_l(mCblk, false);
+ mCblk->lock.unlock();
+
+ if (result == OK)
+ result = mAudioTrack->allocateTimedBuffer(size, buffer);
+ }
+
+ return result;
+}
+
+status_t TimedAudioTrack::queueTimedBuffer(const sp<IMemory>& buffer,
+ int64_t pts)
+{
+ // restart track if it was disabled by audioflinger due to previous underrun
+ if (mActive && (mCblk->flags & CBLK_DISABLED_MSK)) {
+ android_atomic_and(~CBLK_DISABLED_ON, &mCblk->flags);
+ ALOGW("queueTimedBuffer() track %p disabled, restarting", this);
+ mAudioTrack->start(0);
+ }
+
+ return mAudioTrack->queueTimedBuffer(buffer, pts);
+}
+
+status_t TimedAudioTrack::setMediaTimeTransform(const LinearTransform& xform,
+ TargetTimeline target)
+{
+ return mAudioTrack->setMediaTimeTransform(xform, target);
+}
+
+// -------------------------------------------------------------------------
+
bool AudioTrack::processAudioBuffer(const sp<AudioTrackThread>& thread)
{
Buffer audioBuffer;
diff --git a/media/libmedia/IAudioFlinger.cpp b/media/libmedia/IAudioFlinger.cpp
index 4507e5d..ebadbfa 100644
--- a/media/libmedia/IAudioFlinger.cpp
+++ b/media/libmedia/IAudioFlinger.cpp
@@ -90,6 +90,7 @@
uint32_t flags,
const sp<IMemory>& sharedBuffer,
audio_io_handle_t output,
+ bool isTimed,
int *sessionId,
status_t *status)
{
@@ -105,6 +106,7 @@
data.writeInt32(flags);
data.writeStrongBinder(sharedBuffer->asBinder());
data.writeInt32((int32_t) output);
+ data.writeInt32(isTimed);
int lSessionId = 0;
if (sessionId != NULL) {
lSessionId = *sessionId;
@@ -689,11 +691,12 @@
uint32_t flags = data.readInt32();
sp<IMemory> buffer = interface_cast<IMemory>(data.readStrongBinder());
audio_io_handle_t output = (audio_io_handle_t) data.readInt32();
+ bool isTimed = data.readInt32();
int sessionId = data.readInt32();
status_t status;
sp<IAudioTrack> track = createTrack(pid,
(audio_stream_type_t) streamType, sampleRate, format,
- channelCount, bufferCount, flags, buffer, output, &sessionId, &status);
+ channelCount, bufferCount, flags, buffer, output, isTimed, &sessionId, &status);
reply->writeInt32(sessionId);
reply->writeInt32(status);
reply->writeStrongBinder(track->asBinder());
diff --git a/media/libmedia/IAudioTrack.cpp b/media/libmedia/IAudioTrack.cpp
index a7958de..28ebbbfc 100644
--- a/media/libmedia/IAudioTrack.cpp
+++ b/media/libmedia/IAudioTrack.cpp
@@ -35,7 +35,10 @@
FLUSH,
MUTE,
PAUSE,
- ATTACH_AUX_EFFECT
+ ATTACH_AUX_EFFECT,
+ ALLOCATE_TIMED_BUFFER,
+ QUEUE_TIMED_BUFFER,
+ SET_MEDIA_TIME_TRANSFORM,
};
class BpAudioTrack : public BpInterface<IAudioTrack>
@@ -114,6 +117,52 @@
}
return status;
}
+
+ virtual status_t allocateTimedBuffer(size_t size, sp<IMemory>* buffer) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
+ data.writeInt32(size);
+ status_t status = remote()->transact(ALLOCATE_TIMED_BUFFER,
+ data, &reply);
+ if (status == NO_ERROR) {
+ status = reply.readInt32();
+ if (status == NO_ERROR) {
+ *buffer = interface_cast<IMemory>(reply.readStrongBinder());
+ }
+ }
+ return status;
+ }
+
+ virtual status_t queueTimedBuffer(const sp<IMemory>& buffer,
+ int64_t pts) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
+ data.writeStrongBinder(buffer->asBinder());
+ data.writeInt64(pts);
+ status_t status = remote()->transact(QUEUE_TIMED_BUFFER,
+ data, &reply);
+ if (status == NO_ERROR) {
+ status = reply.readInt32();
+ }
+ return status;
+ }
+
+ virtual status_t setMediaTimeTransform(const LinearTransform& xform,
+ int target) {
+ Parcel data, reply;
+ data.writeInterfaceToken(IAudioTrack::getInterfaceDescriptor());
+ data.writeInt64(xform.a_zero);
+ data.writeInt64(xform.b_zero);
+ data.writeInt32(xform.a_to_b_numer);
+ data.writeInt32(xform.a_to_b_denom);
+ data.writeInt32(target);
+ status_t status = remote()->transact(SET_MEDIA_TIME_TRANSFORM,
+ data, &reply);
+ if (status == NO_ERROR) {
+ status = reply.readInt32();
+ }
+ return status;
+ }
};
IMPLEMENT_META_INTERFACE(AudioTrack, "android.media.IAudioTrack");
@@ -159,10 +208,38 @@
reply->writeInt32(attachAuxEffect(data.readInt32()));
return NO_ERROR;
} break;
+ case ALLOCATE_TIMED_BUFFER: {
+ CHECK_INTERFACE(IAudioTrack, data, reply);
+ sp<IMemory> buffer;
+ status_t status = allocateTimedBuffer(data.readInt32(), &buffer);
+ reply->writeInt32(status);
+ if (status == NO_ERROR) {
+ reply->writeStrongBinder(buffer->asBinder());
+ }
+ return NO_ERROR;
+ } break;
+ case QUEUE_TIMED_BUFFER: {
+ CHECK_INTERFACE(IAudioTrack, data, reply);
+ sp<IMemory> buffer = interface_cast<IMemory>(
+ data.readStrongBinder());
+ uint64_t pts = data.readInt64();
+ reply->writeInt32(queueTimedBuffer(buffer, pts));
+ return NO_ERROR;
+ } break;
+ case SET_MEDIA_TIME_TRANSFORM: {
+ CHECK_INTERFACE(IAudioTrack, data, reply);
+ LinearTransform xform;
+ xform.a_zero = data.readInt64();
+ xform.b_zero = data.readInt64();
+ xform.a_to_b_numer = data.readInt32();
+ xform.a_to_b_denom = data.readInt32();
+ int target = data.readInt32();
+ reply->writeInt32(setMediaTimeTransform(xform, target));
+ return NO_ERROR;
+ } break;
default:
return BBinder::onTransact(code, data, reply, flags);
}
}
}; // namespace android
-
diff --git a/media/libmedia/IEffect.cpp b/media/libmedia/IEffect.cpp
index d469e28..5d40cc8 100644
--- a/media/libmedia/IEffect.cpp
+++ b/media/libmedia/IEffect.cpp
@@ -83,8 +83,15 @@
size = *pReplySize;
}
data.writeInt32(size);
- remote()->transact(COMMAND, data, &reply);
- status_t status = reply.readInt32();
+
+ status_t status = remote()->transact(COMMAND, data, &reply);
+ if (status != NO_ERROR) {
+ if (pReplySize != NULL)
+ *pReplySize = 0;
+ return status;
+ }
+
+ status = reply.readInt32();
size = reply.readInt32();
if (size != 0 && pReplyData != NULL && pReplySize != NULL) {
reply.read(pReplyData, size);
diff --git a/media/libmedia/Visualizer.cpp b/media/libmedia/Visualizer.cpp
index 13b64e9..70f8c0c 100644
--- a/media/libmedia/Visualizer.cpp
+++ b/media/libmedia/Visualizer.cpp
@@ -168,7 +168,7 @@
uint32_t replySize = mCaptureSize;
status = command(VISUALIZER_CMD_CAPTURE, 0, NULL, &replySize, waveform);
ALOGV("getWaveForm() command returned %d", status);
- if (replySize == 0) {
+ if ((status == NO_ERROR) && (replySize == 0)) {
status = NOT_ENOUGH_DATA;
}
} else {
diff --git a/media/libmediaplayerservice/Android.mk b/media/libmediaplayerservice/Android.mk
index a3e2517..e521648 100644
--- a/media/libmediaplayerservice/Android.mk
+++ b/media/libmediaplayerservice/Android.mk
@@ -29,7 +29,8 @@
libstagefright_omx \
libstagefright_foundation \
libgui \
- libdl
+ libdl \
+ libaah_rtp
LOCAL_STATIC_LIBRARIES := \
libstagefright_nuplayer \
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 4df7f3d..764eddc 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -70,6 +70,11 @@
#include <OMX.h>
+namespace android {
+sp<MediaPlayerBase> createAAH_TXPlayer();
+sp<MediaPlayerBase> createAAH_RXPlayer();
+}
+
namespace {
using android::media::Metadata;
using android::status_t;
@@ -593,6 +598,14 @@
return NU_PLAYER;
}
+ if (!strncasecmp("aahRX://", url, 8)) {
+ return AAH_RX_PLAYER;
+ }
+
+ if (!strncasecmp("aahTX://", url, 8)) {
+ return AAH_TX_PLAYER;
+ }
+
// use MidiFile for MIDI extensions
int lenURL = strlen(url);
for (int i = 0; i < NELEM(FILE_EXTS); ++i) {
@@ -629,6 +642,14 @@
ALOGV("Create Test Player stub");
p = new TestPlayerStub();
break;
+ case AAH_RX_PLAYER:
+ ALOGV(" create A@H RX Player");
+ p = createAAH_RXPlayer();
+ break;
+ case AAH_TX_PLAYER:
+ ALOGV(" create A@H TX Player");
+ p = createAAH_TXPlayer();
+ break;
default:
ALOGE("Unknown player type: %d", playerType);
return NULL;
@@ -1031,9 +1052,21 @@
status_t MediaPlayerService::Client::setVolume(float leftVolume, float rightVolume)
{
ALOGV("[%d] setVolume(%f, %f)", mConnId, leftVolume, rightVolume);
- // TODO: for hardware output, call player instead
- Mutex::Autolock l(mLock);
- if (mAudioOutput != 0) mAudioOutput->setVolume(leftVolume, rightVolume);
+
+ // for hardware output, call player instead
+ sp<MediaPlayerBase> p = getPlayer();
+ {
+ Mutex::Autolock l(mLock);
+ if (p != 0 && p->hardwareOutput()) {
+ MediaPlayerHWInterface* hwp =
+ reinterpret_cast<MediaPlayerHWInterface*>(p.get());
+ return hwp->setVolume(leftVolume, rightVolume);
+ } else {
+ if (mAudioOutput != 0) mAudioOutput->setVolume(leftVolume, rightVolume);
+ return NO_ERROR;
+ }
+ }
+
return NO_ERROR;
}
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 483e5ab..3f9ba47 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -93,13 +93,7 @@
# The following was shamelessly copied from external/webkit/Android.mk and
# currently must follow the same logic to determine how webkit was built and
-# if it's safe to link against libchromium.net
-
-# V8 also requires an ARMv7 CPU, and since we must use jsc, we cannot
-# use the Chrome http stack either.
-ifneq ($(strip $(ARCH_ARM_HAVE_ARMV7A)),true)
- USE_ALT_HTTP := true
-endif
+# if it's safe to link against libchromium_net
# See if the user has specified a stack they want to use
HTTP_STACK = $(HTTP)
diff --git a/media/libstagefright/AudioSource.cpp b/media/libstagefright/AudioSource.cpp
index fef2a00..5b2ea1f 100644
--- a/media/libstagefright/AudioSource.cpp
+++ b/media/libstagefright/AudioSource.cpp
@@ -282,8 +282,6 @@
mPrevSampleTimeUs = mStartTimeUs;
}
- int64_t timestampUs = mPrevSampleTimeUs;
-
size_t numLostBytes = 0;
if (mNumFramesReceived > 0) { // Ignore earlier frame lost
// getInputFramesLost() returns the number of lost frames.
@@ -293,37 +291,58 @@
CHECK_EQ(numLostBytes & 1, 0u);
CHECK_EQ(audioBuffer.size & 1, 0u);
- size_t bufferSize = numLostBytes + audioBuffer.size;
- MediaBuffer *buffer = new MediaBuffer(bufferSize);
if (numLostBytes > 0) {
- memset(buffer->data(), 0, numLostBytes);
- memcpy((uint8_t *) buffer->data() + numLostBytes,
- audioBuffer.i16, audioBuffer.size);
- } else {
- if (audioBuffer.size == 0) {
- ALOGW("Nothing is available from AudioRecord callback buffer");
- buffer->release();
- return OK;
- }
- memcpy((uint8_t *) buffer->data(),
- audioBuffer.i16, audioBuffer.size);
+ // Loss of audio frames should happen rarely; thus the LOGW should
+ // not cause a logging spam
+ ALOGW("Lost audio record data: %d bytes", numLostBytes);
}
+ while (numLostBytes > 0) {
+ size_t bufferSize = numLostBytes;
+ if (numLostBytes > kMaxBufferSize) {
+ numLostBytes -= kMaxBufferSize;
+ bufferSize = kMaxBufferSize;
+ } else {
+ numLostBytes = 0;
+ }
+ MediaBuffer *lostAudioBuffer = new MediaBuffer(bufferSize);
+ memset(lostAudioBuffer->data(), 0, bufferSize);
+ lostAudioBuffer->set_range(0, bufferSize);
+ queueInputBuffer_l(lostAudioBuffer, timeUs);
+ }
+
+ if (audioBuffer.size == 0) {
+ ALOGW("Nothing is available from AudioRecord callback buffer");
+ return OK;
+ }
+
+ const size_t bufferSize = audioBuffer.size;
+ MediaBuffer *buffer = new MediaBuffer(bufferSize);
+ memcpy((uint8_t *) buffer->data(),
+ audioBuffer.i16, audioBuffer.size);
buffer->set_range(0, bufferSize);
- timestampUs += ((1000000LL * (bufferSize >> 1)) +
- (mSampleRate >> 1)) / mSampleRate;
+ queueInputBuffer_l(buffer, timeUs);
+ return OK;
+}
+
+void AudioSource::queueInputBuffer_l(MediaBuffer *buffer, int64_t timeUs) {
+ const size_t bufferSize = buffer->range_length();
+ const size_t frameSize = mRecord->frameSize();
+ const int64_t timestampUs =
+ mPrevSampleTimeUs +
+ ((1000000LL * (bufferSize / frameSize)) +
+ (mSampleRate >> 1)) / mSampleRate;
if (mNumFramesReceived == 0) {
buffer->meta_data()->setInt64(kKeyAnchorTime, mStartTimeUs);
}
+
buffer->meta_data()->setInt64(kKeyTime, mPrevSampleTimeUs);
buffer->meta_data()->setInt64(kKeyDriftTime, timeUs - mInitialReadTimeUs);
mPrevSampleTimeUs = timestampUs;
- mNumFramesReceived += buffer->range_length() / sizeof(int16_t);
+ mNumFramesReceived += bufferSize / frameSize;
mBuffersReceived.push_back(buffer);
mFrameAvailableCondition.signal();
-
- return OK;
}
void AudioSource::trackMaxAmplitude(int16_t *data, int nSamples) {
diff --git a/native/android/Android.mk b/native/android/Android.mk
index 9940442f..e2c99ee 100644
--- a/native/android/Android.mk
+++ b/native/android/Android.mk
@@ -18,6 +18,7 @@
LOCAL_SHARED_LIBRARIES := \
libcutils \
+ libandroidfw \
libutils \
libbinder \
libui \
diff --git a/native/android/asset_manager.cpp b/native/android/asset_manager.cpp
index f5db57c..01db1d3 100644
--- a/native/android/asset_manager.cpp
+++ b/native/android/asset_manager.cpp
@@ -18,9 +18,9 @@
#include <utils/Log.h>
#include <android/asset_manager_jni.h>
-#include <utils/AssetManager.h>
-#include <utils/AssetDir.h>
-#include <utils/Asset.h>
+#include <androidfw/Asset.h>
+#include <androidfw/AssetDir.h>
+#include <androidfw/AssetManager.h>
#include <utils/threads.h>
#include "jni.h"
diff --git a/native/android/configuration.cpp b/native/android/configuration.cpp
index 687924b..7eb51dd 100644
--- a/native/android/configuration.cpp
+++ b/native/android/configuration.cpp
@@ -17,7 +17,7 @@
#define LOG_TAG "Configuration"
#include <utils/Log.h>
-#include <utils/AssetManager.h>
+#include <androidfw/AssetManager.h>
#include <android_runtime/android_content_res_Configuration.h>
diff --git a/native/android/input.cpp b/native/android/input.cpp
index 91671c3..6eb2990 100644
--- a/native/android/input.cpp
+++ b/native/android/input.cpp
@@ -18,8 +18,8 @@
#include <utils/Log.h>
#include <android/input.h>
-#include <ui/Input.h>
-#include <ui/InputTransport.h>
+#include <androidfw/Input.h>
+#include <androidfw/InputTransport.h>
#include <utils/Looper.h>
#include <utils/RefBase.h>
#include <utils/Vector.h>
diff --git a/native/android/obb.cpp b/native/android/obb.cpp
index e0cb1a6..e990024 100644
--- a/native/android/obb.cpp
+++ b/native/android/obb.cpp
@@ -18,8 +18,8 @@
#include <android/obb.h>
+#include <androidfw/ObbFile.h>
#include <utils/Log.h>
-#include <utils/ObbFile.h>
using namespace android;
diff --git a/opengl/java/android/opengl/Group.java b/opengl/java/android/opengl/Group.java
deleted file mode 100644
index 1ef2953..0000000
--- a/opengl/java/android/opengl/Group.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (C) 2006 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 android.opengl;
-
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.ShortBuffer;
-import java.io.DataInputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Iterator;
-import javax.microedition.khronos.opengles.*;
-
-class MaterialIndices {
-
- private Material material = null;
- private ShortBuffer indexBuffer = null;
-
- public MaterialIndices(Material material, ShortBuffer indexBuffer) {
- this.material = material;
- this.indexBuffer = indexBuffer;
- }
-
- public Material getMaterial() {
- return material;
- }
-
- public ShortBuffer getIndexBuffer() {
- return indexBuffer;
- }
-}
-
-/**
- * {@hide}
- */
-public class Group {
-
- private Object3D parent;
- private String name;
-
- private List<MaterialIndices> materialIndices =
- new ArrayList<MaterialIndices>();
-
- public Group(Object3D parent) {
- this.parent = parent;
- }
-
- public String getName() {
- return name;
- }
-
- public void load(DataInputStream dis) throws IOException {
- dis.readInt(); // name length
- this.name = dis.readUTF();
-
- int numMaterials = dis.readInt();
-
- for (int i = 0; i < numMaterials; i++) {
- dis.readInt(); // material name length
- String matName = dis.readUTF();
- Material material = parent.getMaterial(matName);
-
- int numIndices = dis.readInt();
- byte[] indicesBytes = new byte[numIndices * 2];
- dis.readFully(indicesBytes);
-
- // Swap bytes from network to native order if necessary
- if (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN) {
- int idx = 0;
- for (int j = 0; j < numIndices; j++) {
- byte b0 = indicesBytes[idx];
- byte b1 = indicesBytes[idx + 1];
- indicesBytes[idx] = b1;
- indicesBytes[idx + 1] = b0;
- idx += 2;
- }
- }
-
- ByteBuffer ibb = ByteBuffer.allocateDirect(2*numIndices);
- ibb.order(ByteOrder.nativeOrder());
- ibb.put(indicesBytes);
- ibb.position(0);
-
- ShortBuffer sb = ibb.asShortBuffer();
- materialIndices.add(new MaterialIndices(material, sb));
- }
- }
-
- public int getNumTriangles() {
- int numTriangles = 0;
- Iterator<MaterialIndices> iter = materialIndices.iterator();
- while (iter.hasNext()) {
- MaterialIndices matIdx = iter.next();
- ShortBuffer indexBuffer = matIdx.getIndexBuffer();
- numTriangles += indexBuffer.capacity()/3;
- }
- return numTriangles;
- }
-
- public void draw(GL10 gl) {
- gl.glDisableClientState(gl.GL_COLOR_ARRAY);
-
- gl.glVertexPointer(3, gl.GL_FIXED, 0, parent.getVertexBuffer());
- gl.glEnableClientState(gl.GL_VERTEX_ARRAY);
-
- gl.glNormalPointer(gl.GL_FIXED, 0, parent.getNormalBuffer());
- gl.glEnableClientState(gl.GL_NORMAL_ARRAY);
-
- if (parent.hasTexcoords()) {
- gl.glTexCoordPointer(2, gl.GL_FIXED, 0, parent.getTexcoordBuffer());
- gl.glEnableClientState(gl.GL_TEXTURE_COORD_ARRAY);
- gl.glEnable(gl.GL_TEXTURE_2D);
- } else {
- gl.glDisable(gl.GL_TEXTURE_2D);
- }
-
- Iterator<MaterialIndices> iter = materialIndices.iterator();
- while (iter.hasNext()) {
- MaterialIndices matIdx = iter.next();
- ShortBuffer indexBuffer = matIdx.getIndexBuffer();
- Material mat = matIdx.getMaterial();
- mat.setMaterialParameters(gl);
- if (parent.hasTexcoords() && mat.getMap_Kd().length() > 0) {
- Texture texture = parent.getTexture(mat.getMap_Kd());
- texture.setTextureParameters(gl);
- }
-
- gl.glDrawElements(gl.GL_TRIANGLES,
- indexBuffer.capacity(),
- gl.GL_UNSIGNED_SHORT,
- indexBuffer);
- }
- }
-
- public String toString() {
- return "Group[" +
- "name=" + name +
- "]";
- }
-}
diff --git a/opengl/java/android/opengl/Material.java b/opengl/java/android/opengl/Material.java
deleted file mode 100644
index 60a3e72..0000000
--- a/opengl/java/android/opengl/Material.java
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * Copyright (C) 2006 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 android.opengl;
-
-import java.io.DataInputStream;
-import java.io.IOException;
-import javax.microedition.khronos.opengles.GL10;
-
-/**
- * {@hide}
- */
-public class Material {
-
- private Object3D parent;
- private String name;
- private String map_kd;
- private float[] ka = new float[4];
- private float[] kd = new float[4];
- private float[] ks = new float[4];
- private float ns;
- private int illum;
- private float d;
-
- private static float[] black = { 0.0f, 0.0f, 0.0f, 1.0f };
-
- public Material(Object3D parent) {
- this.parent = parent;
- }
-
- public String getName() {
- return name;
- }
-
- public String getMap_Kd() {
- return map_kd;
- }
-
- public void setMaterialParameters(GL10 gl) {
- gl.glMaterialfv(gl.GL_FRONT_AND_BACK, gl.GL_AMBIENT, kd, 0);
- gl.glMaterialfv(gl.GL_FRONT_AND_BACK, gl.GL_DIFFUSE, kd, 0);
- gl.glMaterialfv(gl.GL_FRONT_AND_BACK, gl.GL_SPECULAR, ks, 0);
- gl.glMaterialf(gl.GL_FRONT_AND_BACK, gl.GL_SHININESS,
- Math.min(Math.max(ns, 0), 128));
-
-// if (illum == 0) {
-// gl.glMaterialfv(gl.GL_FRONT_AND_BACK, gl.GL_AMBIENT, kd, 0);
-// } else {
-// gl.glMaterialfv(gl.GL_FRONT_AND_BACK, gl.GL_AMBIENT, ka, 0);
-// gl.glMaterialfv(gl.GL_FRONT_AND_BACK, gl.GL_DIFFUSE, kd, 0);
-// }
-
-// if (illum > 1) {
-// gl.glMaterialfv(gl.GL_FRONT_AND_BACK, gl.GL_SPECULAR, ks, 0);
-// gl.glMaterialf(gl.GL_FRONT_AND_BACK, gl.GL_SHININESS,
-// Math.min(Math.max(ns, 0), 128));
-// } else {
-// gl.glMaterialfv(gl.GL_FRONT_AND_BACK, gl.GL_SPECULAR, black, 0);
-// }
- }
-
- public void load(DataInputStream dis) throws IOException {
- dis.readInt(); // name length
- this.name = dis.readUTF();
-
- dis.readInt(); // map_kdLength
- this.map_kd = dis.readUTF();
-
- if (parent.hasTexcoords() && map_kd.length() > 0) {
- parent.loadTexture(map_kd);
- }
-
- this.ka[0] = dis.readFloat();
- this.ka[1] = dis.readFloat();
- this.ka[2] = dis.readFloat();
- this.ka[3] = dis.readFloat();
-
- this.kd[0] = dis.readFloat();
- this.kd[1] = dis.readFloat();
- this.kd[2] = dis.readFloat();
- this.kd[3] = dis.readFloat();
-
- this.ks[0] = dis.readFloat();
- this.ks[1] = dis.readFloat();
- this.ks[2] = dis.readFloat();
- this.ks[3] = dis.readFloat();
-
- this.ns = dis.readFloat();
- this.illum = dis.readInt();
- this.d = dis.readFloat();
- }
-
- public String toString() {
- return "Material[" +
- "name=\"" + name + "\"," +
- "ka={" + ka[0] + "," + ka[1] + "," + ka[2] + "}," +
- "kd={" + kd[0] + "," + kd[1] + "," + kd[2] + "}," +
- "ks={" + ks[0] + "," + ks[1] + "," + ks[2] + "}," +
- "ns=" + ns + "," +
- "map_kd=\"" +
- (map_kd == null ? "" : map_kd) +
- "\"," +
- "illum=" + illum + "," +
- "d=" + d +
- "]";
- }
-}
diff --git a/opengl/java/android/opengl/Object3D.java b/opengl/java/android/opengl/Object3D.java
deleted file mode 100644
index 340c6a7..0000000
--- a/opengl/java/android/opengl/Object3D.java
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Copyright (C) 2006 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 android.opengl;
-
-import java.io.BufferedReader;
-import java.io.DataInputStream;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import java.nio.IntBuffer;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import javax.microedition.khronos.opengles.*;
-
-/**
- * {@hide}
- */
-public abstract class Object3D {
-
- private boolean mHasTexcoords = false;
-
- private float mBoundsMinX = Float.MAX_VALUE;
- private float mBoundsMaxX = Float.MIN_VALUE;
- private float mBoundsMinY = Float.MAX_VALUE;
- private float mBoundsMaxY = Float.MIN_VALUE;
- private float mBoundsMinZ = Float.MAX_VALUE;
- private float mBoundsMaxZ = Float.MIN_VALUE;
-
- private IntBuffer mVertexBuffer;
- private IntBuffer mNormalBuffer;
- private IntBuffer mTexcoordBuffer;
-
- // All groups, by name
- private Map<String, Group> mGroups;
-
- // All materials, by name
- private Map<String, Material> mMaterials;
-
- // All texture maps, by name
- private Map<String, Texture> mTextures;
-
- public Object3D() {
- reset();
- }
-
- /**
- * Override this method with an implementation that contructs
- * and InputStream from the given filename. For example, if the
- * source files are to be retrieved using an AssetManager,
- * the implementation would use AssetManager.load() to
- * get the input stream.
- */
- public abstract InputStream readFile(String filename) throws IOException;
-
- private void reset() {
- mVertexBuffer = mNormalBuffer = mTexcoordBuffer = null;
-
- mGroups = new HashMap<String,Group>();
- mMaterials = new HashMap<String,Material>();
- mTextures = new HashMap<String,Texture>();
- }
-
- public Material getMaterial(String name) {
- Material mat = mMaterials.get(name);
- return mat;
- }
-
- public Texture getTexture(String name) {
- return mTextures.get(name);
- }
-
- public IntBuffer getVertexBuffer() {
- return mVertexBuffer;
- }
-
- public IntBuffer getNormalBuffer() {
- return mNormalBuffer;
- }
-
- public IntBuffer getTexcoordBuffer() {
- return mTexcoordBuffer;
- }
-
- public int getNumTriangles() {
- int numTriangles = 0;
- Iterator<Group> iter = mGroups.values().iterator();
- while (iter.hasNext()) {
- numTriangles += iter.next().getNumTriangles();
- }
- return numTriangles;
- }
-
- public boolean hasTexcoords() {
- return mHasTexcoords;
- }
-
- public float getBoundsMinX() {
- return mBoundsMinX;
- }
-
- public float getBoundsMaxX() {
- return mBoundsMaxX;
- }
-
- public float getBoundsMinY() {
- return mBoundsMinY;
- }
-
- public float getBoundsMaxY() {
- return mBoundsMaxY;
- }
-
- public float getBoundsMinZ() {
- return mBoundsMinZ;
- }
-
- public float getBoundsMaxZ() {
- return mBoundsMaxZ;
- }
-
- public void loadTexture(String name) throws IOException {
- InputStream is = readFile(name + ".raw");
- Texture texture = new Texture(is);
- mTextures.put(name, texture);
- }
-
- private static void verifyByte(DataInputStream dis, int b)
- throws IOException {
- int x = dis.read() & 0xff;
- if (x != b) {
- throw new RuntimeException("Bad byte: " +
- x +
- " (expected " + b + ")");
- }
- }
-
- public void load(String filename) throws IOException {
- reset();
-
- DataInputStream dis = new DataInputStream(readFile(filename));
- verifyByte(dis, 'g' + 128);
- verifyByte(dis, 'l');
- verifyByte(dis, 'e');
- verifyByte(dis, 's');
-
- int numTuples = dis.readInt();
-
- this.mBoundsMinX = dis.readFloat();
- this.mBoundsMaxX = dis.readFloat();
- this.mBoundsMinY = dis.readFloat();
- this.mBoundsMaxY = dis.readFloat();
- this.mBoundsMinZ = dis.readFloat();
- this.mBoundsMaxZ = dis.readFloat();
-
- this.mHasTexcoords = dis.readInt() == 1;
-
- int intsPerTuple = mHasTexcoords ? 8 : 6;
- int numInts = numTuples*intsPerTuple;
-
- int len = 4*numTuples*(mHasTexcoords ? 8 : 6);
-
- byte[] tmp = new byte[len];
- int tidx = 0;
- while (tidx < len) {
- tidx += dis.read(tmp, tidx, len - tidx);
- }
- if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) {
- for (int i = 0; i < len; i += 4) {
- byte tmp0 = tmp[i];
- byte tmp1 = tmp[i + 1];
- byte tmp2 = tmp[i + 2];
- byte tmp3 = tmp[i + 3];
- tmp[i] = tmp3;
- tmp[i + 1] = tmp2;
- tmp[i + 2] = tmp1;
- tmp[i + 3] = tmp0;
- }
- }
-
- ByteBuffer allbb = ByteBuffer.allocateDirect(len);
- allbb.order(ByteOrder.nativeOrder());
- allbb.put(tmp);
-
- allbb.position(0);
- allbb.limit(4*3*numTuples);
- ByteBuffer vbb = allbb.slice();
- this.mVertexBuffer = vbb.asIntBuffer();
- mVertexBuffer.position(0);
-
- if (mHasTexcoords) {
- allbb.position(allbb.limit());
- allbb.limit(allbb.position() + 4*2*numTuples);
- ByteBuffer tbb = allbb.slice();
- this.mTexcoordBuffer = tbb.asIntBuffer();
- mTexcoordBuffer.position(0);
- }
-
- allbb.position(allbb.limit());
- allbb.limit(allbb.position() + 4*3*numTuples);
- ByteBuffer nbb = allbb.slice();
- this.mNormalBuffer = nbb.asIntBuffer();
- mNormalBuffer.position(0);
-
- int numMaterials = dis.readInt();
- for (int i = 0; i < numMaterials; i++) {
- Material mat = new Material(this);
- mat.load(dis);
- mMaterials.put(mat.getName(), mat);
- }
-
- int numGroups = dis.readInt();
- for (int i = 0; i < numGroups; i++) {
- Group g = new Group(this);
- g.load(dis);
- mGroups.put(g.getName(), g);
- }
- }
-
- public void draw(GL10 gl) {
- Iterator<Group> iter = mGroups.values().iterator();
- while (iter.hasNext()) {
- iter.next().draw(gl);
- }
- }
-}
-
diff --git a/opengl/java/android/opengl/Texture.java b/opengl/java/android/opengl/Texture.java
deleted file mode 100644
index dcd894d..0000000
--- a/opengl/java/android/opengl/Texture.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Copyright (C) 2006 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 android.opengl;
-
-import java.io.InputStream;
-import java.io.IOException;
-import java.nio.Buffer;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-import javax.microedition.khronos.opengles.GL10;
-
-import android.content.res.AssetManager;
-
-/**
- * {@hide}
- */
-public class Texture {
-
- private int width, height, bpp;
- private ByteBuffer data;
- private int name = -1;
-
- // Texture maps have the following format. All integers
- // are 16 bits, high byte first. Pixels are in 5/6/5
- // RGB format, low byte first.
- //
- // width
- // height
- // pixel (0, 0)
- // pixel (1, 0)
- // ...
- // pixel (width - 1, height - 1)
-
- private int readInt16(InputStream is) throws IOException {
- return is.read() | (is.read() << 8);
- }
-
- public Texture(InputStream is) throws IOException {
- this.width = readInt16(is);
- this.height = readInt16(is);
- this.bpp = 2;
-
- int npixels = width*height;
- int nbytes = npixels*bpp;
- byte[] arr = new byte[nbytes];
-
- int idx = 0;
- while (idx < nbytes) {
- int nread = is.read(arr, idx, nbytes - idx);
- idx += nread;
- }
-
- if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN) {
- // Swap pairs of bytes on big-endian platforms
- for (int i = 0; i < npixels; i++) {
- int j = i*2;
- int k = j + 1;
-
- byte tmp = arr[j];
- arr[j] = arr[k];
- arr[k] = tmp;
- }
- }
-
- this.data = ByteBuffer.allocateDirect(arr.length);
- this.data.order(ByteOrder.nativeOrder());
- data.put(arr);
- data.position(0);
- }
-
- private int loadTexture(GL10 gl,
- int textureUnit,
- int minFilter, int magFilter,
- int wrapS, int wrapT,
- int mode,
- int width, int height,
- int dataType,
- Buffer data) {
- int[] texture = new int[1];
- gl.glGenTextures(1, texture, 0);
-
- gl.glEnable(gl.GL_TEXTURE_2D);
- gl.glClientActiveTexture(textureUnit);
- gl.glBindTexture(gl.GL_TEXTURE_2D, texture[0]);
- gl.glTexParameterf(gl.GL_TEXTURE_2D,
- gl.GL_TEXTURE_MIN_FILTER,
- minFilter);
- gl.glTexParameterf(gl.GL_TEXTURE_2D,
- gl.GL_TEXTURE_MAG_FILTER,
- magFilter);
- gl.glTexParameterf(gl.GL_TEXTURE_2D,
- gl.GL_TEXTURE_WRAP_S,
- wrapS);
- gl.glTexParameterf(gl.GL_TEXTURE_2D,
- gl.GL_TEXTURE_WRAP_T,
- wrapT);
- gl.glTexEnvf(gl.GL_TEXTURE_ENV, gl.GL_TEXTURE_ENV_MODE, mode);
-
- gl.glTexImage2D(gl.GL_TEXTURE_2D, 0, gl.GL_RGB,
- width, height,
- 0, gl.GL_RGB, dataType,
- data);
-
- return texture[0];
- }
-
- public void setTextureParameters(GL10 gl) {
- if (name < 0) {
- name = loadTexture(gl,
- gl.GL_TEXTURE0,
- gl.GL_NEAREST, gl.GL_NEAREST,
- gl.GL_REPEAT, gl.GL_REPEAT,
- gl.GL_MODULATE,
- width, height,
- gl.GL_UNSIGNED_SHORT_5_6_5,
- data);
- }
-
- gl.glBindTexture(gl.GL_TEXTURE_2D, name);
- }
-}
diff --git a/opengl/libs/GLES_trace/TODO.txt b/opengl/libs/GLES_trace/TODO.txt
deleted file mode 100644
index f5e6e95..0000000
--- a/opengl/libs/GLES_trace/TODO.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-TODO:
- - Context - Currently, we don't do anything regarding the contexts that are created.
- Need to maintain more state regarding contexts, and figure out what happens in the
- presence of multiple contexts.
-
- - Transport: Each GLMessage is sent via a socket as soon as the message is received.
- i.e., there is no buffering of messages. Buffering should improve performance.
-
- - Initialization: On first connection, send some basic information that includes:
- 1. version of the trace library
- 2. implementation dependent GL state variables such as # of vertex arrays etc.
-
- - eglSwapBuffers: The images are lzf compressed, but there is no mode that transfers
- only the differences from the previous images.
diff --git a/opengl/libs/GLES_trace/gltrace.proto b/opengl/libs/GLES_trace/gltrace.proto
index 11cf24f..2893e6e 100644
--- a/opengl/libs/GLES_trace/gltrace.proto
+++ b/opengl/libs/GLES_trace/gltrace.proto
@@ -543,11 +543,13 @@
required int32 context_id = 1; // GL context ID
required int64 start_time = 2; // time when call was invoked
- required int32 duration = 3; // duration of the call
+ required int32 duration = 3; // duration of the call (MONOTONIC TIME)
required Function function = 4 [default = invalid]; // GL function called
repeated DataType args = 5; // GL function's arguments
optional DataType returnValue = 6; // GL function's return value
optional FrameBuffer fb = 7; // contents of the framebuffer
+
+ optional int32 threadtime = 8; // duration of the call (THREAD TIME)
};
diff --git a/opengl/libs/GLES_trace/src/gltrace.pb.cpp b/opengl/libs/GLES_trace/src/gltrace.pb.cpp
index bb9d4a7..d5f8180 100644
--- a/opengl/libs/GLES_trace/src/gltrace.pb.cpp
+++ b/opengl/libs/GLES_trace/src/gltrace.pb.cpp
@@ -1663,6 +1663,7 @@
const int GLMessage::kArgsFieldNumber;
const int GLMessage::kReturnValueFieldNumber;
const int GLMessage::kFbFieldNumber;
+const int GLMessage::kThreadtimeFieldNumber;
#endif // !_MSC_VER
GLMessage::GLMessage()
@@ -1689,6 +1690,7 @@
function_ = 3000;
returnvalue_ = NULL;
fb_ = NULL;
+ threadtime_ = 0;
::memset(_has_bits_, 0, sizeof(_has_bits_));
}
@@ -1730,6 +1732,7 @@
if (_has_bit(6)) {
if (fb_ != NULL) fb_->::android::gltrace::GLMessage_FrameBuffer::Clear();
}
+ threadtime_ = 0;
}
args_.Clear();
::memset(_has_bits_, 0, sizeof(_has_bits_));
@@ -1846,6 +1849,22 @@
} else {
goto handle_uninterpreted;
}
+ if (input->ExpectTag(64)) goto parse_threadtime;
+ break;
+ }
+
+ // optional int32 threadtime = 8;
+ case 8: {
+ if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
+ ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
+ parse_threadtime:
+ DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+ ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
+ input, &threadtime_)));
+ _set_bit(7);
+ } else {
+ goto handle_uninterpreted;
+ }
if (input->ExpectAtEnd()) return true;
break;
}
@@ -1906,6 +1925,11 @@
7, this->fb(), output);
}
+ // optional int32 threadtime = 8;
+ if (_has_bit(7)) {
+ ::google::protobuf::internal::WireFormatLite::WriteInt32(8, this->threadtime(), output);
+ }
+
}
int GLMessage::ByteSize() const {
@@ -1953,6 +1977,13 @@
this->fb());
}
+ // optional int32 threadtime = 8;
+ if (has_threadtime()) {
+ total_size += 1 +
+ ::google::protobuf::internal::WireFormatLite::Int32Size(
+ this->threadtime());
+ }
+
}
// repeated .android.gltrace.GLMessage.DataType args = 5;
total_size += 1 * this->args_size();
@@ -1995,6 +2026,9 @@
if (from._has_bit(6)) {
mutable_fb()->::android::gltrace::GLMessage_FrameBuffer::MergeFrom(from.fb());
}
+ if (from._has_bit(7)) {
+ set_threadtime(from.threadtime());
+ }
}
}
@@ -2028,6 +2062,7 @@
args_.Swap(&other->args_);
std::swap(returnvalue_, other->returnvalue_);
std::swap(fb_, other->fb_);
+ std::swap(threadtime_, other->threadtime_);
std::swap(_has_bits_[0], other->_has_bits_[0]);
std::swap(_cached_size_, other->_cached_size_);
}
diff --git a/opengl/libs/GLES_trace/src/gltrace.pb.h b/opengl/libs/GLES_trace/src/gltrace.pb.h
index e3b8990..a4fcbd3 100644
--- a/opengl/libs/GLES_trace/src/gltrace.pb.h
+++ b/opengl/libs/GLES_trace/src/gltrace.pb.h
@@ -1418,6 +1418,13 @@
inline const ::android::gltrace::GLMessage_FrameBuffer& fb() const;
inline ::android::gltrace::GLMessage_FrameBuffer* mutable_fb();
+ // optional int32 threadtime = 8;
+ inline bool has_threadtime() const;
+ inline void clear_threadtime();
+ static const int kThreadtimeFieldNumber = 8;
+ inline ::google::protobuf::int32 threadtime() const;
+ inline void set_threadtime(::google::protobuf::int32 value);
+
// @@protoc_insertion_point(class_scope:android.gltrace.GLMessage)
private:
mutable int _cached_size_;
@@ -1429,11 +1436,12 @@
::google::protobuf::RepeatedPtrField< ::android::gltrace::GLMessage_DataType > args_;
::android::gltrace::GLMessage_DataType* returnvalue_;
::android::gltrace::GLMessage_FrameBuffer* fb_;
+ ::google::protobuf::int32 threadtime_;
friend void protobuf_AddDesc_gltrace_2eproto();
friend void protobuf_AssignDesc_gltrace_2eproto();
friend void protobuf_ShutdownFile_gltrace_2eproto();
- ::google::protobuf::uint32 _has_bits_[(7 + 31) / 32];
+ ::google::protobuf::uint32 _has_bits_[(8 + 31) / 32];
// WHY DOES & HAVE LOWER PRECEDENCE THAN != !?
inline bool _has_bit(int index) const {
@@ -1860,6 +1868,22 @@
return fb_;
}
+// optional int32 threadtime = 8;
+inline bool GLMessage::has_threadtime() const {
+ return _has_bit(7);
+}
+inline void GLMessage::clear_threadtime() {
+ threadtime_ = 0;
+ _clear_bit(7);
+}
+inline ::google::protobuf::int32 GLMessage::threadtime() const {
+ return threadtime_;
+}
+inline void GLMessage::set_threadtime(::google::protobuf::int32 value) {
+ _set_bit(7);
+ threadtime_ = value;
+}
+
// @@protoc_insertion_point(namespace_scope)
diff --git a/opengl/libs/GLES_trace/src/gltrace_api.cpp b/opengl/libs/GLES_trace/src/gltrace_api.cpp
index a2366ac..358bf54 100644
--- a/opengl/libs/GLES_trace/src/gltrace_api.cpp
+++ b/opengl/libs/GLES_trace/src/gltrace_api.cpp
@@ -43,11 +43,15 @@
arg_texture->add_intvalue((int)texture);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glActiveTexture(texture);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -70,11 +74,15 @@
arg_shader->add_intvalue(shader);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glAttachShader(program, shader);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -103,11 +111,15 @@
arg_name->add_intvalue((int)name);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glBindAttribLocation(program, index, name);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -130,11 +142,15 @@
arg_buffer->add_intvalue(buffer);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glBindBuffer(target, buffer);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -157,11 +173,15 @@
arg_framebuffer->add_intvalue(framebuffer);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glBindFramebuffer(target, framebuffer);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -184,11 +204,15 @@
arg_renderbuffer->add_intvalue(renderbuffer);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glBindRenderbuffer(target, renderbuffer);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -211,11 +235,15 @@
arg_texture->add_intvalue(texture);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glBindTexture(target, texture);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -250,11 +278,15 @@
arg_alpha->add_floatvalue(alpha);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glBlendColor(red, green, blue, alpha);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -271,11 +303,15 @@
arg_mode->add_intvalue((int)mode);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glBlendEquation(mode);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -298,11 +334,15 @@
arg_modeAlpha->add_intvalue((int)modeAlpha);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glBlendEquationSeparate(modeRGB, modeAlpha);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -325,11 +365,15 @@
arg_dfactor->add_intvalue((int)dfactor);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glBlendFunc(sfactor, dfactor);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -364,11 +408,15 @@
arg_dstAlpha->add_intvalue((int)dstAlpha);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glBlendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -403,11 +451,15 @@
arg_usage->add_intvalue((int)usage);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glBufferData(target, size, data, usage);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -442,11 +494,15 @@
arg_data->add_intvalue((int)data);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glBufferSubData(target, offset, size, data);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -463,9 +519,11 @@
arg_target->add_intvalue((int)target);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
GLenum retValue = glContext->hooks->gl.glCheckFramebufferStatus(target);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
// set return value
GLMessage_DataType *rt = glmsg.mutable_returnvalue();
@@ -473,7 +531,9 @@
rt->set_type(GLMessage::DataType::ENUM);
rt->add_intvalue((int)retValue);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -492,11 +552,15 @@
arg_mask->add_intvalue(mask);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glClear(mask);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -531,11 +595,15 @@
arg_alpha->add_floatvalue(alpha);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glClearColor(red, green, blue, alpha);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -552,11 +620,15 @@
arg_depth->add_floatvalue(depth);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glClearDepthf(depth);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -573,11 +645,15 @@
arg_s->add_intvalue(s);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glClearStencil(s);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -612,11 +688,15 @@
arg_alpha->add_boolvalue(alpha);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glColorMask(red, green, blue, alpha);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -633,11 +713,15 @@
arg_shader->add_intvalue(shader);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glCompileShader(shader);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -696,11 +780,15 @@
arg_data->add_intvalue((int)data);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glCompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -765,11 +853,15 @@
arg_data->add_intvalue((int)data);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -828,11 +920,15 @@
arg_border->add_intvalue(border);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glCopyTexImage2D(target, level, internalformat, x, y, width, height, border);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -891,11 +987,15 @@
arg_height->add_intvalue(height);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -906,9 +1006,11 @@
glmsg.set_function(GLMessage::glCreateProgram);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
GLuint retValue = glContext->hooks->gl.glCreateProgram();
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
// set return value
GLMessage_DataType *rt = glmsg.mutable_returnvalue();
@@ -916,7 +1018,9 @@
rt->set_type(GLMessage::DataType::INT);
rt->add_intvalue(retValue);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -935,9 +1039,11 @@
arg_type->add_intvalue((int)type);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
GLuint retValue = glContext->hooks->gl.glCreateShader(type);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
// set return value
GLMessage_DataType *rt = glmsg.mutable_returnvalue();
@@ -945,7 +1051,9 @@
rt->set_type(GLMessage::DataType::INT);
rt->add_intvalue(retValue);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -964,11 +1072,15 @@
arg_mode->add_intvalue((int)mode);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glCullFace(mode);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -991,11 +1103,15 @@
arg_buffers->add_intvalue((int)buffers);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glDeleteBuffers(n, buffers);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -1018,11 +1134,15 @@
arg_framebuffers->add_intvalue((int)framebuffers);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glDeleteFramebuffers(n, framebuffers);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -1039,11 +1159,15 @@
arg_program->add_intvalue(program);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glDeleteProgram(program);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -1066,11 +1190,15 @@
arg_renderbuffers->add_intvalue((int)renderbuffers);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glDeleteRenderbuffers(n, renderbuffers);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -1087,11 +1215,15 @@
arg_shader->add_intvalue(shader);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glDeleteShader(shader);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -1114,11 +1246,15 @@
arg_textures->add_intvalue((int)textures);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glDeleteTextures(n, textures);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -1135,11 +1271,15 @@
arg_func->add_intvalue((int)func);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glDepthFunc(func);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -1156,11 +1296,15 @@
arg_flag->add_boolvalue(flag);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glDepthMask(flag);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -1183,11 +1327,15 @@
arg_zFar->add_floatvalue(zFar);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glDepthRangef(zNear, zFar);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -1210,11 +1358,15 @@
arg_shader->add_intvalue(shader);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glDetachShader(program, shader);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -1231,11 +1383,15 @@
arg_cap->add_intvalue((int)cap);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glDisable(cap);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -1252,11 +1408,15 @@
arg_index->add_intvalue(index);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glDisableVertexAttribArray(index);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -1285,11 +1445,15 @@
arg_count->add_intvalue(count);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glDrawArrays(mode, first, count);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -1324,11 +1488,15 @@
arg_indices->add_intvalue((int)indices);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glDrawElements(mode, count, type, indices);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -1345,11 +1513,15 @@
arg_cap->add_intvalue((int)cap);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glEnable(cap);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -1366,11 +1538,15 @@
arg_index->add_intvalue(index);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glEnableVertexAttribArray(index);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -1381,11 +1557,15 @@
glmsg.set_function(GLMessage::glFinish);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glFinish();
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -1396,11 +1576,15 @@
glmsg.set_function(GLMessage::glFlush);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glFlush();
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -1435,11 +1619,15 @@
arg_renderbuffer->add_intvalue(renderbuffer);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glFramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -1480,11 +1668,15 @@
arg_level->add_intvalue(level);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glFramebufferTexture2D(target, attachment, textarget, texture, level);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -1501,11 +1693,15 @@
arg_mode->add_intvalue((int)mode);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glFrontFace(mode);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -1528,11 +1724,15 @@
arg_buffers->add_intvalue((int)buffers);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGenBuffers(n, buffers);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -1549,11 +1749,15 @@
arg_target->add_intvalue((int)target);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGenerateMipmap(target);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -1576,11 +1780,15 @@
arg_framebuffers->add_intvalue((int)framebuffers);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGenFramebuffers(n, framebuffers);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -1603,11 +1811,15 @@
arg_renderbuffers->add_intvalue((int)renderbuffers);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGenRenderbuffers(n, renderbuffers);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -1630,11 +1842,15 @@
arg_textures->add_intvalue((int)textures);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGenTextures(n, textures);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -1687,11 +1903,15 @@
arg_name->add_intvalue((int)name);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetActiveAttrib(program, index, bufsize, length, size, type, name);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -1744,11 +1964,15 @@
arg_name->add_intvalue((int)name);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetActiveUniform(program, index, bufsize, length, size, type, name);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -1783,11 +2007,15 @@
arg_shaders->add_intvalue((int)shaders);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetAttachedShaders(program, maxcount, count, shaders);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -1810,9 +2038,11 @@
arg_name->add_intvalue((int)name);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
int retValue = glContext->hooks->gl.glGetAttribLocation(program, name);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
// set return value
GLMessage_DataType *rt = glmsg.mutable_returnvalue();
@@ -1820,7 +2050,9 @@
rt->set_type(GLMessage::DataType::INT);
rt->add_intvalue(retValue);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -1845,11 +2077,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetBooleanv(pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -1878,11 +2114,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetBufferParameteriv(target, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -1893,9 +2133,11 @@
glmsg.set_function(GLMessage::glGetError);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
GLenum retValue = glContext->hooks->gl.glGetError();
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
// set return value
GLMessage_DataType *rt = glmsg.mutable_returnvalue();
@@ -1903,7 +2145,9 @@
rt->set_type(GLMessage::DataType::ENUM);
rt->add_intvalue((int)retValue);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -1928,11 +2172,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetFloatv(pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -1967,11 +2215,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetFramebufferAttachmentParameteriv(target, attachment, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -1994,11 +2246,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetIntegerv(pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -2027,11 +2283,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetProgramiv(program, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -2066,11 +2326,15 @@
arg_infolog->add_intvalue((int)infolog);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetProgramInfoLog(program, bufsize, length, infolog);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -2099,11 +2363,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetRenderbufferParameteriv(target, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -2132,11 +2400,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetShaderiv(shader, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -2171,11 +2443,15 @@
arg_infolog->add_intvalue((int)infolog);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetShaderInfoLog(shader, bufsize, length, infolog);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -2210,11 +2486,15 @@
arg_precision->add_intvalue((int)precision);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetShaderPrecisionFormat(shadertype, precisiontype, range, precision);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -2249,11 +2529,15 @@
arg_source->add_intvalue((int)source);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetShaderSource(shader, bufsize, length, source);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -2270,9 +2554,11 @@
arg_name->add_intvalue((int)name);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
const GLubyte* retValue = glContext->hooks->gl.glGetString(name);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
// set return value
GLMessage_DataType *rt = glmsg.mutable_returnvalue();
@@ -2280,7 +2566,9 @@
rt->set_type(GLMessage::DataType::INT);
rt->add_intvalue((int)retValue);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -2311,11 +2599,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetTexParameterfv(target, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -2344,11 +2636,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetTexParameteriv(target, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -2377,11 +2673,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetUniformfv(program, location, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -2410,11 +2710,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetUniformiv(program, location, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -2437,9 +2741,11 @@
arg_name->add_intvalue((int)name);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
int retValue = glContext->hooks->gl.glGetUniformLocation(program, name);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
// set return value
GLMessage_DataType *rt = glmsg.mutable_returnvalue();
@@ -2447,7 +2753,9 @@
rt->set_type(GLMessage::DataType::INT);
rt->add_intvalue(retValue);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -2478,11 +2786,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetVertexAttribfv(index, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -2511,11 +2823,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetVertexAttribiv(index, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -2544,11 +2860,15 @@
arg_pointer->add_intvalue((int)pointer);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetVertexAttribPointerv(index, pname, pointer);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -2571,11 +2891,15 @@
arg_mode->add_intvalue((int)mode);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glHint(target, mode);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -2592,9 +2916,11 @@
arg_buffer->add_intvalue(buffer);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
GLboolean retValue = glContext->hooks->gl.glIsBuffer(buffer);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
// set return value
GLMessage_DataType *rt = glmsg.mutable_returnvalue();
@@ -2602,7 +2928,9 @@
rt->set_type(GLMessage::DataType::BOOL);
rt->add_boolvalue(retValue);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -2621,9 +2949,11 @@
arg_cap->add_intvalue((int)cap);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
GLboolean retValue = glContext->hooks->gl.glIsEnabled(cap);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
// set return value
GLMessage_DataType *rt = glmsg.mutable_returnvalue();
@@ -2631,7 +2961,9 @@
rt->set_type(GLMessage::DataType::BOOL);
rt->add_boolvalue(retValue);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -2650,9 +2982,11 @@
arg_framebuffer->add_intvalue(framebuffer);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
GLboolean retValue = glContext->hooks->gl.glIsFramebuffer(framebuffer);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
// set return value
GLMessage_DataType *rt = glmsg.mutable_returnvalue();
@@ -2660,7 +2994,9 @@
rt->set_type(GLMessage::DataType::BOOL);
rt->add_boolvalue(retValue);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -2679,9 +3015,11 @@
arg_program->add_intvalue(program);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
GLboolean retValue = glContext->hooks->gl.glIsProgram(program);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
// set return value
GLMessage_DataType *rt = glmsg.mutable_returnvalue();
@@ -2689,7 +3027,9 @@
rt->set_type(GLMessage::DataType::BOOL);
rt->add_boolvalue(retValue);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -2708,9 +3048,11 @@
arg_renderbuffer->add_intvalue(renderbuffer);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
GLboolean retValue = glContext->hooks->gl.glIsRenderbuffer(renderbuffer);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
// set return value
GLMessage_DataType *rt = glmsg.mutable_returnvalue();
@@ -2718,7 +3060,9 @@
rt->set_type(GLMessage::DataType::BOOL);
rt->add_boolvalue(retValue);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -2737,9 +3081,11 @@
arg_shader->add_intvalue(shader);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
GLboolean retValue = glContext->hooks->gl.glIsShader(shader);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
// set return value
GLMessage_DataType *rt = glmsg.mutable_returnvalue();
@@ -2747,7 +3093,9 @@
rt->set_type(GLMessage::DataType::BOOL);
rt->add_boolvalue(retValue);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -2766,9 +3114,11 @@
arg_texture->add_intvalue(texture);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
GLboolean retValue = glContext->hooks->gl.glIsTexture(texture);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
// set return value
GLMessage_DataType *rt = glmsg.mutable_returnvalue();
@@ -2776,7 +3126,9 @@
rt->set_type(GLMessage::DataType::BOOL);
rt->add_boolvalue(retValue);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -2795,11 +3147,15 @@
arg_width->add_floatvalue(width);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glLineWidth(width);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -2816,11 +3172,15 @@
arg_program->add_intvalue(program);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glLinkProgram(program);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -2843,11 +3203,15 @@
arg_param->add_intvalue(param);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glPixelStorei(pname, param);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -2870,11 +3234,15 @@
arg_units->add_floatvalue(units);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glPolygonOffset(factor, units);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -2927,11 +3295,15 @@
arg_pixels->add_intvalue((int)pixels);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glReadPixels(x, y, width, height, format, type, pixels);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -2942,11 +3314,15 @@
glmsg.set_function(GLMessage::glReleaseShaderCompiler);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glReleaseShaderCompiler();
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -2981,11 +3357,15 @@
arg_height->add_intvalue(height);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glRenderbufferStorage(target, internalformat, width, height);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -3008,11 +3388,15 @@
arg_invert->add_boolvalue(invert);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glSampleCoverage(value, invert);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -3047,11 +3431,15 @@
arg_height->add_intvalue(height);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glScissor(x, y, width, height);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -3092,11 +3480,15 @@
arg_length->add_intvalue(length);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glShaderBinary(n, shaders, binaryformat, binary, length);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -3131,11 +3523,15 @@
arg_length->add_intvalue((int)length);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glShaderSource(shader, count, string, length);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -3164,11 +3560,15 @@
arg_mask->add_intvalue(mask);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glStencilFunc(func, ref, mask);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -3203,11 +3603,15 @@
arg_mask->add_intvalue(mask);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glStencilFuncSeparate(face, func, ref, mask);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -3224,11 +3628,15 @@
arg_mask->add_intvalue(mask);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glStencilMask(mask);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -3251,11 +3659,15 @@
arg_mask->add_intvalue(mask);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glStencilMaskSeparate(face, mask);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -3284,11 +3696,15 @@
arg_zpass->add_intvalue((int)zpass);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glStencilOp(fail, zfail, zpass);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -3323,11 +3739,15 @@
arg_zpass->add_intvalue((int)zpass);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glStencilOpSeparate(face, fail, zfail, zpass);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -3392,11 +3812,15 @@
arg_pixels->add_intvalue((int)pixels);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glTexImage2D(target, level, internalformat, width, height, border, format, type, pixels);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -3425,11 +3849,15 @@
arg_param->add_floatvalue(param);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glTexParameterf(target, pname, param);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -3458,11 +3886,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glTexParameterfv(target, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -3491,11 +3923,15 @@
arg_param->add_intvalue(param);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glTexParameteri(target, pname, param);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -3524,11 +3960,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glTexParameteriv(target, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -3593,11 +4033,15 @@
arg_pixels->add_intvalue((int)pixels);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -3620,11 +4064,15 @@
arg_x->add_floatvalue(x);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glUniform1f(location, x);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -3653,11 +4101,15 @@
arg_v->add_intvalue((int)v);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glUniform1fv(location, count, v);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -3680,11 +4132,15 @@
arg_x->add_intvalue(x);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glUniform1i(location, x);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -3713,11 +4169,15 @@
arg_v->add_intvalue((int)v);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glUniform1iv(location, count, v);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -3746,11 +4206,15 @@
arg_y->add_floatvalue(y);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glUniform2f(location, x, y);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -3779,11 +4243,15 @@
arg_v->add_intvalue((int)v);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glUniform2fv(location, count, v);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -3812,11 +4280,15 @@
arg_y->add_intvalue(y);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glUniform2i(location, x, y);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -3845,11 +4317,15 @@
arg_v->add_intvalue((int)v);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glUniform2iv(location, count, v);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -3884,11 +4360,15 @@
arg_z->add_floatvalue(z);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glUniform3f(location, x, y, z);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -3917,11 +4397,15 @@
arg_v->add_intvalue((int)v);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glUniform3fv(location, count, v);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -3956,11 +4440,15 @@
arg_z->add_intvalue(z);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glUniform3i(location, x, y, z);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -3989,11 +4477,15 @@
arg_v->add_intvalue((int)v);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glUniform3iv(location, count, v);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -4034,11 +4526,15 @@
arg_w->add_floatvalue(w);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glUniform4f(location, x, y, z, w);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -4067,11 +4563,15 @@
arg_v->add_intvalue((int)v);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glUniform4fv(location, count, v);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -4112,11 +4612,15 @@
arg_w->add_intvalue(w);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glUniform4i(location, x, y, z, w);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -4145,11 +4649,15 @@
arg_v->add_intvalue((int)v);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glUniform4iv(location, count, v);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -4184,11 +4692,15 @@
arg_value->add_intvalue((int)value);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glUniformMatrix2fv(location, count, transpose, value);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -4223,11 +4735,15 @@
arg_value->add_intvalue((int)value);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glUniformMatrix3fv(location, count, transpose, value);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -4262,11 +4778,15 @@
arg_value->add_intvalue((int)value);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glUniformMatrix4fv(location, count, transpose, value);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -4283,11 +4803,15 @@
arg_program->add_intvalue(program);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glUseProgram(program);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -4304,11 +4828,15 @@
arg_program->add_intvalue(program);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glValidateProgram(program);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -4331,11 +4859,15 @@
arg_x->add_floatvalue(x);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glVertexAttrib1f(indx, x);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -4358,11 +4890,15 @@
arg_values->add_intvalue((int)values);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glVertexAttrib1fv(indx, values);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -4391,11 +4927,15 @@
arg_y->add_floatvalue(y);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glVertexAttrib2f(indx, x, y);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -4418,11 +4958,15 @@
arg_values->add_intvalue((int)values);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glVertexAttrib2fv(indx, values);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -4457,11 +5001,15 @@
arg_z->add_floatvalue(z);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glVertexAttrib3f(indx, x, y, z);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -4484,11 +5032,15 @@
arg_values->add_intvalue((int)values);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glVertexAttrib3fv(indx, values);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -4529,11 +5081,15 @@
arg_w->add_floatvalue(w);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glVertexAttrib4f(indx, x, y, z, w);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -4556,11 +5112,15 @@
arg_values->add_intvalue((int)values);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glVertexAttrib4fv(indx, values);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -4607,11 +5167,15 @@
arg_ptr->add_intvalue((int)ptr);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glVertexAttribPointer(indx, size, type, normalized, stride, ptr);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -4646,11 +5210,15 @@
arg_height->add_intvalue(height);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glViewport(x, y, width, height);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -4676,11 +5244,15 @@
arg_image->add_intvalue((int)image);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glEGLImageTargetTexture2DOES(target, image);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -4703,11 +5275,15 @@
arg_image->add_intvalue((int)image);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glEGLImageTargetRenderbufferStorageOES(target, image);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -4748,11 +5324,15 @@
arg_binary->add_intvalue((int)binary);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetProgramBinaryOES(program, bufSize, length, binaryFormat, binary);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -4787,11 +5367,15 @@
arg_length->add_intvalue(length);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glProgramBinaryOES(program, binaryFormat, binary, length);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -4814,9 +5398,11 @@
arg_access->add_intvalue((int)access);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
void* retValue = glContext->hooks->gl.glMapBufferOES(target, access);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
// set return value
GLMessage_DataType *rt = glmsg.mutable_returnvalue();
@@ -4824,7 +5410,9 @@
rt->set_type(GLMessage::DataType::INT);
rt->add_intvalue((int)retValue);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -4843,9 +5431,11 @@
arg_target->add_intvalue((int)target);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
GLboolean retValue = glContext->hooks->gl.glUnmapBufferOES(target);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
// set return value
GLMessage_DataType *rt = glmsg.mutable_returnvalue();
@@ -4853,7 +5443,9 @@
rt->set_type(GLMessage::DataType::BOOL);
rt->add_boolvalue(retValue);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -4884,11 +5476,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetBufferPointervOES(target, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -4959,11 +5555,15 @@
arg_pixels->add_intvalue((int)pixels);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glTexImage3DOES(target, level, internalformat, width, height, depth, border, format, type, pixels);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -5040,11 +5640,15 @@
arg_pixels->add_intvalue((int)pixels);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glTexSubImage3DOES(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -5109,11 +5713,15 @@
arg_height->add_intvalue(height);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glCopyTexSubImage3DOES(target, level, xoffset, yoffset, zoffset, x, y, width, height);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -5178,11 +5786,15 @@
arg_data->add_intvalue((int)data);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glCompressedTexImage3DOES(target, level, internalformat, width, height, depth, border, imageSize, data);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -5259,11 +5871,15 @@
arg_data->add_intvalue((int)data);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glCompressedTexSubImage3DOES(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -5310,11 +5926,15 @@
arg_zoffset->add_intvalue(zoffset);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glFramebufferTexture3DOES(target, attachment, textarget, texture, level, zoffset);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -5331,11 +5951,15 @@
arg_array->add_intvalue(array);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glBindVertexArrayOES(array);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -5358,11 +5982,15 @@
arg_arrays->add_intvalue((int)arrays);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glDeleteVertexArraysOES(n, arrays);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -5385,11 +6013,15 @@
arg_arrays->add_intvalue((int)arrays);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGenVertexArraysOES(n, arrays);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -5406,9 +6038,11 @@
arg_array->add_intvalue(array);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
GLboolean retValue = glContext->hooks->gl.glIsVertexArrayOES(array);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
// set return value
GLMessage_DataType *rt = glmsg.mutable_returnvalue();
@@ -5416,7 +6050,9 @@
rt->set_type(GLMessage::DataType::BOOL);
rt->add_boolvalue(retValue);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -5447,11 +6083,15 @@
arg_groups->add_intvalue((int)groups);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetPerfMonitorGroupsAMD(numGroups, groupsSize, groups);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -5492,11 +6132,15 @@
arg_counters->add_intvalue((int)counters);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetPerfMonitorCountersAMD(group, numCounters, maxActiveCounters, counterSize, counters);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -5531,11 +6175,15 @@
arg_groupString->add_intvalue((int)groupString);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetPerfMonitorGroupStringAMD(group, bufSize, length, groupString);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -5576,11 +6224,15 @@
arg_counterString->add_intvalue((int)counterString);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetPerfMonitorCounterStringAMD(group, counter, bufSize, length, counterString);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -5615,11 +6267,15 @@
arg_data->add_intvalue((int)data);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetPerfMonitorCounterInfoAMD(group, counter, pname, data);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -5642,11 +6298,15 @@
arg_monitors->add_intvalue((int)monitors);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGenPerfMonitorsAMD(n, monitors);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -5669,11 +6329,15 @@
arg_monitors->add_intvalue((int)monitors);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glDeletePerfMonitorsAMD(n, monitors);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -5714,11 +6378,15 @@
arg_countersList->add_intvalue((int)countersList);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glSelectPerfMonitorCountersAMD(monitor, enable, group, numCounters, countersList);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -5735,11 +6403,15 @@
arg_monitor->add_intvalue(monitor);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glBeginPerfMonitorAMD(monitor);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -5756,11 +6428,15 @@
arg_monitor->add_intvalue(monitor);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glEndPerfMonitorAMD(monitor);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -5801,11 +6477,15 @@
arg_bytesWritten->add_intvalue((int)bytesWritten);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetPerfMonitorCounterDataAMD(monitor, pname, dataSize, data, bytesWritten);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -5876,11 +6556,15 @@
arg_filter->add_intvalue((int)filter);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glBlitFramebufferANGLE(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -5921,11 +6605,15 @@
arg_height->add_intvalue(height);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glRenderbufferStorageMultisampleANGLE(target, samples, internalformat, width, height);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -5966,11 +6654,15 @@
arg_height->add_intvalue(height);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glRenderbufferStorageMultisampleAPPLE(target, samples, internalformat, width, height);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -5981,11 +6673,15 @@
glmsg.set_function(GLMessage::glResolveMultisampleFramebufferAPPLE);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glResolveMultisampleFramebufferAPPLE();
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -6020,11 +6716,15 @@
arg_label->add_intvalue((int)label);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glLabelObjectEXT(type, object, length, label);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -6065,11 +6765,15 @@
arg_label->add_intvalue((int)label);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetObjectLabelEXT(type, object, bufSize, length, label);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -6092,11 +6796,15 @@
arg_marker->add_intvalue((int)marker);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glInsertEventMarkerEXT(length, marker);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -6119,11 +6827,15 @@
arg_marker->add_intvalue((int)marker);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glPushGroupMarkerEXT(length, marker);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -6134,11 +6846,15 @@
glmsg.set_function(GLMessage::glPopGroupMarkerEXT);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glPopGroupMarkerEXT();
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -6167,11 +6883,15 @@
arg_attachments->add_intvalue((int)attachments);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glDiscardFramebufferEXT(target, numAttachments, attachments);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -6212,11 +6932,15 @@
arg_height->add_intvalue(height);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glRenderbufferStorageMultisampleEXT(target, samples, internalformat, width, height);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -6263,11 +6987,15 @@
arg_samples->add_intvalue(samples);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glFramebufferTexture2DMultisampleEXT(target, attachment, textarget, texture, level, samples);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -6302,11 +7030,15 @@
arg_primcount->add_intvalue(primcount);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glMultiDrawArraysEXT(mode, first, count, primcount);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -6347,11 +7079,15 @@
arg_primcount->add_intvalue(primcount);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glMultiDrawElementsEXT(mode, count, type, indices, primcount);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -6374,11 +7110,15 @@
arg_ids->add_intvalue((int)ids);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGenQueriesEXT(n, ids);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -6401,11 +7141,15 @@
arg_ids->add_intvalue((int)ids);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glDeleteQueriesEXT(n, ids);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -6422,9 +7166,11 @@
arg_id->add_intvalue(id);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
GLboolean retValue = glContext->hooks->gl.glIsQueryEXT(id);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
// set return value
GLMessage_DataType *rt = glmsg.mutable_returnvalue();
@@ -6432,7 +7178,9 @@
rt->set_type(GLMessage::DataType::BOOL);
rt->add_boolvalue(retValue);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -6457,11 +7205,15 @@
arg_id->add_intvalue(id);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glBeginQueryEXT(target, id);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -6478,11 +7230,15 @@
arg_target->add_intvalue((int)target);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glEndQueryEXT(target);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -6511,11 +7267,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetQueryivEXT(target, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -6544,11 +7304,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetQueryObjectuivEXT(id, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -6559,9 +7323,11 @@
glmsg.set_function(GLMessage::glGetGraphicsResetStatusEXT);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
GLenum retValue = glContext->hooks->gl.glGetGraphicsResetStatusEXT();
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
// set return value
GLMessage_DataType *rt = glmsg.mutable_returnvalue();
@@ -6569,7 +7335,9 @@
rt->set_type(GLMessage::DataType::ENUM);
rt->add_intvalue((int)retValue);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -6630,11 +7398,15 @@
arg_data->add_intvalue((int)data);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glReadnPixelsEXT(x, y, width, height, format, type, bufSize, data);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -6669,11 +7441,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetnUniformfvEXT(program, location, bufSize, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -6708,11 +7484,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetnUniformivEXT(program, location, bufSize, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -6741,11 +7521,15 @@
arg_program->add_intvalue(program);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glUseProgramStagesEXT(pipeline, stages, program);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -6768,11 +7552,15 @@
arg_program->add_intvalue(program);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glActiveShaderProgramEXT(pipeline, program);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -6801,9 +7589,11 @@
arg_strings->add_intvalue((int)strings);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
GLuint retValue = glContext->hooks->gl.glCreateShaderProgramvEXT(type, count, strings);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
// set return value
GLMessage_DataType *rt = glmsg.mutable_returnvalue();
@@ -6811,7 +7601,9 @@
rt->set_type(GLMessage::DataType::INT);
rt->add_intvalue(retValue);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -6830,11 +7622,15 @@
arg_pipeline->add_intvalue(pipeline);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glBindProgramPipelineEXT(pipeline);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -6857,11 +7653,15 @@
arg_pipelines->add_intvalue((int)pipelines);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glDeleteProgramPipelinesEXT(n, pipelines);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -6884,11 +7684,15 @@
arg_pipelines->add_intvalue((int)pipelines);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGenProgramPipelinesEXT(n, pipelines);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -6905,9 +7709,11 @@
arg_pipeline->add_intvalue(pipeline);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
GLboolean retValue = glContext->hooks->gl.glIsProgramPipelineEXT(pipeline);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
// set return value
GLMessage_DataType *rt = glmsg.mutable_returnvalue();
@@ -6915,7 +7721,9 @@
rt->set_type(GLMessage::DataType::BOOL);
rt->add_boolvalue(retValue);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -6946,11 +7754,15 @@
arg_value->add_intvalue(value);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glProgramParameteriEXT(program, pname, value);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -6979,11 +7791,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetProgramPipelineivEXT(pipeline, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -7012,11 +7828,15 @@
arg_x->add_intvalue(x);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glProgramUniform1iEXT(program, location, x);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -7051,11 +7871,15 @@
arg_y->add_intvalue(y);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glProgramUniform2iEXT(program, location, x, y);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -7096,11 +7920,15 @@
arg_z->add_intvalue(z);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glProgramUniform3iEXT(program, location, x, y, z);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -7147,11 +7975,15 @@
arg_w->add_intvalue(w);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glProgramUniform4iEXT(program, location, x, y, z, w);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -7180,11 +8012,15 @@
arg_x->add_floatvalue(x);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glProgramUniform1fEXT(program, location, x);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -7219,11 +8055,15 @@
arg_y->add_floatvalue(y);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glProgramUniform2fEXT(program, location, x, y);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -7264,11 +8104,15 @@
arg_z->add_floatvalue(z);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glProgramUniform3fEXT(program, location, x, y, z);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -7315,11 +8159,15 @@
arg_w->add_floatvalue(w);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glProgramUniform4fEXT(program, location, x, y, z, w);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -7354,11 +8202,15 @@
arg_value->add_intvalue((int)value);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glProgramUniform1ivEXT(program, location, count, value);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -7393,11 +8245,15 @@
arg_value->add_intvalue((int)value);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glProgramUniform2ivEXT(program, location, count, value);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -7432,11 +8288,15 @@
arg_value->add_intvalue((int)value);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glProgramUniform3ivEXT(program, location, count, value);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -7471,11 +8331,15 @@
arg_value->add_intvalue((int)value);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glProgramUniform4ivEXT(program, location, count, value);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -7510,11 +8374,15 @@
arg_value->add_intvalue((int)value);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glProgramUniform1fvEXT(program, location, count, value);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -7549,11 +8417,15 @@
arg_value->add_intvalue((int)value);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glProgramUniform2fvEXT(program, location, count, value);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -7588,11 +8460,15 @@
arg_value->add_intvalue((int)value);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glProgramUniform3fvEXT(program, location, count, value);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -7627,11 +8503,15 @@
arg_value->add_intvalue((int)value);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glProgramUniform4fvEXT(program, location, count, value);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -7672,11 +8552,15 @@
arg_value->add_intvalue((int)value);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glProgramUniformMatrix2fvEXT(program, location, count, transpose, value);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -7717,11 +8601,15 @@
arg_value->add_intvalue((int)value);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glProgramUniformMatrix3fvEXT(program, location, count, transpose, value);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -7762,11 +8650,15 @@
arg_value->add_intvalue((int)value);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glProgramUniformMatrix4fvEXT(program, location, count, transpose, value);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -7783,11 +8675,15 @@
arg_pipeline->add_intvalue(pipeline);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glValidateProgramPipelineEXT(pipeline);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -7822,11 +8718,15 @@
arg_infoLog->add_intvalue((int)infoLog);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetProgramPipelineInfoLogEXT(pipeline, bufSize, length, infoLog);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -7861,11 +8761,15 @@
arg_width->add_intvalue(width);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glTexStorage1DEXT(target, levels, internalformat, width);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -7906,11 +8810,15 @@
arg_height->add_intvalue(height);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glTexStorage2DEXT(target, levels, internalformat, width, height);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -7957,11 +8865,15 @@
arg_depth->add_intvalue(depth);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glTexStorage3DEXT(target, levels, internalformat, width, height, depth);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -8002,11 +8914,15 @@
arg_width->add_intvalue(width);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glTextureStorage1DEXT(texture, target, levels, internalformat, width);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -8053,11 +8969,15 @@
arg_height->add_intvalue(height);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glTextureStorage2DEXT(texture, target, levels, internalformat, width, height);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -8110,11 +9030,15 @@
arg_depth->add_intvalue(depth);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glTextureStorage3DEXT(texture, target, levels, internalformat, width, height, depth);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -8155,11 +9079,15 @@
arg_height->add_intvalue(height);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glRenderbufferStorageMultisampleIMG(target, samples, internalformat, width, height);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -8206,11 +9134,15 @@
arg_samples->add_intvalue(samples);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glFramebufferTexture2DMultisampleIMG(target, attachment, textarget, texture, level, samples);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -8227,11 +9159,15 @@
arg_mask->add_boolvalue(mask);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glCoverageMaskNV(mask);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -8248,11 +9184,15 @@
arg_operation->add_intvalue((int)operation);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glCoverageOperationNV(operation);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -8275,11 +9215,15 @@
arg_bufs->add_intvalue((int)bufs);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glDrawBuffersNV(n, bufs);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -8302,11 +9246,15 @@
arg_fences->add_intvalue((int)fences);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glDeleteFencesNV(n, fences);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -8329,11 +9277,15 @@
arg_fences->add_intvalue((int)fences);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGenFencesNV(n, fences);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -8350,9 +9302,11 @@
arg_fence->add_intvalue(fence);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
GLboolean retValue = glContext->hooks->gl.glIsFenceNV(fence);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
// set return value
GLMessage_DataType *rt = glmsg.mutable_returnvalue();
@@ -8360,7 +9314,9 @@
rt->set_type(GLMessage::DataType::BOOL);
rt->add_boolvalue(retValue);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -8379,9 +9335,11 @@
arg_fence->add_intvalue(fence);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
GLboolean retValue = glContext->hooks->gl.glTestFenceNV(fence);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
// set return value
GLMessage_DataType *rt = glmsg.mutable_returnvalue();
@@ -8389,7 +9347,9 @@
rt->set_type(GLMessage::DataType::BOOL);
rt->add_boolvalue(retValue);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -8420,11 +9380,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetFenceivNV(fence, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -8441,11 +9405,15 @@
arg_fence->add_intvalue(fence);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glFinishFenceNV(fence);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -8468,11 +9436,15 @@
arg_condition->add_intvalue((int)condition);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glSetFenceNV(fence, condition);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -8489,11 +9461,15 @@
arg_mode->add_intvalue((int)mode);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glReadBufferNV(mode);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -8516,11 +9492,15 @@
arg_ref->add_floatvalue(ref);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glAlphaFuncQCOM(func, ref);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -8549,11 +9529,15 @@
arg_driverControls->add_intvalue((int)driverControls);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetDriverControlsQCOM(num, size, driverControls);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -8588,11 +9572,15 @@
arg_driverControlString->add_intvalue((int)driverControlString);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetDriverControlStringQCOM(driverControl, bufSize, length, driverControlString);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -8609,11 +9597,15 @@
arg_driverControl->add_intvalue(driverControl);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glEnableDriverControlQCOM(driverControl);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -8630,11 +9622,15 @@
arg_driverControl->add_intvalue(driverControl);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glDisableDriverControlQCOM(driverControl);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -8663,11 +9659,15 @@
arg_numTextures->add_intvalue((int)numTextures);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glExtGetTexturesQCOM(textures, maxTextures, numTextures);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -8696,11 +9696,15 @@
arg_numBuffers->add_intvalue((int)numBuffers);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glExtGetBuffersQCOM(buffers, maxBuffers, numBuffers);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -8729,11 +9733,15 @@
arg_numRenderbuffers->add_intvalue((int)numRenderbuffers);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glExtGetRenderbuffersQCOM(renderbuffers, maxRenderbuffers, numRenderbuffers);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -8762,11 +9770,15 @@
arg_numFramebuffers->add_intvalue((int)numFramebuffers);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glExtGetFramebuffersQCOM(framebuffers, maxFramebuffers, numFramebuffers);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -8807,11 +9819,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glExtGetTexLevelParameterivQCOM(texture, face, level, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -8840,11 +9856,15 @@
arg_param->add_intvalue(param);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glExtTexObjectStateOverrideiQCOM(target, pname, param);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -8921,11 +9941,15 @@
arg_texels->add_intvalue((int)texels);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glExtGetTexSubImageQCOM(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, texels);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -8948,11 +9972,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glExtGetBufferPointervQCOM(target, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -8981,11 +10009,15 @@
arg_numShaders->add_intvalue((int)numShaders);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glExtGetShadersQCOM(shaders, maxShaders, numShaders);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -9014,11 +10046,15 @@
arg_numPrograms->add_intvalue((int)numPrograms);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glExtGetProgramsQCOM(programs, maxPrograms, numPrograms);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -9035,9 +10071,11 @@
arg_program->add_intvalue(program);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
GLboolean retValue = glContext->hooks->gl.glExtIsProgramBinaryQCOM(program);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
// set return value
GLMessage_DataType *rt = glmsg.mutable_returnvalue();
@@ -9045,7 +10083,9 @@
rt->set_type(GLMessage::DataType::BOOL);
rt->add_boolvalue(retValue);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -9082,11 +10122,15 @@
arg_length->add_intvalue((int)length);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glExtGetProgramBinarySourceQCOM(program, shadertype, source, length);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -9127,11 +10171,15 @@
arg_preserveMask->add_intvalue(preserveMask);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glStartTilingQCOM(x, y, width, height, preserveMask);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -9148,11 +10196,15 @@
arg_preserveMask->add_intvalue(preserveMask);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glEndTilingQCOM(preserveMask);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -9178,11 +10230,15 @@
arg_ref->add_floatvalue(ref);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glAlphaFunc(func, ref);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -9205,11 +10261,15 @@
arg_equation->add_intvalue((int)equation);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glClipPlanef(plane, equation);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -9244,11 +10304,15 @@
arg_alpha->add_floatvalue(alpha);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glColor4f(red, green, blue, alpha);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -9271,11 +10335,15 @@
arg_param->add_floatvalue(param);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glFogf(pname, param);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -9298,11 +10366,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glFogfv(pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -9349,11 +10421,15 @@
arg_zFar->add_floatvalue(zFar);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glFrustumf(left, right, bottom, top, zNear, zFar);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -9376,11 +10452,15 @@
arg_eqn->add_intvalue((int)eqn);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetClipPlanef(pname, eqn);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -9409,11 +10489,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetLightfv(light, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -9442,11 +10526,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetMaterialfv(face, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -9475,11 +10563,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetTexEnvfv(env, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -9502,11 +10594,15 @@
arg_param->add_floatvalue(param);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glLightModelf(pname, param);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -9529,11 +10625,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glLightModelfv(pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -9562,11 +10662,15 @@
arg_param->add_floatvalue(param);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glLightf(light, pname, param);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -9595,11 +10699,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glLightfv(light, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -9616,11 +10724,15 @@
arg_m->add_intvalue((int)m);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glLoadMatrixf(m);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -9649,11 +10761,15 @@
arg_param->add_floatvalue(param);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glMaterialf(face, pname, param);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -9682,11 +10798,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glMaterialfv(face, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -9703,11 +10823,15 @@
arg_m->add_intvalue((int)m);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glMultMatrixf(m);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -9748,11 +10872,15 @@
arg_q->add_floatvalue(q);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glMultiTexCoord4f(target, s, t, r, q);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -9781,11 +10909,15 @@
arg_nz->add_floatvalue(nz);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glNormal3f(nx, ny, nz);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -9832,11 +10964,15 @@
arg_zFar->add_floatvalue(zFar);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glOrthof(left, right, bottom, top, zNear, zFar);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -9859,11 +10995,15 @@
arg_param->add_floatvalue(param);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glPointParameterf(pname, param);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -9886,11 +11026,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glPointParameterfv(pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -9907,11 +11051,15 @@
arg_size->add_floatvalue(size);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glPointSize(size);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -9946,11 +11094,15 @@
arg_z->add_floatvalue(z);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glRotatef(angle, x, y, z);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -9979,11 +11131,15 @@
arg_z->add_floatvalue(z);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glScalef(x, y, z);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -10012,11 +11168,15 @@
arg_param->add_floatvalue(param);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glTexEnvf(target, pname, param);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -10045,11 +11205,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glTexEnvfv(target, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -10078,11 +11242,15 @@
arg_z->add_floatvalue(z);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glTranslatef(x, y, z);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -10105,11 +11273,15 @@
arg_ref->add_intvalue(ref);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glAlphaFuncx(func, ref);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -10144,11 +11316,15 @@
arg_alpha->add_intvalue(alpha);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glClearColorx(red, green, blue, alpha);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -10165,11 +11341,15 @@
arg_depth->add_intvalue(depth);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glClearDepthx(depth);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -10186,11 +11366,15 @@
arg_texture->add_intvalue((int)texture);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glClientActiveTexture(texture);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -10213,11 +11397,15 @@
arg_equation->add_intvalue((int)equation);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glClipPlanex(plane, equation);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -10252,11 +11440,15 @@
arg_alpha->add_intvalue((int)alpha);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glColor4ub(red, green, blue, alpha);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -10291,11 +11483,15 @@
arg_alpha->add_intvalue(alpha);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glColor4x(red, green, blue, alpha);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -10330,11 +11526,15 @@
arg_pointer->add_intvalue((int)pointer);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glColorPointer(size, type, stride, pointer);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -10357,11 +11557,15 @@
arg_zFar->add_intvalue(zFar);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glDepthRangex(zNear, zFar);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -10378,11 +11582,15 @@
arg_array->add_intvalue((int)array);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glDisableClientState(array);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -10399,11 +11607,15 @@
arg_array->add_intvalue((int)array);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glEnableClientState(array);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -10426,11 +11638,15 @@
arg_param->add_intvalue(param);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glFogx(pname, param);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -10453,11 +11669,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glFogxv(pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -10504,11 +11724,15 @@
arg_zFar->add_intvalue(zFar);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glFrustumx(left, right, bottom, top, zNear, zFar);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -10531,11 +11755,15 @@
arg_eqn->add_intvalue((int)eqn);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetClipPlanex(pname, eqn);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -10558,11 +11786,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetFixedv(pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -10591,11 +11823,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetLightxv(light, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -10624,11 +11860,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetMaterialxv(face, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -10651,11 +11891,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetPointerv(pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -10684,11 +11928,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetTexEnviv(env, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -10717,11 +11965,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetTexEnvxv(env, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -10750,11 +12002,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetTexParameterxv(target, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -10777,11 +12033,15 @@
arg_param->add_intvalue(param);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glLightModelx(pname, param);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -10804,11 +12064,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glLightModelxv(pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -10837,11 +12101,15 @@
arg_param->add_intvalue(param);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glLightx(light, pname, param);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -10870,11 +12138,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glLightxv(light, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -10891,11 +12163,15 @@
arg_width->add_intvalue(width);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glLineWidthx(width);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -10906,11 +12182,15 @@
glmsg.set_function(GLMessage::glLoadIdentity);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glLoadIdentity();
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -10927,11 +12207,15 @@
arg_m->add_intvalue((int)m);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glLoadMatrixx(m);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -10948,11 +12232,15 @@
arg_opcode->add_intvalue((int)opcode);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glLogicOp(opcode);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -10981,11 +12269,15 @@
arg_param->add_intvalue(param);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glMaterialx(face, pname, param);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -11014,11 +12306,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glMaterialxv(face, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -11035,11 +12331,15 @@
arg_mode->add_intvalue((int)mode);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glMatrixMode(mode);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -11056,11 +12356,15 @@
arg_m->add_intvalue((int)m);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glMultMatrixx(m);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -11101,11 +12405,15 @@
arg_q->add_intvalue(q);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glMultiTexCoord4x(target, s, t, r, q);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -11134,11 +12442,15 @@
arg_nz->add_intvalue(nz);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glNormal3x(nx, ny, nz);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -11167,11 +12479,15 @@
arg_pointer->add_intvalue((int)pointer);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glNormalPointer(type, stride, pointer);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -11218,11 +12534,15 @@
arg_zFar->add_intvalue(zFar);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glOrthox(left, right, bottom, top, zNear, zFar);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -11245,11 +12565,15 @@
arg_param->add_intvalue(param);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glPointParameterx(pname, param);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -11272,11 +12596,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glPointParameterxv(pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -11293,11 +12621,15 @@
arg_size->add_intvalue(size);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glPointSizex(size);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -11320,11 +12652,15 @@
arg_units->add_intvalue(units);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glPolygonOffsetx(factor, units);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -11335,11 +12671,15 @@
glmsg.set_function(GLMessage::glPopMatrix);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glPopMatrix();
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -11350,11 +12690,15 @@
glmsg.set_function(GLMessage::glPushMatrix);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glPushMatrix();
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -11389,11 +12733,15 @@
arg_z->add_intvalue(z);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glRotatex(angle, x, y, z);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -11416,11 +12764,15 @@
arg_invert->add_boolvalue(invert);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glSampleCoveragex(value, invert);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -11449,11 +12801,15 @@
arg_z->add_intvalue(z);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glScalex(x, y, z);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -11470,11 +12826,15 @@
arg_mode->add_intvalue((int)mode);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glShadeModel(mode);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -11509,11 +12869,15 @@
arg_pointer->add_intvalue((int)pointer);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glTexCoordPointer(size, type, stride, pointer);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -11542,11 +12906,15 @@
arg_param->add_intvalue(param);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glTexEnvi(target, pname, param);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -11575,11 +12943,15 @@
arg_param->add_intvalue(param);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glTexEnvx(target, pname, param);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -11608,11 +12980,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glTexEnviv(target, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -11641,11 +13017,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glTexEnvxv(target, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -11674,11 +13054,15 @@
arg_param->add_intvalue(param);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glTexParameterx(target, pname, param);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -11707,11 +13091,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glTexParameterxv(target, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -11740,11 +13128,15 @@
arg_z->add_intvalue(z);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glTranslatex(x, y, z);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -11779,11 +13171,15 @@
arg_pointer->add_intvalue((int)pointer);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glVertexPointer(size, type, stride, pointer);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -11812,11 +13208,15 @@
arg_pointer->add_intvalue((int)pointer);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glPointSizePointerOES(type, stride, pointer);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -11842,11 +13242,15 @@
arg_modeAlpha->add_intvalue((int)modeAlpha);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glBlendEquationSeparateOES(modeRGB, modeAlpha);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -11881,11 +13285,15 @@
arg_dstAlpha->add_intvalue((int)dstAlpha);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glBlendFuncSeparateOES(srcRGB, dstRGB, srcAlpha, dstAlpha);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -11902,11 +13310,15 @@
arg_mode->add_intvalue((int)mode);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glBlendEquationOES(mode);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -11947,11 +13359,15 @@
arg_height->add_intvalue(height);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glDrawTexsOES(x, y, z, width, height);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -11992,11 +13408,15 @@
arg_height->add_intvalue(height);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glDrawTexiOES(x, y, z, width, height);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -12037,11 +13457,15 @@
arg_height->add_intvalue(height);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glDrawTexxOES(x, y, z, width, height);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -12058,11 +13482,15 @@
arg_coords->add_intvalue((int)coords);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glDrawTexsvOES(coords);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -12079,11 +13507,15 @@
arg_coords->add_intvalue((int)coords);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glDrawTexivOES(coords);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -12100,11 +13532,15 @@
arg_coords->add_intvalue((int)coords);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glDrawTexxvOES(coords);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -12145,11 +13581,15 @@
arg_height->add_floatvalue(height);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glDrawTexfOES(x, y, z, width, height);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -12166,11 +13606,15 @@
arg_coords->add_intvalue((int)coords);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glDrawTexfvOES(coords);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -12193,11 +13637,15 @@
arg_ref->add_intvalue(ref);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glAlphaFuncxOES(func, ref);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -12232,11 +13680,15 @@
arg_alpha->add_intvalue(alpha);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glClearColorxOES(red, green, blue, alpha);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -12253,11 +13705,15 @@
arg_depth->add_intvalue(depth);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glClearDepthxOES(depth);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -12280,11 +13736,15 @@
arg_equation->add_intvalue((int)equation);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glClipPlanexOES(plane, equation);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -12319,11 +13779,15 @@
arg_alpha->add_intvalue(alpha);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glColor4xOES(red, green, blue, alpha);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -12346,11 +13810,15 @@
arg_zFar->add_intvalue(zFar);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glDepthRangexOES(zNear, zFar);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -12373,11 +13841,15 @@
arg_param->add_intvalue(param);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glFogxOES(pname, param);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -12400,11 +13872,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glFogxvOES(pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -12451,11 +13927,15 @@
arg_zFar->add_intvalue(zFar);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glFrustumxOES(left, right, bottom, top, zNear, zFar);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -12478,11 +13958,15 @@
arg_eqn->add_intvalue((int)eqn);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetClipPlanexOES(pname, eqn);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -12505,11 +13989,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetFixedvOES(pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -12538,11 +14026,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetLightxvOES(light, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -12571,11 +14063,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetMaterialxvOES(face, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -12604,11 +14100,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetTexEnvxvOES(env, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -12637,11 +14137,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetTexParameterxvOES(target, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -12664,11 +14168,15 @@
arg_param->add_intvalue(param);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glLightModelxOES(pname, param);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -12691,11 +14199,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glLightModelxvOES(pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -12724,11 +14236,15 @@
arg_param->add_intvalue(param);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glLightxOES(light, pname, param);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -12757,11 +14273,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glLightxvOES(light, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -12778,11 +14298,15 @@
arg_width->add_intvalue(width);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glLineWidthxOES(width);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -12799,11 +14323,15 @@
arg_m->add_intvalue((int)m);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glLoadMatrixxOES(m);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -12832,11 +14360,15 @@
arg_param->add_intvalue(param);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glMaterialxOES(face, pname, param);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -12865,11 +14397,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glMaterialxvOES(face, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -12886,11 +14422,15 @@
arg_m->add_intvalue((int)m);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glMultMatrixxOES(m);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -12931,11 +14471,15 @@
arg_q->add_intvalue(q);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glMultiTexCoord4xOES(target, s, t, r, q);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -12964,11 +14508,15 @@
arg_nz->add_intvalue(nz);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glNormal3xOES(nx, ny, nz);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -13015,11 +14563,15 @@
arg_zFar->add_intvalue(zFar);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glOrthoxOES(left, right, bottom, top, zNear, zFar);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -13042,11 +14594,15 @@
arg_param->add_intvalue(param);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glPointParameterxOES(pname, param);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -13069,11 +14625,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glPointParameterxvOES(pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -13090,11 +14650,15 @@
arg_size->add_intvalue(size);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glPointSizexOES(size);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -13117,11 +14681,15 @@
arg_units->add_intvalue(units);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glPolygonOffsetxOES(factor, units);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -13156,11 +14724,15 @@
arg_z->add_intvalue(z);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glRotatexOES(angle, x, y, z);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -13183,11 +14755,15 @@
arg_invert->add_boolvalue(invert);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glSampleCoveragexOES(value, invert);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -13216,11 +14792,15 @@
arg_z->add_intvalue(z);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glScalexOES(x, y, z);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -13249,11 +14829,15 @@
arg_param->add_intvalue(param);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glTexEnvxOES(target, pname, param);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -13282,11 +14866,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glTexEnvxvOES(target, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -13315,11 +14903,15 @@
arg_param->add_intvalue(param);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glTexParameterxOES(target, pname, param);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -13348,11 +14940,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glTexParameterxvOES(target, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -13381,11 +14977,15 @@
arg_z->add_intvalue(z);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glTranslatexOES(x, y, z);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -13402,9 +15002,11 @@
arg_renderbuffer->add_intvalue(renderbuffer);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
GLboolean retValue = glContext->hooks->gl.glIsRenderbufferOES(renderbuffer);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
// set return value
GLMessage_DataType *rt = glmsg.mutable_returnvalue();
@@ -13412,7 +15014,9 @@
rt->set_type(GLMessage::DataType::BOOL);
rt->add_boolvalue(retValue);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -13437,11 +15041,15 @@
arg_renderbuffer->add_intvalue(renderbuffer);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glBindRenderbufferOES(target, renderbuffer);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -13464,11 +15072,15 @@
arg_renderbuffers->add_intvalue((int)renderbuffers);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glDeleteRenderbuffersOES(n, renderbuffers);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -13491,11 +15103,15 @@
arg_renderbuffers->add_intvalue((int)renderbuffers);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGenRenderbuffersOES(n, renderbuffers);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -13530,11 +15146,15 @@
arg_height->add_intvalue(height);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glRenderbufferStorageOES(target, internalformat, width, height);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -13563,11 +15183,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetRenderbufferParameterivOES(target, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -13584,9 +15208,11 @@
arg_framebuffer->add_intvalue(framebuffer);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
GLboolean retValue = glContext->hooks->gl.glIsFramebufferOES(framebuffer);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
// set return value
GLMessage_DataType *rt = glmsg.mutable_returnvalue();
@@ -13594,7 +15220,9 @@
rt->set_type(GLMessage::DataType::BOOL);
rt->add_boolvalue(retValue);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -13619,11 +15247,15 @@
arg_framebuffer->add_intvalue(framebuffer);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glBindFramebufferOES(target, framebuffer);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -13646,11 +15278,15 @@
arg_framebuffers->add_intvalue((int)framebuffers);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glDeleteFramebuffersOES(n, framebuffers);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -13673,11 +15309,15 @@
arg_framebuffers->add_intvalue((int)framebuffers);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGenFramebuffersOES(n, framebuffers);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -13694,9 +15334,11 @@
arg_target->add_intvalue((int)target);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
GLenum retValue = glContext->hooks->gl.glCheckFramebufferStatusOES(target);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
// set return value
GLMessage_DataType *rt = glmsg.mutable_returnvalue();
@@ -13704,7 +15346,9 @@
rt->set_type(GLMessage::DataType::ENUM);
rt->add_intvalue((int)retValue);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -13741,11 +15385,15 @@
arg_renderbuffer->add_intvalue(renderbuffer);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glFramebufferRenderbufferOES(target, attachment, renderbuffertarget, renderbuffer);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -13786,11 +15434,15 @@
arg_level->add_intvalue(level);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glFramebufferTexture2DOES(target, attachment, textarget, texture, level);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -13825,11 +15477,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetFramebufferAttachmentParameterivOES(target, attachment, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -13846,11 +15502,15 @@
arg_target->add_intvalue((int)target);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGenerateMipmapOES(target);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -13867,11 +15527,15 @@
arg_matrixpaletteindex->add_intvalue(matrixpaletteindex);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glCurrentPaletteMatrixOES(matrixpaletteindex);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -13882,11 +15546,15 @@
glmsg.set_function(GLMessage::glLoadPaletteFromModelViewMatrixOES);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glLoadPaletteFromModelViewMatrixOES();
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -13921,11 +15589,15 @@
arg_pointer->add_intvalue((int)pointer);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glMatrixIndexPointerOES(size, type, stride, pointer);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -13960,11 +15632,15 @@
arg_pointer->add_intvalue((int)pointer);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glWeightPointerOES(size, type, stride, pointer);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -13987,9 +15663,11 @@
arg_exponent->add_intvalue((int)exponent);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
GLbitfield retValue = glContext->hooks->gl.glQueryMatrixxOES(mantissa, exponent);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
// set return value
GLMessage_DataType *rt = glmsg.mutable_returnvalue();
@@ -13997,7 +15675,9 @@
rt->set_type(GLMessage::DataType::INT);
rt->add_intvalue(retValue);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
return retValue;
@@ -14022,11 +15702,15 @@
arg_zFar->add_floatvalue(zFar);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glDepthRangefOES(zNear, zFar);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -14073,11 +15757,15 @@
arg_zFar->add_floatvalue(zFar);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glFrustumfOES(left, right, bottom, top, zNear, zFar);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -14124,11 +15812,15 @@
arg_zFar->add_floatvalue(zFar);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glOrthofOES(left, right, bottom, top, zNear, zFar);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -14151,11 +15843,15 @@
arg_equation->add_intvalue((int)equation);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glClipPlanefOES(plane, equation);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -14178,11 +15874,15 @@
arg_eqn->add_intvalue((int)eqn);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetClipPlanefOES(pname, eqn);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -14199,11 +15899,15 @@
arg_depth->add_floatvalue(depth);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glClearDepthfOES(depth);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -14232,11 +15936,15 @@
arg_param->add_floatvalue(param);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glTexGenfOES(coord, pname, param);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -14265,11 +15973,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glTexGenfvOES(coord, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -14298,11 +16010,15 @@
arg_param->add_intvalue(param);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glTexGeniOES(coord, pname, param);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -14331,11 +16047,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glTexGenivOES(coord, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -14364,11 +16084,15 @@
arg_param->add_intvalue(param);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glTexGenxOES(coord, pname, param);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -14397,11 +16121,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glTexGenxvOES(coord, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -14430,11 +16158,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetTexGenfvOES(coord, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -14463,11 +16195,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetTexGenivOES(coord, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -14496,11 +16232,15 @@
arg_params->add_intvalue((int)params);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glGetTexGenxvOES(coord, pname, params);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -14523,11 +16263,15 @@
arg_eqn->add_intvalue((int)eqn);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glClipPlanefIMG(p, eqn);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
@@ -14550,11 +16294,15 @@
arg_eqn->add_intvalue((int)eqn);
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
glContext->hooks->gl.glClipPlanexIMG(p, eqn);
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
}
diff --git a/opengl/libs/GLES_trace/src/gltrace_fixup.cpp b/opengl/libs/GLES_trace/src/gltrace_fixup.cpp
index 3e185bc..6c4feb5 100644
--- a/opengl/libs/GLES_trace/src/gltrace_fixup.cpp
+++ b/opengl/libs/GLES_trace/src/gltrace_fixup.cpp
@@ -379,13 +379,16 @@
arg_location->add_intvalue(location);
}
-void fixupGLMessage(GLTraceContext *context, nsecs_t start, nsecs_t end, GLMessage *glmsg) {
+void fixupGLMessage(GLTraceContext *context, nsecs_t wallStart, nsecs_t wallEnd,
+ nsecs_t threadStart, nsecs_t threadEnd,
+ GLMessage *glmsg) {
// for all messages, set the current context id
glmsg->set_context_id(context->getId());
// set start time and duration
- glmsg->set_start_time(start);
- glmsg->set_duration((unsigned)(end - start));
+ glmsg->set_start_time(wallStart);
+ glmsg->set_duration((unsigned)(wallEnd - wallStart));
+ glmsg->set_threadtime((unsigned)(threadEnd - threadStart));
// do any custom message dependent processing
switch (glmsg->function()) {
diff --git a/opengl/libs/GLES_trace/src/gltrace_fixup.h b/opengl/libs/GLES_trace/src/gltrace_fixup.h
index 64f7545..f63b056 100644
--- a/opengl/libs/GLES_trace/src/gltrace_fixup.h
+++ b/opengl/libs/GLES_trace/src/gltrace_fixup.h
@@ -25,7 +25,9 @@
namespace android {
namespace gltrace {
-void fixupGLMessage(GLTraceContext *curContext, nsecs_t start, nsecs_t end, GLMessage *message);
+void fixupGLMessage(GLTraceContext *curContext, nsecs_t wallStart, nsecs_t wallEnd,
+ nsecs_t threadStart, nsecs_t threadEnd,
+ GLMessage *message);
void fixup_addFBContents(GLTraceContext *curContext, GLMessage *message, FBBinding fbToRead);
};
diff --git a/opengl/libs/GLES_trace/tools/genapi.py b/opengl/libs/GLES_trace/tools/genapi.py
index 557e407..e1660be 100755
--- a/opengl/libs/GLES_trace/tools/genapi.py
+++ b/opengl/libs/GLES_trace/tools/genapi.py
@@ -162,13 +162,15 @@
<!--(end)-->
// call function
- nsecs_t start_time = systemTime();
+ nsecs_t wallStartTime = systemTime(SYSTEM_TIME_MONOTONIC);
+ nsecs_t threadStartTime = systemTime(SYSTEM_TIME_THREAD);
<!--(if retType != "void")-->
$!retType!$ retValue = glContext->hooks->gl.$!callsite!$;
<!--(else)-->
glContext->hooks->gl.$!callsite!$;
<!--(end)-->
- nsecs_t end_time = systemTime();
+ nsecs_t threadEndTime = systemTime(SYSTEM_TIME_THREAD);
+ nsecs_t wallEndTime = systemTime(SYSTEM_TIME_MONOTONIC);
<!--(if retType != "void")-->
// set return value
@@ -178,7 +180,9 @@
rt->$!retDataType.getProtobufCall()!$retValue);
<!--(end)-->
- fixupGLMessage(glContext, start_time, end_time, &glmsg);
+ fixupGLMessage(glContext, wallStartTime, wallEndTime,
+ threadStartTime, threadEndTime,
+ &glmsg);
glContext->traceGLMessage(&glmsg);
<!--(if retType != "void")-->
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index 3beaac9..3a8e3fc 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -148,4 +148,7 @@
<!-- Development settings -->
<bool name="def_stay_on_while_plugged_in">false</bool>
+ <!-- Number of retries for connecting to DHCP.
+ Value here is the same as WifiStateMachine.DEFAULT_MAX_DHCP_RETRIES -->
+ <integer name="def_max_dhcp_retries">9</integer>
</resources>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index 882aa66..330a189 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -1602,6 +1602,9 @@
loadBooleanSetting(stmt, Settings.Secure.NETSTATS_ENABLED,
R.bool.def_netstats_enabled);
+
+ loadIntegerSetting(stmt, Settings.Secure.WIFI_MAX_DHCP_RETRY_COUNT,
+ R.integer.def_max_dhcp_retries);
} finally {
if (stmt != null) stmt.close();
}
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index b87b8c3..301dbf5 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -115,6 +115,10 @@
final TypedValue mMinWidthMajor = new TypedValue();
final TypedValue mMinWidthMinor = new TypedValue();
+ TypedValue mFixedWidthMajor;
+ TypedValue mFixedWidthMinor;
+ TypedValue mFixedHeightMajor;
+ TypedValue mFixedHeightMinor;
// This is the top-level view of the window, containing the window decor.
private DecorView mDecor;
@@ -2088,6 +2092,44 @@
final boolean isPortrait = metrics.widthPixels < metrics.heightPixels;
final int widthMode = getMode(widthMeasureSpec);
+ final int heightMode = getMode(heightMeasureSpec);
+
+ boolean fixedWidth = false;
+ if (widthMode == AT_MOST) {
+ final TypedValue tvw = isPortrait ? mFixedWidthMinor : mFixedWidthMajor;
+ if (tvw != null && tvw.type != TypedValue.TYPE_NULL) {
+ fixedWidth = true;
+ final int w;
+ if (tvw.type == TypedValue.TYPE_DIMENSION) {
+ w = (int) tvw.getDimension(metrics);
+ } else if (tvw.type == TypedValue.TYPE_FRACTION) {
+ w = (int) tvw.getFraction(metrics.widthPixels, metrics.widthPixels);
+ } else {
+ w = 0;
+ }
+
+ final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
+ widthMeasureSpec = MeasureSpec.makeMeasureSpec(Math.min(w, widthSize), EXACTLY);
+ }
+ }
+
+ if (heightMode == AT_MOST) {
+ final TypedValue tvh = isPortrait ? mFixedHeightMajor : mFixedHeightMinor;
+ if (tvh != null && tvh.type != TypedValue.TYPE_NULL) {
+ final int h;
+ if (tvh.type == TypedValue.TYPE_DIMENSION) {
+ h = (int) tvh.getDimension(metrics);
+ } else if (tvh.type == TypedValue.TYPE_FRACTION) {
+ h = (int) tvh.getFraction(metrics.heightPixels, metrics.heightPixels);
+ } else {
+ h = 0;
+ }
+
+ final int heightSize = MeasureSpec.getSize(heightMeasureSpec);
+ heightMeasureSpec =
+ MeasureSpec.makeMeasureSpec(Math.min(h, heightSize), EXACTLY);
+ }
+ }
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
@@ -2096,21 +2138,22 @@
widthMeasureSpec = MeasureSpec.makeMeasureSpec(width, EXACTLY);
- final TypedValue tv = isPortrait ? mMinWidthMinor : mMinWidthMajor;
+ if (!fixedWidth && widthMode == AT_MOST) {
+ final TypedValue tv = isPortrait ? mMinWidthMinor : mMinWidthMajor;
+ if (tv.type != TypedValue.TYPE_NULL) {
+ final int min;
+ if (tv.type == TypedValue.TYPE_DIMENSION) {
+ min = (int)tv.getDimension(metrics);
+ } else if (tv.type == TypedValue.TYPE_FRACTION) {
+ min = (int)tv.getFraction(metrics.widthPixels, metrics.widthPixels);
+ } else {
+ min = 0;
+ }
- if (widthMode == AT_MOST && tv.type != TypedValue.TYPE_NULL) {
- final int min;
- if (tv.type == TypedValue.TYPE_DIMENSION) {
- min = (int)tv.getDimension(metrics);
- } else if (tv.type == TypedValue.TYPE_FRACTION) {
- min = (int)tv.getFraction(metrics.widthPixels, metrics.widthPixels);
- } else {
- min = 0;
- }
-
- if (width < min) {
- widthMeasureSpec = MeasureSpec.makeMeasureSpec(min, EXACTLY);
- measure = true;
+ if (width < min) {
+ widthMeasureSpec = MeasureSpec.makeMeasureSpec(min, EXACTLY);
+ measure = true;
+ }
}
}
@@ -2571,6 +2614,26 @@
a.getValue(com.android.internal.R.styleable.Window_windowMinWidthMajor, mMinWidthMajor);
a.getValue(com.android.internal.R.styleable.Window_windowMinWidthMinor, mMinWidthMinor);
+ if (a.hasValue(com.android.internal.R.styleable.Window_windowFixedWidthMajor)) {
+ if (mFixedWidthMajor == null) mFixedWidthMajor = new TypedValue();
+ a.getValue(com.android.internal.R.styleable.Window_windowFixedWidthMajor,
+ mFixedWidthMajor);
+ }
+ if (a.hasValue(com.android.internal.R.styleable.Window_windowFixedWidthMinor)) {
+ if (mFixedWidthMinor == null) mFixedWidthMinor = new TypedValue();
+ a.getValue(com.android.internal.R.styleable.Window_windowFixedWidthMinor,
+ mFixedWidthMinor);
+ }
+ if (a.hasValue(com.android.internal.R.styleable.Window_windowFixedHeightMajor)) {
+ if (mFixedHeightMajor == null) mFixedHeightMajor = new TypedValue();
+ a.getValue(com.android.internal.R.styleable.Window_windowFixedHeightMajor,
+ mFixedHeightMajor);
+ }
+ if (a.hasValue(com.android.internal.R.styleable.Window_windowFixedHeightMinor)) {
+ if (mFixedHeightMinor == null) mFixedHeightMinor = new TypedValue();
+ a.getValue(com.android.internal.R.styleable.Window_windowFixedHeightMinor,
+ mFixedHeightMinor);
+ }
final Context context = getContext();
final int targetSdk = context.getApplicationInfo().targetSdkVersion;
diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk
index 157405a..22fa752 100644
--- a/services/audioflinger/Android.mk
+++ b/services/audioflinger/Android.mk
@@ -7,6 +7,7 @@
AudioMixer.cpp.arm \
AudioResampler.cpp.arm \
AudioPolicyService.cpp \
+ AudioBufferProvider.cpp \
ServiceUtilities.cpp
# AudioResamplerSinc.cpp.arm
# AudioResamplerCubic.cpp.arm
@@ -17,6 +18,7 @@
LOCAL_SHARED_LIBRARIES := \
libaudioutils \
+ libcommon_time_client \
libcutils \
libutils \
libbinder \
diff --git a/include/ui/PowerManager.h b/services/audioflinger/AudioBufferProvider.cpp
similarity index 61%
copy from include/ui/PowerManager.h
copy to services/audioflinger/AudioBufferProvider.cpp
index dd80318..678fd58 100644
--- a/include/ui/PowerManager.h
+++ b/services/audioflinger/AudioBufferProvider.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010 The Android Open Source Project
+ * Copyright (C) 2011 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.
@@ -14,20 +14,15 @@
* limitations under the License.
*/
-#ifndef _UI_POWER_MANAGER_H
-#define _UI_POWER_MANAGER_H
+#undef __STRICT_ANSI__
+#define __STDINT_LIMITS
+#define __STDC_LIMIT_MACROS
+#include <stdint.h>
+#include "AudioBufferProvider.h"
namespace android {
-enum {
- POWER_MANAGER_OTHER_EVENT = 0,
- POWER_MANAGER_BUTTON_EVENT = 1,
- POWER_MANAGER_TOUCH_EVENT = 2,
+const int64_t AudioBufferProvider::kInvalidPTS = INT64_MAX;
- POWER_MANAGER_LAST_EVENT = POWER_MANAGER_TOUCH_EVENT, // Last valid event code.
-};
-
-} // namespace android
-
-#endif // _UI_POWER_MANAGER_H
+}; // namespace android
diff --git a/services/audioflinger/AudioBufferProvider.h b/services/audioflinger/AudioBufferProvider.h
index 81c5c39..62ad6bd 100644
--- a/services/audioflinger/AudioBufferProvider.h
+++ b/services/audioflinger/AudioBufferProvider.h
@@ -38,8 +38,15 @@
};
virtual ~AudioBufferProvider() {}
-
- virtual status_t getNextBuffer(Buffer* buffer) = 0;
+
+ // value representing an invalid presentation timestamp
+ static const int64_t kInvalidPTS;
+
+ // pts is the local time when the next sample yielded by getNextBuffer
+ // will be rendered.
+ // Pass kInvalidPTS if the PTS is unknown or not applicable.
+ virtual status_t getNextBuffer(Buffer* buffer, int64_t pts) = 0;
+
virtual void releaseBuffer(Buffer* buffer) = 0;
};
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 0248687..2e2834c 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -61,6 +61,9 @@
#include <powermanager/PowerManager.h>
// #define DEBUG_CPU_USAGE 10 // log statistics every n wall clock seconds
+#include <common_time/cc_helper.h>
+#include <common_time/local_clock.h>
+
// ----------------------------------------------------------------------------
@@ -69,7 +72,6 @@
static const char kDeadlockedString[] = "AudioFlinger may be deadlocked\n";
static const char kHardwareLockedString[] = "Hardware lock is taken\n";
-//static const nsecs_t kStandbyTimeInNsecs = seconds(3);
static const float MAX_GAIN = 4096.0f;
static const uint32_t MAX_GAIN_INT = 0x1000;
@@ -99,6 +101,7 @@
// maximum divider applied to the active sleep time in the mixer thread loop
static const uint32_t kMaxThreadSleepTimeShift = 2;
+nsecs_t AudioFlinger::mStandbyTimeInNsecs = kDefaultStandbyTimeInNsecs;
// ----------------------------------------------------------------------------
@@ -147,11 +150,14 @@
AudioFlinger::AudioFlinger()
: BnAudioFlinger(),
- mPrimaryHardwareDev(NULL),
- mHardwareStatus(AUDIO_HW_IDLE), // see also onFirstRef()
- mMasterVolume(1.0f), mMasterMute(false), mNextUniqueId(1),
- mMode(AUDIO_MODE_INVALID),
- mBtNrecIsOff(false)
+ mPrimaryHardwareDev(NULL),
+ mHardwareStatus(AUDIO_HW_IDLE), // see also onFirstRef()
+ mMasterVolume(1.0f),
+ mMasterVolumeSupportLvl(MVS_NONE),
+ mMasterMute(false),
+ mNextUniqueId(1),
+ mMode(AUDIO_MODE_INVALID),
+ mBtNrecIsOff(false)
{
}
@@ -162,6 +168,18 @@
Mutex::Autolock _l(mLock);
/* TODO: move all this work into an Init() function */
+ char val_str[PROPERTY_VALUE_MAX] = { 0 };
+ if (property_get("ro.audio.flinger_standbytime_ms", val_str, NULL) >= 0) {
+ uint32_t int_val;
+ if (1 == sscanf(val_str, "%u", &int_val)) {
+ mStandbyTimeInNsecs = milliseconds(int_val);
+ ALOGI("Using %u mSec as standby time.", int_val);
+ } else {
+ mStandbyTimeInNsecs = kDefaultStandbyTimeInNsecs;
+ ALOGI("Using default %u mSec as standby time.",
+ (uint32_t)(mStandbyTimeInNsecs / 1000000));
+ }
+ }
for (size_t i = 0; i < ARRAY_SIZE(audio_interfaces); i++) {
const hw_module_t *mod;
@@ -193,6 +211,32 @@
AutoMutex lock(mHardwareLock);
+ // Determine the level of master volume support the primary audio HAL has,
+ // and set the initial master volume at the same time.
+ float initialVolume = 1.0;
+ mMasterVolumeSupportLvl = MVS_NONE;
+ if (0 == mPrimaryHardwareDev->init_check(mPrimaryHardwareDev)) {
+ audio_hw_device_t *dev = mPrimaryHardwareDev;
+
+ mHardwareStatus = AUDIO_HW_GET_MASTER_VOLUME;
+ if ((NULL != dev->get_master_volume) &&
+ (NO_ERROR == dev->get_master_volume(dev, &initialVolume))) {
+ mMasterVolumeSupportLvl = MVS_FULL;
+ } else {
+ mMasterVolumeSupportLvl = MVS_SETONLY;
+ initialVolume = 1.0;
+ }
+
+ mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
+ if ((NULL == dev->set_master_volume) ||
+ (NO_ERROR != dev->set_master_volume(dev, initialVolume))) {
+ mMasterVolumeSupportLvl = MVS_NONE;
+ }
+ mHardwareStatus = AUDIO_HW_INIT;
+ }
+
+ // Set the mode for each audio HAL, and try to set the initial volume (if
+ // supported) for all of the non-primary audio HALs.
for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
audio_hw_device_t *dev = mAudioHwDevs[i];
@@ -203,11 +247,22 @@
mMode = AUDIO_MODE_NORMAL; // assigned multiple times with same value
mHardwareStatus = AUDIO_HW_SET_MODE;
dev->set_mode(dev, mMode);
- mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
- dev->set_master_volume(dev, 1.0f);
- mHardwareStatus = AUDIO_HW_IDLE;
+
+ if ((dev != mPrimaryHardwareDev) &&
+ (NULL != dev->set_master_volume)) {
+ mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
+ dev->set_master_volume(dev, initialVolume);
+ }
+
+ mHardwareStatus = AUDIO_HW_INIT;
}
}
+
+ mMasterVolumeSW = (MVS_NONE == mMasterVolumeSupportLvl)
+ ? initialVolume
+ : 1.0;
+ mMasterVolume = initialVolume;
+ mHardwareStatus = AUDIO_HW_IDLE;
}
AudioFlinger::~AudioFlinger()
@@ -273,7 +328,10 @@
String8 result;
hardware_call_state hardwareStatus = mHardwareStatus;
- snprintf(buffer, SIZE, "Hardware status: %d\n", hardwareStatus);
+ snprintf(buffer, SIZE, "Hardware status: %d\n"
+ "Standby Time mSec: %u\n",
+ hardwareStatus,
+ (uint32_t)(mStandbyTimeInNsecs / 1000000));
result.append(buffer);
write(fd, result.string(), result.size());
return NO_ERROR;
@@ -377,6 +435,7 @@
uint32_t flags,
const sp<IMemory>& sharedBuffer,
audio_io_handle_t output,
+ bool isTimed,
int *sessionId,
status_t *status)
{
@@ -435,7 +494,7 @@
ALOGV("createTrack() lSessionId: %d", lSessionId);
track = thread->createTrack_l(client, streamType, sampleRate, format,
- channelMask, frameCount, sharedBuffer, lSessionId, &lStatus);
+ channelMask, frameCount, sharedBuffer, lSessionId, isTimed, &lStatus);
// move effect chain to this output thread if an effect on same session was waiting
// for a track to be created
@@ -528,20 +587,29 @@
return PERMISSION_DENIED;
}
+ float swmv = value;
+
// when hw supports master volume, don't scale in sw mixer
- { // scope for the lock
- AutoMutex lock(mHardwareLock);
- mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
- if (mPrimaryHardwareDev->set_master_volume(mPrimaryHardwareDev, value) == NO_ERROR) {
- value = 1.0f;
+ if (MVS_NONE != mMasterVolumeSupportLvl) {
+ for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
+ AutoMutex lock(mHardwareLock);
+ audio_hw_device_t *dev = mAudioHwDevs[i];
+
+ mHardwareStatus = AUDIO_HW_SET_MASTER_VOLUME;
+ if (NULL != dev->set_master_volume) {
+ dev->set_master_volume(dev, value);
+ }
+ mHardwareStatus = AUDIO_HW_IDLE;
}
- mHardwareStatus = AUDIO_HW_IDLE;
+
+ swmv = 1.0;
}
Mutex::Autolock _l(mLock);
- mMasterVolume = value;
+ mMasterVolume = value;
+ mMasterVolumeSW = swmv;
for (size_t i = 0; i < mPlaybackThreads.size(); i++)
- mPlaybackThreads.valueAt(i)->setMasterVolume(value);
+ mPlaybackThreads.valueAt(i)->setMasterVolume(swmv);
return NO_ERROR;
}
@@ -635,12 +703,36 @@
return masterVolume_l();
}
+float AudioFlinger::masterVolumeSW() const
+{
+ Mutex::Autolock _l(mLock);
+ return masterVolumeSW_l();
+}
+
bool AudioFlinger::masterMute() const
{
Mutex::Autolock _l(mLock);
return masterMute_l();
}
+float AudioFlinger::masterVolume_l() const
+{
+ if (MVS_FULL == mMasterVolumeSupportLvl) {
+ float ret_val;
+ AutoMutex lock(mHardwareLock);
+
+ mHardwareStatus = AUDIO_HW_GET_MASTER_VOLUME;
+ assert(NULL != mPrimaryHardwareDev);
+ assert(NULL != mPrimaryHardwareDev->get_master_volume);
+
+ mPrimaryHardwareDev->get_master_volume(mPrimaryHardwareDev, &ret_val);
+ mHardwareStatus = AUDIO_HW_IDLE;
+ return ret_val;
+ }
+
+ return mMasterVolume;
+}
+
status_t AudioFlinger::setStreamVolume(audio_stream_type_t stream, float value,
audio_io_handle_t output)
{
@@ -814,7 +906,7 @@
for (size_t i = 0; i < mAudioHwDevs.size(); i++) {
audio_hw_device_t *dev = mAudioHwDevs[i];
char *s = dev->get_parameters(dev, keys.string());
- out_s8 += String8(s);
+ out_s8 += String8(s ? s : "");
free(s);
}
return out_s8;
@@ -1367,7 +1459,7 @@
mOutput(output),
// Assumes constructor is called by AudioFlinger with it's mLock held,
// but it would be safer to explicitly pass initial masterVolume as parameter
- mMasterVolume(audioFlinger->masterVolume_l()),
+ mMasterVolume(audioFlinger->masterVolumeSW_l()),
mLastWriteTime(0), mNumWrites(0), mNumDelayedWrites(0), mInWrite(false)
{
snprintf(mName, kNameLength, "AudioOut_%d", id);
@@ -1485,6 +1577,7 @@
int frameCount,
const sp<IMemory>& sharedBuffer,
int sessionId,
+ bool isTimed,
status_t *status)
{
sp<Track> track;
@@ -1535,9 +1628,14 @@
}
}
- track = new Track(this, client, streamType, sampleRate, format,
- channelMask, frameCount, sharedBuffer, sessionId);
- if (track->getCblk() == NULL || track->name() < 0) {
+ if (!isTimed) {
+ track = new Track(this, client, streamType, sampleRate, format,
+ channelMask, frameCount, sharedBuffer, sessionId);
+ } else {
+ track = TimedTrack::create(this, client, streamType, sampleRate, format,
+ channelMask, frameCount, sharedBuffer, sessionId);
+ }
+ if (track == NULL || track->getCblk() == NULL || track->name() < 0) {
lStatus = NO_MEMORY;
goto Exit;
}
@@ -1941,7 +2039,7 @@
}
}
- standbyTime = systemTime() + kStandbyTimeInNsecs;
+ standbyTime = systemTime() + mStandbyTimeInNsecs;
sleepTime = idleSleepTime;
sleepTimeShift = 0;
continue;
@@ -1957,8 +2055,21 @@
}
if (CC_LIKELY(mixerStatus == MIXER_TRACKS_READY)) {
+ // obtain the presentation timestamp of the next output buffer
+ int64_t pts;
+ status_t status = INVALID_OPERATION;
+
+ if (NULL != mOutput->stream->get_next_write_timestamp) {
+ status = mOutput->stream->get_next_write_timestamp(
+ mOutput->stream, &pts);
+ }
+
+ if (status != NO_ERROR) {
+ pts = AudioBufferProvider::kInvalidPTS;
+ }
+
// mix buffers...
- mAudioMixer->process();
+ mAudioMixer->process(pts);
// increase sleep time progressively when application underrun condition clears.
// Only increase sleep time if the mixer is ready for two consecutive times to avoid
// that a steady state of alternating ready/not ready conditions keeps the sleep time
@@ -1967,7 +2078,7 @@
sleepTimeShift--;
}
sleepTime = 0;
- standbyTime = systemTime() + kStandbyTimeInNsecs;
+ standbyTime = systemTime() + mStandbyTimeInNsecs;
//TODO: delay standby when effects have a tail
} else {
// If no tracks are ready, sleep once for the duration of an output
@@ -2114,7 +2225,7 @@
ALOG_ASSERT(minFrames <= cblk->frameCount);
}
}
- if ((cblk->framesReady() >= minFrames) && track->isReady() &&
+ if ((track->framesReady() >= minFrames) && track->isReady() &&
!track->isPaused() && !track->isTerminated())
{
//ALOGV("track %d u=%08x, s=%08x [OK] on thread %p", name, cblk->user, cblk->server, this);
@@ -2184,7 +2295,7 @@
uint16_t sendLevel = cblk->getSendLevel_U4_12();
// send level comes from shared memory and so may be corrupt
- if (sendLevel >= MAX_GAIN_INT) {
+ if (sendLevel > MAX_GAIN_INT) {
ALOGV("Track send level out of range: %04X", sendLevel);
sendLevel = MAX_GAIN_INT;
}
@@ -2205,25 +2316,21 @@
}
// Convert volumes from 8.24 to 4.12 format
- int16_t left, right, aux;
// This additional clamping is needed in case chain->setVolume_l() overshot
- uint32_t v_clamped = (vl + (1 << 11)) >> 12;
- if (v_clamped > MAX_GAIN_INT) v_clamped = MAX_GAIN_INT;
- left = int16_t(v_clamped);
- v_clamped = (vr + (1 << 11)) >> 12;
- if (v_clamped > MAX_GAIN_INT) v_clamped = MAX_GAIN_INT;
- right = int16_t(v_clamped);
+ vl = (vl + (1 << 11)) >> 12;
+ if (vl > MAX_GAIN_INT) vl = MAX_GAIN_INT;
+ vr = (vr + (1 << 11)) >> 12;
+ if (vr > MAX_GAIN_INT) vr = MAX_GAIN_INT;
- if (va > MAX_GAIN_INT) va = MAX_GAIN_INT;
- aux = int16_t(va);
+ if (va > MAX_GAIN_INT) va = MAX_GAIN_INT; // va is uint32_t, so no need to check for -
// XXX: these things DON'T need to be done each time
mAudioMixer->setBufferProvider(name, track);
mAudioMixer->enable(name);
- mAudioMixer->setParameter(name, param, AudioMixer::VOLUME0, (void *)left);
- mAudioMixer->setParameter(name, param, AudioMixer::VOLUME1, (void *)right);
- mAudioMixer->setParameter(name, param, AudioMixer::AUXLEVEL, (void *)aux);
+ mAudioMixer->setParameter(name, param, AudioMixer::VOLUME0, (void *)vl);
+ mAudioMixer->setParameter(name, param, AudioMixer::VOLUME1, (void *)vr);
+ mAudioMixer->setParameter(name, param, AudioMixer::AUXLEVEL, (void *)va);
mAudioMixer->setParameter(
name,
AudioMixer::TRACK,
@@ -2577,7 +2684,6 @@
sp<Track> trackToRemove;
sp<Track> activeTrack;
nsecs_t standbyTime = systemTime();
- int8_t *curBuf;
size_t mixBufferSize = mFrameCount*mFrameSize;
uint32_t activeSleepTime = activeSleepTimeUs();
uint32_t idleSleepTime = idleSleepTimeUs();
@@ -2781,11 +2887,12 @@
if (CC_LIKELY(mixerStatus == MIXER_TRACKS_READY)) {
AudioBufferProvider::Buffer buffer;
size_t frameCount = mFrameCount;
- curBuf = (int8_t *)mMixBuffer;
+ int8_t *curBuf = (int8_t *)mMixBuffer;
// output audio to hardware
while (frameCount) {
buffer.frameCount = frameCount;
- activeTrack->getNextBuffer(&buffer);
+ activeTrack->getNextBuffer(&buffer,
+ AudioBufferProvider::kInvalidPTS);
if (CC_UNLIKELY(buffer.raw == NULL)) {
memset(curBuf, 0, frameCount * mFrameSize);
break;
@@ -3038,7 +3145,7 @@
}
}
- standbyTime = systemTime() + kStandbyTimeInNsecs;
+ standbyTime = systemTime() + mStandbyTimeInNsecs;
sleepTime = idleSleepTime;
continue;
}
@@ -3055,7 +3162,7 @@
if (CC_LIKELY(mixerStatus == MIXER_TRACKS_READY)) {
// mix buffers...
if (outputsReady(outputTracks)) {
- mAudioMixer->process();
+ mAudioMixer->process(AudioBufferProvider::kInvalidPTS);
} else {
memset(mMixBuffer, 0, mixBufferSize);
}
@@ -3092,7 +3199,7 @@
// enable changes in effect chain
unlockEffectChains(effectChains);
- standbyTime = systemTime() + kStandbyTimeInNsecs;
+ standbyTime = systemTime() + mStandbyTimeInNsecs;
for (size_t i = 0; i < outputTracks.size(); i++) {
outputTracks[i]->write(mMixBuffer, writeFrames);
}
@@ -3142,7 +3249,7 @@
{
Mutex::Autolock _l(mLock);
for (size_t i = 0; i < mOutputTracks.size(); i++) {
- if (mOutputTracks[i]->thread() == (ThreadBase *)thread) {
+ if (mOutputTracks[i]->thread() == thread) {
mOutputTracks[i]->destroy();
mOutputTracks.removeAt(i);
updateWaitTime();
@@ -3443,7 +3550,8 @@
(int)mAuxBuffer);
}
-status_t AudioFlinger::PlaybackThread::Track::getNextBuffer(AudioBufferProvider::Buffer* buffer)
+status_t AudioFlinger::PlaybackThread::Track::getNextBuffer(
+ AudioBufferProvider::Buffer* buffer, int64_t pts)
{
audio_track_cblk_t* cblk = this->cblk();
uint32_t framesReady;
@@ -3484,10 +3592,14 @@
return NOT_ENOUGH_DATA;
}
+uint32_t AudioFlinger::PlaybackThread::Track::framesReady() const{
+ return mCblk->framesReady();
+}
+
bool AudioFlinger::PlaybackThread::Track::isReady() const {
if (mFillingUpStatus != FS_FILLING || isStopped() || isPausing()) return true;
- if (mCblk->framesReady() >= mCblk->frameCount ||
+ if (framesReady() >= mCblk->frameCount ||
(mCblk->flags & CBLK_FORCEREADY_MSK)) {
mFillingUpStatus = FS_FILLED;
android_atomic_and(~CBLK_FORCEREADY_MSK, &mCblk->flags);
@@ -3644,6 +3756,406 @@
mAuxBuffer = buffer;
}
+// timed audio tracks
+
+sp<AudioFlinger::PlaybackThread::TimedTrack>
+AudioFlinger::PlaybackThread::TimedTrack::create(
+ const wp<ThreadBase>& thread,
+ const sp<Client>& client,
+ audio_stream_type_t streamType,
+ uint32_t sampleRate,
+ audio_format_t format,
+ uint32_t channelMask,
+ int frameCount,
+ const sp<IMemory>& sharedBuffer,
+ int sessionId) {
+ if (!client->reserveTimedTrack())
+ return NULL;
+
+ sp<TimedTrack> track = new TimedTrack(
+ thread, client, streamType, sampleRate, format, channelMask, frameCount,
+ sharedBuffer, sessionId);
+
+ if (track == NULL) {
+ client->releaseTimedTrack();
+ return NULL;
+ }
+
+ return track;
+}
+
+AudioFlinger::PlaybackThread::TimedTrack::TimedTrack(
+ const wp<ThreadBase>& thread,
+ const sp<Client>& client,
+ audio_stream_type_t streamType,
+ uint32_t sampleRate,
+ audio_format_t format,
+ uint32_t channelMask,
+ int frameCount,
+ const sp<IMemory>& sharedBuffer,
+ int sessionId)
+ : Track(thread, client, streamType, sampleRate, format, channelMask,
+ frameCount, sharedBuffer, sessionId),
+ mTimedSilenceBuffer(NULL),
+ mTimedSilenceBufferSize(0),
+ mTimedAudioOutputOnTime(false),
+ mMediaTimeTransformValid(false)
+{
+ LocalClock lc;
+ mLocalTimeFreq = lc.getLocalFreq();
+
+ mLocalTimeToSampleTransform.a_zero = 0;
+ mLocalTimeToSampleTransform.b_zero = 0;
+ mLocalTimeToSampleTransform.a_to_b_numer = sampleRate;
+ mLocalTimeToSampleTransform.a_to_b_denom = mLocalTimeFreq;
+ LinearTransform::reduce(&mLocalTimeToSampleTransform.a_to_b_numer,
+ &mLocalTimeToSampleTransform.a_to_b_denom);
+}
+
+AudioFlinger::PlaybackThread::TimedTrack::~TimedTrack() {
+ mClient->releaseTimedTrack();
+ delete [] mTimedSilenceBuffer;
+}
+
+status_t AudioFlinger::PlaybackThread::TimedTrack::allocateTimedBuffer(
+ size_t size, sp<IMemory>* buffer) {
+
+ Mutex::Autolock _l(mTimedBufferQueueLock);
+
+ trimTimedBufferQueue_l();
+
+ // lazily initialize the shared memory heap for timed buffers
+ if (mTimedMemoryDealer == NULL) {
+ const int kTimedBufferHeapSize = 512 << 10;
+
+ mTimedMemoryDealer = new MemoryDealer(kTimedBufferHeapSize,
+ "AudioFlingerTimed");
+ if (mTimedMemoryDealer == NULL)
+ return NO_MEMORY;
+ }
+
+ sp<IMemory> newBuffer = mTimedMemoryDealer->allocate(size);
+ if (newBuffer == NULL) {
+ newBuffer = mTimedMemoryDealer->allocate(size);
+ if (newBuffer == NULL)
+ return NO_MEMORY;
+ }
+
+ *buffer = newBuffer;
+ return NO_ERROR;
+}
+
+// caller must hold mTimedBufferQueueLock
+void AudioFlinger::PlaybackThread::TimedTrack::trimTimedBufferQueue_l() {
+ int64_t mediaTimeNow;
+ {
+ Mutex::Autolock mttLock(mMediaTimeTransformLock);
+ if (!mMediaTimeTransformValid)
+ return;
+
+ int64_t targetTimeNow;
+ status_t res = (mMediaTimeTransformTarget == TimedAudioTrack::COMMON_TIME)
+ ? mCCHelper.getCommonTime(&targetTimeNow)
+ : mCCHelper.getLocalTime(&targetTimeNow);
+
+ if (OK != res)
+ return;
+
+ if (!mMediaTimeTransform.doReverseTransform(targetTimeNow,
+ &mediaTimeNow)) {
+ return;
+ }
+ }
+
+ size_t trimIndex;
+ for (trimIndex = 0; trimIndex < mTimedBufferQueue.size(); trimIndex++) {
+ if (mTimedBufferQueue[trimIndex].pts() > mediaTimeNow)
+ break;
+ }
+
+ if (trimIndex) {
+ mTimedBufferQueue.removeItemsAt(0, trimIndex);
+ }
+}
+
+status_t AudioFlinger::PlaybackThread::TimedTrack::queueTimedBuffer(
+ const sp<IMemory>& buffer, int64_t pts) {
+
+ {
+ Mutex::Autolock mttLock(mMediaTimeTransformLock);
+ if (!mMediaTimeTransformValid)
+ return INVALID_OPERATION;
+ }
+
+ Mutex::Autolock _l(mTimedBufferQueueLock);
+
+ mTimedBufferQueue.add(TimedBuffer(buffer, pts));
+
+ return NO_ERROR;
+}
+
+status_t AudioFlinger::PlaybackThread::TimedTrack::setMediaTimeTransform(
+ const LinearTransform& xform, TimedAudioTrack::TargetTimeline target) {
+
+ ALOGV("%s az=%lld bz=%lld n=%d d=%u tgt=%d", __PRETTY_FUNCTION__,
+ xform.a_zero, xform.b_zero, xform.a_to_b_numer, xform.a_to_b_denom,
+ target);
+
+ if (!(target == TimedAudioTrack::LOCAL_TIME ||
+ target == TimedAudioTrack::COMMON_TIME)) {
+ return BAD_VALUE;
+ }
+
+ Mutex::Autolock lock(mMediaTimeTransformLock);
+ mMediaTimeTransform = xform;
+ mMediaTimeTransformTarget = target;
+ mMediaTimeTransformValid = true;
+
+ return NO_ERROR;
+}
+
+#define min(a, b) ((a) < (b) ? (a) : (b))
+
+// implementation of getNextBuffer for tracks whose buffers have timestamps
+status_t AudioFlinger::PlaybackThread::TimedTrack::getNextBuffer(
+ AudioBufferProvider::Buffer* buffer, int64_t pts)
+{
+ if (pts == AudioBufferProvider::kInvalidPTS) {
+ buffer->raw = 0;
+ buffer->frameCount = 0;
+ return INVALID_OPERATION;
+ }
+
+ // get ahold of the output stream that these samples will be written to
+ sp<ThreadBase> thread = mThread.promote();
+ if (thread == NULL) {
+ buffer->raw = 0;
+ buffer->frameCount = 0;
+ return INVALID_OPERATION;
+ }
+ PlaybackThread* playbackThread = static_cast<PlaybackThread*>(thread.get());
+
+ Mutex::Autolock _l(mTimedBufferQueueLock);
+
+ while (true) {
+
+ // if we have no timed buffers, then fail
+ if (mTimedBufferQueue.isEmpty()) {
+ buffer->raw = 0;
+ buffer->frameCount = 0;
+ return NOT_ENOUGH_DATA;
+ }
+
+ TimedBuffer& head = mTimedBufferQueue.editItemAt(0);
+
+ // calculate the PTS of the head of the timed buffer queue expressed in
+ // local time
+ int64_t headLocalPTS;
+ {
+ Mutex::Autolock mttLock(mMediaTimeTransformLock);
+
+ assert(mMediaTimeTransformValid);
+
+ if (mMediaTimeTransform.a_to_b_denom == 0) {
+ // the transform represents a pause, so yield silence
+ timedYieldSilence(buffer->frameCount, buffer);
+ return NO_ERROR;
+ }
+
+ int64_t transformedPTS;
+ if (!mMediaTimeTransform.doForwardTransform(head.pts(),
+ &transformedPTS)) {
+ // the transform failed. this shouldn't happen, but if it does
+ // then just drop this buffer
+ ALOGW("timedGetNextBuffer transform failed");
+ buffer->raw = 0;
+ buffer->frameCount = 0;
+ mTimedBufferQueue.removeAt(0);
+ return NO_ERROR;
+ }
+
+ if (mMediaTimeTransformTarget == TimedAudioTrack::COMMON_TIME) {
+ if (OK != mCCHelper.commonTimeToLocalTime(transformedPTS,
+ &headLocalPTS)) {
+ buffer->raw = 0;
+ buffer->frameCount = 0;
+ return INVALID_OPERATION;
+ }
+ } else {
+ headLocalPTS = transformedPTS;
+ }
+ }
+
+ // adjust the head buffer's PTS to reflect the portion of the head buffer
+ // that has already been consumed
+ int64_t effectivePTS = headLocalPTS +
+ ((head.position() / mCblk->frameSize) * mLocalTimeFreq / sampleRate());
+
+ // Calculate the delta in samples between the head of the input buffer
+ // queue and the start of the next output buffer that will be written.
+ // If the transformation fails because of over or underflow, it means
+ // that the sample's position in the output stream is so far out of
+ // whack that it should just be dropped.
+ int64_t sampleDelta;
+ if (llabs(effectivePTS - pts) >= (static_cast<int64_t>(1) << 31)) {
+ ALOGV("*** head buffer is too far from PTS: dropped buffer");
+ mTimedBufferQueue.removeAt(0);
+ continue;
+ }
+ if (!mLocalTimeToSampleTransform.doForwardTransform(
+ (effectivePTS - pts) << 32, &sampleDelta)) {
+ ALOGV("*** too late during sample rate transform: dropped buffer");
+ mTimedBufferQueue.removeAt(0);
+ continue;
+ }
+
+ ALOGV("*** %s head.pts=%lld head.pos=%d pts=%lld sampleDelta=[%d.%08x]",
+ __PRETTY_FUNCTION__, head.pts(), head.position(), pts,
+ static_cast<int32_t>((sampleDelta >= 0 ? 0 : 1) + (sampleDelta >> 32)),
+ static_cast<uint32_t>(sampleDelta & 0xFFFFFFFF));
+
+ // if the delta between the ideal placement for the next input sample and
+ // the current output position is within this threshold, then we will
+ // concatenate the next input samples to the previous output
+ const int64_t kSampleContinuityThreshold =
+ (static_cast<int64_t>(sampleRate()) << 32) / 10;
+
+ // if this is the first buffer of audio that we're emitting from this track
+ // then it should be almost exactly on time.
+ const int64_t kSampleStartupThreshold = 1LL << 32;
+
+ if ((mTimedAudioOutputOnTime && llabs(sampleDelta) <= kSampleContinuityThreshold) ||
+ (!mTimedAudioOutputOnTime && llabs(sampleDelta) <= kSampleStartupThreshold)) {
+ // the next input is close enough to being on time, so concatenate it
+ // with the last output
+ timedYieldSamples(buffer);
+
+ ALOGV("*** on time: head.pos=%d frameCount=%u", head.position(), buffer->frameCount);
+ return NO_ERROR;
+ } else if (sampleDelta > 0) {
+ // the gap between the current output position and the proper start of
+ // the next input sample is too big, so fill it with silence
+ uint32_t framesUntilNextInput = (sampleDelta + 0x80000000) >> 32;
+
+ timedYieldSilence(framesUntilNextInput, buffer);
+ ALOGV("*** silence: frameCount=%u", buffer->frameCount);
+ return NO_ERROR;
+ } else {
+ // the next input sample is late
+ uint32_t lateFrames = static_cast<uint32_t>(-((sampleDelta + 0x80000000) >> 32));
+ size_t onTimeSamplePosition =
+ head.position() + lateFrames * mCblk->frameSize;
+
+ if (onTimeSamplePosition > head.buffer()->size()) {
+ // all the remaining samples in the head are too late, so
+ // drop it and move on
+ ALOGV("*** too late: dropped buffer");
+ mTimedBufferQueue.removeAt(0);
+ continue;
+ } else {
+ // skip over the late samples
+ head.setPosition(onTimeSamplePosition);
+
+ // yield the available samples
+ timedYieldSamples(buffer);
+
+ ALOGV("*** late: head.pos=%d frameCount=%u", head.position(), buffer->frameCount);
+ return NO_ERROR;
+ }
+ }
+ }
+}
+
+// Yield samples from the timed buffer queue head up to the given output
+// buffer's capacity.
+//
+// Caller must hold mTimedBufferQueueLock
+void AudioFlinger::PlaybackThread::TimedTrack::timedYieldSamples(
+ AudioBufferProvider::Buffer* buffer) {
+
+ const TimedBuffer& head = mTimedBufferQueue[0];
+
+ buffer->raw = (static_cast<uint8_t*>(head.buffer()->pointer()) +
+ head.position());
+
+ uint32_t framesLeftInHead = ((head.buffer()->size() - head.position()) /
+ mCblk->frameSize);
+ size_t framesRequested = buffer->frameCount;
+ buffer->frameCount = min(framesLeftInHead, framesRequested);
+
+ mTimedAudioOutputOnTime = true;
+}
+
+// Yield samples of silence up to the given output buffer's capacity
+//
+// Caller must hold mTimedBufferQueueLock
+void AudioFlinger::PlaybackThread::TimedTrack::timedYieldSilence(
+ uint32_t numFrames, AudioBufferProvider::Buffer* buffer) {
+
+ // lazily allocate a buffer filled with silence
+ if (mTimedSilenceBufferSize < numFrames * mCblk->frameSize) {
+ delete [] mTimedSilenceBuffer;
+ mTimedSilenceBufferSize = numFrames * mCblk->frameSize;
+ mTimedSilenceBuffer = new uint8_t[mTimedSilenceBufferSize];
+ memset(mTimedSilenceBuffer, 0, mTimedSilenceBufferSize);
+ }
+
+ buffer->raw = mTimedSilenceBuffer;
+ size_t framesRequested = buffer->frameCount;
+ buffer->frameCount = min(numFrames, framesRequested);
+
+ mTimedAudioOutputOnTime = false;
+}
+
+void AudioFlinger::PlaybackThread::TimedTrack::releaseBuffer(
+ AudioBufferProvider::Buffer* buffer) {
+
+ Mutex::Autolock _l(mTimedBufferQueueLock);
+
+ // If the buffer which was just released is part of the buffer at the head
+ // of the queue, be sure to update the amt of the buffer which has been
+ // consumed. If the buffer being returned is not part of the head of the
+ // queue, its either because the buffer is part of the silence buffer, or
+ // because the head of the timed queue was trimmed after the mixer called
+ // getNextBuffer but before the mixer called releaseBuffer.
+ if ((buffer->raw != mTimedSilenceBuffer) && mTimedBufferQueue.size()) {
+ TimedBuffer& head = mTimedBufferQueue.editItemAt(0);
+
+ void* start = head.buffer()->pointer();
+ void* end = head.buffer()->pointer() + head.buffer()->size();
+
+ if ((buffer->raw >= start) && (buffer->raw <= end)) {
+ head.setPosition(head.position() +
+ (buffer->frameCount * mCblk->frameSize));
+ if (static_cast<size_t>(head.position()) >= head.buffer()->size()) {
+ mTimedBufferQueue.removeAt(0);
+ }
+ }
+ }
+
+ buffer->raw = 0;
+ buffer->frameCount = 0;
+}
+
+uint32_t AudioFlinger::PlaybackThread::TimedTrack::framesReady() const {
+ Mutex::Autolock _l(mTimedBufferQueueLock);
+
+ uint32_t frames = 0;
+ for (size_t i = 0; i < mTimedBufferQueue.size(); i++) {
+ const TimedBuffer& tb = mTimedBufferQueue[i];
+ frames += (tb.buffer()->size() - tb.position()) / mCblk->frameSize;
+ }
+
+ return frames;
+}
+
+AudioFlinger::PlaybackThread::TimedTrack::TimedBuffer::TimedBuffer()
+ : mPTS(0), mPosition(0) {}
+
+AudioFlinger::PlaybackThread::TimedTrack::TimedBuffer::TimedBuffer(
+ const sp<IMemory>& buffer, int64_t pts)
+ : mBuffer(buffer), mPTS(pts), mPosition(0) {}
+
// ----------------------------------------------------------------------------
// RecordTrack constructor must be called with AudioFlinger::mLock held
@@ -3680,7 +4192,7 @@
}
}
-status_t AudioFlinger::RecordThread::RecordTrack::getNextBuffer(AudioBufferProvider::Buffer* buffer)
+status_t AudioFlinger::RecordThread::RecordTrack::getNextBuffer(AudioBufferProvider::Buffer* buffer, int64_t pts)
{
audio_track_cblk_t* cblk = this->cblk();
uint32_t framesAvail;
@@ -3985,10 +4497,9 @@
void AudioFlinger::PlaybackThread::OutputTrack::clearBufferQueue()
{
size_t size = mBufferQueue.size();
- Buffer *pBuffer;
for (size_t i = 0; i < size; i++) {
- pBuffer = mBufferQueue.itemAt(i);
+ Buffer *pBuffer = mBufferQueue.itemAt(i);
delete [] pBuffer->mBuffer;
delete pBuffer;
}
@@ -4002,7 +4513,8 @@
mAudioFlinger(audioFlinger),
// FIXME should be a "k" constant not hard-coded, in .h or ro. property, see 4 lines below
mMemoryDealer(new MemoryDealer(1024*1024, "AudioFlinger::Client")),
- mPid(pid)
+ mPid(pid),
+ mTimedTrackCount(0)
{
// 1 MB of address space is good for 32 tracks, 8 buffers each, 4 KB/buffer
}
@@ -4018,6 +4530,31 @@
return mMemoryDealer;
}
+// Reserve one of the limited slots for a timed audio track associated
+// with this client
+bool AudioFlinger::Client::reserveTimedTrack()
+{
+ const int kMaxTimedTracksPerClient = 4;
+
+ Mutex::Autolock _l(mTimedTrackLock);
+
+ if (mTimedTrackCount >= kMaxTimedTracksPerClient) {
+ ALOGW("can not create timed track - pid %d has exceeded the limit",
+ mPid);
+ return false;
+ }
+
+ mTimedTrackCount++;
+ return true;
+}
+
+// Release a slot for a timed audio track
+void AudioFlinger::Client::releaseTimedTrack()
+{
+ Mutex::Autolock _l(mTimedTrackLock);
+ mTimedTrackCount--;
+}
+
// ----------------------------------------------------------------------------
AudioFlinger::NotificationClient::NotificationClient(const sp<AudioFlinger>& audioFlinger,
@@ -4034,9 +4571,7 @@
void AudioFlinger::NotificationClient::binderDied(const wp<IBinder>& who)
{
sp<NotificationClient> keep(this);
- {
- mAudioFlinger->removeNotificationClient(mPid);
- }
+ mAudioFlinger->removeNotificationClient(mPid);
}
// ----------------------------------------------------------------------------
@@ -4084,6 +4619,38 @@
return mTrack->attachAuxEffect(EffectId);
}
+status_t AudioFlinger::TrackHandle::allocateTimedBuffer(size_t size,
+ sp<IMemory>* buffer) {
+ if (!mTrack->isTimedTrack())
+ return INVALID_OPERATION;
+
+ PlaybackThread::TimedTrack* tt =
+ reinterpret_cast<PlaybackThread::TimedTrack*>(mTrack.get());
+ return tt->allocateTimedBuffer(size, buffer);
+}
+
+status_t AudioFlinger::TrackHandle::queueTimedBuffer(const sp<IMemory>& buffer,
+ int64_t pts) {
+ if (!mTrack->isTimedTrack())
+ return INVALID_OPERATION;
+
+ PlaybackThread::TimedTrack* tt =
+ reinterpret_cast<PlaybackThread::TimedTrack*>(mTrack.get());
+ return tt->queueTimedBuffer(buffer, pts);
+}
+
+status_t AudioFlinger::TrackHandle::setMediaTimeTransform(
+ const LinearTransform& xform, int target) {
+
+ if (!mTrack->isTimedTrack())
+ return INVALID_OPERATION;
+
+ PlaybackThread::TimedTrack* tt =
+ reinterpret_cast<PlaybackThread::TimedTrack*>(mTrack.get());
+ return tt->setMediaTimeTransform(
+ xform, static_cast<TimedAudioTrack::TargetTimeline>(target));
+}
+
status_t AudioFlinger::TrackHandle::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
@@ -4313,7 +4880,8 @@
}
buffer.frameCount = mFrameCount;
- if (CC_LIKELY(mActiveTrack->getNextBuffer(&buffer) == NO_ERROR)) {
+ if (CC_LIKELY(mActiveTrack->getNextBuffer(
+ &buffer, AudioBufferProvider::kInvalidPTS) == NO_ERROR)) {
size_t framesOut = buffer.frameCount;
if (mResampler == NULL) {
// no resampling
@@ -4591,7 +5159,7 @@
return NO_ERROR;
}
-status_t AudioFlinger::RecordThread::getNextBuffer(AudioBufferProvider::Buffer* buffer)
+status_t AudioFlinger::RecordThread::getNextBuffer(AudioBufferProvider::Buffer* buffer, int64_t pts)
{
size_t framesReq = buffer->frameCount;
size_t framesReady = mFrameCount - mRsmpInIndex;
@@ -4979,8 +5547,7 @@
}
}
}
- void *param2 = NULL;
- audioConfigChanged_l(AudioSystem::OUTPUT_CLOSED, output, param2);
+ audioConfigChanged_l(AudioSystem::OUTPUT_CLOSED, output, NULL);
mPlaybackThreads.removeItem(output);
}
thread->exit();
@@ -5124,8 +5691,7 @@
}
ALOGV("closeInput() %d", input);
- void *param2 = NULL;
- audioConfigChanged_l(AudioSystem::INPUT_CLOSED, input, param2);
+ audioConfigChanged_l(AudioSystem::INPUT_CLOSED, input, NULL);
mRecordThreads.removeItem(input);
}
thread->exit();
@@ -5157,8 +5723,7 @@
for (size_t i = 0; i < mPlaybackThreads.size(); i++) {
PlaybackThread *thread = mPlaybackThreads.valueAt(i).get();
- if (thread != dstThread &&
- thread->type() != ThreadBase::DIRECT) {
+ if (thread != dstThread && thread->type() != ThreadBase::DIRECT) {
MixerThread *srcThread = (MixerThread *)thread;
srcThread->setStreamValid(stream, false);
srcThread->invalidateTracks(stream);
@@ -5281,33 +5846,20 @@
// checkPlaybackThread_l() must be called with AudioFlinger::mLock held
AudioFlinger::PlaybackThread *AudioFlinger::checkPlaybackThread_l(audio_io_handle_t output) const
{
- PlaybackThread *thread = NULL;
- if (mPlaybackThreads.indexOfKey(output) >= 0) {
- thread = (PlaybackThread *)mPlaybackThreads.valueFor(output).get();
- }
- return thread;
+ return mPlaybackThreads.valueFor(output).get();
}
// checkMixerThread_l() must be called with AudioFlinger::mLock held
AudioFlinger::MixerThread *AudioFlinger::checkMixerThread_l(audio_io_handle_t output) const
{
PlaybackThread *thread = checkPlaybackThread_l(output);
- if (thread != NULL) {
- if (thread->type() == ThreadBase::DIRECT) {
- thread = NULL;
- }
- }
- return (MixerThread *)thread;
+ return thread != NULL && thread->type() != ThreadBase::DIRECT ? (MixerThread *) thread : NULL;
}
// checkRecordThread_l() must be called with AudioFlinger::mLock held
AudioFlinger::RecordThread *AudioFlinger::checkRecordThread_l(audio_io_handle_t input) const
{
- RecordThread *thread = NULL;
- if (mRecordThreads.indexOfKey(input) >= 0) {
- thread = (RecordThread *)mRecordThreads.valueFor(input).get();
- }
- return thread;
+ return mRecordThreads.valueFor(input).get();
}
uint32_t AudioFlinger::nextUniqueId()
@@ -5670,10 +6222,7 @@
goto Exit;
}
// Only Pre processor effects are allowed on input threads and only on input threads
- if ((mType == RECORD &&
- (desc->flags & EFFECT_FLAG_TYPE_MASK) != EFFECT_FLAG_TYPE_PRE_PROC) ||
- (mType != RECORD &&
- (desc->flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC)) {
+ if ((mType == RECORD) != ((desc->flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC)) {
ALOGW("createEffect_l() effect %s (flags %08x) created on wrong thread type %d",
desc->name, desc->flags, mType);
lStatus = BAD_VALUE;
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index aa0b8f8..50712cf 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -22,11 +22,14 @@
#include <sys/types.h>
#include <limits.h>
+#include <common_time/cc_helper.h>
+
#include <media/IAudioFlinger.h>
#include <media/IAudioFlingerClient.h>
#include <media/IAudioTrack.h>
#include <media/IAudioRecord.h>
#include <media/AudioSystem.h>
+#include <media/AudioTrack.h>
#include <utils/Atomic.h>
#include <utils/Errors.h>
@@ -55,7 +58,7 @@
// ----------------------------------------------------------------------------
-static const nsecs_t kStandbyTimeInNsecs = seconds(3);
+static const nsecs_t kDefaultStandbyTimeInNsecs = seconds(3);
class AudioFlinger :
public BinderService<AudioFlinger>,
@@ -78,6 +81,7 @@
uint32_t flags,
const sp<IMemory>& sharedBuffer,
audio_io_handle_t output,
+ bool isTimed,
int *sessionId,
status_t *status);
@@ -102,6 +106,7 @@
virtual status_t setMasterMute(bool muted);
virtual float masterVolume() const;
+ virtual float masterVolumeSW() const;
virtual bool masterMute() const;
virtual status_t setStreamVolume(audio_stream_type_t stream, float value,
@@ -206,6 +211,8 @@
audio_hw_device_t* findSuitableHwDev_l(uint32_t devices);
void purgeStaleEffects_l();
+ static nsecs_t mStandbyTimeInNsecs;
+
// Internal dump utilites.
status_t dumpPermissionDenial(int fd, const Vector<String16>& args);
status_t dumpClients(int fd, const Vector<String16>& args);
@@ -220,12 +227,18 @@
pid_t pid() const { return mPid; }
sp<AudioFlinger> audioFlinger() const { return mAudioFlinger; }
+ bool reserveTimedTrack();
+ void releaseTimedTrack();
+
private:
Client(const Client&);
Client& operator = (const Client&);
const sp<AudioFlinger> mAudioFlinger;
const sp<MemoryDealer> mMemoryDealer;
const pid_t mPid;
+
+ Mutex mTimedTrackLock;
+ int mTimedTrackCount;
};
// --- Notification Client ---
@@ -333,7 +346,9 @@
TrackBase(const TrackBase&);
TrackBase& operator = (const TrackBase&);
- virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer) = 0;
+ virtual status_t getNextBuffer(
+ AudioBufferProvider::Buffer* buffer,
+ int64_t pts) = 0;
virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer);
audio_format_t format() const {
@@ -609,7 +624,6 @@
int16_t *mainBuffer() const { return mMainBuffer; }
int auxEffectId() const { return mAuxEffectId; }
-
protected:
friend class ThreadBase;
friend class TrackHandle;
@@ -620,7 +634,11 @@
Track(const Track&);
Track& operator = (const Track&);
- virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer);
+ virtual status_t getNextBuffer(
+ AudioBufferProvider::Buffer* buffer,
+ int64_t pts);
+ virtual uint32_t framesReady() const;
+
bool isMuted() const { return mMute; }
bool isPausing() const {
return mState == PAUSING;
@@ -636,6 +654,8 @@
return (mStreamType == AUDIO_STREAM_CNT);
}
+ virtual bool isTimedTrack() const { return false; }
+
// we don't really need a lock for these
volatile bool mMute;
// FILLED state is used for suppressing volume ramp at begin of playing
@@ -652,6 +672,79 @@
bool mHasVolumeController;
}; // end of Track
+ class TimedTrack : public Track {
+ public:
+ static sp<TimedTrack> create(const wp<ThreadBase>& thread,
+ const sp<Client>& client,
+ audio_stream_type_t streamType,
+ uint32_t sampleRate,
+ audio_format_t format,
+ uint32_t channelMask,
+ int frameCount,
+ const sp<IMemory>& sharedBuffer,
+ int sessionId);
+ ~TimedTrack();
+
+ class TimedBuffer {
+ public:
+ TimedBuffer();
+ TimedBuffer(const sp<IMemory>& buffer, int64_t pts);
+ const sp<IMemory>& buffer() const { return mBuffer; }
+ int64_t pts() const { return mPTS; }
+ int position() const { return mPosition; }
+ void setPosition(int pos) { mPosition = pos; }
+ private:
+ sp<IMemory> mBuffer;
+ int64_t mPTS;
+ int mPosition;
+ };
+
+ virtual bool isTimedTrack() const { return true; }
+
+ virtual uint32_t framesReady() const;
+
+ virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer,
+ int64_t pts);
+ virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer);
+ void timedYieldSamples(AudioBufferProvider::Buffer* buffer);
+ void timedYieldSilence(uint32_t numFrames,
+ AudioBufferProvider::Buffer* buffer);
+
+ status_t allocateTimedBuffer(size_t size,
+ sp<IMemory>* buffer);
+ status_t queueTimedBuffer(const sp<IMemory>& buffer,
+ int64_t pts);
+ status_t setMediaTimeTransform(const LinearTransform& xform,
+ TimedAudioTrack::TargetTimeline target);
+ void trimTimedBufferQueue_l();
+
+ private:
+ TimedTrack(const wp<ThreadBase>& thread,
+ const sp<Client>& client,
+ audio_stream_type_t streamType,
+ uint32_t sampleRate,
+ audio_format_t format,
+ uint32_t channelMask,
+ int frameCount,
+ const sp<IMemory>& sharedBuffer,
+ int sessionId);
+
+ uint64_t mLocalTimeFreq;
+ LinearTransform mLocalTimeToSampleTransform;
+ sp<MemoryDealer> mTimedMemoryDealer;
+ Vector<TimedBuffer> mTimedBufferQueue;
+ uint8_t* mTimedSilenceBuffer;
+ uint32_t mTimedSilenceBufferSize;
+ mutable Mutex mTimedBufferQueueLock;
+ bool mTimedAudioOutputOnTime;
+ CCHelper mCCHelper;
+
+ Mutex mMediaTimeTransformLock;
+ LinearTransform mMediaTimeTransform;
+ bool mMediaTimeTransformValid;
+ TimedAudioTrack::TargetTimeline mMediaTimeTransformTarget;
+ };
+
// playback track
class OutputTrack : public Track {
@@ -673,7 +766,7 @@
virtual status_t start(pid_t tid);
virtual void stop();
bool write(int16_t* data, uint32_t frames);
- bool bufferQueueEmpty() const { return (mBufferQueue.size() == 0) ? true : false; }
+ bool bufferQueueEmpty() const { return mBufferQueue.size() == 0; }
bool isActive() const { return mActive; }
const wp<ThreadBase>& thread() const { return mThread; }
@@ -726,6 +819,7 @@
int frameCount,
const sp<IMemory>& sharedBuffer,
int sessionId,
+ bool isTimed,
status_t *status);
AudioStreamOut* getOutput() const;
@@ -900,8 +994,8 @@
uint32_t nextUniqueId();
status_t moveEffectChain_l(int sessionId,
- AudioFlinger::PlaybackThread *srcThread,
- AudioFlinger::PlaybackThread *dstThread,
+ PlaybackThread *srcThread,
+ PlaybackThread *dstThread,
bool reRegister);
PlaybackThread *primaryPlaybackThread_l();
uint32_t primaryOutputDevice_l();
@@ -920,6 +1014,12 @@
virtual void mute(bool);
virtual void pause();
virtual status_t attachAuxEffect(int effectId);
+ virtual status_t allocateTimedBuffer(size_t size,
+ sp<IMemory>* buffer);
+ virtual status_t queueTimedBuffer(const sp<IMemory>& buffer,
+ int64_t pts);
+ virtual status_t setMediaTimeTransform(const LinearTransform& xform,
+ int target);
virtual status_t onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
private:
@@ -967,7 +1067,9 @@
RecordTrack(const RecordTrack&);
RecordTrack& operator = (const RecordTrack&);
- virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer);
+ virtual status_t getNextBuffer(
+ AudioBufferProvider::Buffer* buffer,
+ int64_t pts);
bool mOverflow;
};
@@ -1004,7 +1106,8 @@
AudioStreamIn* clearInput();
virtual audio_stream_t* stream();
- virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer);
+ virtual status_t getNextBuffer(AudioBufferProvider::Buffer* buffer,
+ int64_t pts);
virtual void releaseBuffer(AudioBufferProvider::Buffer* buffer);
virtual bool checkForNewParameters_l();
virtual String8 getParameters(const String8& keys);
@@ -1401,6 +1504,28 @@
friend class RecordThread;
friend class PlaybackThread;
+ enum master_volume_support {
+ // MVS_NONE:
+ // Audio HAL has no support for master volume, either setting or
+ // getting. All master volume control must be implemented in SW by the
+ // AudioFlinger mixing core.
+ MVS_NONE,
+
+ // MVS_SETONLY:
+ // Audio HAL has support for setting master volume, but not for getting
+ // master volume (original HAL design did not include a getter).
+ // AudioFlinger needs to keep track of the last set master volume in
+ // addition to needing to set an initial, default, master volume at HAL
+ // load time.
+ MVS_SETONLY,
+
+ // MVS_FULL:
+ // Audio HAL has support both for setting and getting master volume.
+ // AudioFlinger should send all set and get master volume requests
+ // directly to the HAL.
+ MVS_FULL,
+ };
+
mutable Mutex mLock;
DefaultKeyedVector< pid_t, wp<Client> > mClients; // see ~Client()
@@ -1429,6 +1554,7 @@
AUDIO_SET_VOICE_VOLUME,
AUDIO_SET_PARAMETER,
AUDIO_HW_GET_INPUT_BUFFER_SIZE,
+ AUDIO_HW_GET_MASTER_VOLUME,
};
mutable hardware_call_state mHardwareStatus; // for dump only
@@ -1439,6 +1565,8 @@
// both are protected by mLock
float mMasterVolume;
+ float mMasterVolumeSW;
+ master_volume_support mMasterVolumeSupportLvl;
bool mMasterMute;
DefaultKeyedVector< audio_io_handle_t, sp<RecordThread> > mRecordThreads;
@@ -1451,7 +1579,8 @@
// protected by mLock
Vector<AudioSessionRef*> mAudioSessionRefs;
- float masterVolume_l() const { return mMasterVolume; }
+ float masterVolume_l() const;
+ float masterVolumeSW_l() const { return mMasterVolumeSW; }
bool masterMute_l() const { return mMasterMute; }
private:
diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp
index cb7678b..020d62a 100644
--- a/services/audioflinger/AudioMixer.cpp
+++ b/services/audioflinger/AudioMixer.cpp
@@ -33,6 +33,8 @@
#include <system/audio.h>
#include <audio_utils/primitives.h>
+#include <common_time/local_clock.h>
+#include <common_time/cc_helper.h>
#include "AudioMixer.h"
@@ -45,6 +47,9 @@
{
// AudioMixer is not yet capable of multi-channel beyond stereo
assert(2 == MAX_NUM_CHANNELS);
+
+ LocalClock lc;
+
mState.enabledTracks= 0;
mState.needsChanged = 0;
mState.frameCount = frameCount;
@@ -80,6 +85,7 @@
t->sampleRate = mSampleRate;
t->mainBuffer = NULL;
t->auxBuffer = NULL;
+ t->localTimeFreq = lc.getLocalFreq();
t++;
}
}
@@ -251,6 +257,7 @@
}
break;
case AUXLEVEL:
+ //assert(0 <= valueInt && valueInt <= MAX_GAIN_INT);
if (track.auxLevel != valueInt) {
ALOGV("setParameter(VOLUME, AUXLEVEL: %04x)", valueInt);
track.prevAuxLevel = track.auxLevel << 16;
@@ -289,6 +296,7 @@
if (resampler == NULL) {
resampler = AudioResampler::create(
format, channelCount, devSampleRate);
+ resampler->setLocalTimeFreq(localTimeFreq);
}
return true;
}
@@ -333,13 +341,13 @@
-void AudioMixer::process()
+void AudioMixer::process(int64_t pts)
{
- mState.hook(&mState);
+ mState.hook(&mState, pts);
}
-void AudioMixer::process__validate(state_t* state)
+void AudioMixer::process__validate(state_t* state, int64_t pts)
{
ALOGW_IF(!state->needsChanged,
"in process__validate() but nothing's invalid");
@@ -443,7 +451,7 @@
countActiveTracks, state->enabledTracks,
all16BitsStereoNoResample, resampling, volumeRamp);
- state->hook(state);
+ state->hook(state, pts);
// Now that the volume ramp has been done, set optimal state and
// track hooks for subsequent mixer process
@@ -549,7 +557,7 @@
}
t->prevVolume[0] = vl;
t->prevVolume[1] = vr;
- t->adjustVolumeRamp((aux != NULL));
+ t->adjustVolumeRamp(aux != NULL);
}
void AudioMixer::volumeStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux)
@@ -558,7 +566,7 @@
const int16_t vr = t->volume[1];
if (CC_UNLIKELY(aux != NULL)) {
- const int16_t va = (int16_t)t->auxLevel;
+ const int16_t va = t->auxLevel;
do {
int16_t l = (int16_t)(*temp++ >> 12);
int16_t r = (int16_t)(*temp++ >> 12);
@@ -757,7 +765,7 @@
}
// no-op case
-void AudioMixer::process__nop(state_t* state)
+void AudioMixer::process__nop(state_t* state, int64_t pts)
{
uint32_t e0 = state->enabledTracks;
size_t bufSize = state->frameCount * sizeof(int16_t) * MAX_NUM_CHANNELS;
@@ -787,7 +795,9 @@
size_t outFrames = state->frameCount;
while (outFrames) {
t1.buffer.frameCount = outFrames;
- t1.bufferProvider->getNextBuffer(&t1.buffer);
+ int64_t outputPTS = calculateOutputPTS(
+ t1, pts, state->frameCount - outFrames);
+ t1.bufferProvider->getNextBuffer(&t1.buffer, outputPTS);
if (t1.buffer.raw == NULL) break;
outFrames -= t1.buffer.frameCount;
t1.bufferProvider->releaseBuffer(&t1.buffer);
@@ -797,7 +807,7 @@
}
// generic code without resampling
-void AudioMixer::process__genericNoResampling(state_t* state)
+void AudioMixer::process__genericNoResampling(state_t* state, int64_t pts)
{
int32_t outTemp[BLOCKSIZE * MAX_NUM_CHANNELS] __attribute__((aligned(32)));
@@ -809,7 +819,7 @@
e0 &= ~(1<<i);
track_t& t = state->tracks[i];
t.buffer.frameCount = state->frameCount;
- t.bufferProvider->getNextBuffer(&t.buffer);
+ t.bufferProvider->getNextBuffer(&t.buffer, pts);
t.frameCount = t.buffer.frameCount;
t.in = t.buffer.raw;
// t.in == NULL can happen if the track was flushed just after having
@@ -853,7 +863,7 @@
while (outFrames) {
size_t inFrames = (t.frameCount > outFrames)?outFrames:t.frameCount;
if (inFrames) {
- (t.hook)(&t, outTemp + (BLOCKSIZE-outFrames)*MAX_NUM_CHANNELS, inFrames, state->resampleTemp, aux);
+ t.hook(&t, outTemp + (BLOCKSIZE-outFrames)*MAX_NUM_CHANNELS, inFrames, state->resampleTemp, aux);
t.frameCount -= inFrames;
outFrames -= inFrames;
if (CC_UNLIKELY(aux != NULL)) {
@@ -863,7 +873,9 @@
if (t.frameCount == 0 && outFrames) {
t.bufferProvider->releaseBuffer(&t.buffer);
t.buffer.frameCount = (state->frameCount - numFrames) - (BLOCKSIZE - outFrames);
- t.bufferProvider->getNextBuffer(&t.buffer);
+ int64_t outputPTS = calculateOutputPTS(
+ t, pts, numFrames + (BLOCKSIZE - outFrames));
+ t.bufferProvider->getNextBuffer(&t.buffer, outputPTS);
t.in = t.buffer.raw;
if (t.in == NULL) {
enabledTracks &= ~(1<<i);
@@ -892,7 +904,7 @@
// generic code with resampling
-void AudioMixer::process__genericResampling(state_t* state)
+void AudioMixer::process__genericResampling(state_t* state, int64_t pts)
{
// this const just means that local variable outTemp doesn't change
int32_t* const outTemp = state->outputTemp;
@@ -932,14 +944,16 @@
// acquire/release the buffers because it's done by
// the resampler.
if ((t.needs & NEEDS_RESAMPLE__MASK) == NEEDS_RESAMPLE_ENABLED) {
- (t.hook)(&t, outTemp, numFrames, state->resampleTemp, aux);
+ t.resampler->setPTS(pts);
+ t.hook(&t, outTemp, numFrames, state->resampleTemp, aux);
} else {
size_t outFrames = 0;
while (outFrames < numFrames) {
t.buffer.frameCount = numFrames - outFrames;
- t.bufferProvider->getNextBuffer(&t.buffer);
+ int64_t outputPTS = calculateOutputPTS(t, pts, outFrames);
+ t.bufferProvider->getNextBuffer(&t.buffer, outputPTS);
t.in = t.buffer.raw;
// t.in == NULL can happen if the track was flushed just after having
// been enabled for mixing.
@@ -948,7 +962,7 @@
if (CC_UNLIKELY(aux != NULL)) {
aux += outFrames;
}
- (t.hook)(&t, outTemp + outFrames*MAX_NUM_CHANNELS, t.buffer.frameCount, state->resampleTemp, aux);
+ t.hook(&t, outTemp + outFrames*MAX_NUM_CHANNELS, t.buffer.frameCount, state->resampleTemp, aux);
outFrames += t.buffer.frameCount;
t.bufferProvider->releaseBuffer(&t.buffer);
}
@@ -959,7 +973,8 @@
}
// one track, 16 bits stereo without resampling is the most common case
-void AudioMixer::process__OneTrack16BitsStereoNoResampling(state_t* state)
+void AudioMixer::process__OneTrack16BitsStereoNoResampling(state_t* state,
+ int64_t pts)
{
// This method is only called when state->enabledTracks has exactly
// one bit set. The asserts below would verify this, but are commented out
@@ -979,7 +994,8 @@
const uint32_t vrl = t.volumeRL;
while (numFrames) {
b.frameCount = numFrames;
- t.bufferProvider->getNextBuffer(&b);
+ int64_t outputPTS = calculateOutputPTS(t, pts, out - t.mainBuffer);
+ t.bufferProvider->getNextBuffer(&b, outputPTS);
const int16_t *in = b.i16;
// in == NULL can happen if the track was flushed just after having
@@ -1023,7 +1039,8 @@
// 2 tracks is also a common case
// NEVER used in current implementation of process__validate()
// only use if the 2 tracks have the same output buffer
-void AudioMixer::process__TwoTracks16BitsStereoNoResampling(state_t* state)
+void AudioMixer::process__TwoTracks16BitsStereoNoResampling(state_t* state,
+ int64_t pts)
{
int i;
uint32_t en = state->enabledTracks;
@@ -1057,7 +1074,9 @@
if (frameCount0 == 0) {
b0.frameCount = numFrames;
- t0.bufferProvider->getNextBuffer(&b0);
+ int64_t outputPTS = calculateOutputPTS(t0, pts,
+ out - t0.mainBuffer);
+ t0.bufferProvider->getNextBuffer(&b0, outputPTS);
if (b0.i16 == NULL) {
if (buff == NULL) {
buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount];
@@ -1071,7 +1090,9 @@
}
if (frameCount1 == 0) {
b1.frameCount = numFrames;
- t1.bufferProvider->getNextBuffer(&b1);
+ int64_t outputPTS = calculateOutputPTS(t1, pts,
+ out - t0.mainBuffer);
+ t1.bufferProvider->getNextBuffer(&b1, outputPTS);
if (b1.i16 == NULL) {
if (buff == NULL) {
buff = new int16_t[MAX_NUM_CHANNELS * state->frameCount];
@@ -1117,5 +1138,14 @@
}
#endif
+int64_t AudioMixer::calculateOutputPTS(const track_t& t, int64_t basePTS,
+ int outputFrameIndex)
+{
+ if (AudioBufferProvider::kInvalidPTS == basePTS)
+ return AudioBufferProvider::kInvalidPTS;
+
+ return basePTS + ((outputFrameIndex * t.localTimeFreq) / t.sampleRate);
+}
+
// ----------------------------------------------------------------------------
}; // namespace android
diff --git a/services/audioflinger/AudioMixer.h b/services/audioflinger/AudioMixer.h
index c956918..b210212 100644
--- a/services/audioflinger/AudioMixer.h
+++ b/services/audioflinger/AudioMixer.h
@@ -79,7 +79,7 @@
void setParameter(int name, int target, int param, void *value);
void setBufferProvider(int name, AudioBufferProvider* bufferProvider);
- void process();
+ void process(int64_t pts);
uint32_t trackNames() const { return mTrackNames; }
@@ -114,7 +114,6 @@
struct state_t;
struct track_t;
- typedef void (*mix_t)(state_t* state);
typedef void (*hook_t)(track_t* t, int32_t* output, size_t numOutFrames, int32_t* temp, int32_t* aux);
static const int BLOCKSIZE = 16; // 4 cache lines
@@ -128,30 +127,46 @@
int32_t prevVolume[MAX_NUM_CHANNELS];
+ // 16-byte boundary
+
int32_t volumeInc[MAX_NUM_CHANNELS];
- int32_t auxLevel;
int32_t auxInc;
int32_t prevAuxLevel;
+ // 16-byte boundary
+
+ int16_t auxLevel; // 0 <= auxLevel <= MAX_GAIN_INT, but signed for mul performance
uint16_t frameCount;
- uint8_t channelCount : 4;
- uint8_t enabled : 1;
- uint8_t reserved0 : 3;
- uint8_t format;
- uint32_t channelMask;
+ uint8_t channelCount; // 1 or 2, redundant with (needs & NEEDS_CHANNEL_COUNT__MASK)
+ uint8_t format; // always 16
+ uint16_t enabled; // actually bool
+ uint32_t channelMask; // currently under-used
AudioBufferProvider* bufferProvider;
- mutable AudioBufferProvider::Buffer buffer;
+
+ // 16-byte boundary
+
+ mutable AudioBufferProvider::Buffer buffer; // 8 bytes
hook_t hook;
const void* in; // current location in buffer
+ // 16-byte boundary
+
AudioResampler* resampler;
uint32_t sampleRate;
int32_t* mainBuffer;
int32_t* auxBuffer;
+ // 16-byte boundary
+
+ uint64_t localTimeFreq;
+
+ int64_t padding;
+
+ // 16-byte boundary
+
bool setResampler(uint32_t sampleRate, uint32_t devSampleRate);
bool doesResample() const { return resampler != NULL; }
void resetResampler() { if (resampler != NULL) resampler->reset(); }
@@ -165,7 +180,7 @@
uint32_t enabledTracks;
uint32_t needsChanged;
size_t frameCount;
- mix_t hook;
+ void (*hook)(state_t* state, int64_t pts); // one of process__*, never NULL
int32_t *outputTemp;
int32_t *resampleTemp;
int32_t reserved[2];
@@ -187,14 +202,19 @@
static void volumeRampStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux);
static void volumeStereo(track_t* t, int32_t* out, size_t frameCount, int32_t* temp, int32_t* aux);
- static void process__validate(state_t* state);
- static void process__nop(state_t* state);
- static void process__genericNoResampling(state_t* state);
- static void process__genericResampling(state_t* state);
- static void process__OneTrack16BitsStereoNoResampling(state_t* state);
+ static void process__validate(state_t* state, int64_t pts);
+ static void process__nop(state_t* state, int64_t pts);
+ static void process__genericNoResampling(state_t* state, int64_t pts);
+ static void process__genericResampling(state_t* state, int64_t pts);
+ static void process__OneTrack16BitsStereoNoResampling(state_t* state,
+ int64_t pts);
#if 0
- static void process__TwoTracks16BitsStereoNoResampling(state_t* state);
+ static void process__TwoTracks16BitsStereoNoResampling(state_t* state,
+ int64_t pts);
#endif
+
+ static int64_t calculateOutputPTS(const track_t& t, int64_t basePTS,
+ int outputFrameIndex);
};
// ----------------------------------------------------------------------------
diff --git a/services/audioflinger/AudioPolicyService.cpp b/services/audioflinger/AudioPolicyService.cpp
index 041b5a8..987b039 100644
--- a/services/audioflinger/AudioPolicyService.cpp
+++ b/services/audioflinger/AudioPolicyService.cpp
@@ -116,19 +116,7 @@
// release audio pre processing resources
for (size_t i = 0; i < mInputSources.size(); i++) {
- InputSourceDesc *source = mInputSources.valueAt(i);
- Vector <EffectDesc *> effects = source->mEffects;
- for (size_t j = 0; j < effects.size(); j++) {
- delete effects[j]->mName;
- Vector <effect_param_t *> params = effects[j]->mParams;
- for (size_t k = 0; k < params.size(); k++) {
- delete params[k];
- }
- params.clear();
- delete effects[j];
- }
- effects.clear();
- delete source;
+ delete mInputSources.valueAt(i);
}
mInputSources.clear();
@@ -616,8 +604,7 @@
{
Vector<sp<AudioEffect> > fxVector = inputDesc->mEffects;
for (size_t i = 0; i < fxVector.size(); i++) {
- sp<AudioEffect> fx = fxVector.itemAt(i);
- fx->setEnabled(enabled);
+ fxVector.itemAt(i)->setEnabled(enabled);
}
}
@@ -1243,7 +1230,7 @@
node = node->next;
continue;
}
- EffectDesc *effect = new EffectDesc(*effects[i]);
+ EffectDesc *effect = new EffectDesc(*effects[i]); // deep copy
loadEffectParameters(node, effect->mParams);
ALOGV("loadInputSource() adding effect %s uuid %08x", effect->mName, effect->mUuid.timeLow);
source->mEffects.add(effect);
@@ -1294,11 +1281,7 @@
ALOGW("loadEffect() invalid uuid %s", node->value);
return NULL;
}
- EffectDesc *effect = new EffectDesc();
- effect->mName = strdup(root->name);
- memcpy(&effect->mUuid, &uuid, sizeof(effect_uuid_t));
-
- return effect;
+ return new EffectDesc(root->name, uuid);
}
status_t AudioPolicyService::loadEffects(cnode *root, Vector <EffectDesc *>& effects)
diff --git a/services/audioflinger/AudioPolicyService.h b/services/audioflinger/AudioPolicyService.h
index fdaf576..679fd30 100644
--- a/services/audioflinger/AudioPolicyService.h
+++ b/services/audioflinger/AudioPolicyService.h
@@ -233,8 +233,33 @@
class EffectDesc {
public:
- EffectDesc() {}
- virtual ~EffectDesc() {}
+ EffectDesc(const char *name, const effect_uuid_t& uuid) :
+ mName(strdup(name)),
+ mUuid(uuid) { }
+ EffectDesc(const EffectDesc& orig) :
+ mName(strdup(orig.mName)),
+ mUuid(orig.mUuid) {
+ // deep copy mParams
+ for (size_t k = 0; k < orig.mParams.size(); k++) {
+ effect_param_t *origParam = orig.mParams[k];
+ // psize and vsize are rounded up to an int boundary for allocation
+ size_t origSize = sizeof(effect_param_t) +
+ ((origParam->psize + 3) & ~3) +
+ ((origParam->vsize + 3) & ~3);
+ effect_param_t *dupParam = (effect_param_t *) malloc(origSize);
+ memcpy(dupParam, origParam, origSize);
+ // This works because the param buffer allocation is also done by
+ // multiples of 4 bytes originally. In theory we should memcpy only
+ // the actual param size, that is without rounding vsize.
+ mParams.add(dupParam);
+ }
+ }
+ /*virtual*/ ~EffectDesc() {
+ free(mName);
+ for (size_t k = 0; k < mParams.size(); k++) {
+ free(mParams[k]);
+ }
+ }
char *mName;
effect_uuid_t mUuid;
Vector <effect_param_t *> mParams;
@@ -243,7 +268,11 @@
class InputSourceDesc {
public:
InputSourceDesc() {}
- virtual ~InputSourceDesc() {}
+ /*virtual*/ ~InputSourceDesc() {
+ for (size_t j = 0; j < mEffects.size(); j++) {
+ delete mEffects[j];
+ }
+ }
Vector <EffectDesc *> mEffects;
};
diff --git a/services/audioflinger/AudioResampler.cpp b/services/audioflinger/AudioResampler.cpp
index 9486b9c..398ba0b 100644
--- a/services/audioflinger/AudioResampler.cpp
+++ b/services/audioflinger/AudioResampler.cpp
@@ -122,7 +122,8 @@
int32_t sampleRate) :
mBitDepth(bitDepth), mChannelCount(inChannelCount),
mSampleRate(sampleRate), mInSampleRate(sampleRate), mInputIndex(0),
- mPhaseFraction(0) {
+ mPhaseFraction(0), mLocalTimeFreq(0),
+ mPTS(AudioBufferProvider::kInvalidPTS) {
// sanity check on format
if ((bitDepth != 16) ||(inChannelCount < 1) || (inChannelCount > 2)) {
ALOGE("Unsupported sample format, %d bits, %d channels", bitDepth,
@@ -150,6 +151,23 @@
mVolume[1] = right;
}
+void AudioResampler::setLocalTimeFreq(uint64_t freq) {
+ mLocalTimeFreq = freq;
+}
+
+void AudioResampler::setPTS(int64_t pts) {
+ mPTS = pts;
+}
+
+int64_t AudioResampler::calculateOutputPTS(int outputFrameIndex) {
+
+ if (mPTS == AudioBufferProvider::kInvalidPTS) {
+ return AudioBufferProvider::kInvalidPTS;
+ } else {
+ return mPTS + ((outputFrameIndex * mLocalTimeFreq) / mSampleRate);
+ }
+}
+
void AudioResampler::reset() {
mInputIndex = 0;
mPhaseFraction = 0;
@@ -196,7 +214,8 @@
// buffer is empty, fetch a new one
while (mBuffer.frameCount == 0) {
mBuffer.frameCount = inFrameCount;
- provider->getNextBuffer(&mBuffer);
+ provider->getNextBuffer(&mBuffer,
+ calculateOutputPTS(outputIndex / 2));
if (mBuffer.raw == NULL) {
goto resampleStereo16_exit;
}
@@ -290,7 +309,8 @@
// buffer is empty, fetch a new one
while (mBuffer.frameCount == 0) {
mBuffer.frameCount = inFrameCount;
- provider->getNextBuffer(&mBuffer);
+ provider->getNextBuffer(&mBuffer,
+ calculateOutputPTS(outputIndex / 2));
if (mBuffer.raw == NULL) {
mInputIndex = inputIndex;
mPhaseFraction = phaseFraction;
diff --git a/services/audioflinger/AudioResampler.h b/services/audioflinger/AudioResampler.h
index c23016e..9deb796 100644
--- a/services/audioflinger/AudioResampler.h
+++ b/services/audioflinger/AudioResampler.h
@@ -49,6 +49,10 @@
virtual void init() = 0;
virtual void setSampleRate(int32_t inSampleRate);
virtual void setVolume(int16_t left, int16_t right);
+ virtual void setLocalTimeFreq(uint64_t freq);
+
+ // set the PTS of the next buffer output by the resampler
+ virtual void setPTS(int64_t pts);
virtual void resample(int32_t* out, size_t outFrameCount,
AudioBufferProvider* provider) = 0;
@@ -72,6 +76,8 @@
AudioResampler(const AudioResampler&);
AudioResampler& operator=(const AudioResampler&);
+ int64_t calculateOutputPTS(int outputFrameIndex);
+
const int32_t mBitDepth;
const int32_t mChannelCount;
const int32_t mSampleRate;
@@ -85,6 +91,8 @@
size_t mInputIndex;
int32_t mPhaseIncrement;
uint32_t mPhaseFraction;
+ uint64_t mLocalTimeFreq;
+ int64_t mPTS;
};
// ----------------------------------------------------------------------------
diff --git a/services/audioflinger/AudioResamplerCubic.cpp b/services/audioflinger/AudioResamplerCubic.cpp
index c0e760e..18e59e9 100644
--- a/services/audioflinger/AudioResamplerCubic.cpp
+++ b/services/audioflinger/AudioResamplerCubic.cpp
@@ -65,7 +65,7 @@
// fetch first buffer
if (mBuffer.frameCount == 0) {
mBuffer.frameCount = inFrameCount;
- provider->getNextBuffer(&mBuffer);
+ provider->getNextBuffer(&mBuffer, mPTS);
if (mBuffer.raw == NULL)
return;
// ALOGW("New buffer: offset=%p, frames=%dn", mBuffer.raw, mBuffer.frameCount);
@@ -95,7 +95,8 @@
inputIndex = 0;
provider->releaseBuffer(&mBuffer);
mBuffer.frameCount = inFrameCount;
- provider->getNextBuffer(&mBuffer);
+ provider->getNextBuffer(&mBuffer,
+ calculateOutputPTS(outputIndex / 2));
if (mBuffer.raw == NULL)
goto save_state; // ugly, but efficient
in = mBuffer.i16;
@@ -130,7 +131,7 @@
// fetch first buffer
if (mBuffer.frameCount == 0) {
mBuffer.frameCount = inFrameCount;
- provider->getNextBuffer(&mBuffer);
+ provider->getNextBuffer(&mBuffer, mPTS);
if (mBuffer.raw == NULL)
return;
// ALOGW("New buffer: offset=%p, frames=%d", mBuffer.raw, mBuffer.frameCount);
@@ -160,7 +161,8 @@
inputIndex = 0;
provider->releaseBuffer(&mBuffer);
mBuffer.frameCount = inFrameCount;
- provider->getNextBuffer(&mBuffer);
+ provider->getNextBuffer(&mBuffer,
+ calculateOutputPTS(outputIndex / 2));
if (mBuffer.raw == NULL)
goto save_state; // ugly, but efficient
// ALOGW("New buffer: offset=%p, frames=%dn", mBuffer.raw, mBuffer.frameCount);
@@ -181,4 +183,3 @@
// ----------------------------------------------------------------------------
}
; // namespace android
-
diff --git a/services/audioflinger/AudioResamplerSinc.cpp b/services/audioflinger/AudioResamplerSinc.cpp
index 7a27b81..d373c08 100644
--- a/services/audioflinger/AudioResamplerSinc.cpp
+++ b/services/audioflinger/AudioResamplerSinc.cpp
@@ -203,7 +203,8 @@
// buffer is empty, fetch a new one
while (mBuffer.frameCount == 0) {
mBuffer.frameCount = inFrameCount;
- provider->getNextBuffer(&mBuffer);
+ provider->getNextBuffer(&mBuffer,
+ calculateOutputPTS(outputIndex / 2));
if (mBuffer.raw == NULL) {
goto resample_exit;
}
@@ -354,4 +355,3 @@
// ----------------------------------------------------------------------------
}; // namespace android
-
diff --git a/services/common_time/Android.mk b/services/common_time/Android.mk
new file mode 100644
index 0000000..e534d49
--- /dev/null
+++ b/services/common_time/Android.mk
@@ -0,0 +1,34 @@
+LOCAL_PATH:= $(call my-dir)
+
+#
+# common_time_service
+#
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := \
+ common_clock_service.cpp \
+ common_time_config_service.cpp \
+ common_time_server.cpp \
+ common_time_server_api.cpp \
+ common_time_server_packets.cpp \
+ clock_recovery.cpp \
+ common_clock.cpp \
+ main.cpp
+
+# Uncomment to enable vesbose logging and debug service.
+#TIME_SERVICE_DEBUG=true
+ifeq ($(TIME_SERVICE_DEBUG), true)
+LOCAL_SRC_FILES += diag_thread.cpp
+LOCAL_CFLAGS += -DTIME_SERVICE_DEBUG
+endif
+
+LOCAL_SHARED_LIBRARIES := \
+ libbinder \
+ libcommon_time_client \
+ libutils
+
+LOCAL_MODULE_TAGS := optional
+LOCAL_MODULE := common_time
+
+include $(BUILD_EXECUTABLE)
diff --git a/services/common_time/clock_recovery.cpp b/services/common_time/clock_recovery.cpp
new file mode 100644
index 0000000..6c98d32
--- /dev/null
+++ b/services/common_time/clock_recovery.cpp
@@ -0,0 +1,321 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+/*
+ * A service that exchanges time synchronization information between
+ * a master that defines a timeline and clients that follow the timeline.
+ */
+
+#define __STDC_LIMIT_MACROS
+#define LOG_TAG "common_time"
+#include <utils/Log.h>
+#include <stdint.h>
+
+#include <common_time/local_clock.h>
+#include <assert.h>
+
+#include "clock_recovery.h"
+#include "common_clock.h"
+#ifdef TIME_SERVICE_DEBUG
+#include "diag_thread.h"
+#endif
+
+// Define log macro so we can make LOGV into LOGE when we are exclusively
+// debugging this code.
+#ifdef TIME_SERVICE_DEBUG
+#define LOG_TS ALOGE
+#else
+#define LOG_TS ALOGV
+#endif
+
+namespace android {
+
+ClockRecoveryLoop::ClockRecoveryLoop(LocalClock* local_clock,
+ CommonClock* common_clock) {
+ assert(NULL != local_clock);
+ assert(NULL != common_clock);
+
+ local_clock_ = local_clock;
+ common_clock_ = common_clock;
+
+ local_clock_can_slew_ = local_clock_->initCheck() &&
+ (local_clock_->setLocalSlew(0) == OK);
+
+ reset(true, true);
+
+#ifdef TIME_SERVICE_DEBUG
+ diag_thread_ = new DiagThread(common_clock_, local_clock_);
+ if (diag_thread_ != NULL) {
+ status_t res = diag_thread_->startWorkThread();
+ if (res != OK)
+ ALOGW("Failed to start A@H clock recovery diagnostic thread.");
+ } else
+ ALOGW("Failed to allocate diagnostic thread.");
+#endif
+}
+
+ClockRecoveryLoop::~ClockRecoveryLoop() {
+#ifdef TIME_SERVICE_DEBUG
+ diag_thread_->stopWorkThread();
+#endif
+}
+
+// Constants.
+const float ClockRecoveryLoop::dT = 1.0;
+const float ClockRecoveryLoop::Kc = 1.0f;
+const float ClockRecoveryLoop::Ti = 15.0f;
+const float ClockRecoveryLoop::Tf = 0.05;
+const float ClockRecoveryLoop::bias_Fc = 0.01;
+const float ClockRecoveryLoop::bias_RC = (dT / (2 * 3.14159f * bias_Fc));
+const float ClockRecoveryLoop::bias_Alpha = (dT / (bias_RC + dT));
+const int64_t ClockRecoveryLoop::panic_thresh_ = 50000;
+const int64_t ClockRecoveryLoop::control_thresh_ = 10000;
+const float ClockRecoveryLoop::COmin = -100.0f;
+const float ClockRecoveryLoop::COmax = 100.0f;
+
+void ClockRecoveryLoop::reset(bool position, bool frequency) {
+ Mutex::Autolock lock(&lock_);
+ reset_l(position, frequency);
+}
+
+uint32_t ClockRecoveryLoop::findMinRTTNdx(DisciplineDataPoint* data,
+ uint32_t count) {
+ uint32_t min_rtt = 0;
+ for (uint32_t i = 1; i < count; ++i)
+ if (data[min_rtt].rtt > data[i].rtt)
+ min_rtt = i;
+
+ return min_rtt;
+}
+
+bool ClockRecoveryLoop::pushDisciplineEvent(int64_t local_time,
+ int64_t nominal_common_time,
+ int64_t rtt) {
+ Mutex::Autolock lock(&lock_);
+
+ int64_t local_common_time = 0;
+ common_clock_->localToCommon(local_time, &local_common_time);
+ int64_t raw_delta = nominal_common_time - local_common_time;
+
+#ifdef TIME_SERVICE_DEBUG
+ ALOGE("local=%lld, common=%lld, delta=%lld, rtt=%lld\n",
+ local_common_time, nominal_common_time,
+ raw_delta, rtt);
+#endif
+
+ // If we have not defined a basis for common time, then we need to use these
+ // initial points to do so. In order to avoid significant initial error
+ // from a particularly bad startup data point, we collect the first N data
+ // points and choose the best of them before moving on.
+ if (!common_clock_->isValid()) {
+ if (startup_filter_wr_ < kStartupFilterSize) {
+ DisciplineDataPoint& d = startup_filter_data_[startup_filter_wr_];
+ d.local_time = local_time;
+ d.nominal_common_time = nominal_common_time;
+ d.rtt = rtt;
+ startup_filter_wr_++;
+ }
+
+ if (startup_filter_wr_ == kStartupFilterSize) {
+ uint32_t min_rtt = findMinRTTNdx(startup_filter_data_,
+ kStartupFilterSize);
+
+ common_clock_->setBasis(
+ startup_filter_data_[min_rtt].local_time,
+ startup_filter_data_[min_rtt].nominal_common_time);
+ }
+
+ return true;
+ }
+
+ int64_t observed_common;
+ int64_t delta;
+ float delta_f, dCO;
+ int32_t correction_cur;
+
+ if (OK != common_clock_->localToCommon(local_time, &observed_common)) {
+ // Since we just checked to make certain that this conversion was valid,
+ // and no one else in the system should be messing with it, if this
+ // conversion is suddenly invalid, it is a good reason to panic.
+ ALOGE("Failed to convert local time to common time in %s:%d",
+ __PRETTY_FUNCTION__, __LINE__);
+ return false;
+ }
+
+ // Implement a filter which should match NTP filtering behavior when a
+ // client is associated with only one peer of lower stratum. Basically,
+ // always use the best of the N last data points, where best is defined as
+ // lowest round trip time. NTP uses an N of 8; we use a value of 6.
+ //
+ // TODO(johngro) : experiment with other filter strategies. The goal here
+ // is to mitigate the effects of high RTT data points which typically have
+ // large asymmetries in the TX/RX legs. Downside of the existing NTP
+ // approach (particularly because of the PID controller we are using to
+ // produce the control signal from the filtered data) are that the rate at
+ // which discipline events are actually acted upon becomes irregular and can
+ // become drawn out (the time between actionable event can go way up). If
+ // the system receives a strong high quality data point, the proportional
+ // component of the controller can produce a strong correction which is left
+ // in place for too long causing overshoot. In addition, the integral
+ // component of the system currently is an approximation based on the
+ // assumption of a more or less homogeneous sampling of the error. Its
+ // unclear what the effect of undermining this assumption would be right
+ // now.
+
+ // Two ideas which come to mind immediately would be to...
+ // 1) Keep a history of more data points (32 or so) and ignore data points
+ // whose RTT is more than a certain number of standard deviations outside
+ // of the norm.
+ // 2) Eliminate the PID controller portion of this system entirely.
+ // Instead, move to a system which uses a very wide filter (128 data
+ // points or more) with a sum-of-least-squares line fitting approach to
+ // tracking the long term drift. This would take the place of the I
+ // component in the current PID controller. Also use a much more narrow
+ // outlier-rejector filter (as described in #1) to drive a short term
+ // correction factor similar to the P component of the PID controller.
+ assert(filter_wr_ < kFilterSize);
+ filter_data_[filter_wr_].local_time = local_time;
+ filter_data_[filter_wr_].observed_common_time = observed_common;
+ filter_data_[filter_wr_].nominal_common_time = nominal_common_time;
+ filter_data_[filter_wr_].rtt = rtt;
+ filter_data_[filter_wr_].point_used = false;
+ uint32_t current_point = filter_wr_;
+ filter_wr_ = (filter_wr_ + 1) % kFilterSize;
+ if (!filter_wr_)
+ filter_full_ = true;
+
+ uint32_t scan_end = filter_full_ ? kFilterSize : filter_wr_;
+ uint32_t min_rtt = findMinRTTNdx(filter_data_, scan_end);
+ // We only use packets with low RTTs for control. If the packet RTT
+ // is less than the panic threshold, we can probably eat the jitter with the
+ // control loop. Otherwise, take the packet only if it better than all
+ // of the packets we have in the history. That way we try to track
+ // something, even if it is noisy.
+ if (current_point == min_rtt || rtt < control_thresh_) {
+ delta_f = delta = nominal_common_time - observed_common;
+
+ // Compute the error then clamp to the panic threshold. If we ever
+ // exceed this amt of error, its time to panic and reset the system.
+ // Given that the error in the measurement of the error could be as
+ // high as the RTT of the data point, we don't actually panic until
+ // the implied error (delta) is greater than the absolute panic
+ // threashold plus the RTT. IOW - we don't panic until we are
+ // absoluely sure that our best case sync is worse than the absolute
+ // panic threshold.
+ int64_t effective_panic_thresh = panic_thresh_ + rtt;
+ if ((delta > effective_panic_thresh) ||
+ (delta < -effective_panic_thresh)) {
+ // PANIC!!!
+ reset_l(false, true);
+ return false;
+ }
+
+ } else {
+ // We do not have a good packet to look at, but we also do not want to
+ // free-run the clock at some crazy slew rate. So we guess the
+ // trajectory of the clock based on the last controller output and the
+ // estimated bias of our clock against the master.
+ // The net effect of this is that CO == CObias after some extended
+ // period of no feedback.
+ delta_f = last_delta_f_ - dT*(CO - CObias);
+ delta = delta_f;
+ }
+
+ // Velocity form PI control equation.
+ dCO = Kc * (1.0f + dT/Ti) * delta_f - Kc * last_delta_f_;
+ CO += dCO * Tf; // Filter CO by applying gain <1 here.
+
+ // Save error terms for later.
+ last_delta_f_ = delta_f;
+ last_delta_ = delta;
+
+ // Clamp CO to +/- 100ppm.
+ if (CO < COmin)
+ CO = COmin;
+ else if (CO > COmax)
+ CO = COmax;
+
+ // Update the controller bias.
+ CObias = bias_Alpha * CO + (1.0f - bias_Alpha) * lastCObias;
+ lastCObias = CObias;
+
+ // Convert PPM to 16-bit int range. Add some guard band (-0.01) so we
+ // don't get fp weirdness.
+ correction_cur = CO * 327.66;
+
+ // If there was a change in the amt of correction to use, update the
+ // system.
+ if (correction_cur_ != correction_cur) {
+ correction_cur_ = correction_cur;
+ applySlew();
+ }
+
+ LOG_TS("clock_loop %lld %f %f %f %d\n", raw_delta, delta_f, CO, CObias, correction_cur);
+
+#ifdef TIME_SERVICE_DEBUG
+ diag_thread_->pushDisciplineEvent(
+ local_time,
+ observed_common,
+ nominal_common_time,
+ correction_cur,
+ rtt);
+#endif
+
+ return true;
+}
+
+int32_t ClockRecoveryLoop::getLastErrorEstimate() {
+ Mutex::Autolock lock(&lock_);
+
+ if (last_delta_valid_)
+ return last_delta_;
+ else
+ return ICommonClock::kErrorEstimateUnknown;
+}
+
+void ClockRecoveryLoop::reset_l(bool position, bool frequency) {
+ assert(NULL != common_clock_);
+
+ if (position) {
+ common_clock_->resetBasis();
+ startup_filter_wr_ = 0;
+ }
+
+ if (frequency) {
+ last_delta_valid_ = false;
+ last_delta_ = 0;
+ last_delta_f_ = 0.0;
+ correction_cur_ = 0x0;
+ CO = 0.0f;
+ lastCObias = CObias = 0.0f;
+ applySlew();
+ }
+
+ filter_wr_ = 0;
+ filter_full_ = false;
+}
+
+void ClockRecoveryLoop::applySlew() {
+ if (local_clock_can_slew_) {
+ local_clock_->setLocalSlew(correction_cur_);
+ } else {
+ // The SW clock recovery implemented by the common clock class expects
+ // values expressed in PPM. CO is in ppm.
+ common_clock_->setSlew(local_clock_->getLocalTime(), CO);
+ }
+}
+
+} // namespace android
diff --git a/services/common_time/clock_recovery.h b/services/common_time/clock_recovery.h
new file mode 100644
index 0000000..b7362be
--- /dev/null
+++ b/services/common_time/clock_recovery.h
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#ifndef __CLOCK_RECOVERY_H__
+#define __CLOCK_RECOVERY_H__
+
+#include <stdint.h>
+#include <common_time/ICommonClock.h>
+#include <utils/LinearTransform.h>
+#include <utils/threads.h>
+
+#ifdef TIME_SERVICE_DEBUG
+#include "diag_thread.h"
+#endif
+
+namespace android {
+
+class CommonClock;
+class LocalClock;
+
+class ClockRecoveryLoop {
+ public:
+ ClockRecoveryLoop(LocalClock* local_clock, CommonClock* common_clock);
+ ~ClockRecoveryLoop();
+
+ void reset(bool position, bool frequency);
+ bool pushDisciplineEvent(int64_t local_time,
+ int64_t nominal_common_time,
+ int64_t data_point_rtt);
+ int32_t getLastErrorEstimate();
+
+ private:
+
+ // Tuned using the "Good Gain" method.
+ // See:
+ // http://techteach.no/publications/books/dynamics_and_control/tuning_pid_controller.pdf
+
+ // Controller period (1Hz for now).
+ static const float dT;
+
+ // Controller gain, positive and unitless. Larger values converge faster,
+ // but can cause instability.
+ static const float Kc;
+
+ // Integral reset time. Smaller values cause loop to track faster, but can
+ // also cause instability.
+ static const float Ti;
+
+ // Controller output filter time constant. Range (0-1). Smaller values make
+ // output smoother, but slow convergence.
+ static const float Tf;
+
+ // Low-pass filter for bias tracker.
+ static const float bias_Fc; // HZ
+ static const float bias_RC; // Computed in constructor.
+ static const float bias_Alpha; // Computed inconstructor.
+
+ // The maximum allowed error (as indicated by a pushDisciplineEvent) before
+ // we panic.
+ static const int64_t panic_thresh_;
+
+ // The maximum allowed error rtt time for packets to be used for control
+ // feedback, unless the packet is the best in recent memory.
+ static const int64_t control_thresh_;
+
+ typedef struct {
+ int64_t local_time;
+ int64_t observed_common_time;
+ int64_t nominal_common_time;
+ int64_t rtt;
+ bool point_used;
+ } DisciplineDataPoint;
+
+ static uint32_t findMinRTTNdx(DisciplineDataPoint* data, uint32_t count);
+
+ void reset_l(bool position, bool frequency);
+ void applySlew();
+
+ // The local clock HW abstraction we use as the basis for common time.
+ LocalClock* local_clock_;
+ bool local_clock_can_slew_;
+
+ // The common clock we end up controlling along with the lock used to
+ // serialize operations.
+ CommonClock* common_clock_;
+ Mutex lock_;
+
+ // parameters maintained while running and reset during a reset
+ // of the frequency correction.
+ bool last_delta_valid_;
+ int32_t last_delta_;
+ float last_delta_f_;
+ int32_t integrated_error_;
+ int32_t correction_cur_;
+
+ // Contoller Output.
+ float CO;
+
+ // Bias tracking for trajectory estimation.
+ float CObias;
+ float lastCObias;
+
+ // Controller output bounds. The controller will not try to
+ // slew faster that +/-100ppm offset from center per interation.
+ static const float COmin;
+ static const float COmax;
+
+ // State kept for filtering the discipline data.
+ static const uint32_t kFilterSize = 16;
+ DisciplineDataPoint filter_data_[kFilterSize];
+ uint32_t filter_wr_;
+ bool filter_full_;
+
+ static const uint32_t kStartupFilterSize = 4;
+ DisciplineDataPoint startup_filter_data_[kStartupFilterSize];
+ uint32_t startup_filter_wr_;
+
+#ifdef TIME_SERVICE_DEBUG
+ sp<DiagThread> diag_thread_;
+#endif
+};
+
+} // namespace android
+
+#endif // __CLOCK_RECOVERY_H__
diff --git a/services/common_time/common_clock.cpp b/services/common_time/common_clock.cpp
new file mode 100644
index 0000000..c9eb388
--- /dev/null
+++ b/services/common_time/common_clock.cpp
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#define __STDC_LIMIT_MACROS
+
+#define LOG_TAG "common_time"
+#include <utils/Log.h>
+
+#include <stdint.h>
+
+#include <utils/Errors.h>
+#include <utils/LinearTransform.h>
+
+#include "common_clock.h"
+
+namespace android {
+
+CommonClock::CommonClock() {
+ cur_slew_ = 0;
+ cur_trans_valid_ = false;
+
+ cur_trans_.a_zero = 0;
+ cur_trans_.b_zero = 0;
+ cur_trans_.a_to_b_numer = local_to_common_freq_numer_ = 1;
+ cur_trans_.a_to_b_denom = local_to_common_freq_denom_ = 1;
+ duration_trans_ = cur_trans_;
+}
+
+bool CommonClock::init(uint64_t local_freq) {
+ Mutex::Autolock lock(&lock_);
+
+ if (!local_freq)
+ return false;
+
+ uint64_t numer = kCommonFreq;
+ uint64_t denom = local_freq;
+
+ LinearTransform::reduce(&numer, &denom);
+ if ((numer > UINT32_MAX) || (denom > UINT32_MAX)) {
+ ALOGE("Overflow in CommonClock::init while trying to reduce %lld/%lld",
+ kCommonFreq, local_freq);
+ return false;
+ }
+
+ cur_trans_.a_to_b_numer = local_to_common_freq_numer_ =
+ static_cast<uint32_t>(numer);
+ cur_trans_.a_to_b_denom = local_to_common_freq_denom_ =
+ static_cast<uint32_t>(denom);
+ duration_trans_ = cur_trans_;
+
+ return true;
+}
+
+status_t CommonClock::localToCommon(int64_t local, int64_t *common_out) const {
+ Mutex::Autolock lock(&lock_);
+
+ if (!cur_trans_valid_)
+ return INVALID_OPERATION;
+
+ if (!cur_trans_.doForwardTransform(local, common_out))
+ return INVALID_OPERATION;
+
+ return OK;
+}
+
+status_t CommonClock::commonToLocal(int64_t common, int64_t *local_out) const {
+ Mutex::Autolock lock(&lock_);
+
+ if (!cur_trans_valid_)
+ return INVALID_OPERATION;
+
+ if (!cur_trans_.doReverseTransform(common, local_out))
+ return INVALID_OPERATION;
+
+ return OK;
+}
+
+int64_t CommonClock::localDurationToCommonDuration(int64_t localDur) const {
+ int64_t ret;
+ duration_trans_.doForwardTransform(localDur, &ret);
+ return ret;
+}
+
+void CommonClock::setBasis(int64_t local, int64_t common) {
+ Mutex::Autolock lock(&lock_);
+
+ cur_trans_.a_zero = local;
+ cur_trans_.b_zero = common;
+ cur_trans_valid_ = true;
+}
+
+void CommonClock::resetBasis() {
+ Mutex::Autolock lock(&lock_);
+
+ cur_trans_.a_zero = 0;
+ cur_trans_.b_zero = 0;
+ cur_trans_valid_ = false;
+}
+
+status_t CommonClock::setSlew(int64_t change_time, int32_t ppm) {
+ Mutex::Autolock lock(&lock_);
+
+ int64_t new_local_basis;
+ int64_t new_common_basis;
+
+ if (cur_trans_valid_) {
+ new_local_basis = change_time;
+ if (!cur_trans_.doForwardTransform(change_time, &new_common_basis)) {
+ ALOGE("Overflow when attempting to set slew rate to %d", ppm);
+ return INVALID_OPERATION;
+ }
+ } else {
+ new_local_basis = 0;
+ new_common_basis = 0;
+ }
+
+ cur_slew_ = ppm;
+ uint32_t n1 = local_to_common_freq_numer_;
+ uint32_t n2 = 1000000 + cur_slew_;
+
+ uint32_t d1 = local_to_common_freq_denom_;
+ uint32_t d2 = 1000000;
+
+ // n1/d1 has already been reduced, no need to do so here.
+ LinearTransform::reduce(&n1, &d2);
+ LinearTransform::reduce(&n2, &d1);
+ LinearTransform::reduce(&n2, &d2);
+
+ cur_trans_.a_zero = new_local_basis;
+ cur_trans_.b_zero = new_common_basis;
+ cur_trans_.a_to_b_numer = n1 * n2;
+ cur_trans_.a_to_b_denom = d1 * d2;
+
+ return OK;
+}
+
+} // namespace android
diff --git a/services/common_time/common_clock.h b/services/common_time/common_clock.h
new file mode 100644
index 0000000..b786fdc
--- /dev/null
+++ b/services/common_time/common_clock.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#ifndef __COMMON_CLOCK_H__
+#define __COMMON_CLOCK_H__
+
+#include <stdint.h>
+
+#include <utils/Errors.h>
+#include <utils/LinearTransform.h>
+#include <utils/threads.h>
+
+namespace android {
+
+class CommonClock {
+ public:
+ CommonClock();
+
+ bool init(uint64_t local_freq);
+
+ status_t localToCommon(int64_t local, int64_t *common_out) const;
+ status_t commonToLocal(int64_t common, int64_t *local_out) const;
+ int64_t localDurationToCommonDuration(int64_t localDur) const;
+ uint64_t getCommonFreq() const { return kCommonFreq; }
+ bool isValid() const { return cur_trans_valid_; }
+ status_t setSlew(int64_t change_time, int32_t ppm);
+ void setBasis(int64_t local, int64_t common);
+ void resetBasis();
+ private:
+ mutable Mutex lock_;
+
+ int32_t cur_slew_;
+ uint32_t local_to_common_freq_numer_;
+ uint32_t local_to_common_freq_denom_;
+
+ LinearTransform duration_trans_;
+ LinearTransform cur_trans_;
+ bool cur_trans_valid_;
+
+ static const uint64_t kCommonFreq = 1000000ull;
+};
+
+} // namespace android
+#endif // __COMMON_CLOCK_H__
diff --git a/services/common_time/common_clock_service.cpp b/services/common_time/common_clock_service.cpp
new file mode 100644
index 0000000..9ca6f35
--- /dev/null
+++ b/services/common_time/common_clock_service.cpp
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#include <common_time/local_clock.h>
+#include <utils/String8.h>
+
+#include "common_clock_service.h"
+#include "common_clock.h"
+#include "common_time_server.h"
+
+namespace android {
+
+sp<CommonClockService> CommonClockService::instantiate(
+ CommonTimeServer& timeServer) {
+ sp<CommonClockService> tcc = new CommonClockService(timeServer);
+ if (tcc == NULL)
+ return NULL;
+
+ defaultServiceManager()->addService(ICommonClock::kServiceName, tcc);
+ return tcc;
+}
+
+status_t CommonClockService::dump(int fd, const Vector<String16>& args) {
+ Mutex::Autolock lock(mRegistrationLock);
+ return mTimeServer.dumpClockInterface(fd, args, mListeners.size());
+}
+
+status_t CommonClockService::isCommonTimeValid(bool* valid,
+ uint32_t* timelineID) {
+ return mTimeServer.isCommonTimeValid(valid, timelineID);
+}
+
+status_t CommonClockService::commonTimeToLocalTime(int64_t commonTime,
+ int64_t* localTime) {
+ return mTimeServer.getCommonClock().commonToLocal(commonTime, localTime);
+}
+
+status_t CommonClockService::localTimeToCommonTime(int64_t localTime,
+ int64_t* commonTime) {
+ return mTimeServer.getCommonClock().localToCommon(localTime, commonTime);
+}
+
+status_t CommonClockService::getCommonTime(int64_t* commonTime) {
+ return localTimeToCommonTime(mTimeServer.getLocalClock().getLocalTime(), commonTime);
+}
+
+status_t CommonClockService::getCommonFreq(uint64_t* freq) {
+ *freq = mTimeServer.getCommonClock().getCommonFreq();
+ return OK;
+}
+
+status_t CommonClockService::getLocalTime(int64_t* localTime) {
+ *localTime = mTimeServer.getLocalClock().getLocalTime();
+ return OK;
+}
+
+status_t CommonClockService::getLocalFreq(uint64_t* freq) {
+ *freq = mTimeServer.getLocalClock().getLocalFreq();
+ return OK;
+}
+
+status_t CommonClockService::getEstimatedError(int32_t* estimate) {
+ *estimate = mTimeServer.getEstimatedError();
+ return OK;
+}
+
+status_t CommonClockService::getTimelineID(uint64_t* id) {
+ *id = mTimeServer.getTimelineID();
+ return OK;
+}
+
+status_t CommonClockService::getState(State* state) {
+ *state = mTimeServer.getState();
+ return OK;
+}
+
+status_t CommonClockService::getMasterAddr(struct sockaddr_storage* addr) {
+ return mTimeServer.getMasterAddr(addr);
+}
+
+status_t CommonClockService::registerListener(
+ const sp<ICommonClockListener>& listener) {
+ Mutex::Autolock lock(mRegistrationLock);
+
+ { // scoping for autolock pattern
+ Mutex::Autolock lock(mCallbackLock);
+ // check whether this is a duplicate
+ for (size_t i = 0; i < mListeners.size(); i++) {
+ if (mListeners[i]->asBinder() == listener->asBinder())
+ return ALREADY_EXISTS;
+ }
+ }
+
+ mListeners.add(listener);
+ mTimeServer.reevaluateAutoDisableState(0 != mListeners.size());
+ return listener->asBinder()->linkToDeath(this);
+}
+
+status_t CommonClockService::unregisterListener(
+ const sp<ICommonClockListener>& listener) {
+ Mutex::Autolock lock(mRegistrationLock);
+ status_t ret_val = NAME_NOT_FOUND;
+
+ { // scoping for autolock pattern
+ Mutex::Autolock lock(mCallbackLock);
+ for (size_t i = 0; i < mListeners.size(); i++) {
+ if (mListeners[i]->asBinder() == listener->asBinder()) {
+ mListeners[i]->asBinder()->unlinkToDeath(this);
+ mListeners.removeAt(i);
+ ret_val = OK;
+ break;
+ }
+ }
+ }
+
+ mTimeServer.reevaluateAutoDisableState(0 != mListeners.size());
+ return ret_val;
+}
+
+void CommonClockService::binderDied(const wp<IBinder>& who) {
+ Mutex::Autolock lock(mRegistrationLock);
+
+ { // scoping for autolock pattern
+ Mutex::Autolock lock(mCallbackLock);
+ for (size_t i = 0; i < mListeners.size(); i++) {
+ if (mListeners[i]->asBinder() == who) {
+ mListeners.removeAt(i);
+ break;
+ }
+ }
+ }
+
+ mTimeServer.reevaluateAutoDisableState(0 != mListeners.size());
+}
+
+void CommonClockService::notifyOnTimelineChanged(uint64_t timelineID) {
+ Mutex::Autolock lock(mCallbackLock);
+
+ for (size_t i = 0; i < mListeners.size(); i++) {
+ mListeners[i]->onTimelineChanged(timelineID);
+ }
+}
+
+}; // namespace android
diff --git a/services/common_time/common_clock_service.h b/services/common_time/common_clock_service.h
new file mode 100644
index 0000000..a65e398
--- /dev/null
+++ b/services/common_time/common_clock_service.h
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#include <common_time/ICommonClock.h>
+
+#ifndef ANDROID_COMMON_CLOCK_SERVICE_H
+#define ANDROID_COMMON_CLOCK_SERVICE_H
+
+namespace android {
+
+class CommonTimeServer;
+
+class CommonClockService : public BnCommonClock,
+ public android::IBinder::DeathRecipient {
+ public:
+ static sp<CommonClockService> instantiate(CommonTimeServer& timeServer);
+
+ virtual status_t dump(int fd, const Vector<String16>& args);
+
+ virtual status_t isCommonTimeValid(bool* valid, uint32_t *timelineID);
+ virtual status_t commonTimeToLocalTime(int64_t common_time,
+ int64_t* local_time);
+ virtual status_t localTimeToCommonTime(int64_t local_time,
+ int64_t* common_time);
+ virtual status_t getCommonTime(int64_t* common_time);
+ virtual status_t getCommonFreq(uint64_t* freq);
+ virtual status_t getLocalTime(int64_t* local_time);
+ virtual status_t getLocalFreq(uint64_t* freq);
+ virtual status_t getEstimatedError(int32_t* estimate);
+ virtual status_t getTimelineID(uint64_t* id);
+ virtual status_t getState(ICommonClock::State* state);
+ virtual status_t getMasterAddr(struct sockaddr_storage* addr);
+
+ virtual status_t registerListener(
+ const sp<ICommonClockListener>& listener);
+ virtual status_t unregisterListener(
+ const sp<ICommonClockListener>& listener);
+
+ void notifyOnTimelineChanged(uint64_t timelineID);
+
+ private:
+ CommonClockService(CommonTimeServer& timeServer)
+ : mTimeServer(timeServer) { };
+
+ virtual void binderDied(const wp<IBinder>& who);
+
+ CommonTimeServer& mTimeServer;
+
+ // locks used to synchronize access to the list of registered listeners.
+ // The callback lock is held whenever the list is used to perform callbacks
+ // or while the list is being modified. The registration lock used to
+ // serialize access across registerListener, unregisterListener, and
+ // binderDied.
+ //
+ // The reason for two locks is that registerListener, unregisterListener,
+ // and binderDied each call into the core service and obtain the core
+ // service thread lock when they call reevaluateAutoDisableState. The core
+ // service thread obtains the main thread lock whenever its thread is
+ // running, and sometimes needs to call notifyOnTimelineChanged which then
+ // obtains the callback lock. If callers of registration functions were
+ // holding the callback lock when they called into the core service, we
+ // would have a classic A/B, B/A ordering deadlock. To avoid this, the
+ // registration functions hold the registration lock for the duration of
+ // their call, but hold the callback lock only while they mutate the list.
+ // This way, the list's size cannot change (because of the registration
+ // lock) during the call into reevaluateAutoDisableState, but the core work
+ // thread can still safely call notifyOnTimelineChanged while holding the
+ // main thread lock.
+ Mutex mCallbackLock;
+ Mutex mRegistrationLock;
+
+ Vector<sp<ICommonClockListener> > mListeners;
+};
+
+}; // namespace android
+
+#endif // ANDROID_COMMON_CLOCK_SERVICE_H
diff --git a/services/common_time/common_time_config_service.cpp b/services/common_time/common_time_config_service.cpp
new file mode 100644
index 0000000..9585618
--- /dev/null
+++ b/services/common_time/common_time_config_service.cpp
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#include <utils/String8.h>
+
+#include "common_time_config_service.h"
+#include "common_time_server.h"
+
+namespace android {
+
+sp<CommonTimeConfigService> CommonTimeConfigService::instantiate(
+ CommonTimeServer& timeServer) {
+ sp<CommonTimeConfigService> ctcs = new CommonTimeConfigService(timeServer);
+ if (ctcs == NULL)
+ return NULL;
+
+ defaultServiceManager()->addService(ICommonTimeConfig::kServiceName, ctcs);
+ return ctcs;
+}
+
+status_t CommonTimeConfigService::dump(int fd, const Vector<String16>& args) {
+ return mTimeServer.dumpConfigInterface(fd, args);
+}
+
+status_t CommonTimeConfigService::getMasterElectionPriority(uint8_t *priority) {
+ return mTimeServer.getMasterElectionPriority(priority);
+}
+
+status_t CommonTimeConfigService::setMasterElectionPriority(uint8_t priority) {
+ return mTimeServer.setMasterElectionPriority(priority);
+}
+
+status_t CommonTimeConfigService::getMasterElectionEndpoint(
+ struct sockaddr_storage *addr) {
+ return mTimeServer.getMasterElectionEndpoint(addr);
+}
+
+status_t CommonTimeConfigService::setMasterElectionEndpoint(
+ const struct sockaddr_storage *addr) {
+ return mTimeServer.setMasterElectionEndpoint(addr);
+}
+
+status_t CommonTimeConfigService::getMasterElectionGroupId(uint64_t *id) {
+ return mTimeServer.getMasterElectionGroupId(id);
+}
+
+status_t CommonTimeConfigService::setMasterElectionGroupId(uint64_t id) {
+ return mTimeServer.setMasterElectionGroupId(id);
+}
+
+status_t CommonTimeConfigService::getInterfaceBinding(String16& ifaceName) {
+ String8 tmp;
+ status_t ret = mTimeServer.getInterfaceBinding(tmp);
+ ifaceName = String16(tmp);
+ return ret;
+}
+
+status_t CommonTimeConfigService::setInterfaceBinding(const String16& ifaceName) {
+ String8 tmp(ifaceName);
+ return mTimeServer.setInterfaceBinding(tmp);
+}
+
+status_t CommonTimeConfigService::getMasterAnnounceInterval(int *interval) {
+ return mTimeServer.getMasterAnnounceInterval(interval);
+}
+
+status_t CommonTimeConfigService::setMasterAnnounceInterval(int interval) {
+ return mTimeServer.setMasterAnnounceInterval(interval);
+}
+
+status_t CommonTimeConfigService::getClientSyncInterval(int *interval) {
+ return mTimeServer.getClientSyncInterval(interval);
+}
+
+status_t CommonTimeConfigService::setClientSyncInterval(int interval) {
+ return mTimeServer.setClientSyncInterval(interval);
+}
+
+status_t CommonTimeConfigService::getPanicThreshold(int *threshold) {
+ return mTimeServer.getPanicThreshold(threshold);
+}
+
+status_t CommonTimeConfigService::setPanicThreshold(int threshold) {
+ return mTimeServer.setPanicThreshold(threshold);
+}
+
+status_t CommonTimeConfigService::getAutoDisable(bool *autoDisable) {
+ return mTimeServer.getAutoDisable(autoDisable);
+}
+
+status_t CommonTimeConfigService::setAutoDisable(bool autoDisable) {
+ return mTimeServer.setAutoDisable(autoDisable);
+}
+
+status_t CommonTimeConfigService::forceNetworklessMasterMode() {
+ return mTimeServer.forceNetworklessMasterMode();
+}
+
+}; // namespace android
diff --git a/services/common_time/common_time_config_service.h b/services/common_time/common_time_config_service.h
new file mode 100644
index 0000000..8283c24
--- /dev/null
+++ b/services/common_time/common_time_config_service.h
@@ -0,0 +1,59 @@
+/* * Copyright (C) 2012 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.
+ */
+
+#include <common_time/ICommonTimeConfig.h>
+
+#ifndef ANDROID_COMMON_TIME_CONFIG_SERVICE_H
+#define ANDROID_COMMON_TIME_CONFIG_SERVICE_H
+
+namespace android {
+
+class String16;
+class CommonTimeServer;
+
+class CommonTimeConfigService : public BnCommonTimeConfig {
+ public:
+ static sp<CommonTimeConfigService> instantiate(CommonTimeServer& timeServer);
+
+ virtual status_t dump(int fd, const Vector<String16>& args);
+
+ virtual status_t getMasterElectionPriority(uint8_t *priority);
+ virtual status_t setMasterElectionPriority(uint8_t priority);
+ virtual status_t getMasterElectionEndpoint(struct sockaddr_storage *addr);
+ virtual status_t setMasterElectionEndpoint(const struct sockaddr_storage *addr);
+ virtual status_t getMasterElectionGroupId(uint64_t *id);
+ virtual status_t setMasterElectionGroupId(uint64_t id);
+ virtual status_t getInterfaceBinding(String16& ifaceName);
+ virtual status_t setInterfaceBinding(const String16& ifaceName);
+ virtual status_t getMasterAnnounceInterval(int *interval);
+ virtual status_t setMasterAnnounceInterval(int interval);
+ virtual status_t getClientSyncInterval(int *interval);
+ virtual status_t setClientSyncInterval(int interval);
+ virtual status_t getPanicThreshold(int *threshold);
+ virtual status_t setPanicThreshold(int threshold);
+ virtual status_t getAutoDisable(bool *autoDisable);
+ virtual status_t setAutoDisable(bool autoDisable);
+ virtual status_t forceNetworklessMasterMode();
+
+ private:
+ CommonTimeConfigService(CommonTimeServer& timeServer)
+ : mTimeServer(timeServer) { }
+ CommonTimeServer& mTimeServer;
+
+};
+
+}; // namespace android
+
+#endif // ANDROID_COMMON_TIME_CONFIG_SERVICE_H
diff --git a/services/common_time/common_time_server.cpp b/services/common_time/common_time_server.cpp
new file mode 100644
index 0000000..ef7fa168
--- /dev/null
+++ b/services/common_time/common_time_server.cpp
@@ -0,0 +1,1380 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+/*
+ * A service that exchanges time synchronization information between
+ * a master that defines a timeline and clients that follow the timeline.
+ */
+
+#define LOG_TAG "common_time"
+#include <utils/Log.h>
+
+#include <arpa/inet.h>
+#include <assert.h>
+#include <fcntl.h>
+#include <linux/if_ether.h>
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <netinet/ip.h>
+#include <poll.h>
+#include <stdio.h>
+#include <sys/eventfd.h>
+#include <sys/ioctl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <common_time/local_clock.h>
+#include <binder/IPCThreadState.h>
+#include <binder/ProcessState.h>
+#include <utils/Timers.h>
+
+#include "common_clock_service.h"
+#include "common_time_config_service.h"
+#include "common_time_server.h"
+#include "common_time_server_packets.h"
+#include "clock_recovery.h"
+#include "common_clock.h"
+
+#define MAX_INT ((int)0x7FFFFFFF)
+
+namespace android {
+
+const char* CommonTimeServer::kDefaultMasterElectionAddr = "239.195.128.88";
+const uint16_t CommonTimeServer::kDefaultMasterElectionPort = 8887;
+const uint64_t CommonTimeServer::kDefaultSyncGroupID = 0;
+const uint8_t CommonTimeServer::kDefaultMasterPriority = 1;
+const uint32_t CommonTimeServer::kDefaultMasterAnnounceIntervalMs = 10000;
+const uint32_t CommonTimeServer::kDefaultSyncRequestIntervalMs = 1000;
+const uint32_t CommonTimeServer::kDefaultPanicThresholdUsec = 50000;
+const bool CommonTimeServer::kDefaultAutoDisable = true;
+const int CommonTimeServer::kSetupRetryTimeoutMs = 30000;
+const int64_t CommonTimeServer::kNoGoodDataPanicThresholdUsec = 600000000ll;
+const uint32_t CommonTimeServer::kRTTDiscardPanicThreshMultiplier = 5;
+
+// timeout value representing an infinite timeout
+const int CommonTimeServer::kInfiniteTimeout = -1;
+
+/*** Initial state constants ***/
+
+// number of WhoIsMaster attempts sent before giving up
+const int CommonTimeServer::kInitial_NumWhoIsMasterRetries = 6;
+
+// timeout used when waiting for a response to a WhoIsMaster request
+const int CommonTimeServer::kInitial_WhoIsMasterTimeoutMs = 500;
+
+/*** Client state constants ***/
+
+// number of sync requests that can fail before a client assumes its master
+// is dead
+const int CommonTimeServer::kClient_NumSyncRequestRetries = 5;
+
+/*** Master state constants ***/
+
+/*** Ronin state constants ***/
+
+// number of WhoIsMaster attempts sent before declaring ourselves master
+const int CommonTimeServer::kRonin_NumWhoIsMasterRetries = 4;
+
+// timeout used when waiting for a response to a WhoIsMaster request
+const int CommonTimeServer::kRonin_WhoIsMasterTimeoutMs = 500;
+
+/*** WaitForElection state constants ***/
+
+// how long do we wait for an announcement from a master before
+// trying another election?
+const int CommonTimeServer::kWaitForElection_TimeoutMs = 5000;
+
+CommonTimeServer::CommonTimeServer()
+ : Thread(false)
+ , mState(ICommonClock::STATE_INITIAL)
+ , mClockRecovery(&mLocalClock, &mCommonClock)
+ , mSocket(-1)
+ , mLastPacketRxLocalTime(0)
+ , mTimelineID(ICommonClock::kInvalidTimelineID)
+ , mClockSynced(false)
+ , mCommonClockHasClients(false)
+ , mInitial_WhoIsMasterRequestTimeouts(0)
+ , mClient_MasterDeviceID(0)
+ , mClient_MasterDevicePriority(0)
+ , mRonin_WhoIsMasterRequestTimeouts(0) {
+ // zero out sync stats
+ resetSyncStats();
+
+ // Setup the master election endpoint to use the default.
+ struct sockaddr_in* meep =
+ reinterpret_cast<struct sockaddr_in*>(&mMasterElectionEP);
+ memset(&mMasterElectionEP, 0, sizeof(mMasterElectionEP));
+ inet_aton(kDefaultMasterElectionAddr, &meep->sin_addr);
+ meep->sin_family = AF_INET;
+ meep->sin_port = htons(kDefaultMasterElectionPort);
+
+ // Zero out the master endpoint.
+ memset(&mMasterEP, 0, sizeof(mMasterEP));
+ mMasterEPValid = false;
+ mBindIfaceValid = false;
+ setForceLowPriority(false);
+
+ // Set all remaining configuration parameters to their defaults.
+ mDeviceID = 0;
+ mSyncGroupID = kDefaultSyncGroupID;
+ mMasterPriority = kDefaultMasterPriority;
+ mMasterAnnounceIntervalMs = kDefaultMasterAnnounceIntervalMs;
+ mSyncRequestIntervalMs = kDefaultSyncRequestIntervalMs;
+ mPanicThresholdUsec = kDefaultPanicThresholdUsec;
+ mAutoDisable = kDefaultAutoDisable;
+
+ // Create the eventfd we will use to signal our thread to wake up when
+ // needed.
+ mWakeupThreadFD = eventfd(0, EFD_NONBLOCK);
+
+ // seed the random number generator (used to generated timeline IDs)
+ srand48(static_cast<unsigned int>(systemTime()));
+}
+
+CommonTimeServer::~CommonTimeServer() {
+ shutdownThread();
+
+ // No need to grab the lock here. We are in the destructor; if the the user
+ // has a thread in any of the APIs while the destructor is being called,
+ // there is a threading problem a the application level we cannot reasonably
+ // do anything about.
+ cleanupSocket_l();
+
+ if (mWakeupThreadFD >= 0) {
+ close(mWakeupThreadFD);
+ mWakeupThreadFD = -1;
+ }
+}
+
+bool CommonTimeServer::startServices() {
+ // start the ICommonClock service
+ mICommonClock = CommonClockService::instantiate(*this);
+ if (mICommonClock == NULL)
+ return false;
+
+ // start the ICommonTimeConfig service
+ mICommonTimeConfig = CommonTimeConfigService::instantiate(*this);
+ if (mICommonTimeConfig == NULL)
+ return false;
+
+ return true;
+}
+
+bool CommonTimeServer::threadLoop() {
+ // Register our service interfaces.
+ if (!startServices())
+ return false;
+
+ // Hold the lock while we are in the main thread loop. It will release the
+ // lock when it blocks, and hold the lock at all other times.
+ mLock.lock();
+ runStateMachine_l();
+ mLock.unlock();
+
+ IPCThreadState::self()->stopProcess();
+ return false;
+}
+
+bool CommonTimeServer::runStateMachine_l() {
+ if (!mLocalClock.initCheck())
+ return false;
+
+ if (!mCommonClock.init(mLocalClock.getLocalFreq()))
+ return false;
+
+ // Enter the initial state.
+ becomeInitial("startup");
+
+ // run the state machine
+ while (!exitPending()) {
+ struct pollfd pfds[2];
+ int rc;
+ int eventCnt = 0;
+ int64_t wakeupTime;
+
+ // We are always interested in our wakeup FD.
+ pfds[eventCnt].fd = mWakeupThreadFD;
+ pfds[eventCnt].events = POLLIN;
+ pfds[eventCnt].revents = 0;
+ eventCnt++;
+
+ // If we have a valid socket, then we are interested in what it has to
+ // say as well.
+ if (mSocket >= 0) {
+ pfds[eventCnt].fd = mSocket;
+ pfds[eventCnt].events = POLLIN;
+ pfds[eventCnt].revents = 0;
+ eventCnt++;
+ }
+
+ // Note, we were holding mLock when this function was called. We
+ // release it only while we are blocking and hold it at all other times.
+ mLock.unlock();
+ rc = poll(pfds, eventCnt, mCurTimeout.msecTillTimeout());
+ wakeupTime = mLocalClock.getLocalTime();
+ mLock.lock();
+
+ // Is it time to shutdown? If so, don't hesitate... just do it.
+ if (exitPending())
+ break;
+
+ // Did the poll fail? This should never happen and is fatal if it does.
+ if (rc < 0) {
+ ALOGE("%s:%d poll failed", __PRETTY_FUNCTION__, __LINE__);
+ return false;
+ }
+
+ if (rc == 0)
+ mCurTimeout.setTimeout(kInfiniteTimeout);
+
+ // Were we woken up on purpose? If so, clear the eventfd with a read.
+ if (pfds[0].revents)
+ clearPendingWakeupEvents_l();
+
+ // Is out bind address dirty? If so, clean up our socket (if any).
+ // Alternatively, do we have an active socket but should be auto
+ // disabled? If so, release the socket and enter the proper sync state.
+ bool droppedSocket = false;
+ if (mBindIfaceDirty || ((mSocket >= 0) && shouldAutoDisable())) {
+ cleanupSocket_l();
+ mBindIfaceDirty = false;
+ droppedSocket = true;
+ }
+
+ // Do we not have a socket but should have one? If so, try to set one
+ // up.
+ if ((mSocket < 0) && mBindIfaceValid && !shouldAutoDisable()) {
+ if (setupSocket_l()) {
+ // Success! We are now joining a new network (either coming
+ // from no network, or coming from a potentially different
+ // network). Force our priority to be lower so that we defer to
+ // any other masters which may already be on the network we are
+ // joining. Later, when we enter either the client or the
+ // master state, we will clear this flag and go back to our
+ // normal election priority.
+ setForceLowPriority(true);
+ switch (mState) {
+ // If we were in initial (whether we had a immediately
+ // before this network or not) we want to simply reset the
+ // system and start again. Forcing a transition from
+ // INITIAL to INITIAL should do the job.
+ case CommonClockService::STATE_INITIAL:
+ becomeInitial("bound interface");
+ break;
+
+ // If we were in the master state, then either we were the
+ // master in a no-network situation, or we were the master
+ // of a different network and have moved to a new interface.
+ // In either case, immediately send out a master
+ // announcement at low priority.
+ case CommonClockService::STATE_MASTER:
+ sendMasterAnnouncement();
+ break;
+
+ // If we were in any other state (CLIENT, RONIN, or
+ // WAIT_FOR_ELECTION) then we must be moving from one
+ // network to another. We have lost our old master;
+ // transition to RONIN in an attempt to find a new master.
+ // If there are none out there, we will just assume
+ // responsibility for the timeline we used to be a client
+ // of.
+ default:
+ becomeRonin("bound interface");
+ break;
+ }
+ } else {
+ // That's odd... we failed to set up our socket. This could be
+ // due to some transient network change which will work itself
+ // out shortly; schedule a retry attempt in the near future.
+ mCurTimeout.setTimeout(kSetupRetryTimeoutMs);
+ }
+
+ // One way or the other, we don't have any data to process at this
+ // point (since we just tried to bulid a new socket). Loop back
+ // around and wait for the next thing to do.
+ continue;
+ } else if (droppedSocket) {
+ // We just lost our socket, and for whatever reason (either no
+ // config, or auto disable engaged) we are not supposed to rebuild
+ // one at this time. We are not going to rebuild our socket until
+ // something about our config/auto-disabled status changes, so we
+ // are basically in network-less mode. If we are already in either
+ // INITIAL or MASTER, just stay there until something changes. If
+ // we are in any other state (CLIENT, RONIN or WAIT_FOR_ELECTION),
+ // then transition to either INITIAL or MASTER depending on whether
+ // or not our timeline is valid.
+ ALOGI("Entering networkless mode interface is %s, "
+ "shouldAutoDisable = %s",
+ mBindIfaceValid ? "valid" : "invalid",
+ shouldAutoDisable() ? "true" : "false");
+ if ((mState != ICommonClock::STATE_INITIAL) &&
+ (mState != ICommonClock::STATE_MASTER)) {
+ if (mTimelineID == ICommonClock::kInvalidTimelineID)
+ becomeInitial("network-less mode");
+ else
+ becomeMaster("network-less mode");
+ }
+
+ continue;
+ }
+
+ // Did we wakeup with no signalled events across all of our FDs? If so,
+ // we must have hit our timeout.
+ if (rc == 0) {
+ if (!handleTimeout())
+ ALOGE("handleTimeout failed");
+ continue;
+ }
+
+ // Does our socket have data for us (assuming we still have one, we
+ // may have RXed a packet at the same time as a config change telling us
+ // to shut our socket down)? If so, process its data.
+ if ((mSocket >= 0) && (eventCnt > 1) && (pfds[1].revents)) {
+ mLastPacketRxLocalTime = wakeupTime;
+ if (!handlePacket())
+ ALOGE("handlePacket failed");
+ }
+ }
+
+ cleanupSocket_l();
+ return true;
+}
+
+void CommonTimeServer::clearPendingWakeupEvents_l() {
+ int64_t tmp;
+ read(mWakeupThreadFD, &tmp, sizeof(tmp));
+}
+
+void CommonTimeServer::wakeupThread_l() {
+ int64_t tmp = 1;
+ write(mWakeupThreadFD, &tmp, sizeof(tmp));
+}
+
+void CommonTimeServer::cleanupSocket_l() {
+ if (mSocket >= 0) {
+ close(mSocket);
+ mSocket = -1;
+ }
+}
+
+void CommonTimeServer::shutdownThread() {
+ // Flag the work thread for shutdown.
+ this->requestExit();
+
+ // Signal the thread in case its sleeping.
+ mLock.lock();
+ wakeupThread_l();
+ mLock.unlock();
+
+ // Wait for the thread to exit.
+ this->join();
+}
+
+bool CommonTimeServer::setupSocket_l() {
+ int rc;
+ bool ret_val = false;
+ struct sockaddr_in* ipv4_addr = NULL;
+ char masterElectionEPStr[64];
+ const int one = 1;
+
+ // This should never be needed, but if we happened to have an old socket
+ // lying around, be sure to not leak it before proceeding.
+ cleanupSocket_l();
+
+ // If we don't have a valid endpoint to bind to, then how did we get here in
+ // the first place? Regardless, we know that we are going to fail to bind,
+ // so don't even try.
+ if (!mBindIfaceValid)
+ return false;
+
+ sockaddrToString(mMasterElectionEP, true, masterElectionEPStr,
+ sizeof(masterElectionEPStr));
+ ALOGI("Building socket :: bind = %s master election = %s",
+ mBindIface.string(), masterElectionEPStr);
+
+ // TODO: add proper support for IPv6. Right now, we block IPv6 addresses at
+ // the configuration interface level.
+ if (AF_INET != mMasterElectionEP.ss_family) {
+ ALOGW("TODO: add proper IPv6 support");
+ goto bailout;
+ }
+
+ // open a UDP socket for the timeline serivce
+ mSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ if (mSocket < 0) {
+ ALOGE("Failed to create socket (errno = %d)", errno);
+ goto bailout;
+ }
+
+ // Bind to the selected interface using Linux's spiffy SO_BINDTODEVICE.
+ struct ifreq ifr;
+ memset(&ifr, 0, sizeof(ifr));
+ snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", mBindIface.string());
+ ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = 0;
+ rc = setsockopt(mSocket, SOL_SOCKET, SO_BINDTODEVICE,
+ (void *)&ifr, sizeof(ifr));
+ if (rc) {
+ ALOGE("Failed to bind socket at to interface %s (errno = %d)",
+ ifr.ifr_name, errno);
+ goto bailout;
+ }
+
+ // Bind our socket to INADDR_ANY and the master election port. The
+ // interface binding we made using SO_BINDTODEVICE should limit us to
+ // traffic only on the interface we are interested in. We need to bind to
+ // INADDR_ANY and the specific master election port in order to be able to
+ // receive both unicast traffic and master election multicast traffic with
+ // just a single socket.
+ struct sockaddr_in bindAddr;
+ ipv4_addr = reinterpret_cast<struct sockaddr_in*>(&mMasterElectionEP);
+ memcpy(&bindAddr, ipv4_addr, sizeof(bindAddr));
+ bindAddr.sin_addr.s_addr = INADDR_ANY;
+ rc = bind(mSocket,
+ reinterpret_cast<const sockaddr *>(&bindAddr),
+ sizeof(bindAddr));
+ if (rc) {
+ ALOGE("Failed to bind socket to port %hu (errno = %d)",
+ ntohs(bindAddr.sin_port), errno);
+ goto bailout;
+ }
+
+ if (0xE0000000 == (ntohl(ipv4_addr->sin_addr.s_addr) & 0xF0000000)) {
+ // If our master election endpoint is a multicast address, be sure to join
+ // the multicast group.
+ struct ip_mreq mreq;
+ mreq.imr_multiaddr = ipv4_addr->sin_addr;
+ mreq.imr_interface.s_addr = htonl(INADDR_ANY);
+ rc = setsockopt(mSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+ &mreq, sizeof(mreq));
+ if (rc == -1) {
+ ALOGE("Failed to join multicast group at %s. (errno = %d)",
+ masterElectionEPStr, errno);
+ goto bailout;
+ }
+
+ // disable loopback of multicast packets
+ const int zero = 0;
+ rc = setsockopt(mSocket, IPPROTO_IP, IP_MULTICAST_LOOP,
+ &zero, sizeof(zero));
+ if (rc == -1) {
+ ALOGE("Failed to disable multicast loopback (errno = %d)", errno);
+ goto bailout;
+ }
+ } else
+ if (ntohl(ipv4_addr->sin_addr.s_addr) != 0xFFFFFFFF) {
+ // If the master election address is neither broadcast, nor multicast,
+ // then we are misconfigured. The config API layer should prevent this
+ // from ever happening.
+ goto bailout;
+ }
+
+ // Set the TTL of sent packets to 1. (Time protocol sync should never leave
+ // the local subnet)
+ rc = setsockopt(mSocket, IPPROTO_IP, IP_TTL, &one, sizeof(one));
+ if (rc == -1) {
+ ALOGE("Failed to set TTL to %d (errno = %d)", one, errno);
+ goto bailout;
+ }
+
+ // get the device's unique ID
+ if (!assignDeviceID())
+ goto bailout;
+
+ ret_val = true;
+
+bailout:
+ if (!ret_val)
+ cleanupSocket_l();
+ return ret_val;
+}
+
+// generate a unique device ID that can be used for arbitration
+bool CommonTimeServer::assignDeviceID() {
+ if (!mBindIfaceValid)
+ return false;
+
+ struct ifreq ifr;
+ memset(&ifr, 0, sizeof(ifr));
+ ifr.ifr_addr.sa_family = AF_INET;
+ strlcpy(ifr.ifr_name, mBindIface.string(), IFNAMSIZ);
+
+ int rc = ioctl(mSocket, SIOCGIFHWADDR, &ifr);
+ if (rc) {
+ ALOGE("%s:%d ioctl failed", __PRETTY_FUNCTION__, __LINE__);
+ return false;
+ }
+
+ if (ifr.ifr_addr.sa_family != ARPHRD_ETHER) {
+ ALOGE("%s:%d got non-Ethernet address", __PRETTY_FUNCTION__, __LINE__);
+ return false;
+ }
+
+ mDeviceID = 0;
+ for (int i = 0; i < ETH_ALEN; i++) {
+ mDeviceID = (mDeviceID << 8) | ifr.ifr_hwaddr.sa_data[i];
+ }
+
+ return true;
+}
+
+// generate a new timeline ID
+void CommonTimeServer::assignTimelineID() {
+ do {
+ mTimelineID = (static_cast<uint64_t>(lrand48()) << 32)
+ | static_cast<uint64_t>(lrand48());
+ } while (mTimelineID == ICommonClock::kInvalidTimelineID);
+}
+
+// Select a preference between the device IDs of two potential masters.
+// Returns true if the first ID wins, or false if the second ID wins.
+bool CommonTimeServer::arbitrateMaster(
+ uint64_t deviceID1, uint8_t devicePrio1,
+ uint64_t deviceID2, uint8_t devicePrio2) {
+ return ((devicePrio1 > devicePrio2) ||
+ ((devicePrio1 == devicePrio2) && (deviceID1 > deviceID2)));
+}
+
+bool CommonTimeServer::handlePacket() {
+ uint8_t buf[256];
+ struct sockaddr_storage srcAddr;
+ socklen_t srcAddrLen = sizeof(srcAddr);
+
+ ssize_t recvBytes = recvfrom(
+ mSocket, buf, sizeof(buf), 0,
+ reinterpret_cast<const sockaddr *>(&srcAddr), &srcAddrLen);
+
+ if (recvBytes < 0) {
+ ALOGE("%s:%d recvfrom failed", __PRETTY_FUNCTION__, __LINE__);
+ return false;
+ }
+
+ UniversalTimeServicePacket pkt;
+ recvBytes = pkt.deserializePacket(buf, recvBytes, mSyncGroupID);
+ if (recvBytes < 0)
+ return false;
+
+ bool result;
+ switch (pkt.packetType) {
+ case TIME_PACKET_WHO_IS_MASTER_REQUEST:
+ result = handleWhoIsMasterRequest(&pkt.p.who_is_master_request,
+ srcAddr);
+ break;
+
+ case TIME_PACKET_WHO_IS_MASTER_RESPONSE:
+ result = handleWhoIsMasterResponse(&pkt.p.who_is_master_response,
+ srcAddr);
+ break;
+
+ case TIME_PACKET_SYNC_REQUEST:
+ result = handleSyncRequest(&pkt.p.sync_request, srcAddr);
+ break;
+
+ case TIME_PACKET_SYNC_RESPONSE:
+ result = handleSyncResponse(&pkt.p.sync_response, srcAddr);
+ break;
+
+ case TIME_PACKET_MASTER_ANNOUNCEMENT:
+ result = handleMasterAnnouncement(&pkt.p.master_announcement,
+ srcAddr);
+ break;
+
+ default: {
+ ALOGD("%s:%d unknown packet type(%d)",
+ __PRETTY_FUNCTION__, __LINE__, pkt.packetType);
+ result = false;
+ } break;
+ }
+
+ return result;
+}
+
+bool CommonTimeServer::handleTimeout() {
+ // If we have no socket, then this must be a timeout to retry socket setup.
+ if (mSocket < 0)
+ return true;
+
+ switch (mState) {
+ case ICommonClock::STATE_INITIAL:
+ return handleTimeoutInitial();
+ case ICommonClock::STATE_CLIENT:
+ return handleTimeoutClient();
+ case ICommonClock::STATE_MASTER:
+ return handleTimeoutMaster();
+ case ICommonClock::STATE_RONIN:
+ return handleTimeoutRonin();
+ case ICommonClock::STATE_WAIT_FOR_ELECTION:
+ return handleTimeoutWaitForElection();
+ }
+
+ return false;
+}
+
+bool CommonTimeServer::handleTimeoutInitial() {
+ if (++mInitial_WhoIsMasterRequestTimeouts ==
+ kInitial_NumWhoIsMasterRetries) {
+ // none of our attempts to discover a master succeeded, so make
+ // this device the master
+ return becomeMaster("initial timeout");
+ } else {
+ // retry the WhoIsMaster request
+ return sendWhoIsMasterRequest();
+ }
+}
+
+bool CommonTimeServer::handleTimeoutClient() {
+ if (shouldPanicNotGettingGoodData())
+ return becomeInitial("timeout panic, no good data");
+
+ if (mClient_SyncRequestPending) {
+ mClient_SyncRequestPending = false;
+
+ if (++mClient_SyncRequestTimeouts < kClient_NumSyncRequestRetries) {
+ // a sync request has timed out, so retry
+ return sendSyncRequest();
+ } else {
+ // The master has failed to respond to a sync request for too many
+ // times in a row. Assume the master is dead and start electing
+ // a new master.
+ return becomeRonin("master not responding");
+ }
+ } else {
+ // initiate the next sync request
+ return sendSyncRequest();
+ }
+}
+
+bool CommonTimeServer::handleTimeoutMaster() {
+ // send another announcement from the master
+ return sendMasterAnnouncement();
+}
+
+bool CommonTimeServer::handleTimeoutRonin() {
+ if (++mRonin_WhoIsMasterRequestTimeouts == kRonin_NumWhoIsMasterRetries) {
+ // no other master is out there, so we won the election
+ return becomeMaster("no better masters detected");
+ } else {
+ return sendWhoIsMasterRequest();
+ }
+}
+
+bool CommonTimeServer::handleTimeoutWaitForElection() {
+ return becomeRonin("timeout waiting for election conclusion");
+}
+
+bool CommonTimeServer::handleWhoIsMasterRequest(
+ const WhoIsMasterRequestPacket* request,
+ const sockaddr_storage& srcAddr) {
+ if (mState == ICommonClock::STATE_MASTER) {
+ // is this request related to this master's timeline?
+ if (request->timelineID != ICommonClock::kInvalidTimelineID &&
+ request->timelineID != mTimelineID)
+ return true;
+
+ WhoIsMasterResponsePacket pkt;
+ pkt.initHeader(mTimelineID, mSyncGroupID);
+ pkt.deviceID = mDeviceID;
+ pkt.devicePriority = effectivePriority();
+
+ uint8_t buf[256];
+ ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
+ if (bufSz < 0)
+ return false;
+
+ ssize_t sendBytes = sendto(
+ mSocket, buf, bufSz, 0,
+ reinterpret_cast<const sockaddr *>(&srcAddr),
+ sizeof(srcAddr));
+ if (sendBytes == -1) {
+ ALOGE("%s:%d sendto failed", __PRETTY_FUNCTION__, __LINE__);
+ return false;
+ }
+ } else if (mState == ICommonClock::STATE_RONIN) {
+ // if we hear a WhoIsMaster request from another device following
+ // the same timeline and that device wins arbitration, then we will stop
+ // trying to elect ourselves master and will instead wait for an
+ // announcement from the election winner
+ if (request->timelineID != mTimelineID)
+ return true;
+
+ if (arbitrateMaster(request->senderDeviceID,
+ request->senderDevicePriority,
+ mDeviceID,
+ effectivePriority()))
+ return becomeWaitForElection("would lose election");
+
+ return true;
+ } else if (mState == ICommonClock::STATE_INITIAL) {
+ // If a group of devices booted simultaneously (e.g. after a power
+ // outage) and all of them are in the initial state and there is no
+ // master, then each device may time out and declare itself master at
+ // the same time. To avoid this, listen for
+ // WhoIsMaster(InvalidTimeline) requests from peers. If we would lose
+ // arbitration against that peer, reset our timeout count so that the
+ // peer has a chance to become master before we time out.
+ if (request->timelineID == ICommonClock::kInvalidTimelineID &&
+ arbitrateMaster(request->senderDeviceID,
+ request->senderDevicePriority,
+ mDeviceID,
+ effectivePriority())) {
+ mInitial_WhoIsMasterRequestTimeouts = 0;
+ }
+ }
+
+ return true;
+}
+
+bool CommonTimeServer::handleWhoIsMasterResponse(
+ const WhoIsMasterResponsePacket* response,
+ const sockaddr_storage& srcAddr) {
+ if (mState == ICommonClock::STATE_INITIAL || mState == ICommonClock::STATE_RONIN) {
+ return becomeClient(srcAddr,
+ response->deviceID,
+ response->devicePriority,
+ response->timelineID,
+ "heard whois response");
+ } else if (mState == ICommonClock::STATE_CLIENT) {
+ // if we get multiple responses because there are multiple devices
+ // who believe that they are master, then follow the master that
+ // wins arbitration
+ if (arbitrateMaster(response->deviceID,
+ response->devicePriority,
+ mClient_MasterDeviceID,
+ mClient_MasterDevicePriority)) {
+ return becomeClient(srcAddr,
+ response->deviceID,
+ response->devicePriority,
+ response->timelineID,
+ "heard whois response");
+ }
+ }
+
+ return true;
+}
+
+bool CommonTimeServer::handleSyncRequest(const SyncRequestPacket* request,
+ const sockaddr_storage& srcAddr) {
+ SyncResponsePacket pkt;
+ pkt.initHeader(mTimelineID, mSyncGroupID);
+
+ if ((mState == ICommonClock::STATE_MASTER) &&
+ (mTimelineID == request->timelineID)) {
+ int64_t rxLocalTime = mLastPacketRxLocalTime;
+ int64_t rxCommonTime;
+
+ // If we are master on an actual network and have actual clients, then
+ // we are no longer low priority.
+ setForceLowPriority(false);
+
+ if (OK != mCommonClock.localToCommon(rxLocalTime, &rxCommonTime)) {
+ return false;
+ }
+
+ int64_t txLocalTime = mLocalClock.getLocalTime();;
+ int64_t txCommonTime;
+ if (OK != mCommonClock.localToCommon(txLocalTime, &txCommonTime)) {
+ return false;
+ }
+
+ pkt.nak = 0;
+ pkt.clientTxLocalTime = request->clientTxLocalTime;
+ pkt.masterRxCommonTime = rxCommonTime;
+ pkt.masterTxCommonTime = txCommonTime;
+ } else {
+ pkt.nak = 1;
+ pkt.clientTxLocalTime = 0;
+ pkt.masterRxCommonTime = 0;
+ pkt.masterTxCommonTime = 0;
+ }
+
+ uint8_t buf[256];
+ ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
+ if (bufSz < 0)
+ return false;
+
+ ssize_t sendBytes = sendto(
+ mSocket, &buf, bufSz, 0,
+ reinterpret_cast<const sockaddr *>(&srcAddr),
+ sizeof(srcAddr));
+ if (sendBytes == -1) {
+ ALOGE("%s:%d sendto failed", __PRETTY_FUNCTION__, __LINE__);
+ return false;
+ }
+
+ return true;
+}
+
+bool CommonTimeServer::handleSyncResponse(
+ const SyncResponsePacket* response,
+ const sockaddr_storage& srcAddr) {
+ if (mState != ICommonClock::STATE_CLIENT)
+ return true;
+
+ assert(mMasterEPValid);
+ if (!sockaddrMatch(srcAddr, mMasterEP, true)) {
+ char srcEP[64], expectedEP[64];
+ sockaddrToString(srcAddr, true, srcEP, sizeof(srcEP));
+ sockaddrToString(mMasterEP, true, expectedEP, sizeof(expectedEP));
+ ALOGI("Dropping sync response from unexpected address."
+ " Expected %s Got %s", expectedEP, srcEP);
+ return true;
+ }
+
+ if (response->nak) {
+ // if our master is no longer accepting requests, then we need to find
+ // a new master
+ return becomeRonin("master NAK'ed");
+ }
+
+ mClient_SyncRequestPending = 0;
+ mClient_SyncRequestTimeouts = 0;
+ mClient_PacketRTTLog.logRX(response->clientTxLocalTime,
+ mLastPacketRxLocalTime);
+
+ bool result;
+ if (!(mClient_SyncRespsRXedFromCurMaster++)) {
+ // the first request/response exchange between a client and a master
+ // may take unusually long due to ARP, so discard it.
+ result = true;
+ } else {
+ int64_t clientTxLocalTime = response->clientTxLocalTime;
+ int64_t clientRxLocalTime = mLastPacketRxLocalTime;
+ int64_t masterTxCommonTime = response->masterTxCommonTime;
+ int64_t masterRxCommonTime = response->masterRxCommonTime;
+
+ int64_t rtt = (clientRxLocalTime - clientTxLocalTime);
+ int64_t avgLocal = (clientTxLocalTime + clientRxLocalTime) >> 1;
+ int64_t avgCommon = (masterTxCommonTime + masterRxCommonTime) >> 1;
+
+ // if the RTT of the packet is significantly larger than the panic
+ // threshold, we should simply discard it. Its better to do nothing
+ // than to take cues from a packet like that.
+ int rttCommon = mCommonClock.localDurationToCommonDuration(rtt);
+ if (rttCommon > (static_cast<int64_t>(mPanicThresholdUsec) *
+ kRTTDiscardPanicThreshMultiplier)) {
+ ALOGV("Dropping sync response with RTT of %lld uSec", rttCommon);
+ mClient_ExpiredSyncRespsRXedFromCurMaster++;
+ if (shouldPanicNotGettingGoodData())
+ return becomeInitial("RX panic, no good data");
+ } else {
+ result = mClockRecovery.pushDisciplineEvent(avgLocal, avgCommon, rttCommon);
+ mClient_LastGoodSyncRX = clientRxLocalTime;
+
+ if (result) {
+ // indicate to listeners that we've synced to the common timeline
+ notifyClockSync();
+ } else {
+ ALOGE("Panic! Observed clock sync error is too high to tolerate,"
+ " resetting state machine and starting over.");
+ notifyClockSyncLoss();
+ return becomeInitial("panic");
+ }
+ }
+ }
+
+ mCurTimeout.setTimeout(mSyncRequestIntervalMs);
+ return result;
+}
+
+bool CommonTimeServer::handleMasterAnnouncement(
+ const MasterAnnouncementPacket* packet,
+ const sockaddr_storage& srcAddr) {
+ uint64_t newDeviceID = packet->deviceID;
+ uint8_t newDevicePrio = packet->devicePriority;
+ uint64_t newTimelineID = packet->timelineID;
+
+ if (mState == ICommonClock::STATE_INITIAL ||
+ mState == ICommonClock::STATE_RONIN ||
+ mState == ICommonClock::STATE_WAIT_FOR_ELECTION) {
+ // if we aren't currently following a master, then start following
+ // this new master
+ return becomeClient(srcAddr,
+ newDeviceID,
+ newDevicePrio,
+ newTimelineID,
+ "heard master announcement");
+ } else if (mState == ICommonClock::STATE_CLIENT) {
+ // if the new master wins arbitration against our current master,
+ // then become a client of the new master
+ if (arbitrateMaster(newDeviceID,
+ newDevicePrio,
+ mClient_MasterDeviceID,
+ mClient_MasterDevicePriority))
+ return becomeClient(srcAddr,
+ newDeviceID,
+ newDevicePrio,
+ newTimelineID,
+ "heard master announcement");
+ } else if (mState == ICommonClock::STATE_MASTER) {
+ // two masters are competing - if the new one wins arbitration, then
+ // cease acting as master
+ if (arbitrateMaster(newDeviceID, newDevicePrio,
+ mDeviceID, effectivePriority()))
+ return becomeClient(srcAddr, newDeviceID,
+ newDevicePrio, newTimelineID,
+ "heard master announcement");
+ }
+
+ return true;
+}
+
+bool CommonTimeServer::sendWhoIsMasterRequest() {
+ assert(mState == ICommonClock::STATE_INITIAL || mState == ICommonClock::STATE_RONIN);
+
+ // If we have no socket, then we must be in the unconfigured initial state.
+ // Don't report any errors, just don't try to send the initial who-is-master
+ // query. Eventually, our network will either become configured, or we will
+ // be forced into network-less master mode by higher level code.
+ if (mSocket < 0) {
+ assert(mState == ICommonClock::STATE_INITIAL);
+ return true;
+ }
+
+ bool ret = false;
+ WhoIsMasterRequestPacket pkt;
+ pkt.initHeader(mSyncGroupID);
+ pkt.senderDeviceID = mDeviceID;
+ pkt.senderDevicePriority = effectivePriority();
+
+ uint8_t buf[256];
+ ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
+ if (bufSz >= 0) {
+ ssize_t sendBytes = sendto(
+ mSocket, buf, bufSz, 0,
+ reinterpret_cast<const sockaddr *>(&mMasterElectionEP),
+ sizeof(mMasterElectionEP));
+ if (sendBytes < 0)
+ ALOGE("WhoIsMaster sendto failed (errno %d)", errno);
+ ret = true;
+ }
+
+ if (mState == ICommonClock::STATE_INITIAL) {
+ mCurTimeout.setTimeout(kInitial_WhoIsMasterTimeoutMs);
+ } else {
+ mCurTimeout.setTimeout(kRonin_WhoIsMasterTimeoutMs);
+ }
+
+ return ret;
+}
+
+bool CommonTimeServer::sendSyncRequest() {
+ // If we are sending sync requests, then we must be in the client state and
+ // we must have a socket (when we have no network, we are only supposed to
+ // be in INITIAL or MASTER)
+ assert(mState == ICommonClock::STATE_CLIENT);
+ assert(mSocket >= 0);
+
+ bool ret = false;
+ SyncRequestPacket pkt;
+ pkt.initHeader(mTimelineID, mSyncGroupID);
+ pkt.clientTxLocalTime = mLocalClock.getLocalTime();
+
+ if (!mClient_FirstSyncTX)
+ mClient_FirstSyncTX = pkt.clientTxLocalTime;
+
+ mClient_PacketRTTLog.logTX(pkt.clientTxLocalTime);
+
+ uint8_t buf[256];
+ ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
+ if (bufSz >= 0) {
+ ssize_t sendBytes = sendto(
+ mSocket, buf, bufSz, 0,
+ reinterpret_cast<const sockaddr *>(&mMasterEP),
+ sizeof(mMasterEP));
+ if (sendBytes < 0)
+ ALOGE("SyncRequest sendto failed (errno %d)", errno);
+ ret = true;
+ }
+
+ mClient_SyncsSentToCurMaster++;
+ mCurTimeout.setTimeout(mSyncRequestIntervalMs);
+ mClient_SyncRequestPending = true;
+
+ return ret;
+}
+
+bool CommonTimeServer::sendMasterAnnouncement() {
+ bool ret = false;
+ assert(mState == ICommonClock::STATE_MASTER);
+
+ // If we are being asked to send a master announcement, but we have no
+ // socket, we must be in network-less master mode. Don't bother to send the
+ // announcement, and don't bother to schedule a timeout. When the network
+ // comes up, the work thread will get poked and start the process of
+ // figuring out who the current master should be.
+ if (mSocket < 0) {
+ mCurTimeout.setTimeout(kInfiniteTimeout);
+ return true;
+ }
+
+ MasterAnnouncementPacket pkt;
+ pkt.initHeader(mTimelineID, mSyncGroupID);
+ pkt.deviceID = mDeviceID;
+ pkt.devicePriority = effectivePriority();
+
+ uint8_t buf[256];
+ ssize_t bufSz = pkt.serializePacket(buf, sizeof(buf));
+ if (bufSz >= 0) {
+ ssize_t sendBytes = sendto(
+ mSocket, buf, bufSz, 0,
+ reinterpret_cast<const sockaddr *>(&mMasterElectionEP),
+ sizeof(mMasterElectionEP));
+ if (sendBytes < 0)
+ ALOGE("MasterAnnouncement sendto failed (errno %d)", errno);
+ ret = true;
+ }
+
+ mCurTimeout.setTimeout(mMasterAnnounceIntervalMs);
+ return ret;
+}
+
+bool CommonTimeServer::becomeClient(const sockaddr_storage& masterEP,
+ uint64_t masterDeviceID,
+ uint8_t masterDevicePriority,
+ uint64_t timelineID,
+ const char* cause) {
+ char newEPStr[64], oldEPStr[64];
+ sockaddrToString(masterEP, true, newEPStr, sizeof(newEPStr));
+ sockaddrToString(mMasterEP, mMasterEPValid, oldEPStr, sizeof(oldEPStr));
+
+ ALOGI("%s --> CLIENT (%s) :%s"
+ " OldMaster: %02x-%014llx::%016llx::%s"
+ " NewMaster: %02x-%014llx::%016llx::%s",
+ stateToString(mState), cause,
+ (mTimelineID != timelineID) ? " (new timeline)" : "",
+ mClient_MasterDevicePriority, mClient_MasterDeviceID,
+ mTimelineID, oldEPStr,
+ masterDevicePriority, masterDeviceID,
+ timelineID, newEPStr);
+
+ if (mTimelineID != timelineID) {
+ // start following a new timeline
+ mTimelineID = timelineID;
+ mClockRecovery.reset(true, true);
+ notifyClockSyncLoss();
+ } else {
+ // start following a new master on the existing timeline
+ mClockRecovery.reset(false, true);
+ }
+
+ mMasterEP = masterEP;
+ mMasterEPValid = true;
+ setForceLowPriority(false);
+
+ mClient_MasterDeviceID = masterDeviceID;
+ mClient_MasterDevicePriority = masterDevicePriority;
+ resetSyncStats();
+
+ setState(ICommonClock::STATE_CLIENT);
+
+ // add some jitter to when the various clients send their requests
+ // in order to reduce the likelihood that a group of clients overload
+ // the master after receiving a master announcement
+ usleep((lrand48() % 100) * 1000);
+
+ return sendSyncRequest();
+}
+
+bool CommonTimeServer::becomeMaster(const char* cause) {
+ uint64_t oldTimelineID = mTimelineID;
+ if (mTimelineID == ICommonClock::kInvalidTimelineID) {
+ // this device has not been following any existing timeline,
+ // so it will create a new timeline and declare itself master
+ assert(!mCommonClock.isValid());
+
+ // set the common time basis
+ mCommonClock.setBasis(mLocalClock.getLocalTime(), 0);
+
+ // assign an arbitrary timeline iD
+ assignTimelineID();
+
+ // notify listeners that we've created a common timeline
+ notifyClockSync();
+ }
+
+ ALOGI("%s --> MASTER (%s) : %s timeline %016llx",
+ stateToString(mState), cause,
+ (oldTimelineID == mTimelineID) ? "taking ownership of"
+ : "creating new",
+ mTimelineID);
+
+ memset(&mMasterEP, 0, sizeof(mMasterEP));
+ mMasterEPValid = false;
+ setForceLowPriority(false);
+ mClient_MasterDevicePriority = effectivePriority();
+ mClient_MasterDeviceID = mDeviceID;
+ mClockRecovery.reset(false, true);
+ resetSyncStats();
+
+ setState(ICommonClock::STATE_MASTER);
+ return sendMasterAnnouncement();
+}
+
+bool CommonTimeServer::becomeRonin(const char* cause) {
+ // If we were the client of a given timeline, but had never received even a
+ // single time sync packet, then we transition back to Initial instead of
+ // Ronin. If we transition to Ronin and end up becoming the new Master, we
+ // will be unable to service requests for other clients because we never
+ // actually knew what time it was. By going to initial, we ensure that
+ // other clients who know what time it is, but would lose master arbitration
+ // in the Ronin case, will step up and become the proper new master of the
+ // old timeline.
+
+ char oldEPStr[64];
+ sockaddrToString(mMasterEP, mMasterEPValid, oldEPStr, sizeof(oldEPStr));
+ memset(&mMasterEP, 0, sizeof(mMasterEP));
+ mMasterEPValid = false;
+
+ if (mCommonClock.isValid()) {
+ ALOGI("%s --> RONIN (%s) : lost track of previously valid timeline "
+ "%02x-%014llx::%016llx::%s (%d TXed %d RXed %d RXExpired)",
+ stateToString(mState), cause,
+ mClient_MasterDevicePriority, mClient_MasterDeviceID,
+ mTimelineID, oldEPStr,
+ mClient_SyncsSentToCurMaster,
+ mClient_SyncRespsRXedFromCurMaster,
+ mClient_ExpiredSyncRespsRXedFromCurMaster);
+
+ mRonin_WhoIsMasterRequestTimeouts = 0;
+ setState(ICommonClock::STATE_RONIN);
+ return sendWhoIsMasterRequest();
+ } else {
+ ALOGI("%s --> INITIAL (%s) : never synced timeline "
+ "%02x-%014llx::%016llx::%s (%d TXed %d RXed %d RXExpired)",
+ stateToString(mState), cause,
+ mClient_MasterDevicePriority, mClient_MasterDeviceID,
+ mTimelineID, oldEPStr,
+ mClient_SyncsSentToCurMaster,
+ mClient_SyncRespsRXedFromCurMaster,
+ mClient_ExpiredSyncRespsRXedFromCurMaster);
+
+ return becomeInitial("ronin, no timeline");
+ }
+}
+
+bool CommonTimeServer::becomeWaitForElection(const char* cause) {
+ ALOGI("%s --> WAIT_FOR_ELECTION (%s) : dropping out of election,"
+ " waiting %d mSec for completion.",
+ stateToString(mState), cause, kWaitForElection_TimeoutMs);
+
+ setState(ICommonClock::STATE_WAIT_FOR_ELECTION);
+ mCurTimeout.setTimeout(kWaitForElection_TimeoutMs);
+ return true;
+}
+
+bool CommonTimeServer::becomeInitial(const char* cause) {
+ ALOGI("Entering INITIAL (%s), total reset.", cause);
+
+ setState(ICommonClock::STATE_INITIAL);
+
+ // reset clock recovery
+ mClockRecovery.reset(true, true);
+
+ // reset internal state bookkeeping.
+ mCurTimeout.setTimeout(kInfiniteTimeout);
+ memset(&mMasterEP, 0, sizeof(mMasterEP));
+ mMasterEPValid = false;
+ mLastPacketRxLocalTime = 0;
+ mTimelineID = ICommonClock::kInvalidTimelineID;
+ mClockSynced = false;
+ mInitial_WhoIsMasterRequestTimeouts = 0;
+ mClient_MasterDeviceID = 0;
+ mClient_MasterDevicePriority = 0;
+ mRonin_WhoIsMasterRequestTimeouts = 0;
+ resetSyncStats();
+
+ // send the first request to discover the master
+ return sendWhoIsMasterRequest();
+}
+
+void CommonTimeServer::notifyClockSync() {
+ if (!mClockSynced) {
+ mClockSynced = true;
+ mICommonClock->notifyOnTimelineChanged(mTimelineID);
+ }
+}
+
+void CommonTimeServer::notifyClockSyncLoss() {
+ if (mClockSynced) {
+ mClockSynced = false;
+ mICommonClock->notifyOnTimelineChanged(
+ ICommonClock::kInvalidTimelineID);
+ }
+}
+
+void CommonTimeServer::setState(ICommonClock::State s) {
+ mState = s;
+}
+
+const char* CommonTimeServer::stateToString(ICommonClock::State s) {
+ switch(s) {
+ case ICommonClock::STATE_INITIAL:
+ return "INITIAL";
+ case ICommonClock::STATE_CLIENT:
+ return "CLIENT";
+ case ICommonClock::STATE_MASTER:
+ return "MASTER";
+ case ICommonClock::STATE_RONIN:
+ return "RONIN";
+ case ICommonClock::STATE_WAIT_FOR_ELECTION:
+ return "WAIT_FOR_ELECTION";
+ default:
+ return "unknown";
+ }
+}
+
+void CommonTimeServer::sockaddrToString(const sockaddr_storage& addr,
+ bool addrValid,
+ char* buf, size_t bufLen) {
+ if (!bufLen || !buf)
+ return;
+
+ if (addrValid) {
+ switch (addr.ss_family) {
+ case AF_INET: {
+ const struct sockaddr_in* sa =
+ reinterpret_cast<const struct sockaddr_in*>(&addr);
+ unsigned long a = ntohl(sa->sin_addr.s_addr);
+ uint16_t p = ntohs(sa->sin_port);
+ snprintf(buf, bufLen, "%lu.%lu.%lu.%lu:%hu",
+ ((a >> 24) & 0xFF), ((a >> 16) & 0xFF),
+ ((a >> 8) & 0xFF), (a & 0xFF), p);
+ } break;
+
+ case AF_INET6: {
+ const struct sockaddr_in6* sa =
+ reinterpret_cast<const struct sockaddr_in6*>(&addr);
+ const uint8_t* a = sa->sin6_addr.s6_addr;
+ uint16_t p = ntohs(sa->sin6_port);
+ snprintf(buf, bufLen,
+ "%02X%02X:%02X%02X:%02X%02X:%02X%02X:"
+ "%02X%02X:%02X%02X:%02X%02X:%02X%02X port %hd",
+ a[0], a[1], a[ 2], a[ 3], a[ 4], a[ 5], a[ 6], a[ 7],
+ a[8], a[9], a[10], a[11], a[12], a[13], a[14], a[15],
+ p);
+ } break;
+
+ default:
+ snprintf(buf, bufLen,
+ "<unknown sockaddr family %d>", addr.ss_family);
+ break;
+ }
+ } else {
+ snprintf(buf, bufLen, "<none>");
+ }
+
+ buf[bufLen - 1] = 0;
+}
+
+bool CommonTimeServer::sockaddrMatch(const sockaddr_storage& a1,
+ const sockaddr_storage& a2,
+ bool matchAddressOnly) {
+ if (a1.ss_family != a2.ss_family)
+ return false;
+
+ switch (a1.ss_family) {
+ case AF_INET: {
+ const struct sockaddr_in* sa1 =
+ reinterpret_cast<const struct sockaddr_in*>(&a1);
+ const struct sockaddr_in* sa2 =
+ reinterpret_cast<const struct sockaddr_in*>(&a2);
+
+ if (sa1->sin_addr.s_addr != sa2->sin_addr.s_addr)
+ return false;
+
+ return (matchAddressOnly || (sa1->sin_port == sa2->sin_port));
+ } break;
+
+ case AF_INET6: {
+ const struct sockaddr_in6* sa1 =
+ reinterpret_cast<const struct sockaddr_in6*>(&a1);
+ const struct sockaddr_in6* sa2 =
+ reinterpret_cast<const struct sockaddr_in6*>(&a2);
+
+ if (memcmp(&sa1->sin6_addr, &sa2->sin6_addr, sizeof(sa2->sin6_addr)))
+ return false;
+
+ return (matchAddressOnly || (sa1->sin6_port == sa2->sin6_port));
+ } break;
+
+ // Huh? We don't deal in non-IPv[46] addresses. Not sure how we got
+ // here, but we don't know how to comapre these addresses and simply
+ // default to a no-match decision.
+ default: return false;
+ }
+}
+
+void CommonTimeServer::TimeoutHelper::setTimeout(int msec) {
+ mTimeoutValid = (msec >= 0);
+ if (mTimeoutValid)
+ mEndTime = systemTime() +
+ (static_cast<nsecs_t>(msec) * 1000000);
+}
+
+int CommonTimeServer::TimeoutHelper::msecTillTimeout() {
+ if (!mTimeoutValid)
+ return kInfiniteTimeout;
+
+ nsecs_t now = systemTime();
+ if (now >= mEndTime)
+ return 0;
+
+ uint64_t deltaMsec = (((mEndTime - now) + 999999) / 1000000);
+
+ if (deltaMsec > static_cast<uint64_t>(MAX_INT))
+ return MAX_INT;
+
+ return static_cast<int>(deltaMsec);
+}
+
+bool CommonTimeServer::shouldPanicNotGettingGoodData() {
+ if (mClient_FirstSyncTX) {
+ int64_t now = mLocalClock.getLocalTime();
+ int64_t delta = now - (mClient_LastGoodSyncRX
+ ? mClient_LastGoodSyncRX
+ : mClient_FirstSyncTX);
+ int64_t deltaUsec = mCommonClock.localDurationToCommonDuration(delta);
+
+ if (deltaUsec >= kNoGoodDataPanicThresholdUsec)
+ return true;
+ }
+
+ return false;
+}
+
+void CommonTimeServer::PacketRTTLog::logTX(int64_t txTime) {
+ txTimes[wrPtr] = txTime;
+ rxTimes[wrPtr] = 0;
+ wrPtr = (wrPtr + 1) % RTT_LOG_SIZE;
+ if (!wrPtr)
+ logFull = true;
+}
+
+void CommonTimeServer::PacketRTTLog::logRX(int64_t txTime, int64_t rxTime) {
+ if (!logFull && !wrPtr)
+ return;
+
+ uint32_t i = logFull ? wrPtr : 0;
+ do {
+ if (txTimes[i] == txTime) {
+ rxTimes[i] = rxTime;
+ break;
+ }
+ i = (i + 1) % RTT_LOG_SIZE;
+ } while (i != wrPtr);
+}
+
+} // namespace android
diff --git a/services/common_time/common_time_server.h b/services/common_time/common_time_server.h
new file mode 100644
index 0000000..a0f549f
--- /dev/null
+++ b/services/common_time/common_time_server.h
@@ -0,0 +1,330 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#ifndef ANDROID_COMMON_TIME_SERVER_H
+#define ANDROID_COMMON_TIME_SERVER_H
+
+#include <arpa/inet.h>
+#include <stdint.h>
+#include <linux/socket.h>
+
+#include <common_time/ICommonClock.h>
+#include <common_time/local_clock.h>
+#include <utils/String8.h>
+
+#include "clock_recovery.h"
+#include "common_clock.h"
+#include "common_time_server_packets.h"
+
+#define RTT_LOG_SIZE 30
+
+namespace android {
+
+class CommonClockService;
+class CommonTimeConfigService;
+
+/***** time service implementation *****/
+
+class CommonTimeServer : public Thread {
+ public:
+ CommonTimeServer();
+ ~CommonTimeServer();
+
+ bool startServices();
+
+ // Common Clock API methods
+ CommonClock& getCommonClock() { return mCommonClock; }
+ LocalClock& getLocalClock() { return mLocalClock; }
+ uint64_t getTimelineID();
+ int32_t getEstimatedError();
+ ICommonClock::State getState();
+ status_t getMasterAddr(struct sockaddr_storage* addr);
+ status_t isCommonTimeValid(bool* valid, uint32_t* timelineID);
+
+ // Config API methods
+ status_t getMasterElectionPriority(uint8_t *priority);
+ status_t setMasterElectionPriority(uint8_t priority);
+ status_t getMasterElectionEndpoint(struct sockaddr_storage *addr);
+ status_t setMasterElectionEndpoint(const struct sockaddr_storage *addr);
+ status_t getMasterElectionGroupId(uint64_t *id);
+ status_t setMasterElectionGroupId(uint64_t id);
+ status_t getInterfaceBinding(String8& ifaceName);
+ status_t setInterfaceBinding(const String8& ifaceName);
+ status_t getMasterAnnounceInterval(int *interval);
+ status_t setMasterAnnounceInterval(int interval);
+ status_t getClientSyncInterval(int *interval);
+ status_t setClientSyncInterval(int interval);
+ status_t getPanicThreshold(int *threshold);
+ status_t setPanicThreshold(int threshold);
+ status_t getAutoDisable(bool *autoDisable);
+ status_t setAutoDisable(bool autoDisable);
+ status_t forceNetworklessMasterMode();
+
+ // Method used by the CommonClockService to notify the core service about
+ // changes in the number of active common clock clients.
+ void reevaluateAutoDisableState(bool commonClockHasClients);
+
+ status_t dumpClockInterface(int fd, const Vector<String16>& args,
+ size_t activeClients);
+ status_t dumpConfigInterface(int fd, const Vector<String16>& args);
+
+ private:
+ class PacketRTTLog {
+ public:
+ PacketRTTLog() {
+ resetLog();
+ }
+
+ void resetLog() {
+ wrPtr = 0;
+ logFull = 0;
+ }
+
+ void logTX(int64_t txTime);
+ void logRX(int64_t txTime, int64_t rxTime);
+ void dumpLog(int fd, const CommonClock& cclk);
+
+ private:
+ uint32_t wrPtr;
+ bool logFull;
+ int64_t txTimes[RTT_LOG_SIZE];
+ int64_t rxTimes[RTT_LOG_SIZE];
+ };
+
+ class TimeoutHelper {
+ public:
+ TimeoutHelper() : mTimeoutValid(false) { }
+
+ void setTimeout(int msec);
+ int msecTillTimeout();
+
+ private:
+ bool mTimeoutValid;
+ nsecs_t mEndTime;
+ };
+
+ bool threadLoop();
+
+ bool runStateMachine_l();
+ bool setupSocket_l();
+
+ void assignTimelineID();
+ bool assignDeviceID();
+
+ static bool arbitrateMaster(uint64_t deviceID1, uint8_t devicePrio1,
+ uint64_t deviceID2, uint8_t devicePrio2);
+
+ bool handlePacket();
+ bool handleWhoIsMasterRequest (const WhoIsMasterRequestPacket* request,
+ const sockaddr_storage& srcAddr);
+ bool handleWhoIsMasterResponse(const WhoIsMasterResponsePacket* response,
+ const sockaddr_storage& srcAddr);
+ bool handleSyncRequest (const SyncRequestPacket* request,
+ const sockaddr_storage& srcAddr);
+ bool handleSyncResponse (const SyncResponsePacket* response,
+ const sockaddr_storage& srcAddr);
+ bool handleMasterAnnouncement (const MasterAnnouncementPacket* packet,
+ const sockaddr_storage& srcAddr);
+
+ bool handleTimeout();
+ bool handleTimeoutInitial();
+ bool handleTimeoutClient();
+ bool handleTimeoutMaster();
+ bool handleTimeoutRonin();
+ bool handleTimeoutWaitForElection();
+
+ bool sendWhoIsMasterRequest();
+ bool sendSyncRequest();
+ bool sendMasterAnnouncement();
+
+ bool becomeClient(const sockaddr_storage& masterAddr,
+ uint64_t masterDeviceID,
+ uint8_t masterDevicePriority,
+ uint64_t timelineID,
+ const char* cause);
+ bool becomeMaster(const char* cause);
+ bool becomeRonin(const char* cause);
+ bool becomeWaitForElection(const char* cause);
+ bool becomeInitial(const char* cause);
+
+ void notifyClockSync();
+ void notifyClockSyncLoss();
+
+ ICommonClock::State mState;
+ void setState(ICommonClock::State s);
+
+ void clearPendingWakeupEvents_l();
+ void wakeupThread_l();
+ void cleanupSocket_l();
+ void shutdownThread();
+
+ inline uint8_t effectivePriority() const {
+ return (mMasterPriority & 0x7F) |
+ (mForceLowPriority ? 0x00 : 0x80);
+ }
+
+ inline bool shouldAutoDisable() const {
+ return (mAutoDisable && !mCommonClockHasClients);
+ }
+
+ inline void resetSyncStats() {
+ mClient_SyncRequestPending = false;
+ mClient_SyncRequestTimeouts = 0;
+ mClient_SyncsSentToCurMaster = 0;
+ mClient_SyncRespsRXedFromCurMaster = 0;
+ mClient_ExpiredSyncRespsRXedFromCurMaster = 0;
+ mClient_FirstSyncTX = 0;
+ mClient_LastGoodSyncRX = 0;
+ mClient_PacketRTTLog.resetLog();
+ }
+
+ bool shouldPanicNotGettingGoodData();
+
+ // Helper to keep track of the state machine's current timeout
+ TimeoutHelper mCurTimeout;
+
+ // common clock, local clock abstraction, and clock recovery loop
+ CommonClock mCommonClock;
+ LocalClock mLocalClock;
+ ClockRecoveryLoop mClockRecovery;
+
+ // implementation of ICommonClock
+ sp<CommonClockService> mICommonClock;
+
+ // implementation of ICommonTimeConfig
+ sp<CommonTimeConfigService> mICommonTimeConfig;
+
+ // UDP socket for the time sync protocol
+ int mSocket;
+
+ // eventfd used to wakeup the work thread in response to configuration
+ // changes.
+ int mWakeupThreadFD;
+
+ // timestamp captured when a packet is received
+ int64_t mLastPacketRxLocalTime;
+
+ // ID of the timeline that this device is following
+ uint64_t mTimelineID;
+
+ // flag for whether the clock has been synced to a timeline
+ bool mClockSynced;
+
+ // flag used to indicate that clients should be considered to be lower
+ // priority than all of their peers during elections. This flag is set and
+ // cleared by the state machine. It is set when the client joins a new
+ // network. If the client had been a master in the old network (or an
+ // isolated master with no network connectivity) it should defer to any
+ // masters which may already be on the network. It will be cleared whenever
+ // the state machine transitions to the master state.
+ bool mForceLowPriority;
+ inline void setForceLowPriority(bool val) {
+ mForceLowPriority = val;
+ if (mState == ICommonClock::STATE_MASTER)
+ mClient_MasterDevicePriority = effectivePriority();
+ }
+
+ // Lock to synchronize access to internal state and configuration.
+ Mutex mLock;
+
+ // Flag updated by the common clock service to indicate that it does or does
+ // not currently have registered clients. When the the auto disable flag is
+ // cleared on the common time service, the service will participate in
+ // network synchronization whenever it has a valid network interface to bind
+ // to. When the auto disable flag is set on the common time service, it
+ // will only participate in network synchronization when it has both a valid
+ // interface AND currently active common clock clients.
+ bool mCommonClockHasClients;
+
+ // Configuration info
+ struct sockaddr_storage mMasterElectionEP; // Endpoint over which we conduct master election
+ String8 mBindIface; // Endpoint for the service to bind to.
+ bool mBindIfaceValid; // whether or not the bind Iface is valid.
+ bool mBindIfaceDirty; // whether or not the bind Iface is valid.
+ struct sockaddr_storage mMasterEP; // Endpoint of our current master (if any)
+ bool mMasterEPValid;
+ uint64_t mDeviceID; // unique ID of this device
+ uint64_t mSyncGroupID; // synchronization group ID of this device.
+ uint8_t mMasterPriority; // Priority of this device in master election.
+ uint32_t mMasterAnnounceIntervalMs;
+ uint32_t mSyncRequestIntervalMs;
+ uint32_t mPanicThresholdUsec;
+ bool mAutoDisable;
+
+ // Config defaults.
+ static const char* kDefaultMasterElectionAddr;
+ static const uint16_t kDefaultMasterElectionPort;
+ static const uint64_t kDefaultSyncGroupID;
+ static const uint8_t kDefaultMasterPriority;
+ static const uint32_t kDefaultMasterAnnounceIntervalMs;
+ static const uint32_t kDefaultSyncRequestIntervalMs;
+ static const uint32_t kDefaultPanicThresholdUsec;
+ static const bool kDefaultAutoDisable;
+
+ // Priority mask and shift fields.
+ static const uint64_t kDeviceIDMask;
+ static const uint8_t kDevicePriorityMask;
+ static const uint8_t kDevicePriorityHiLowBit;
+ static const uint32_t kDevicePriorityShift;
+
+ // Unconfgurable constants
+ static const int kSetupRetryTimeoutMs;
+ static const int64_t kNoGoodDataPanicThresholdUsec;
+ static const uint32_t kRTTDiscardPanicThreshMultiplier;
+
+ /*** status while in the Initial state ***/
+ int mInitial_WhoIsMasterRequestTimeouts;
+ static const int kInitial_NumWhoIsMasterRetries;
+ static const int kInitial_WhoIsMasterTimeoutMs;
+
+ /*** status while in the Client state ***/
+ uint64_t mClient_MasterDeviceID;
+ uint8_t mClient_MasterDevicePriority;
+ bool mClient_SyncRequestPending;
+ int mClient_SyncRequestTimeouts;
+ uint32_t mClient_SyncsSentToCurMaster;
+ uint32_t mClient_SyncRespsRXedFromCurMaster;
+ uint32_t mClient_ExpiredSyncRespsRXedFromCurMaster;
+ int64_t mClient_FirstSyncTX;
+ int64_t mClient_LastGoodSyncRX;
+ PacketRTTLog mClient_PacketRTTLog;
+ static const int kClient_NumSyncRequestRetries;
+
+
+ /*** status while in the Master state ***/
+ static const uint32_t kDefaultMaster_AnnouncementIntervalMs;
+
+ /*** status while in the Ronin state ***/
+ int mRonin_WhoIsMasterRequestTimeouts;
+ static const int kRonin_NumWhoIsMasterRetries;
+ static const int kRonin_WhoIsMasterTimeoutMs;
+
+ /*** status while in the WaitForElection state ***/
+ static const int kWaitForElection_TimeoutMs;
+
+ static const int kInfiniteTimeout;
+
+ static const char* stateToString(ICommonClock::State s);
+ static void sockaddrToString(const sockaddr_storage& addr, bool addrValid,
+ char* buf, size_t bufLen);
+ static bool sockaddrMatch(const sockaddr_storage& a1,
+ const sockaddr_storage& a2,
+ bool matchAddressOnly);
+};
+
+} // namespace android
+
+#endif // ANDROID_COMMON_TIME_SERVER_H
diff --git a/services/common_time/common_time_server_api.cpp b/services/common_time/common_time_server_api.cpp
new file mode 100644
index 0000000..fb8c261
--- /dev/null
+++ b/services/common_time/common_time_server_api.cpp
@@ -0,0 +1,435 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+/*
+ * A service that exchanges time synchronization information between
+ * a master that defines a timeline and clients that follow the timeline.
+ */
+
+#define LOG_TAG "common_time"
+#include <utils/Log.h>
+
+#include <binder/IServiceManager.h>
+#include <binder/IPCThreadState.h>
+
+#include "common_time_server.h"
+
+namespace android {
+
+//
+// Clock API
+//
+uint64_t CommonTimeServer::getTimelineID() {
+ AutoMutex _lock(&mLock);
+ return mTimelineID;
+}
+
+ICommonClock::State CommonTimeServer::getState() {
+ AutoMutex _lock(&mLock);
+ return mState;
+}
+
+status_t CommonTimeServer::getMasterAddr(struct sockaddr_storage* addr) {
+ AutoMutex _lock(&mLock);
+ if (mMasterEPValid) {
+ memcpy(addr, &mMasterEP, sizeof(*addr));
+ return OK;
+ }
+
+ return UNKNOWN_ERROR;
+}
+
+int32_t CommonTimeServer::getEstimatedError() {
+ AutoMutex _lock(&mLock);
+
+ if (ICommonClock::STATE_MASTER == mState)
+ return 0;
+
+ if (!mClockSynced)
+ return ICommonClock::kErrorEstimateUnknown;
+
+ return mClockRecovery.getLastErrorEstimate();
+}
+
+status_t CommonTimeServer::isCommonTimeValid(bool* valid,
+ uint32_t* timelineID) {
+ AutoMutex _lock(&mLock);
+ *valid = mCommonClock.isValid();
+ *timelineID = mTimelineID;
+ return OK;
+}
+
+//
+// Config API
+//
+status_t CommonTimeServer::getMasterElectionPriority(uint8_t *priority) {
+ AutoMutex _lock(&mLock);
+ *priority = mMasterPriority;
+ return OK;
+}
+
+status_t CommonTimeServer::setMasterElectionPriority(uint8_t priority) {
+ AutoMutex _lock(&mLock);
+
+ if (priority > 0x7F)
+ return BAD_VALUE;
+
+ mMasterPriority = priority;
+ return OK;
+}
+
+status_t CommonTimeServer::getMasterElectionEndpoint(
+ struct sockaddr_storage *addr) {
+ AutoMutex _lock(&mLock);
+ memcpy(addr, &mMasterElectionEP, sizeof(*addr));
+ return OK;
+}
+
+status_t CommonTimeServer::setMasterElectionEndpoint(
+ const struct sockaddr_storage *addr) {
+ AutoMutex _lock(&mLock);
+
+ if (!addr)
+ return BAD_VALUE;
+
+ // TODO: add proper support for IPv6
+ if (addr->ss_family != AF_INET)
+ return BAD_VALUE;
+
+ // Only multicast and broadcast endpoints with explicit ports are allowed.
+ uint16_t ipv4Port = ntohs(
+ reinterpret_cast<const struct sockaddr_in*>(addr)->sin_port);
+ if (!ipv4Port)
+ return BAD_VALUE;
+
+ uint32_t ipv4Addr = ntohl(
+ reinterpret_cast<const struct sockaddr_in*>(addr)->sin_addr.s_addr);
+ if ((ipv4Addr != 0xFFFFFFFF) && (0xE0000000 != (ipv4Addr & 0xF0000000)))
+ return BAD_VALUE;
+
+ memcpy(&mMasterElectionEP, addr, sizeof(mMasterElectionEP));
+
+ // Force a rebind in order to change election enpoints.
+ mBindIfaceDirty = true;
+ wakeupThread_l();
+ return OK;
+}
+
+status_t CommonTimeServer::getMasterElectionGroupId(uint64_t *id) {
+ AutoMutex _lock(&mLock);
+ *id = mSyncGroupID;
+ return OK;
+}
+
+status_t CommonTimeServer::setMasterElectionGroupId(uint64_t id) {
+ AutoMutex _lock(&mLock);
+ mSyncGroupID = id;
+ return OK;
+}
+
+status_t CommonTimeServer::getInterfaceBinding(String8& ifaceName) {
+ AutoMutex _lock(&mLock);
+ if (!mBindIfaceValid)
+ return INVALID_OPERATION;
+ ifaceName = mBindIface;
+ return OK;
+}
+
+status_t CommonTimeServer::setInterfaceBinding(const String8& ifaceName) {
+ AutoMutex _lock(&mLock);
+
+ mBindIfaceDirty = true;
+ if (ifaceName.size()) {
+ mBindIfaceValid = true;
+ mBindIface = ifaceName;
+ } else {
+ mBindIfaceValid = false;
+ mBindIface.clear();
+ }
+
+ wakeupThread_l();
+ return OK;
+}
+
+status_t CommonTimeServer::getMasterAnnounceInterval(int *interval) {
+ AutoMutex _lock(&mLock);
+ *interval = mMasterAnnounceIntervalMs;
+ return OK;
+}
+
+status_t CommonTimeServer::setMasterAnnounceInterval(int interval) {
+ AutoMutex _lock(&mLock);
+
+ if (interval > (6 *3600000)) // Max interval is once every 6 hrs
+ return BAD_VALUE;
+
+ if (interval < 500) // Min interval is once per 0.5 seconds
+ return BAD_VALUE;
+
+ mMasterAnnounceIntervalMs = interval;
+ if (ICommonClock::STATE_MASTER == mState) {
+ int pendingTimeout = mCurTimeout.msecTillTimeout();
+ if ((kInfiniteTimeout == pendingTimeout) ||
+ (pendingTimeout > interval)) {
+ mCurTimeout.setTimeout(mMasterAnnounceIntervalMs);
+ wakeupThread_l();
+ }
+ }
+
+ return OK;
+}
+
+status_t CommonTimeServer::getClientSyncInterval(int *interval) {
+ AutoMutex _lock(&mLock);
+ *interval = mSyncRequestIntervalMs;
+ return OK;
+}
+
+status_t CommonTimeServer::setClientSyncInterval(int interval) {
+ AutoMutex _lock(&mLock);
+
+ if (interval > (3600000)) // Max interval is once every 60 min
+ return BAD_VALUE;
+
+ if (interval < 250) // Min interval is once per 0.25 seconds
+ return BAD_VALUE;
+
+ mSyncRequestIntervalMs = interval;
+ if (ICommonClock::STATE_CLIENT == mState) {
+ int pendingTimeout = mCurTimeout.msecTillTimeout();
+ if ((kInfiniteTimeout == pendingTimeout) ||
+ (pendingTimeout > interval)) {
+ mCurTimeout.setTimeout(mSyncRequestIntervalMs);
+ wakeupThread_l();
+ }
+ }
+
+ return OK;
+}
+
+status_t CommonTimeServer::getPanicThreshold(int *threshold) {
+ AutoMutex _lock(&mLock);
+ *threshold = mPanicThresholdUsec;
+ return OK;
+}
+
+status_t CommonTimeServer::setPanicThreshold(int threshold) {
+ AutoMutex _lock(&mLock);
+
+ if (threshold < 1000) // Min threshold is 1mSec
+ return BAD_VALUE;
+
+ mPanicThresholdUsec = threshold;
+ return OK;
+}
+
+status_t CommonTimeServer::getAutoDisable(bool *autoDisable) {
+ AutoMutex _lock(&mLock);
+ *autoDisable = mAutoDisable;
+ return OK;
+}
+
+status_t CommonTimeServer::setAutoDisable(bool autoDisable) {
+ AutoMutex _lock(&mLock);
+ mAutoDisable = autoDisable;
+ wakeupThread_l();
+ return OK;
+}
+
+status_t CommonTimeServer::forceNetworklessMasterMode() {
+ AutoMutex _lock(&mLock);
+
+ // Can't force networkless master mode if we are currently bound to a
+ // network.
+ if (mSocket >= 0)
+ return INVALID_OPERATION;
+
+ becomeMaster("force networkless");
+
+ return OK;
+}
+
+void CommonTimeServer::reevaluateAutoDisableState(bool commonClockHasClients) {
+ AutoMutex _lock(&mLock);
+ bool needWakeup = (mAutoDisable && mMasterEPValid &&
+ (commonClockHasClients != mCommonClockHasClients));
+
+ mCommonClockHasClients = commonClockHasClients;
+
+ if (needWakeup) {
+ ALOGI("Waking up service, auto-disable is engaged and service now has%s"
+ " clients", mCommonClockHasClients ? "" : " no");
+ wakeupThread_l();
+ }
+}
+
+#define dump_printf(a, b...) do { \
+ int res; \
+ res = snprintf(buffer, sizeof(buffer), a, b); \
+ buffer[sizeof(buffer) - 1] = 0; \
+ if (res > 0) \
+ write(fd, buffer, res); \
+} while (0)
+#define checked_percentage(a, b) ((0 == b) ? 0.0f : ((100.0f * a) / b))
+
+status_t CommonTimeServer::dumpClockInterface(int fd,
+ const Vector<String16>& args,
+ size_t activeClients) {
+ AutoMutex _lock(&mLock);
+ const size_t SIZE = 256;
+ char buffer[SIZE];
+
+ if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
+ snprintf(buffer, SIZE, "Permission Denial: "
+ "can't dump CommonClockService from pid=%d, uid=%d\n",
+ IPCThreadState::self()->getCallingPid(),
+ IPCThreadState::self()->getCallingUid());
+ write(fd, buffer, strlen(buffer));
+ } else {
+ int64_t commonTime;
+ int64_t localTime;
+ bool synced;
+ char maStr[64];
+
+ localTime = mLocalClock.getLocalTime();
+ synced = (OK == mCommonClock.localToCommon(localTime, &commonTime));
+ sockaddrToString(mMasterEP, mMasterEPValid, maStr, sizeof(maStr));
+
+ dump_printf("Common Clock Service Status\nLocal time : %lld\n",
+ localTime);
+
+ if (synced)
+ dump_printf("Common time : %lld\n", commonTime);
+ else
+ dump_printf("Common time : %s\n", "not synced");
+
+ dump_printf("Timeline ID : %016llx\n", mTimelineID);
+ dump_printf("State : %s\n", stateToString(mState));
+ dump_printf("Master Addr : %s\n", maStr);
+
+
+ if (synced) {
+ int32_t est = (ICommonClock::STATE_MASTER != mState)
+ ? mClockRecovery.getLastErrorEstimate()
+ : 0;
+ dump_printf("Error Est. : %.3f msec\n",
+ static_cast<float>(est) / 1000.0);
+ } else {
+ dump_printf("Error Est. : %s\n", "unknown");
+ }
+
+ dump_printf("Syncs TXes : %u\n", mClient_SyncsSentToCurMaster);
+ dump_printf("Syncs RXes : %u (%.2f%%)\n",
+ mClient_SyncRespsRXedFromCurMaster,
+ checked_percentage(
+ mClient_SyncRespsRXedFromCurMaster,
+ mClient_SyncsSentToCurMaster));
+ dump_printf("RXs Expired : %u (%.2f%%)\n",
+ mClient_ExpiredSyncRespsRXedFromCurMaster,
+ checked_percentage(
+ mClient_ExpiredSyncRespsRXedFromCurMaster,
+ mClient_SyncsSentToCurMaster));
+
+ if (!mClient_LastGoodSyncRX) {
+ dump_printf("Last Good RX : %s\n", "unknown");
+ } else {
+ int64_t localDelta, usecDelta;
+ localDelta = localTime - mClient_LastGoodSyncRX;
+ usecDelta = mCommonClock.localDurationToCommonDuration(localDelta);
+ dump_printf("Last Good RX : %lld uSec ago\n", usecDelta);
+ }
+
+ dump_printf("Active Clients : %u\n", activeClients);
+ mClient_PacketRTTLog.dumpLog(fd, mCommonClock);
+ }
+
+ return NO_ERROR;
+}
+
+status_t CommonTimeServer::dumpConfigInterface(int fd,
+ const Vector<String16>& args) {
+ AutoMutex _lock(&mLock);
+ const size_t SIZE = 256;
+ char buffer[SIZE];
+
+ if (checkCallingPermission(String16("android.permission.DUMP")) == false) {
+ snprintf(buffer, SIZE, "Permission Denial: "
+ "can't dump CommonTimeConfigService from pid=%d, uid=%d\n",
+ IPCThreadState::self()->getCallingPid(),
+ IPCThreadState::self()->getCallingUid());
+ write(fd, buffer, strlen(buffer));
+ } else {
+ char meStr[64];
+
+ sockaddrToString(mMasterElectionEP, true, meStr, sizeof(meStr));
+
+ dump_printf("Common Time Config Service Status\n"
+ "Bound Interface : %s\n",
+ mBindIfaceValid ? mBindIface.string() : "<unbound>");
+ dump_printf("Master Election Endpoint : %s\n", meStr);
+ dump_printf("Master Election Group ID : %016llx\n", mSyncGroupID);
+ dump_printf("Master Announce Interval : %d mSec\n",
+ mMasterAnnounceIntervalMs);
+ dump_printf("Client Sync Interval : %d mSec\n",
+ mSyncRequestIntervalMs);
+ dump_printf("Panic Threshold : %d uSec\n",
+ mPanicThresholdUsec);
+ dump_printf("Base ME Prio : 0x%02x\n",
+ static_cast<uint32_t>(mMasterPriority));
+ dump_printf("Effective ME Prio : 0x%02x\n",
+ static_cast<uint32_t>(effectivePriority()));
+ dump_printf("Auto Disable Allowed : %s\n",
+ mAutoDisable ? "yes" : "no");
+ dump_printf("Auto Disable Engaged : %s\n",
+ shouldAutoDisable() ? "yes" : "no");
+ }
+
+ return NO_ERROR;
+}
+
+void CommonTimeServer::PacketRTTLog::dumpLog(int fd, const CommonClock& cclk) {
+ const size_t SIZE = 256;
+ char buffer[SIZE];
+ uint32_t avail = !logFull ? wrPtr : RTT_LOG_SIZE;
+
+ if (!avail)
+ return;
+
+ dump_printf("\nPacket Log (%d entries)\n", avail);
+
+ uint32_t ndx = 0;
+ uint32_t i = logFull ? wrPtr : 0;
+ do {
+ if (rxTimes[i]) {
+ int64_t delta = rxTimes[i] - txTimes[i];
+ int64_t deltaUsec = cclk.localDurationToCommonDuration(delta);
+ dump_printf("pkt[%2d] : localTX %12lld localRX %12lld "
+ "(%.3f msec RTT)\n",
+ ndx, txTimes[i], rxTimes[i],
+ static_cast<float>(deltaUsec) / 1000.0);
+ } else {
+ dump_printf("pkt[%2d] : localTX %12lld localRX never\n",
+ ndx, txTimes[i]);
+ }
+ i = (i + 1) % RTT_LOG_SIZE;
+ ndx++;
+ } while (i != wrPtr);
+}
+
+#undef dump_printf
+#undef checked_percentage
+
+} // namespace android
diff --git a/services/common_time/common_time_server_packets.cpp b/services/common_time/common_time_server_packets.cpp
new file mode 100644
index 0000000..9833c37
--- /dev/null
+++ b/services/common_time/common_time_server_packets.cpp
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+/*
+ * A service that exchanges time synchronization information between
+ * a master that defines a timeline and clients that follow the timeline.
+ */
+
+#define LOG_TAG "common_time"
+#include <utils/Log.h>
+
+#include <arpa/inet.h>
+#include <stdint.h>
+
+#include "common_time_server_packets.h"
+
+namespace android {
+
+const uint32_t TimeServicePacketHeader::kMagic =
+ (static_cast<uint32_t>('c') << 24) |
+ (static_cast<uint32_t>('c') << 16) |
+ (static_cast<uint32_t>('l') << 8) |
+ static_cast<uint32_t>('k');
+
+const uint16_t TimeServicePacketHeader::kCurVersion = 1;
+
+#define SERIALIZE_FIELD(field_name, type, converter) \
+ do { \
+ if ((offset + sizeof(field_name)) > length) \
+ return -1; \
+ *((type*)(data + offset)) = converter(field_name); \
+ offset += sizeof(field_name); \
+ } while (0)
+#define SERIALIZE_INT16(field_name) SERIALIZE_FIELD(field_name, int16_t, htons)
+#define SERIALIZE_INT32(field_name) SERIALIZE_FIELD(field_name, int32_t, htonl)
+#define SERIALIZE_INT64(field_name) SERIALIZE_FIELD(field_name, int64_t, htonq)
+
+#define DESERIALIZE_FIELD(field_name, type, converter) \
+ do { \
+ if ((offset + sizeof(field_name)) > length) \
+ return -1; \
+ field_name = converter(*((type*)(data + offset))); \
+ offset += sizeof(field_name); \
+ } while (0)
+#define DESERIALIZE_INT16(field_name) DESERIALIZE_FIELD(field_name, int16_t, ntohs)
+#define DESERIALIZE_INT32(field_name) DESERIALIZE_FIELD(field_name, int32_t, ntohl)
+#define DESERIALIZE_INT64(field_name) DESERIALIZE_FIELD(field_name, int64_t, ntohq)
+
+#define kDevicePriorityShift 56
+#define kDeviceIDMask ((static_cast<uint64_t>(1) << kDevicePriorityShift) - 1)
+
+inline uint64_t packDeviceID(uint64_t devID, uint8_t prio) {
+ return (devID & kDeviceIDMask) |
+ (static_cast<uint64_t>(prio) << kDevicePriorityShift);
+}
+
+inline uint64_t unpackDeviceID(uint64_t packed) {
+ return (packed & kDeviceIDMask);
+}
+
+inline uint8_t unpackDevicePriority(uint64_t packed) {
+ return static_cast<uint8_t>(packed >> kDevicePriorityShift);
+}
+
+ssize_t TimeServicePacketHeader::serializeHeader(uint8_t* data,
+ uint32_t length) {
+ ssize_t offset = 0;
+ int16_t pktType = static_cast<int16_t>(packetType);
+ SERIALIZE_INT32(magic);
+ SERIALIZE_INT16(version);
+ SERIALIZE_INT16(pktType);
+ SERIALIZE_INT64(timelineID);
+ SERIALIZE_INT64(syncGroupID);
+ return offset;
+}
+
+ssize_t TimeServicePacketHeader::deserializeHeader(const uint8_t* data,
+ uint32_t length) {
+ ssize_t offset = 0;
+ int16_t tmp;
+ DESERIALIZE_INT32(magic);
+ DESERIALIZE_INT16(version);
+ DESERIALIZE_INT16(tmp);
+ DESERIALIZE_INT64(timelineID);
+ DESERIALIZE_INT64(syncGroupID);
+ packetType = static_cast<TimeServicePacketType>(tmp);
+ return offset;
+}
+
+ssize_t TimeServicePacketHeader::serializePacket(uint8_t* data,
+ uint32_t length) {
+ ssize_t ret, tmp;
+
+ ret = serializeHeader(data, length);
+ if (ret < 0)
+ return ret;
+
+ data += ret;
+ length -= ret;
+
+ switch (packetType) {
+ case TIME_PACKET_WHO_IS_MASTER_REQUEST:
+ tmp =((WhoIsMasterRequestPacket*)(this))->serializePacket(data,
+ length);
+ break;
+ case TIME_PACKET_WHO_IS_MASTER_RESPONSE:
+ tmp =((WhoIsMasterResponsePacket*)(this))->serializePacket(data,
+ length);
+ break;
+ case TIME_PACKET_SYNC_REQUEST:
+ tmp =((SyncRequestPacket*)(this))->serializePacket(data, length);
+ break;
+ case TIME_PACKET_SYNC_RESPONSE:
+ tmp =((SyncResponsePacket*)(this))->serializePacket(data, length);
+ break;
+ case TIME_PACKET_MASTER_ANNOUNCEMENT:
+ tmp =((MasterAnnouncementPacket*)(this))->serializePacket(data,
+ length);
+ break;
+ default:
+ return -1;
+ }
+
+ if (tmp < 0)
+ return tmp;
+
+ return ret + tmp;
+}
+
+ssize_t UniversalTimeServicePacket::deserializePacket(
+ const uint8_t* data,
+ uint32_t length,
+ uint64_t expectedSyncGroupID) {
+ ssize_t ret;
+ TimeServicePacketHeader* header;
+ if (length < 8)
+ return -1;
+
+ packetType = ntohs(*((uint16_t*)(data + 6)));
+ switch (packetType) {
+ case TIME_PACKET_WHO_IS_MASTER_REQUEST:
+ ret = p.who_is_master_request.deserializePacket(data, length);
+ header = &p.who_is_master_request;
+ break;
+ case TIME_PACKET_WHO_IS_MASTER_RESPONSE:
+ ret = p.who_is_master_response.deserializePacket(data, length);
+ header = &p.who_is_master_response;
+ break;
+ case TIME_PACKET_SYNC_REQUEST:
+ ret = p.sync_request.deserializePacket(data, length);
+ header = &p.sync_request;
+ break;
+ case TIME_PACKET_SYNC_RESPONSE:
+ ret = p.sync_response.deserializePacket(data, length);
+ header = &p.sync_response;
+ break;
+ case TIME_PACKET_MASTER_ANNOUNCEMENT:
+ ret = p.master_announcement.deserializePacket(data, length);
+ header = &p.master_announcement;
+ break;
+ default:
+ return -1;
+ }
+
+ if ((ret >= 0) && !header->checkPacket(expectedSyncGroupID))
+ ret = -1;
+
+ return ret;
+}
+
+ssize_t WhoIsMasterRequestPacket::serializePacket(uint8_t* data,
+ uint32_t length) {
+ ssize_t offset = serializeHeader(data, length);
+ if (offset > 0) {
+ uint64_t packed = packDeviceID(senderDeviceID, senderDevicePriority);
+ SERIALIZE_INT64(packed);
+ }
+ return offset;
+}
+
+ssize_t WhoIsMasterRequestPacket::deserializePacket(const uint8_t* data,
+ uint32_t length) {
+ ssize_t offset = deserializeHeader(data, length);
+ if (offset > 0) {
+ uint64_t packed;
+ DESERIALIZE_INT64(packed);
+ senderDeviceID = unpackDeviceID(packed);
+ senderDevicePriority = unpackDevicePriority(packed);
+ }
+ return offset;
+}
+
+ssize_t WhoIsMasterResponsePacket::serializePacket(uint8_t* data,
+ uint32_t length) {
+ ssize_t offset = serializeHeader(data, length);
+ if (offset > 0) {
+ uint64_t packed = packDeviceID(deviceID, devicePriority);
+ SERIALIZE_INT64(packed);
+ }
+ return offset;
+}
+
+ssize_t WhoIsMasterResponsePacket::deserializePacket(const uint8_t* data,
+ uint32_t length) {
+ ssize_t offset = deserializeHeader(data, length);
+ if (offset > 0) {
+ uint64_t packed;
+ DESERIALIZE_INT64(packed);
+ deviceID = unpackDeviceID(packed);
+ devicePriority = unpackDevicePriority(packed);
+ }
+ return offset;
+}
+
+ssize_t SyncRequestPacket::serializePacket(uint8_t* data,
+ uint32_t length) {
+ ssize_t offset = serializeHeader(data, length);
+ if (offset > 0) {
+ SERIALIZE_INT64(clientTxLocalTime);
+ }
+ return offset;
+}
+
+ssize_t SyncRequestPacket::deserializePacket(const uint8_t* data,
+ uint32_t length) {
+ ssize_t offset = deserializeHeader(data, length);
+ if (offset > 0) {
+ DESERIALIZE_INT64(clientTxLocalTime);
+ }
+ return offset;
+}
+
+ssize_t SyncResponsePacket::serializePacket(uint8_t* data,
+ uint32_t length) {
+ ssize_t offset = serializeHeader(data, length);
+ if (offset > 0) {
+ SERIALIZE_INT64(clientTxLocalTime);
+ SERIALIZE_INT64(masterRxCommonTime);
+ SERIALIZE_INT64(masterTxCommonTime);
+ SERIALIZE_INT32(nak);
+ }
+ return offset;
+}
+
+ssize_t SyncResponsePacket::deserializePacket(const uint8_t* data,
+ uint32_t length) {
+ ssize_t offset = deserializeHeader(data, length);
+ if (offset > 0) {
+ DESERIALIZE_INT64(clientTxLocalTime);
+ DESERIALIZE_INT64(masterRxCommonTime);
+ DESERIALIZE_INT64(masterTxCommonTime);
+ DESERIALIZE_INT32(nak);
+ }
+ return offset;
+}
+
+ssize_t MasterAnnouncementPacket::serializePacket(uint8_t* data,
+ uint32_t length) {
+ ssize_t offset = serializeHeader(data, length);
+ if (offset > 0) {
+ uint64_t packed = packDeviceID(deviceID, devicePriority);
+ SERIALIZE_INT64(packed);
+ }
+ return offset;
+}
+
+ssize_t MasterAnnouncementPacket::deserializePacket(const uint8_t* data,
+ uint32_t length) {
+ ssize_t offset = deserializeHeader(data, length);
+ if (offset > 0) {
+ uint64_t packed;
+ DESERIALIZE_INT64(packed);
+ deviceID = unpackDeviceID(packed);
+ devicePriority = unpackDevicePriority(packed);
+ }
+ return offset;
+}
+
+} // namespace android
+
diff --git a/services/common_time/common_time_server_packets.h b/services/common_time/common_time_server_packets.h
new file mode 100644
index 0000000..57ba8a2
--- /dev/null
+++ b/services/common_time/common_time_server_packets.h
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+#ifndef ANDROID_COMMON_TIME_SERVER_PACKETS_H
+#define ANDROID_COMMON_TIME_SERVER_PACKETS_H
+
+#include <stdint.h>
+#include <common_time/ICommonClock.h>
+
+namespace android {
+
+/***** time sync protocol packets *****/
+
+enum TimeServicePacketType {
+ TIME_PACKET_WHO_IS_MASTER_REQUEST = 1,
+ TIME_PACKET_WHO_IS_MASTER_RESPONSE,
+ TIME_PACKET_SYNC_REQUEST,
+ TIME_PACKET_SYNC_RESPONSE,
+ TIME_PACKET_MASTER_ANNOUNCEMENT,
+};
+
+class TimeServicePacketHeader {
+ public:
+ friend class UniversalTimeServicePacket;
+ // magic number identifying the protocol
+ uint32_t magic;
+
+ // protocol version of the packet
+ uint16_t version;
+
+ // type of the packet
+ TimeServicePacketType packetType;
+
+ // the timeline ID
+ uint64_t timelineID;
+
+ // synchronization group this packet belongs to (used to operate multiple
+ // synchronization domains which all use the same master election endpoint)
+ uint64_t syncGroupID;
+
+ ssize_t serializePacket(uint8_t* data, uint32_t length);
+
+ protected:
+ void initHeader(TimeServicePacketType type,
+ const uint64_t tlID,
+ const uint64_t groupID) {
+ magic = kMagic;
+ version = kCurVersion;
+ packetType = type;
+ timelineID = tlID;
+ syncGroupID = groupID;
+ }
+
+ bool checkPacket(uint64_t expectedSyncGroupID) const {
+ return ((magic == kMagic) &&
+ (version == kCurVersion) &&
+ (!expectedSyncGroupID || (syncGroupID == expectedSyncGroupID)));
+ }
+
+ ssize_t serializeHeader(uint8_t* data, uint32_t length);
+ ssize_t deserializeHeader(const uint8_t* data, uint32_t length);
+
+ private:
+ static const uint32_t kMagic;
+ static const uint16_t kCurVersion;
+};
+
+// packet querying for a suitable master
+class WhoIsMasterRequestPacket : public TimeServicePacketHeader {
+ public:
+ uint64_t senderDeviceID;
+ uint8_t senderDevicePriority;
+
+ void initHeader(const uint64_t groupID) {
+ TimeServicePacketHeader::initHeader(TIME_PACKET_WHO_IS_MASTER_REQUEST,
+ ICommonClock::kInvalidTimelineID,
+ groupID);
+ }
+
+ ssize_t serializePacket(uint8_t* data, uint32_t length);
+ ssize_t deserializePacket(const uint8_t* data, uint32_t length);
+};
+
+// response to a WhoIsMaster request
+class WhoIsMasterResponsePacket : public TimeServicePacketHeader {
+ public:
+ uint64_t deviceID;
+ uint8_t devicePriority;
+
+ void initHeader(const uint64_t tlID, const uint64_t groupID) {
+ TimeServicePacketHeader::initHeader(TIME_PACKET_WHO_IS_MASTER_RESPONSE,
+ tlID, groupID);
+ }
+
+ ssize_t serializePacket(uint8_t* data, uint32_t length);
+ ssize_t deserializePacket(const uint8_t* data, uint32_t length);
+};
+
+// packet sent by a client requesting correspondence between local
+// and common time
+class SyncRequestPacket : public TimeServicePacketHeader {
+ public:
+ // local time when this request was transmitted
+ int64_t clientTxLocalTime;
+
+ void initHeader(const uint64_t tlID, const uint64_t groupID) {
+ TimeServicePacketHeader::initHeader(TIME_PACKET_SYNC_REQUEST,
+ tlID, groupID);
+ }
+
+ ssize_t serializePacket(uint8_t* data, uint32_t length);
+ ssize_t deserializePacket(const uint8_t* data, uint32_t length);
+};
+
+// response to a sync request sent by the master
+class SyncResponsePacket : public TimeServicePacketHeader {
+ public:
+ // local time when this request was transmitted by the client
+ int64_t clientTxLocalTime;
+
+ // common time when the master received the request
+ int64_t masterRxCommonTime;
+
+ // common time when the master transmitted the response
+ int64_t masterTxCommonTime;
+
+ // flag that is set if the recipient of the sync request is not acting
+ // as a master for the requested timeline
+ uint32_t nak;
+
+ void initHeader(const uint64_t tlID, const uint64_t groupID) {
+ TimeServicePacketHeader::initHeader(TIME_PACKET_SYNC_RESPONSE,
+ tlID, groupID);
+ }
+
+ ssize_t serializePacket(uint8_t* data, uint32_t length);
+ ssize_t deserializePacket(const uint8_t* data, uint32_t length);
+};
+
+// announcement of the master's presence
+class MasterAnnouncementPacket : public TimeServicePacketHeader {
+ public:
+ // the master's device ID
+ uint64_t deviceID;
+ uint8_t devicePriority;
+
+ void initHeader(const uint64_t tlID, const uint64_t groupID) {
+ TimeServicePacketHeader::initHeader(TIME_PACKET_MASTER_ANNOUNCEMENT,
+ tlID, groupID);
+ }
+
+ ssize_t serializePacket(uint8_t* data, uint32_t length);
+ ssize_t deserializePacket(const uint8_t* data, uint32_t length);
+};
+
+class UniversalTimeServicePacket {
+ public:
+ uint16_t packetType;
+ union {
+ WhoIsMasterRequestPacket who_is_master_request;
+ WhoIsMasterResponsePacket who_is_master_response;
+ SyncRequestPacket sync_request;
+ SyncResponsePacket sync_response;
+ MasterAnnouncementPacket master_announcement;
+ } p;
+
+ ssize_t deserializePacket(const uint8_t* data,
+ uint32_t length,
+ uint64_t expectedSyncGroupID);
+};
+
+}; // namespace android
+
+#endif // ANDROID_COMMON_TIME_SERVER_PACKETS_H
+
+
diff --git a/services/common_time/diag_thread.cpp b/services/common_time/diag_thread.cpp
new file mode 100644
index 0000000..4cb9551
--- /dev/null
+++ b/services/common_time/diag_thread.cpp
@@ -0,0 +1,323 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#define LOG_TAG "common_time"
+#include <utils/Log.h>
+
+#include <fcntl.h>
+#include <linux/in.h>
+#include <linux/tcp.h>
+#include <poll.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <utils/Errors.h>
+#include <utils/misc.h>
+
+#include <common_time/local_clock.h>
+
+#include "common_clock.h"
+#include "diag_thread.h"
+
+#define kMaxEvents 16
+#define kListenPort 9876
+
+static bool setNonblocking(int fd) {
+ int flags = fcntl(fd, F_GETFL);
+ if (fcntl(fd, F_SETFL, flags | O_NONBLOCK) < 0) {
+ ALOGE("Failed to set socket (%d) to non-blocking mode (errno %d)",
+ fd, errno);
+ return false;
+ }
+
+ return true;
+}
+
+static bool setNodelay(int fd) {
+ int tmp = 1;
+ if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &tmp, sizeof(tmp)) < 0) {
+ ALOGE("Failed to set socket (%d) to no-delay mode (errno %d)",
+ fd, errno);
+ return false;
+ }
+
+ return true;
+}
+
+namespace android {
+
+DiagThread::DiagThread(CommonClock* common_clock, LocalClock* local_clock) {
+ common_clock_ = common_clock;
+ local_clock_ = local_clock;
+ listen_fd_ = -1;
+ data_fd_ = -1;
+ kernel_logID_basis_known_ = false;
+ discipline_log_ID_ = 0;
+}
+
+DiagThread::~DiagThread() {
+}
+
+status_t DiagThread::startWorkThread() {
+ status_t res;
+ stopWorkThread();
+ res = run("Diag");
+
+ if (res != OK)
+ ALOGE("Failed to start work thread (res = %d)", res);
+
+ return res;
+}
+
+void DiagThread::stopWorkThread() {
+ status_t res;
+ res = requestExitAndWait(); // block until thread exit.
+ if (res != OK)
+ ALOGE("Failed to stop work thread (res = %d)", res);
+}
+
+bool DiagThread::openListenSocket() {
+ bool ret = false;
+ int flags;
+ cleanupListenSocket();
+
+ if ((listen_fd_ = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
+ ALOGE("Socket failed.");
+ goto bailout;
+ }
+
+ // Set non-blocking operation
+ if (!setNonblocking(listen_fd_))
+ goto bailout;
+
+ struct sockaddr_in addr;
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_addr.s_addr = INADDR_ANY;
+ addr.sin_port = htons(kListenPort);
+
+ if (bind(listen_fd_, (struct sockaddr*)&addr, sizeof(addr)) < 0) {
+ ALOGE("Bind failed.");
+ goto bailout;
+ }
+
+ if (listen(listen_fd_, 1) < 0) {
+ ALOGE("Listen failed.");
+ goto bailout;
+ }
+
+ ret = true;
+bailout:
+ if (!ret)
+ cleanupListenSocket();
+
+ return ret;
+}
+
+void DiagThread::cleanupListenSocket() {
+ if (listen_fd_ >= 0) {
+ int res;
+
+ struct linger l;
+ l.l_onoff = 1;
+ l.l_linger = 0;
+
+ setsockopt(listen_fd_, SOL_SOCKET, SO_LINGER, &l, sizeof(l));
+ shutdown(listen_fd_, SHUT_RDWR);
+ close(listen_fd_);
+ listen_fd_ = -1;
+ }
+}
+
+void DiagThread::cleanupDataSocket() {
+ if (data_fd_ >= 0) {
+ int res;
+
+ struct linger l;
+ l.l_onoff = 1;
+ l.l_linger = 0;
+
+ setsockopt(data_fd_, SOL_SOCKET, SO_LINGER, &l, sizeof(l));
+ shutdown(data_fd_, SHUT_RDWR);
+ close(data_fd_);
+ data_fd_ = -1;
+ }
+}
+
+void DiagThread::resetLogIDs() {
+ // Drain and discard all of the events from the kernel
+ struct local_time_debug_event events[kMaxEvents];
+ while(local_clock_->getDebugLog(events, kMaxEvents) > 0)
+ ;
+
+ {
+ Mutex::Autolock lock(&discipline_log_lock_);
+ discipline_log_.clear();
+ discipline_log_ID_ = 0;
+ }
+
+ kernel_logID_basis_known_ = false;
+}
+
+void DiagThread::pushDisciplineEvent(int64_t observed_local_time,
+ int64_t observed_common_time,
+ int64_t nominal_common_time,
+ int32_t total_correction,
+ int32_t rtt) {
+ Mutex::Autolock lock(&discipline_log_lock_);
+
+ DisciplineEventRecord evt;
+
+ evt.event_id = discipline_log_ID_++;
+
+ evt.action_local_time = local_clock_->getLocalTime();
+ common_clock_->localToCommon(evt.action_local_time,
+ &evt.action_common_time);
+
+ evt.observed_local_time = observed_local_time;
+ evt.observed_common_time = observed_common_time;
+ evt.nominal_common_time = nominal_common_time;
+ evt.total_correction = total_correction;
+ evt.rtt = rtt;
+
+ discipline_log_.push_back(evt);
+ while (discipline_log_.size() > kMaxDisciplineLogSize)
+ discipline_log_.erase(discipline_log_.begin());
+}
+
+bool DiagThread::threadLoop() {
+ struct pollfd poll_fds[1];
+
+ if (!openListenSocket()) {
+ ALOGE("Failed to open listen socket");
+ goto bailout;
+ }
+
+ while (!exitPending()) {
+ memset(&poll_fds, 0, sizeof(poll_fds));
+
+ if (data_fd_ < 0) {
+ poll_fds[0].fd = listen_fd_;
+ poll_fds[0].events = POLLIN;
+ } else {
+ poll_fds[0].fd = data_fd_;
+ poll_fds[0].events = POLLRDHUP | POLLIN;
+ }
+
+ int poll_res = poll(poll_fds, NELEM(poll_fds), 50);
+ if (poll_res < 0) {
+ ALOGE("Fatal error (%d,%d) while waiting on events",
+ poll_res, errno);
+ goto bailout;
+ }
+
+ if (exitPending())
+ break;
+
+ if (poll_fds[0].revents) {
+ if (poll_fds[0].fd == listen_fd_) {
+ data_fd_ = accept(listen_fd_, NULL, NULL);
+
+ if (data_fd_ < 0) {
+ ALOGW("Failed accept on socket %d with err %d",
+ listen_fd_, errno);
+ } else {
+ if (!setNonblocking(data_fd_))
+ cleanupDataSocket();
+ if (!setNodelay(data_fd_))
+ cleanupDataSocket();
+ }
+ } else
+ if (poll_fds[0].fd == data_fd_) {
+ if (poll_fds[0].revents & POLLRDHUP) {
+ // Connection hung up; time to clean up.
+ cleanupDataSocket();
+ } else
+ if (poll_fds[0].revents & POLLIN) {
+ uint8_t cmd;
+ if (read(data_fd_, &cmd, sizeof(cmd)) > 0) {
+ switch(cmd) {
+ case 'r':
+ case 'R':
+ resetLogIDs();
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ struct local_time_debug_event events[kMaxEvents];
+ int amt = local_clock_->getDebugLog(events, kMaxEvents);
+
+ if (amt > 0) {
+ for (int i = 0; i < amt; i++) {
+ struct local_time_debug_event& e = events[i];
+
+ if (!kernel_logID_basis_known_) {
+ kernel_logID_basis_ = e.local_timesync_event_id;
+ kernel_logID_basis_known_ = true;
+ }
+
+ char buf[1024];
+ int64_t common_time;
+ status_t res = common_clock_->localToCommon(e.local_time,
+ &common_time);
+ snprintf(buf, sizeof(buf), "E,%lld,%lld,%lld,%d\n",
+ e.local_timesync_event_id - kernel_logID_basis_,
+ e.local_time,
+ common_time,
+ (OK == res) ? 1 : 0);
+ buf[sizeof(buf) - 1] = 0;
+
+ if (data_fd_ >= 0)
+ write(data_fd_, buf, strlen(buf));
+ }
+ }
+
+ { // scope for autolock pattern
+ Mutex::Autolock lock(&discipline_log_lock_);
+
+ while (discipline_log_.size() > 0) {
+ char buf[1024];
+ DisciplineEventRecord& e = *discipline_log_.begin();
+ snprintf(buf, sizeof(buf),
+ "D,%lld,%lld,%lld,%lld,%lld,%lld,%d,%d\n",
+ e.event_id,
+ e.action_local_time,
+ e.action_common_time,
+ e.observed_local_time,
+ e.observed_common_time,
+ e.nominal_common_time,
+ e.total_correction,
+ e.rtt);
+ buf[sizeof(buf) - 1] = 0;
+
+ if (data_fd_ >= 0)
+ write(data_fd_, buf, strlen(buf));
+
+ discipline_log_.erase(discipline_log_.begin());
+ }
+ }
+ }
+
+bailout:
+ cleanupDataSocket();
+ cleanupListenSocket();
+ return false;
+}
+
+} // namespace android
diff --git a/services/common_time/diag_thread.h b/services/common_time/diag_thread.h
new file mode 100644
index 0000000..c630e0d
--- /dev/null
+++ b/services/common_time/diag_thread.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+#ifndef __DIAG_THREAD_H__
+#define __DIAG_THREAD_H__
+
+#include <utils/List.h>
+#include <utils/threads.h>
+
+namespace android {
+
+class CommonClock;
+class LocalClock;
+
+class DiagThread : public Thread {
+ public:
+ DiagThread(CommonClock* common_clock, LocalClock* local_clock);
+ ~DiagThread();
+
+ status_t startWorkThread();
+ void stopWorkThread();
+ virtual bool threadLoop();
+
+ void pushDisciplineEvent(int64_t observed_local_time,
+ int64_t observed_common_time,
+ int64_t nominal_common_time,
+ int32_t total_correction,
+ int32_t rtt);
+
+ private:
+ typedef struct {
+ int64_t event_id;
+ int64_t action_local_time;
+ int64_t action_common_time;
+ int64_t observed_local_time;
+ int64_t observed_common_time;
+ int64_t nominal_common_time;
+ int32_t total_correction;
+ int32_t rtt;
+ } DisciplineEventRecord;
+
+ bool openListenSocket();
+ void cleanupListenSocket();
+ void cleanupDataSocket();
+ void resetLogIDs();
+
+ CommonClock* common_clock_;
+ LocalClock* local_clock_;
+ int listen_fd_;
+ int data_fd_;
+
+ int64_t kernel_logID_basis_;
+ bool kernel_logID_basis_known_;
+
+ static const size_t kMaxDisciplineLogSize = 16;
+ Mutex discipline_log_lock_;
+ List<DisciplineEventRecord> discipline_log_;
+ int64_t discipline_log_ID_;
+};
+
+} // namespace android
+
+#endif //__ DIAG_THREAD_H__
diff --git a/services/common_time/main.cpp b/services/common_time/main.cpp
new file mode 100644
index 0000000..49eb30a
--- /dev/null
+++ b/services/common_time/main.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
+/*
+ * A service that exchanges time synchronization information between
+ * a master that defines a timeline and clients that follow the timeline.
+ */
+
+#define LOG_TAG "common_time"
+#include <utils/Log.h>
+
+#include <binder/IPCThreadState.h>
+#include <binder/ProcessState.h>
+
+#include "common_time_server.h"
+
+int main(int argc, char *argv[]) {
+ using namespace android;
+
+ sp<CommonTimeServer> service = new CommonTimeServer();
+ if (service == NULL)
+ return 1;
+
+ ProcessState::self()->startThreadPool();
+ service->run("CommonTimeServer", ANDROID_PRIORITY_NORMAL);
+
+ IPCThreadState::self()->joinThreadPool();
+ return 0;
+}
+
diff --git a/services/input/Android.mk b/services/input/Android.mk
index 86c6c8a..159800f 100644
--- a/services/input/Android.mk
+++ b/services/input/Android.mk
@@ -29,6 +29,7 @@
LOCAL_SHARED_LIBRARIES := \
libcutils \
+ libandroidfw \
libutils \
libhardware \
libhardware_legacy \
diff --git a/services/input/EventHub.cpp b/services/input/EventHub.cpp
index 296c95e..1b74aa6 100644
--- a/services/input/EventHub.cpp
+++ b/services/input/EventHub.cpp
@@ -36,9 +36,9 @@
#include <errno.h>
#include <assert.h>
-#include <ui/KeyLayoutMap.h>
-#include <ui/KeyCharacterMap.h>
-#include <ui/VirtualKeyMap.h>
+#include <androidfw/KeyLayoutMap.h>
+#include <androidfw/KeyCharacterMap.h>
+#include <androidfw/VirtualKeyMap.h>
#include <string.h>
#include <stdint.h>
diff --git a/services/input/EventHub.h b/services/input/EventHub.h
index 8a2afd3..4eb47c6 100644
--- a/services/input/EventHub.h
+++ b/services/input/EventHub.h
@@ -18,11 +18,11 @@
#ifndef _RUNTIME_EVENT_HUB_H
#define _RUNTIME_EVENT_HUB_H
-#include <ui/Input.h>
-#include <ui/Keyboard.h>
-#include <ui/KeyLayoutMap.h>
-#include <ui/KeyCharacterMap.h>
-#include <ui/VirtualKeyMap.h>
+#include <androidfw/Input.h>
+#include <androidfw/Keyboard.h>
+#include <androidfw/KeyLayoutMap.h>
+#include <androidfw/KeyCharacterMap.h>
+#include <androidfw/VirtualKeyMap.h>
#include <utils/String8.h>
#include <utils/threads.h>
#include <utils/Log.h>
diff --git a/services/input/InputApplication.h b/services/input/InputApplication.h
index 67ae94b..c04a935 100644
--- a/services/input/InputApplication.h
+++ b/services/input/InputApplication.h
@@ -17,7 +17,7 @@
#ifndef _UI_INPUT_APPLICATION_H
#define _UI_INPUT_APPLICATION_H
-#include <ui/Input.h>
+#include <androidfw/Input.h>
#include <utils/RefBase.h>
#include <utils/Timers.h>
diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp
index e6e28df..149c0d3 100644
--- a/services/input/InputDispatcher.cpp
+++ b/services/input/InputDispatcher.cpp
@@ -45,7 +45,7 @@
#include "InputDispatcher.h"
#include <cutils/log.h>
-#include <ui/PowerManager.h>
+#include <androidfw/PowerManager.h>
#include <stddef.h>
#include <unistd.h>
diff --git a/services/input/InputDispatcher.h b/services/input/InputDispatcher.h
index 5c517f51..4b36480 100644
--- a/services/input/InputDispatcher.h
+++ b/services/input/InputDispatcher.h
@@ -17,8 +17,8 @@
#ifndef _UI_INPUT_DISPATCHER_H
#define _UI_INPUT_DISPATCHER_H
-#include <ui/Input.h>
-#include <ui/InputTransport.h>
+#include <androidfw/Input.h>
+#include <androidfw/InputTransport.h>
#include <utils/KeyedVector.h>
#include <utils/Vector.h>
#include <utils/threads.h>
diff --git a/services/input/InputListener.h b/services/input/InputListener.h
index f920cd1..b1dc0b8 100644
--- a/services/input/InputListener.h
+++ b/services/input/InputListener.h
@@ -17,7 +17,7 @@
#ifndef _UI_INPUT_LISTENER_H
#define _UI_INPUT_LISTENER_H
-#include <ui/Input.h>
+#include <androidfw/Input.h>
#include <utils/RefBase.h>
#include <utils/Vector.h>
diff --git a/services/input/InputManager.h b/services/input/InputManager.h
index df4d299e..29584c9 100644
--- a/services/input/InputManager.h
+++ b/services/input/InputManager.h
@@ -25,8 +25,8 @@
#include "InputReader.h"
#include "InputDispatcher.h"
-#include <ui/Input.h>
-#include <ui/InputTransport.h>
+#include <androidfw/Input.h>
+#include <androidfw/InputTransport.h>
#include <utils/Errors.h>
#include <utils/Vector.h>
#include <utils/Timers.h>
diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp
index 4be06e4..eccce29 100644
--- a/services/input/InputReader.cpp
+++ b/services/input/InputReader.cpp
@@ -39,8 +39,8 @@
#include "InputReader.h"
#include <cutils/log.h>
-#include <ui/Keyboard.h>
-#include <ui/VirtualKeyMap.h>
+#include <androidfw/Keyboard.h>
+#include <androidfw/VirtualKeyMap.h>
#include <stddef.h>
#include <stdlib.h>
diff --git a/services/input/InputReader.h b/services/input/InputReader.h
index ad89a22..9bbe49c 100644
--- a/services/input/InputReader.h
+++ b/services/input/InputReader.h
@@ -21,7 +21,7 @@
#include "PointerController.h"
#include "InputListener.h"
-#include <ui/Input.h>
+#include <androidfw/Input.h>
#include <ui/DisplayInfo.h>
#include <utils/KeyedVector.h>
#include <utils/threads.h>
diff --git a/services/input/InputWindow.h b/services/input/InputWindow.h
index 38968f9..824a64b 100644
--- a/services/input/InputWindow.h
+++ b/services/input/InputWindow.h
@@ -17,8 +17,8 @@
#ifndef _UI_INPUT_WINDOW_H
#define _UI_INPUT_WINDOW_H
-#include <ui/Input.h>
-#include <ui/InputTransport.h>
+#include <androidfw/Input.h>
+#include <androidfw/InputTransport.h>
#include <utils/RefBase.h>
#include <utils/Timers.h>
#include <utils/String8.h>
diff --git a/services/input/PointerController.h b/services/input/PointerController.h
index 700ef72..39dbf6b 100644
--- a/services/input/PointerController.h
+++ b/services/input/PointerController.h
@@ -20,7 +20,7 @@
#include "SpriteController.h"
#include <ui/DisplayInfo.h>
-#include <ui/Input.h>
+#include <androidfw/Input.h>
#include <utils/RefBase.h>
#include <utils/Looper.h>
#include <utils/String8.h>
diff --git a/services/input/tests/Android.mk b/services/input/tests/Android.mk
index 171db3c..8f8c34b 100644
--- a/services/input/tests/Android.mk
+++ b/services/input/tests/Android.mk
@@ -9,6 +9,7 @@
shared_libraries := \
libcutils \
+ libandroidfw \
libutils \
libhardware \
libhardware_legacy \
diff --git a/services/java/com/android/server/AppWidgetServiceImpl.java b/services/java/com/android/server/AppWidgetServiceImpl.java
index 41ede2e..9c408c4 100644
--- a/services/java/com/android/server/AppWidgetServiceImpl.java
+++ b/services/java/com/android/server/AppWidgetServiceImpl.java
@@ -463,7 +463,7 @@
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_DELETED);
intent.setComponent(p.info.provider);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, id.appWidgetId);
- mContext.sendBroadcast(intent);
+ mContext.sendBroadcast(intent, mUserId);
if (p.instances.size() == 0) {
// cancel the future updates
cancelBroadcasts(p);
@@ -471,7 +471,7 @@
// send the broacast saying that the provider is not in use any more
intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_DISABLED);
intent.setComponent(p.info.provider);
- mContext.sendBroadcast(intent);
+ mContext.sendBroadcast(intent, mUserId);
}
}
}
@@ -515,8 +515,6 @@
+ " safe mode: " + provider);
}
- Binder.restoreCallingIdentity(ident);
-
id.provider = p;
p.instances.add(id);
int instancesSize = p.instances.size();
@@ -1066,7 +1064,7 @@
void sendEnableIntentLocked(Provider p) {
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_ENABLED);
intent.setComponent(p.info.provider);
- mContext.sendBroadcast(intent);
+ mContext.sendBroadcast(intent, mUserId);
}
void sendUpdateIntentLocked(Provider p, int[] appWidgetIds) {
@@ -1074,7 +1072,7 @@
Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
intent.setComponent(p.info.provider);
- mContext.sendBroadcast(intent);
+ mContext.sendBroadcast(intent, mUserId);
}
}
@@ -1477,12 +1475,11 @@
}
AtomicFile savedStateFile() {
- int userId = UserId.getCallingUserId();
- File dir = new File("/data/system/users/" + userId);
+ File dir = new File("/data/system/users/" + mUserId);
File settingsFile = new File(dir, SETTINGS_FILENAME);
if (!dir.exists()) {
dir.mkdirs();
- if (userId == 0) {
+ if (mUserId == 0) {
// Migrate old data
File oldFile = new File("/data/system/" + SETTINGS_FILENAME);
// Method doesn't throw an exception on failure. Ignore any errors
diff --git a/services/java/com/android/server/CommonTimeManagementService.java b/services/java/com/android/server/CommonTimeManagementService.java
new file mode 100644
index 0000000..9a25d2e
--- /dev/null
+++ b/services/java/com/android/server/CommonTimeManagementService.java
@@ -0,0 +1,377 @@
+/*
+ * Copyright (C) 2012 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 com.android.server;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.net.InetAddress;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.net.ConnectivityManager;
+import android.net.IConnectivityManager;
+import android.net.INetworkManagementEventObserver;
+import android.net.InterfaceConfiguration;
+import android.net.NetworkInfo;
+import android.os.Binder;
+import android.os.CommonTimeConfig;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.INetworkManagementService;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemProperties;
+import android.util.Log;
+
+/**
+ * @hide
+ * <p>CommonTimeManagementService manages the configuration of the native Common Time service,
+ * reconfiguring the native service as appropriate in response to changes in network configuration.
+ */
+class CommonTimeManagementService extends Binder {
+ /*
+ * Constants and globals.
+ */
+ private static final String TAG = CommonTimeManagementService.class.getSimpleName();
+ private static final int NATIVE_SERVICE_RECONNECT_TIMEOUT = 5000;
+ private static final String AUTO_DISABLE_PROP = "ro.common_time.auto_disable";
+ private static final String ALLOW_WIFI_PROP = "ro.common_time.allow_wifi";
+ private static final String SERVER_PRIO_PROP = "ro.common_time.server_prio";
+ private static final String NO_INTERFACE_TIMEOUT_PROP = "ro.common_time.no_iface_timeout";
+ private static final boolean AUTO_DISABLE;
+ private static final boolean ALLOW_WIFI;
+ private static final byte BASE_SERVER_PRIO;
+ private static final int NO_INTERFACE_TIMEOUT;
+ private static final InterfaceScoreRule[] IFACE_SCORE_RULES;
+
+ static {
+ int tmp;
+ AUTO_DISABLE = (0 != SystemProperties.getInt(AUTO_DISABLE_PROP, 1));
+ ALLOW_WIFI = (0 != SystemProperties.getInt(ALLOW_WIFI_PROP, 0));
+ tmp = SystemProperties.getInt(SERVER_PRIO_PROP, 1);
+ NO_INTERFACE_TIMEOUT = SystemProperties.getInt(NO_INTERFACE_TIMEOUT_PROP, 60000);
+
+ if (tmp < 1)
+ BASE_SERVER_PRIO = 1;
+ else
+ if (tmp > 30)
+ BASE_SERVER_PRIO = 30;
+ else
+ BASE_SERVER_PRIO = (byte)tmp;
+
+ if (ALLOW_WIFI) {
+ IFACE_SCORE_RULES = new InterfaceScoreRule[] {
+ new InterfaceScoreRule("wlan", (byte)1),
+ new InterfaceScoreRule("eth", (byte)2),
+ };
+ } else {
+ IFACE_SCORE_RULES = new InterfaceScoreRule[] {
+ new InterfaceScoreRule("eth", (byte)2),
+ };
+ }
+ };
+
+ /*
+ * Internal state
+ */
+ private final Context mContext;
+ private INetworkManagementService mNetMgr;
+ private CommonTimeConfig mCTConfig;
+ private String mCurIface;
+ private Handler mReconnectHandler = new Handler();
+ private Handler mNoInterfaceHandler = new Handler();
+ private Object mLock = new Object();
+ private boolean mDetectedAtStartup = false;
+ private byte mEffectivePrio = BASE_SERVER_PRIO;
+
+ /*
+ * Callback handler implementations.
+ */
+ private INetworkManagementEventObserver mIfaceObserver =
+ new INetworkManagementEventObserver.Stub() {
+
+ public void interfaceStatusChanged(String iface, boolean up) {
+ reevaluateServiceState();
+ }
+ public void interfaceLinkStateChanged(String iface, boolean up) {
+ reevaluateServiceState();
+ }
+ public void interfaceAdded(String iface) {
+ reevaluateServiceState();
+ }
+ public void interfaceRemoved(String iface) {
+ reevaluateServiceState();
+ }
+ public void limitReached(String limitName, String iface) { }
+ };
+
+ private BroadcastReceiver mConnectivityMangerObserver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ reevaluateServiceState();
+ }
+ };
+
+ private CommonTimeConfig.OnServerDiedListener mCTServerDiedListener =
+ new CommonTimeConfig.OnServerDiedListener() {
+ public void onServerDied() {
+ scheduleTimeConfigReconnect();
+ }
+ };
+
+ private Runnable mReconnectRunnable = new Runnable() {
+ public void run() { connectToTimeConfig(); }
+ };
+
+ private Runnable mNoInterfaceRunnable = new Runnable() {
+ public void run() { handleNoInterfaceTimeout(); }
+ };
+
+ /*
+ * Public interface (constructor, systemReady and dump)
+ */
+ public CommonTimeManagementService(Context context) {
+ mContext = context;
+ }
+
+ void systemReady() {
+ if (ServiceManager.checkService(CommonTimeConfig.SERVICE_NAME) == null) {
+ Log.i(TAG, "No common time service detected on this platform. " +
+ "Common time services will be unavailable.");
+ return;
+ }
+
+ mDetectedAtStartup = true;
+
+ IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE);
+ mNetMgr = INetworkManagementService.Stub.asInterface(b);
+
+ // Network manager is running along-side us, so we should never receiver a remote exception
+ // while trying to register this observer.
+ try {
+ mNetMgr.registerObserver(mIfaceObserver);
+ }
+ catch (RemoteException e) { }
+
+ // Register with the connectivity manager for connectivity changed intents.
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
+ mContext.registerReceiver(mConnectivityMangerObserver, filter);
+
+ // Connect to the common time config service and apply the initial configuration.
+ connectToTimeConfig();
+ }
+
+ @Override
+ protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
+ != PackageManager.PERMISSION_GRANTED) {
+ pw.println(String.format(
+ "Permission Denial: can't dump CommonTimeManagement service from from " +
+ "pid=%d, uid=%d", Binder.getCallingPid(), Binder.getCallingUid()));
+ return;
+ }
+
+ if (!mDetectedAtStartup) {
+ pw.println("Native Common Time service was not detected at startup. " +
+ "Service is unavailable");
+ return;
+ }
+
+ synchronized (mLock) {
+ pw.println("Current Common Time Management Service Config:");
+ pw.println(String.format(" Native service : %s",
+ (null == mCTConfig) ? "reconnecting"
+ : "alive"));
+ pw.println(String.format(" Bound interface : %s",
+ (null == mCurIface ? "unbound" : mCurIface)));
+ pw.println(String.format(" Allow WiFi : %s", ALLOW_WIFI ? "yes" : "no"));
+ pw.println(String.format(" Allow Auto Disable : %s", AUTO_DISABLE ? "yes" : "no"));
+ pw.println(String.format(" Server Priority : %d", mEffectivePrio));
+ pw.println(String.format(" No iface timeout : %d", NO_INTERFACE_TIMEOUT));
+ }
+ }
+
+ /*
+ * Inner helper classes
+ */
+ private static class InterfaceScoreRule {
+ public final String mPrefix;
+ public final byte mScore;
+ public InterfaceScoreRule(String prefix, byte score) {
+ mPrefix = prefix;
+ mScore = score;
+ }
+ };
+
+ /*
+ * Internal implementation
+ */
+ private void cleanupTimeConfig() {
+ mReconnectHandler.removeCallbacks(mReconnectRunnable);
+ mNoInterfaceHandler.removeCallbacks(mNoInterfaceRunnable);
+ if (null != mCTConfig) {
+ mCTConfig.release();
+ mCTConfig = null;
+ }
+ }
+
+ private void connectToTimeConfig() {
+ // Get access to the common time service configuration interface. If we catch a remote
+ // exception in the process (service crashed or no running for w/e reason), schedule an
+ // attempt to reconnect in the future.
+ cleanupTimeConfig();
+ try {
+ synchronized (mLock) {
+ mCTConfig = new CommonTimeConfig();
+ mCTConfig.setServerDiedListener(mCTServerDiedListener);
+ mCurIface = mCTConfig.getInterfaceBinding();
+ mCTConfig.setAutoDisable(AUTO_DISABLE);
+ mCTConfig.setMasterElectionPriority(mEffectivePrio);
+ }
+
+ if (NO_INTERFACE_TIMEOUT >= 0)
+ mNoInterfaceHandler.postDelayed(mNoInterfaceRunnable, NO_INTERFACE_TIMEOUT);
+
+ reevaluateServiceState();
+ }
+ catch (RemoteException e) {
+ scheduleTimeConfigReconnect();
+ }
+ }
+
+ private void scheduleTimeConfigReconnect() {
+ cleanupTimeConfig();
+ Log.w(TAG, String.format("Native service died, will reconnect in %d mSec",
+ NATIVE_SERVICE_RECONNECT_TIMEOUT));
+ mReconnectHandler.postDelayed(mReconnectRunnable,
+ NATIVE_SERVICE_RECONNECT_TIMEOUT);
+ }
+
+ private void handleNoInterfaceTimeout() {
+ if (null != mCTConfig) {
+ Log.i(TAG, "Timeout waiting for interface to come up. " +
+ "Forcing networkless master mode.");
+ if (CommonTimeConfig.ERROR_DEAD_OBJECT == mCTConfig.forceNetworklessMasterMode())
+ scheduleTimeConfigReconnect();
+ }
+ }
+
+ private void reevaluateServiceState() {
+ String bindIface = null;
+ byte bestScore = -1;
+ try {
+ // Check to see if this interface is suitable to use for time synchronization.
+ //
+ // TODO : This selection algorithm needs to be enhanced for use with mobile devices. In
+ // particular, the choice of whether to a wireless interface or not should not be an all
+ // or nothing thing controlled by properties. It would probably be better if the
+ // platform had some concept of public wireless networks vs. home or friendly wireless
+ // networks (something a user would configure in settings or when a new interface is
+ // added). Then this algorithm could pick only wireless interfaces which were flagged
+ // as friendly, and be dormant when on public wireless networks.
+ //
+ // Another issue which needs to be dealt with is the use of driver supplied interface
+ // name to determine the network type. The fact that the wireless interface on a device
+ // is named "wlan0" is just a matter of convention; its not a 100% rule. For example,
+ // there are devices out there where the wireless is name "tiwlan0", not "wlan0". The
+ // internal network management interfaces in Android have all of the information needed
+ // to make a proper classification, there is just no way (currently) to fetch an
+ // interface's type (available from the ConnectionManager) as well as its address
+ // (available from either the java.net interfaces or from the NetworkManagment service).
+ // Both can enumerate interfaces, but that is no way to correlate their results (no
+ // common shared key; although using the interface name in the connection manager would
+ // be a good start). Until this gets resolved, we resort to substring searching for
+ // tags like wlan and eth.
+ //
+ String ifaceList[] = mNetMgr.listInterfaces();
+ if (null != ifaceList) {
+ for (String iface : ifaceList) {
+
+ byte thisScore = -1;
+ for (InterfaceScoreRule r : IFACE_SCORE_RULES) {
+ if (iface.contains(r.mPrefix)) {
+ thisScore = r.mScore;
+ break;
+ }
+ }
+
+ if (thisScore <= bestScore)
+ continue;
+
+ InterfaceConfiguration config = mNetMgr.getInterfaceConfig(iface);
+ if (null == config)
+ continue;
+
+ if (config.isActive()) {
+ bindIface = iface;
+ bestScore = thisScore;
+ }
+ }
+ }
+ }
+ catch (RemoteException e) {
+ // Bad news; we should not be getting remote exceptions from the connectivity manager
+ // since it is running in SystemServer along side of us. It probably does not matter
+ // what we do here, but go ahead and unbind the common time service in this case, just
+ // so we have some defined behavior.
+ bindIface = null;
+ }
+
+ boolean doRebind = true;
+ synchronized (mLock) {
+ if ((null != bindIface) && (null == mCurIface)) {
+ Log.e(TAG, String.format("Binding common time service to %s.", bindIface));
+ mCurIface = bindIface;
+ } else
+ if ((null == bindIface) && (null != mCurIface)) {
+ Log.e(TAG, "Unbinding common time service.");
+ mCurIface = null;
+ } else
+ if ((null != bindIface) && (null != mCurIface) && !bindIface.equals(mCurIface)) {
+ Log.e(TAG, String.format("Switching common time service binding from %s to %s.",
+ mCurIface, bindIface));
+ mCurIface = bindIface;
+ } else {
+ doRebind = false;
+ }
+ }
+
+ if (doRebind && (null != mCTConfig)) {
+ byte newPrio = (bestScore > 0)
+ ? (byte)(bestScore * BASE_SERVER_PRIO)
+ : BASE_SERVER_PRIO;
+ if (newPrio != mEffectivePrio) {
+ mEffectivePrio = newPrio;
+ mCTConfig.setMasterElectionPriority(mEffectivePrio);
+ }
+
+ int res = mCTConfig.setNetworkBinding(mCurIface);
+ if (res != CommonTimeConfig.SUCCESS)
+ scheduleTimeConfigReconnect();
+
+ else if (NO_INTERFACE_TIMEOUT >= 0) {
+ mNoInterfaceHandler.removeCallbacks(mNoInterfaceRunnable);
+ if (null == mCurIface)
+ mNoInterfaceHandler.postDelayed(mNoInterfaceRunnable, NO_INTERFACE_TIMEOUT);
+ }
+ }
+ }
+}
diff --git a/services/java/com/android/server/PowerManagerService.java b/services/java/com/android/server/PowerManagerService.java
index e953355..7b4372f 100644
--- a/services/java/com/android/server/PowerManagerService.java
+++ b/services/java/com/android/server/PowerManagerService.java
@@ -583,6 +583,7 @@
}
nativeInit();
+ Power.powerInitNative();
synchronized (mLocks) {
updateNativePowerStateLocked();
// We make sure to start out with the screen on due to user activity.
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 0dbc7c3..c9b5997 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -132,6 +132,7 @@
RecognitionManagerService recognition = null;
ThrottleService throttle = null;
NetworkTimeUpdateService networkTimeUpdater = null;
+ CommonTimeManagementService commonTimeMgmtService = null;
// Critical services...
try {
@@ -575,6 +576,14 @@
} catch (Throwable e) {
reportWtf("starting NetworkTimeUpdate service", e);
}
+
+ try {
+ Slog.i(TAG, "CommonTimeManagementService");
+ commonTimeMgmtService = new CommonTimeManagementService(context);
+ ServiceManager.addService("commontime_management", commonTimeMgmtService);
+ } catch (Throwable e) {
+ reportWtf("starting CommonTimeManagementService service", e);
+ }
}
// Before things start rolling, be sure we have decided whether
@@ -653,6 +662,7 @@
final LocationManagerService locationF = location;
final CountryDetectorService countryDetectorF = countryDetector;
final NetworkTimeUpdateService networkTimeUpdaterF = networkTimeUpdater;
+ final CommonTimeManagementService commonTimeMgmtServiceF = commonTimeMgmtService;
final TextServicesManagerService textServiceManagerServiceF = tsms;
final StatusBarManagerService statusBarF = statusBar;
@@ -752,6 +762,11 @@
reportWtf("making Network Time Service ready", e);
}
try {
+ if (commonTimeMgmtServiceF != null) commonTimeMgmtServiceF.systemReady();
+ } catch (Throwable e) {
+ reportWtf("making Common time management service ready", e);
+ }
+ try {
if (textServiceManagerServiceF != null) textServiceManagerServiceF.systemReady();
} catch (Throwable e) {
reportWtf("making Text Services Manager Service ready", e);
diff --git a/services/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
index 586a67e..455325a 100644
--- a/services/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -86,8 +86,8 @@
private static final String LOG_TAG = "AccessibilityManagerService";
- private static final String FUNCTION_REGISTER_EVENT_LISTENER =
- "registerEventListener";
+ private static final String FUNCTION_REGISTER_UI_TEST_AUTOMATION_SERVICE =
+ "registerUiTestAutomationService";
private static int sIdCounter = 0;
@@ -95,10 +95,6 @@
private static final int DO_SET_SERVICE_INFO = 10;
- public static final int ACTIVE_WINDOW_ID = -1;
-
- public static final long ROOT_NODE_ID = -1;
-
private static int sNextWindowId;
final HandlerCaller mCaller;
@@ -241,19 +237,9 @@
if (intent.getAction() == Intent.ACTION_BOOT_COMPLETED) {
synchronized (mLock) {
populateAccessibilityServiceListLocked();
- // get accessibility enabled setting on boot
- mIsAccessibilityEnabled = Settings.Secure.getInt(
- mContext.getContentResolver(),
- Settings.Secure.ACCESSIBILITY_ENABLED, 0) == 1;
-
- manageServicesLocked();
-
- // get touch exploration enabled setting on boot
- mIsTouchExplorationEnabled = Settings.Secure.getInt(
- mContext.getContentResolver(),
- Settings.Secure.TOUCH_EXPLORATION_ENABLED, 0) == 1;
+ handleAccessibilityEnabledSettingChangedLocked();
+ handleTouchExplorationEnabledSettingChangedLocked();
updateInputFilterLocked();
-
sendStateToClientsLocked();
}
@@ -301,9 +287,10 @@
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
-
synchronized (mLock) {
handleAccessibilityEnabledSettingChangedLocked();
+ updateInputFilterLocked();
+ sendStateToClientsLocked();
}
}
});
@@ -315,11 +302,8 @@
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
-
synchronized (mLock) {
- mIsTouchExplorationEnabled = Settings.Secure.getInt(
- mContext.getContentResolver(),
- Settings.Secure.TOUCH_EXPLORATION_ENABLED, 0) == 1;
+ handleTouchExplorationEnabledSettingChangedLocked();
updateInputFilterLocked();
sendStateToClientsLocked();
}
@@ -333,7 +317,6 @@
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
-
synchronized (mLock) {
manageServicesLocked();
}
@@ -475,7 +458,7 @@
public void registerUiTestAutomationService(IEventListener listener,
AccessibilityServiceInfo accessibilityServiceInfo) {
mSecurityPolicy.enforceCallingPermission(Manifest.permission.RETRIEVE_WINDOW_CONTENT,
- FUNCTION_REGISTER_EVENT_LISTENER);
+ FUNCTION_REGISTER_UI_TEST_AUTOMATION_SERVICE);
ComponentName componentName = new ComponentName("foo.bar",
"AutomationAccessibilityService");
synchronized (mLock) {
@@ -905,8 +888,15 @@
} else {
unbindAllServicesLocked();
}
- updateInputFilterLocked();
- sendStateToClientsLocked();
+ }
+
+ /**
+ * Updates the state based on the touch exploration enabled setting.
+ */
+ private void handleTouchExplorationEnabledSettingChangedLocked() {
+ mIsTouchExplorationEnabled = Settings.Secure.getInt(
+ mContext.getContentResolver(),
+ Settings.Secure.TOUCH_EXPLORATION_ENABLED, 0) == 1;
}
private class AccessibilityConnectionWrapper implements DeathRecipient {
@@ -1229,13 +1219,16 @@
public void binderDied() {
synchronized (mLock) {
- unlinkToOwnDeath();
+ // The death recipient is unregistered in tryRemoveServiceLocked
tryRemoveServiceLocked(this);
// We no longer have an automation service, so restore
// the state based on values in the settings database.
if (mIsAutomation) {
mUiAutomationService = null;
handleAccessibilityEnabledSettingChangedLocked();
+ handleTouchExplorationEnabledSettingChangedLocked();
+ updateInputFilterLocked();
+ sendStateToClientsLocked();
}
}
}
@@ -1256,7 +1249,7 @@
}
private int resolveAccessibilityWindowId(int accessibilityWindowId) {
- if (accessibilityWindowId == ACTIVE_WINDOW_ID) {
+ if (accessibilityWindowId == AccessibilityNodeInfo.ACTIVE_WINDOW_ID) {
return mSecurityPolicy.mRetrievalAlowingWindowId;
}
return accessibilityWindowId;
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 9d5caae..8a5e7fc 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -138,7 +138,6 @@
import java.lang.IllegalStateException;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
@@ -2752,7 +2751,13 @@
}
// Just in case...
- mMainStack.appDiedLocked(app);
+ if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
+ if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " +mMainStack.mPausingActivity);
+ mMainStack.mPausingActivity = null;
+ }
+ if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
+ mMainStack.mLastPausedActivity = null;
+ }
// Remove this application's activities from active lists.
mMainStack.removeHistoryRecordsForAppLocked(app);
@@ -5754,7 +5759,7 @@
ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
if (cpr == null) {
- cpr = new ContentProviderRecord(cpi, app.info, comp);
+ cpr = new ContentProviderRecord(this, cpi, app.info, comp);
mProviderMap.putProviderByClass(comp, cpr);
}
if (DEBUG_MU)
@@ -5826,7 +5831,8 @@
return msg;
}
- boolean incProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
+ boolean incProviderCount(ProcessRecord r, final ContentProviderRecord cpr,
+ IBinder externalProcessToken) {
if (r != null) {
Integer cnt = r.conProviders.get(cpr);
if (DEBUG_PROVIDER) Slog.v(TAG,
@@ -5842,12 +5848,13 @@
r.conProviders.put(cpr, new Integer(cnt.intValue()+1));
}
} else {
- cpr.externals++;
+ cpr.addExternalProcessHandleLocked(externalProcessToken);
}
return false;
}
- boolean decProviderCount(ProcessRecord r, ContentProviderRecord cpr) {
+ boolean decProviderCount(ProcessRecord r, final ContentProviderRecord cpr,
+ IBinder externalProcessToken) {
if (r != null) {
Integer cnt = r.conProviders.get(cpr);
if (DEBUG_PROVIDER) Slog.v(TAG,
@@ -5863,13 +5870,13 @@
r.conProviders.put(cpr, new Integer(cnt.intValue()-1));
}
} else {
- cpr.externals++;
+ cpr.removeExternalProcessHandleLocked(externalProcessToken);
}
return false;
}
private final ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
- String name) {
+ String name, IBinder token) {
ContentProviderRecord cpr;
ProviderInfo cpi = null;
@@ -5913,7 +5920,7 @@
// In this case the provider instance already exists, so we can
// return it right away.
- final boolean countChanged = incProviderCount(r, cpr);
+ final boolean countChanged = incProviderCount(r, cpr, token);
if (countChanged) {
if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
// If this is a perceptible app accessing the provider,
@@ -5947,7 +5954,7 @@
Slog.i(TAG,
"Existing provider " + cpr.name.flattenToShortString()
+ " is crashing; detaching " + r);
- boolean lastRef = decProviderCount(r, cpr);
+ boolean lastRef = decProviderCount(r, cpr, token);
appDiedLocked(cpr.proc, cpr.proc.pid, cpr.proc.thread);
if (!lastRef) {
// This wasn't the last ref our process had on
@@ -6005,7 +6012,7 @@
return null;
}
ai = getAppInfoForUser(ai, Binder.getOrigCallingUser());
- cpr = new ContentProviderRecord(cpi, ai, comp);
+ cpr = new ContentProviderRecord(this, cpi, ai, comp);
} catch (RemoteException ex) {
// pm is in same process, this will never happen.
}
@@ -6075,8 +6082,9 @@
if (firstClass) {
mProviderMap.putProviderByClass(comp, cpr);
}
+
mProviderMap.putProviderByName(name, cpr);
- incProviderCount(r, cpr);
+ incProviderCount(r, cpr, token);
}
}
@@ -6116,12 +6124,17 @@
throw new SecurityException(msg);
}
- ContentProviderHolder contentProvider = getContentProviderImpl(caller, name);
- return contentProvider;
+ return getContentProviderImpl(caller, name, null);
}
- private ContentProviderHolder getContentProviderExternal(String name) {
- return getContentProviderImpl(null, name);
+ public ContentProviderHolder getContentProviderExternal(String name, IBinder token) {
+ enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
+ "Do not have permission in call getContentProviderExternal()");
+ return getContentProviderExternalUnchecked(name, token);
+ }
+
+ private ContentProviderHolder getContentProviderExternalUnchecked(String name,IBinder token) {
+ return getContentProviderImpl(null, name, token);
}
/**
@@ -6157,14 +6170,20 @@
+ cpr.info.name + " in process " + r.processName);
return;
} else {
- if (decProviderCount(r, localCpr)) {
+ if (decProviderCount(r, localCpr, null)) {
updateOomAdjLocked();
}
}
}
}
- private void removeContentProviderExternal(String name) {
+ public void removeContentProviderExternal(String name, IBinder token) {
+ enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
+ "Do not have permission in call removeContentProviderExternal()");
+ removeContentProviderExternalUnchecked(name, token);
+ }
+
+ private void removeContentProviderExternalUnchecked(String name, IBinder token) {
synchronized (this) {
ContentProviderRecord cpr = mProviderMap.getProviderByName(name,
Binder.getOrigCallingUser());
@@ -6178,11 +6197,18 @@
ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp,
Binder.getOrigCallingUser());
- localCpr.externals--;
- if (localCpr.externals < 0) {
- Slog.e(TAG, "Externals < 0 for content provider " + localCpr);
+ if (localCpr.hasExternalProcessHandles()) {
+ if (localCpr.removeExternalProcessHandleLocked(token)) {
+ updateOomAdjLocked();
+ } else {
+ Slog.e(TAG, "Attmpt to remove content provider " + localCpr
+ + " with no external reference for token: "
+ + token + ".");
+ }
+ } else {
+ Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
+ + " with no external references.");
}
- updateOomAdjLocked();
}
}
@@ -6286,7 +6312,7 @@
ContentProviderHolder holder = null;
try {
- holder = getContentProviderExternal(name);
+ holder = getContentProviderExternalUnchecked(name, null);
if (holder != null) {
return holder.provider.getType(uri);
}
@@ -6295,7 +6321,7 @@
return null;
} finally {
if (holder != null) {
- removeContentProviderExternal(name);
+ removeContentProviderExternalUnchecked(name, null);
}
Binder.restoreCallingIdentity(ident);
}
@@ -6400,7 +6426,7 @@
public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
enforceNotIsolatedCaller("openContentUri");
String name = uri.getAuthority();
- ContentProviderHolder cph = getContentProviderExternal(name);
+ ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null);
ParcelFileDescriptor pfd = null;
if (cph != null) {
// We record the binder invoker's uid in thread-local storage before
@@ -6422,7 +6448,7 @@
}
// We've got the fd now, so we're done with the provider.
- removeContentProviderExternal(name);
+ removeContentProviderExternalUnchecked(name, null);
} else {
Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
}
@@ -6467,7 +6493,7 @@
mMainStack.stopIfSleepingLocked();
final long endTime = System.currentTimeMillis() + timeout;
while (mMainStack.mResumedActivity != null
- || mMainStack.mPausingActivities.size() > 0) {
+ || mMainStack.mPausingActivity != null) {
long delay = endTime - System.currentTimeMillis();
if (delay <= 0) {
Slog.w(TAG, "Activity manager shutdown timed out");
@@ -8274,13 +8300,8 @@
}
pw.println(" ");
- if (mMainStack.mPausingActivities.size() > 0) {
- pw.println(" mPausingActivities: " + Arrays.toString(
- mMainStack.mPausingActivities.toArray()));
- }
- if (mMainStack.mInputPausedActivities.size() > 0) {
- pw.println(" mInputPausedActivities: " + Arrays.toString(
- mMainStack.mInputPausedActivities.toArray()));
+ if (mMainStack.mPausingActivity != null) {
+ pw.println(" mPausingActivity: " + mMainStack.mPausingActivity);
}
pw.println(" mResumedActivity: " + mMainStack.mResumedActivity);
pw.println(" mFocusedActivity: " + mFocusedActivity);
@@ -10253,7 +10274,7 @@
for (int i=0; i<NL; i++) {
ContentProviderRecord cpr = (ContentProviderRecord)
mLaunchingProviders.get(i);
- if (cpr.clients.size() <= 0 && cpr.externals <= 0) {
+ if (cpr.clients.size() <= 0 && !cpr.hasExternalProcessHandles()) {
synchronized (cpr) {
cpr.launchingApp = null;
cpr.notifyAll();
@@ -13455,7 +13476,7 @@
// If the provider has external (non-framework) process
// dependencies, ensure that its adjustment is at least
// FOREGROUND_APP_ADJ.
- if (cpr.externals != 0) {
+ if (cpr.hasExternalProcessHandles()) {
if (adj > ProcessList.FOREGROUND_APP_ADJ) {
adj = ProcessList.FOREGROUND_APP_ADJ;
schedGroup = Process.THREAD_GROUP_DEFAULT;
@@ -13855,13 +13876,7 @@
private final ActivityRecord resumedAppLocked() {
ActivityRecord resumedActivity = mMainStack.mResumedActivity;
if (resumedActivity == null || resumedActivity.app == null) {
- for (int i=mMainStack.mPausingActivities.size()-1; i>=0; i--) {
- ActivityRecord r = mMainStack.mPausingActivities.get(i);
- if (r.app != null) {
- resumedActivity = r;
- break;
- }
- }
+ resumedActivity = mMainStack.mPausingActivity;
if (resumedActivity == null || resumedActivity.app == null) {
resumedActivity = mMainStack.topRunningActivityLocked(null);
}
diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java
index 977ee84..cdab6c6 100644
--- a/services/java/com/android/server/am/ActivityRecord.java
+++ b/services/java/com/android/server/am/ActivityRecord.java
@@ -602,7 +602,6 @@
public void windowsDrawn() {
synchronized(service) {
- stack.reportActivityDrawnLocked(this);
if (launchTime != 0) {
final long curTime = SystemClock.uptimeMillis();
final long thisTime = curTime - launchTime;
@@ -691,9 +690,7 @@
// Hmmm, who might we be waiting for?
r = stack.mResumedActivity;
if (r == null) {
- if (stack.mPausingActivities.size() > 0) {
- r = stack.mPausingActivities.get(stack.mPausingActivities.size()-1);
- }
+ r = stack.mPausingActivity;
}
// Both of those null? Fall back to 'this' again
if (r == null) {
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index e8c8275..7b8bc26 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -227,13 +227,7 @@
* When we are in the process of pausing an activity, before starting the
* next one, this variable holds the activity that is currently being paused.
*/
- final ArrayList<ActivityRecord> mPausingActivities = new ArrayList<ActivityRecord>();
-
- /**
- * These activities currently have their input paused, as they want for
- * the next top activity to have its windows visible.
- */
- final ArrayList<ActivityRecord> mInputPausedActivities = new ArrayList<ActivityRecord>();
+ ActivityRecord mPausingActivity = null;
/**
* This is the last activity that we put into the paused state. This is
@@ -813,9 +807,9 @@
startPausingLocked(false, true);
return;
}
- if (mPausingActivities.size() > 0) {
+ if (mPausingActivity != null) {
// Still waiting for something to pause; can't sleep yet.
- if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still waiting to pause " + mPausingActivities);
+ if (DEBUG_PAUSE) Slog.v(TAG, "Sleep still waiting to pause " + mPausingActivity);
return;
}
@@ -878,6 +872,11 @@
}
private final void startPausingLocked(boolean userLeaving, boolean uiSleeping) {
+ if (mPausingActivity != null) {
+ RuntimeException e = new RuntimeException();
+ Slog.e(TAG, "Trying to pause when pause is already pending for "
+ + mPausingActivity, e);
+ }
ActivityRecord prev = mResumedActivity;
if (prev == null) {
RuntimeException e = new RuntimeException();
@@ -885,25 +884,19 @@
resumeTopActivityLocked(null);
return;
}
- if (mPausingActivities.contains(prev)) {
- RuntimeException e = new RuntimeException();
- Slog.e(TAG, "Trying to pause when pause when already pausing " + prev, e);
- }
if (DEBUG_STATES) Slog.v(TAG, "Moving to PAUSING: " + prev);
else if (DEBUG_PAUSE) Slog.v(TAG, "Start pausing: " + prev);
mResumedActivity = null;
- mPausingActivities.add(prev);
+ mPausingActivity = prev;
mLastPausedActivity = prev;
prev.state = ActivityState.PAUSING;
prev.task.touchActiveTime();
prev.updateThumbnail(screenshotActivities(prev), null);
mService.updateCpuStats();
- ActivityRecord pausing;
if (prev.app != null && prev.app.thread != null) {
if (DEBUG_PAUSE) Slog.v(TAG, "Enqueueing pending pause: " + prev);
- pausing = prev;
try {
EventLog.writeEvent(EventLogTags.AM_PAUSE_ACTIVITY,
System.identityHashCode(prev),
@@ -916,14 +909,12 @@
} catch (Exception e) {
// Ignore exception, if process died other code will cleanup.
Slog.w(TAG, "Exception thrown during pause", e);
- mPausingActivities.remove(prev);
+ mPausingActivity = null;
mLastPausedActivity = null;
- pausing = null;
}
} else {
- mPausingActivities.remove(prev);
+ mPausingActivity = null;
mLastPausedActivity = null;
- pausing = null;
}
// If we are not going to sleep, we want to ensure the device is
@@ -937,28 +928,18 @@
}
}
- if (pausing != null) {
+
+ if (mPausingActivity != null) {
// Have the window manager pause its key dispatching until the new
// activity has started. If we're pausing the activity just because
// the screen is being turned off and the UI is sleeping, don't interrupt
// key dispatch; the same activity will pick it up again on wakeup.
if (!uiSleeping) {
- pausing.pauseKeyDispatchingLocked();
- mInputPausedActivities.add(prev);
+ prev.pauseKeyDispatchingLocked();
} else {
if (DEBUG_PAUSE) Slog.v(TAG, "Key dispatch not paused for screen off");
}
- if (pausing.configDestroy) {
- // The previous is being paused because the configuration
- // is changing, which means it is actually stopping...
- // To juggle the fact that we are also starting a new
- // instance right now, we need to first completely stop
- // the current instance before starting the new one.
- if (DEBUG_PAUSE) Slog.v(TAG, "Destroying at pause: " + prev);
- destroyActivityLocked(pausing, true, false, "pause-config");
- }
-
// Schedule a pause timeout in case the app doesn't respond.
// We don't give it much time because this directly impacts the
// responsiveness seen by the user.
@@ -970,10 +951,7 @@
// This activity failed to schedule the
// pause, so just treat it as being paused now.
if (DEBUG_PAUSE) Slog.v(TAG, "Activity not running, resuming next.");
- }
-
- if (!mService.isSleeping()) {
- resumeTopActivityLocked(pausing);
+ resumeTopActivityLocked(null);
}
}
@@ -988,17 +966,16 @@
if (index >= 0) {
r = mHistory.get(index);
mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
- if (mPausingActivities.contains(r)) {
+ if (mPausingActivity == r) {
if (DEBUG_STATES) Slog.v(TAG, "Moving to PAUSED: " + r
+ (timeout ? " (due to timeout)" : " (pause complete)"));
r.state = ActivityState.PAUSED;
- completePauseLocked(r);
+ completePauseLocked();
} else {
- ActivityRecord old = mPausingActivities.size() > 0
- ? mPausingActivities.get(0) : null;
EventLog.writeEvent(EventLogTags.AM_FAILED_TO_PAUSE,
System.identityHashCode(r), r.shortComponentName,
- old != null ? old.shortComponentName : "(none)");
+ mPausingActivity != null
+ ? mPausingActivity.shortComponentName : "(none)");
}
}
}
@@ -1024,14 +1001,8 @@
ProcessRecord fgApp = null;
if (mResumedActivity != null) {
fgApp = mResumedActivity.app;
- } else {
- for (int i=mPausingActivities.size()-1; i>=0; i--) {
- ActivityRecord pausing = mPausingActivities.get(i);
- if (pausing.app == r.app) {
- fgApp = pausing.app;
- break;
- }
- }
+ } else if (mPausingActivity != null) {
+ fgApp = mPausingActivity.app;
}
if (r.app != null && fgApp != null && r.app != fgApp
&& r.lastVisibleTime > mService.mPreviousProcessVisibleTime
@@ -1043,49 +1014,58 @@
}
}
- private final void completePauseLocked(ActivityRecord prev) {
+ private final void completePauseLocked() {
+ ActivityRecord prev = mPausingActivity;
if (DEBUG_PAUSE) Slog.v(TAG, "Complete pause: " + prev);
- if (prev.finishing) {
- if (DEBUG_PAUSE) Slog.v(TAG, "Executing finish of activity: " + prev);
- prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE);
- } else if (prev.app != null) {
- if (DEBUG_PAUSE) Slog.v(TAG, "Enqueueing pending stop: " + prev);
- if (prev.waitingVisible) {
- prev.waitingVisible = false;
- mWaitingVisibleActivities.remove(prev);
- if (DEBUG_SWITCH || DEBUG_PAUSE) Slog.v(
- TAG, "Complete pause, no longer waiting: " + prev);
- }
- if (prev.configDestroy) {
- // The previous is being paused because the configuration
- // is changing, which means it is actually stopping...
- // To juggle the fact that we are also starting a new
- // instance right now, we need to first completely stop
- // the current instance before starting the new one.
- if (DEBUG_PAUSE) Slog.v(TAG, "Destroying after pause: " + prev);
- destroyActivityLocked(prev, true, false, "pause-config");
- } else {
- mStoppingActivities.add(prev);
- if (mStoppingActivities.size() > 3) {
- // If we already have a few activities waiting to stop,
- // then give up on things going idle and start clearing
- // them out.
- if (DEBUG_PAUSE) Slog.v(TAG, "To many pending stops, forcing idle");
- scheduleIdleLocked();
- } else {
- checkReadyForSleepLocked();
+ if (prev != null) {
+ if (prev.finishing) {
+ if (DEBUG_PAUSE) Slog.v(TAG, "Executing finish of activity: " + prev);
+ prev = finishCurrentActivityLocked(prev, FINISH_AFTER_VISIBLE);
+ } else if (prev.app != null) {
+ if (DEBUG_PAUSE) Slog.v(TAG, "Enqueueing pending stop: " + prev);
+ if (prev.waitingVisible) {
+ prev.waitingVisible = false;
+ mWaitingVisibleActivities.remove(prev);
+ if (DEBUG_SWITCH || DEBUG_PAUSE) Slog.v(
+ TAG, "Complete pause, no longer waiting: " + prev);
}
+ if (prev.configDestroy) {
+ // The previous is being paused because the configuration
+ // is changing, which means it is actually stopping...
+ // To juggle the fact that we are also starting a new
+ // instance right now, we need to first completely stop
+ // the current instance before starting the new one.
+ if (DEBUG_PAUSE) Slog.v(TAG, "Destroying after pause: " + prev);
+ destroyActivityLocked(prev, true, false, "pause-config");
+ } else {
+ mStoppingActivities.add(prev);
+ if (mStoppingActivities.size() > 3) {
+ // If we already have a few activities waiting to stop,
+ // then give up on things going idle and start clearing
+ // them out.
+ if (DEBUG_PAUSE) Slog.v(TAG, "To many pending stops, forcing idle");
+ scheduleIdleLocked();
+ } else {
+ checkReadyForSleepLocked();
+ }
+ }
+ } else {
+ if (DEBUG_PAUSE) Slog.v(TAG, "App died during pause, not stopping: " + prev);
+ prev = null;
}
- } else {
- if (DEBUG_PAUSE) Slog.v(TAG, "App died during pause, not stopping: " + prev);
- prev = null;
+ mPausingActivity = null;
}
- mPausingActivities.remove(prev);
- if (mService.isSleeping()) {
+ if (!mService.isSleeping()) {
+ resumeTopActivityLocked(prev);
+ } else {
checkReadyForSleepLocked();
}
+
+ if (prev != null) {
+ prev.resumeKeyDispatchingLocked();
+ }
if (prev.app != null && prev.cpuTimeAtResume > 0
&& mService.mBatteryStatsService.isOnBattery()) {
@@ -1142,9 +1122,7 @@
if (mMainStack) {
mService.setFocusedActivityLocked(next);
}
- if (mInputPausedActivities.remove(next)) {
- next.resumeKeyDispatchingLocked();
- }
+ next.resumeKeyDispatchingLocked();
ensureActivitiesVisibleLocked(null, 0);
mService.mWindowManager.executeAppTransition();
mNoAnimActivities.clear();
@@ -1374,6 +1352,13 @@
if (DEBUG_SWITCH) Slog.v(TAG, "Resuming " + next);
+ // If we are currently pausing an activity, then don't do anything
+ // until that is done.
+ if (mPausingActivity != null) {
+ if (DEBUG_SWITCH) Slog.v(TAG, "Skip resume: pausing=" + mPausingActivity);
+ return false;
+ }
+
// Okay we are now going to start a switch, to 'next'. We may first
// have to pause the current activity, but this is an important point
// where we have decided to go to 'next' so keep track of that.
@@ -2455,7 +2440,7 @@
err = startActivityUncheckedLocked(r, sourceRecord,
grantedUriPermissions, grantedMode, onlyIfNeeded, true);
- if (mDismissKeyguardOnNextActivity && mPausingActivities.size() == 0) {
+ if (mDismissKeyguardOnNextActivity && mPausingActivity == null) {
// Someone asked to have the keyguard dismissed on the next
// activity start, but we are not actually doing an activity
// switch... just dismiss the keyguard now, because we
@@ -3126,18 +3111,7 @@
}
mService.notifyAll();
}
-
- void reportActivityDrawnLocked(ActivityRecord r) {
- if (mResumedActivity == r) {
- // Once the resumed activity has been drawn, we can stop
- // pausing input on all other activities.
- for (int i=mInputPausedActivities.size()-1; i>=0; i--) {
- mInputPausedActivities.get(i).resumeKeyDispatchingLocked();
- }
- mInputPausedActivities.clear();
- }
- }
-
+
void reportActivityVisibleLocked(ActivityRecord r) {
for (int i=mWaitingActivityVisible.size()-1; i>=0; i--) {
WaitResult w = mWaitingActivityVisible.get(i);
@@ -3196,9 +3170,7 @@
mService.setFocusedActivityLocked(topRunningActivityLocked(null));
}
}
- if (mInputPausedActivities.remove(r)) {
- r.resumeKeyDispatchingLocked();
- }
+ r.resumeKeyDispatchingLocked();
try {
r.stopped = false;
if (DEBUG_STATES) Slog.v(TAG, "Moving to STOPPING: " + r
@@ -3524,7 +3496,7 @@
// Tell window manager to prepare for this one to be removed.
mService.mWindowManager.setAppVisibility(r.appToken, false);
- if (!mPausingActivities.contains(r)) {
+ if (mPausingActivity == null) {
if (DEBUG_PAUSE) Slog.v(TAG, "Finish needs to pause: " + r);
if (DEBUG_USER_LEAVING) Slog.v(TAG, "finish() => pause with userLeaving=false");
startPausingLocked(false, false);
@@ -3608,20 +3580,6 @@
return r;
}
- final void appDiedLocked(ProcessRecord app) {
- for (int i=mPausingActivities.size()-1; i>=0; i--) {
- ActivityRecord r = mPausingActivities.get(i);
- if (r.app == app) {
- if (DEBUG_PAUSE) Slog.v(TAG, "App died while pausing: " + r);
- mPausingActivities.remove(i);
- mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
- }
- }
- if (mLastPausedActivity != null && mLastPausedActivity.app == app) {
- mLastPausedActivity = null;
- }
- }
-
/**
* Perform the common clean-up of an activity record. This is called both
* as part of destroyActivityLocked() (when destroying the client-side
diff --git a/services/java/com/android/server/am/ContentProviderRecord.java b/services/java/com/android/server/am/ContentProviderRecord.java
index 38355537..f338cfc 100644
--- a/services/java/com/android/server/am/ContentProviderRecord.java
+++ b/services/java/com/android/server/am/ContentProviderRecord.java
@@ -20,24 +20,35 @@
import android.content.ComponentName;
import android.content.pm.ApplicationInfo;
import android.content.pm.ProviderInfo;
+import android.os.IBinder;
+import android.os.IBinder.DeathRecipient;
import android.os.Process;
+import android.os.RemoteException;
+import android.util.Slog;
import java.io.PrintWriter;
+import java.util.HashMap;
import java.util.HashSet;
class ContentProviderRecord extends ContentProviderHolder {
// All attached clients
final HashSet<ProcessRecord> clients = new HashSet<ProcessRecord>();
+ // Handles for non-framework processes supported by this provider
+ HashMap<IBinder, ExternalProcessHandle> externalProcessTokenToHandle;
+ // Count for external process for which we have no handles.
+ int externalProcessNoHandleCount;
+ final ActivityManagerService service;
final int uid;
final ApplicationInfo appInfo;
final ComponentName name;
- int externals; // number of non-framework processes supported by this provider
ProcessRecord proc; // if non-null, hosting process.
ProcessRecord launchingApp; // if non-null, waiting for this app to be launched.
String stringName;
-
- public ContentProviderRecord(ProviderInfo _info, ApplicationInfo ai, ComponentName _name) {
+
+ public ContentProviderRecord(ActivityManagerService _service, ProviderInfo _info,
+ ApplicationInfo ai, ComponentName _name) {
super(_info);
+ service = _service;
uid = ai.uid;
appInfo = ai;
name = _name;
@@ -50,6 +61,7 @@
appInfo = cpr.appInfo;
name = cpr.name;
noReleaseNeeded = cpr.noReleaseNeeded;
+ service = cpr.service;
}
public boolean canRunHere(ProcessRecord app) {
@@ -57,6 +69,57 @@
&& (uid == Process.SYSTEM_UID || uid == app.info.uid);
}
+ public void addExternalProcessHandleLocked(IBinder token) {
+ if (token == null) {
+ externalProcessNoHandleCount++;
+ } else {
+ if (externalProcessTokenToHandle == null) {
+ externalProcessTokenToHandle = new HashMap<IBinder, ExternalProcessHandle>();
+ }
+ ExternalProcessHandle handle = externalProcessTokenToHandle.get(token);
+ if (handle == null) {
+ handle = new ExternalProcessHandle(token);
+ externalProcessTokenToHandle.put(token, handle);
+ }
+ handle.mAcquisitionCount++;
+ }
+ }
+
+ public boolean removeExternalProcessHandleLocked(IBinder token) {
+ if (hasExternalProcessHandles()) {
+ boolean hasHandle = false;
+ if (externalProcessTokenToHandle != null) {
+ ExternalProcessHandle handle = externalProcessTokenToHandle.get(token);
+ if (handle != null) {
+ hasHandle = true;
+ handle.mAcquisitionCount--;
+ if (handle.mAcquisitionCount == 0) {
+ removeExternalProcessHandleInternalLocked(token);
+ return true;
+ }
+ }
+ }
+ if (!hasHandle) {
+ externalProcessNoHandleCount--;
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private void removeExternalProcessHandleInternalLocked(IBinder token) {
+ ExternalProcessHandle handle = externalProcessTokenToHandle.get(token);
+ handle.unlinkFromOwnDeathLocked();
+ externalProcessTokenToHandle.remove(token);
+ if (externalProcessTokenToHandle.size() == 0) {
+ externalProcessTokenToHandle = null;
+ }
+ }
+
+ public boolean hasExternalProcessHandles() {
+ return (externalProcessTokenToHandle != null || externalProcessNoHandleCount > 0);
+ }
+
void dump(PrintWriter pw, String prefix) {
pw.print(prefix); pw.print("package=");
pw.print(info.applicationInfo.packageName);
@@ -73,8 +136,9 @@
pw.print("multiprocess="); pw.print(info.multiprocess);
pw.print(" initOrder="); pw.println(info.initOrder);
}
- if (externals != 0) {
- pw.print(prefix); pw.print("externals="); pw.println(externals);
+ if (hasExternalProcessHandles()) {
+ pw.print(prefix); pw.print("externals=");
+ pw.println(externalProcessTokenToHandle.size());
}
if (clients.size() > 0) {
pw.print(prefix); pw.println("Clients:");
@@ -84,6 +148,7 @@
}
}
+ @Override
public String toString() {
if (stringName != null) {
return stringName;
@@ -96,4 +161,35 @@
sb.append('}');
return stringName = sb.toString();
}
+
+ // This class represents a handle from an external process to a provider.
+ private class ExternalProcessHandle implements DeathRecipient {
+ private static final String LOG_TAG = "ExternalProcessHanldle";
+
+ private final IBinder mToken;
+ private int mAcquisitionCount;
+
+ public ExternalProcessHandle(IBinder token) {
+ mToken = token;
+ try {
+ token.linkToDeath(this, 0);
+ } catch (RemoteException re) {
+ Slog.e(LOG_TAG, "Couldn't register for death for token: " + mToken, re);
+ }
+ }
+
+ public void unlinkFromOwnDeathLocked() {
+ mToken.unlinkToDeath(this, 0);
+ }
+
+ @Override
+ public void binderDied() {
+ synchronized (service) {
+ if (hasExternalProcessHandles() &&
+ externalProcessTokenToHandle.get(mToken) != null) {
+ removeExternalProcessHandleInternalLocked(mToken);
+ }
+ }
+ }
+ }
}
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 1c81bb1..dafc613 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -268,6 +268,7 @@
final TokenWatcher mKeyguardTokenWatcher = new TokenWatcher(
new Handler(), "WindowManagerService.mKeyguardTokenWatcher") {
+ @Override
public void acquired() {
if (shouldAllowDisableKeyguard()) {
mPolicy.enableKeyguard(false);
@@ -276,6 +277,7 @@
Log.v(TAG, "Not disabling keyguard since device policy is enforced");
}
}
+ @Override
public void released() {
mPolicy.enableKeyguard(true);
synchronized (mKeyguardTokenWatcher) {
@@ -599,6 +601,7 @@
private boolean mSyswin = false;
private float mScreenBrightness = -1;
private float mButtonBrightness = -1;
+ private boolean mUpdateRotation = false;
}
private LayoutAndSurfaceFields mInnerFields = new LayoutAndSurfaceFields();
@@ -6377,7 +6380,7 @@
INJECTION_TIMEOUT_MILLIS);
Binder.restoreCallingIdentity(ident);
- return reportInjectionResult(result);
+ return reportInjectionResult(result, pid);
}
/**
@@ -6407,7 +6410,7 @@
INJECTION_TIMEOUT_MILLIS);
Binder.restoreCallingIdentity(ident);
- return reportInjectionResult(result);
+ return reportInjectionResult(result, pid);
}
/**
@@ -6437,7 +6440,7 @@
INJECTION_TIMEOUT_MILLIS);
Binder.restoreCallingIdentity(ident);
- return reportInjectionResult(result);
+ return reportInjectionResult(result, pid);
}
/**
@@ -6458,24 +6461,23 @@
INJECTION_TIMEOUT_MILLIS);
Binder.restoreCallingIdentity(ident);
- return reportInjectionResult(result);
+ return reportInjectionResult(result, pid);
}
- private boolean reportInjectionResult(int result) {
+ private boolean reportInjectionResult(int result, int pid) {
switch (result) {
case InputManager.INPUT_EVENT_INJECTION_PERMISSION_DENIED:
- Slog.w(TAG, "Input event injection permission denied.");
+ Slog.w(TAG, "Input event injection from pid " + pid + " permission denied.");
throw new SecurityException(
"Injecting to another application requires INJECT_EVENTS permission");
case InputManager.INPUT_EVENT_INJECTION_SUCCEEDED:
- //Slog.v(TAG, "Input event injection succeeded.");
return true;
case InputManager.INPUT_EVENT_INJECTION_TIMED_OUT:
- Slog.w(TAG, "Input event injection timed out.");
+ Slog.w(TAG, "Input event injection from pid " + pid + " timed out.");
return false;
case InputManager.INPUT_EVENT_INJECTION_FAILED:
default:
- Slog.w(TAG, "Input event injection failed.");
+ Slog.w(TAG, "Input event injection from pid " + pid + " failed.");
return false;
}
}
@@ -7621,53 +7623,53 @@
* @param innerDh Height of app window.
* @return true if rotation has stopped, false otherwise
*/
- private boolean updateAppsAndRotationAnimationsLocked(long currentTime,
+ private void updateWindowsAppsAndRotationAnimationsLocked(long currentTime,
int innerDw, int innerDh) {
int i;
+ for (i = mWindows.size() - 1; i >= 0; i--) {
+ mInnerFields.mAnimating |= mWindows.get(i).stepAnimationLocked(currentTime);
+ }
+
final int NAT = mAppTokens.size();
for (i=0; i<NAT; i++) {
- if (mAppTokens.get(i).stepAnimationLocked(currentTime,
- innerDw, innerDh)) {
- mInnerFields.mAnimating = true;
- }
+ mInnerFields.mAnimating |=
+ mAppTokens.get(i).stepAnimationLocked(currentTime, innerDw, innerDh);
}
final int NEAT = mExitingAppTokens.size();
for (i=0; i<NEAT; i++) {
- if (mExitingAppTokens.get(i).stepAnimationLocked(currentTime,
- innerDw, innerDh)) {
- mInnerFields.mAnimating = true;
- }
+ mInnerFields.mAnimating |=
+ mExitingAppTokens.get(i).stepAnimationLocked(currentTime, innerDw, innerDh);
}
- boolean updateRotation = false;
if (mScreenRotationAnimation != null) {
if (mScreenRotationAnimation.isAnimating()) {
if (mScreenRotationAnimation.stepAnimation(currentTime)) {
+ mInnerFields.mUpdateRotation = false;
mInnerFields.mAnimating = true;
} else {
- updateRotation = true;
+ mInnerFields.mUpdateRotation = true;
mScreenRotationAnimation.kill();
mScreenRotationAnimation = null;
}
}
}
-
- return updateRotation;
}
/**
* Extracted from {@link #performLayoutAndPlaceSurfacesLockedInner} to reduce size of method.
*
* @param currentTime The time which animations use for calculating transitions.
+ * @param dw Width of app window.
+ * @param dh Height of app window.
* @param innerDw Width of app window.
* @param innerDh Height of app window.
*/
- private void updateWindowsAndWallpaperLocked(final long currentTime,
- final int innerDw, final int innerDh) {
- int i;
- final int N = mWindows.size();
+ private int updateWindowsAndWallpaperLocked(final long currentTime, final int dw, final int dh,
+ final int innerDw, final int innerDh) {
- for (i=N-1; i>=0; i--) {
+ mPolicy.beginAnimationLw(dw, dh);
+
+ for (int i = mWindows.size() - 1; i >= 0; i--) {
WindowState w = mWindows.get(i);
final WindowManager.LayoutParams attrs = w.mAttrs;
@@ -7685,9 +7687,6 @@
final boolean wasAnimating = w.mAnimating;
- int animDw = innerDw;
- int animDh = innerDh;
-
// If the window has moved due to its containing
// content frame changing, then we'd like to animate
// it. The checks here are ordered by what is least
@@ -7699,13 +7698,15 @@
Animation a = AnimationUtils.loadAnimation(mContext,
com.android.internal.R.anim.window_move_from_decor);
w.setAnimation(a);
- animDw = w.mLastFrame.left - w.mFrame.left;
- animDh = w.mLastFrame.top - w.mFrame.top;
+ w.mAnimDw = w.mLastFrame.left - w.mFrame.left;
+ w.mAnimDh = w.mLastFrame.top - w.mFrame.top;
+ } else {
+ w.mAnimDw = innerDw;
+ w.mAnimDh = innerDh;
}
// Execute animation.
- final boolean nowAnimating = w.stepAnimationLocked(currentTime,
- animDw, animDh);
+ final boolean nowAnimating = w.isAnimating();
// If this window is animating, make a note that we have
// an animating window and take care of a request to run
@@ -7847,6 +7848,8 @@
w.performShowLocked();
}
} // end forall windows
+
+ return mPolicy.finishAnimationLw();
}
/**
@@ -8117,7 +8120,7 @@
*
* @return bitmap indicating if another pass through layout must be made.
*/
- private int handleAnimatingAndTransitionLocked() {
+ private int handleAnimatingStoppedAndTransitionLocked() {
int changes = 0;
mAppTransitionRunning = false;
@@ -8653,7 +8656,6 @@
boolean focusDisplayed = false;
mInnerFields.mAnimating = false;
boolean createWatermark = false;
- boolean updateRotation = false;
if (mFxSession == null) {
mFxSession = new SurfaceSession();
@@ -8707,22 +8709,13 @@
// FIRST LOOP: Perform a layout, if needed.
if (repeats < 4) {
- performLayoutLockedInner(repeats == 0, false /*updateInputWindows*/);
+ performLayoutLockedInner(repeats == 1, false /*updateInputWindows*/);
} else {
Slog.w(TAG, "Layout repeat skipped after too many iterations");
}
- changes = 0;
++mTransactionSequence;
- // Update animations of all applications, including those
- // associated with exiting/removed apps
- mInnerFields.mAnimating = false;
-
- // SECOND LOOP: Execute animations and update visibility of windows.
- updateRotation |=
- updateAppsAndRotationAnimationsLocked(currentTime, innerDw, innerDh);
-
if (DEBUG_APP_TRANSITIONS) Slog.v(TAG, "*** ANIM STEP: seq="
+ mTransactionSequence + " mAnimating="
+ mInnerFields.mAnimating);
@@ -8734,11 +8727,7 @@
mInnerFields.mWindowAnimationBackground = null;
mInnerFields.mWindowAnimationBackgroundColor = 0;
- mPolicy.beginAnimationLw(dw, dh);
-
- updateWindowsAndWallpaperLocked(currentTime, innerDw, innerDh);
-
- changes |= mPolicy.finishAnimationLw();
+ changes = updateWindowsAndWallpaperLocked(currentTime, dw, dh, innerDw, innerDh);
if (mInnerFields.mTokenMayBeDrawn) {
changes |= testTokenMayBeDrawnLocked();
@@ -8760,7 +8749,7 @@
// reflects the correct Z-order, but the window list may now
// be out of sync with it. So here we will just rebuild the
// entire app window list. Fun!
- changes |= handleAnimatingAndTransitionLocked();
+ changes |= handleAnimatingStoppedAndTransitionLocked();
}
if (mInnerFields.mWallpaperForceHidingChanged && changes == 0 && !mAppTransitionReady) {
@@ -8783,6 +8772,12 @@
+ Integer.toHexString(changes));
} while (changes != 0);
+ // Update animations of all applications, including those
+ // associated with exiting/removed apps
+ mInnerFields.mAnimating = false;
+
+ updateWindowsAppsAndRotationAnimationsLocked(currentTime, innerDw, innerDh);
+
// THIRD LOOP: Update the surfaces of all windows.
final boolean someoneLosingFocus = mLosingFocus.size() != 0;
@@ -9024,16 +9019,17 @@
mTurnOnScreen = false;
}
- if (updateRotation) {
+ if (mInnerFields.mUpdateRotation) {
if (DEBUG_ORIENTATION) Slog.d(TAG, "Performing post-rotate rotation");
if (updateRotationUncheckedLocked(false)) {
mH.sendEmptyMessage(H.SEND_NEW_CONFIGURATION);
} else {
- updateRotation = false;
+ mInnerFields.mUpdateRotation = false;
}
}
- if (mInnerFields.mOrientationChangeComplete && !needRelayout && !updateRotation) {
+ if (mInnerFields.mOrientationChangeComplete && !needRelayout &&
+ !mInnerFields.mUpdateRotation) {
checkDrawnWindowsLocked();
}
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
index b013d27..d7a7cb0 100644
--- a/services/java/com/android/server/wm/WindowState.java
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -297,6 +297,11 @@
CharSequence mLastTitle;
boolean mWasPaused;
+ // Used to save animation distances between the time they are calculated and when they are
+ // used.
+ int mAnimDw;
+ int mAnimDh;
+
WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token,
WindowState attachedWindow, int seq, WindowManager.LayoutParams a,
int viewVisibility) {
@@ -973,7 +978,7 @@
// This must be called while inside a transaction. Returns true if
// there is more animation to run.
- boolean stepAnimationLocked(long currentTime, int dw, int dh) {
+ boolean stepAnimationLocked(long currentTime) {
if (!mService.mDisplayFrozen && mService.mPolicy.isScreenOnFully()) {
// We will run animations as long as the display isn't frozen.
@@ -985,8 +990,9 @@
WindowManagerService.TAG, "Starting animation in " + this +
" @ " + currentTime + ": ww=" + mFrame.width() +
" wh=" + mFrame.height() +
- " dw=" + dw + " dh=" + dh + " scale=" + mService.mWindowAnimationScale);
- mAnimation.initialize(mFrame.width(), mFrame.height(), dw, dh);
+ " dw=" + mAnimDw + " dh=" + mAnimDh +
+ " scale=" + mService.mWindowAnimationScale);
+ mAnimation.initialize(mFrame.width(), mFrame.height(), mAnimDw, mAnimDh);
mAnimation.setStartTime(currentTime);
mLocalAnimating = true;
mAnimating = true;
diff --git a/services/jni/Android.mk b/services/jni/Android.mk
index c63b84df..c02dd36 100644
--- a/services/jni/Android.mk
+++ b/services/jni/Android.mk
@@ -26,6 +26,7 @@
LOCAL_SHARED_LIBRARIES := \
libandroid_runtime \
+ libandroidfw \
libcutils \
libhardware \
libhardware_legacy \
diff --git a/services/jni/com_android_server_PowerManagerService.h b/services/jni/com_android_server_PowerManagerService.h
index af10711..cc3b5ef5 100644
--- a/services/jni/com_android_server_PowerManagerService.h
+++ b/services/jni/com_android_server_PowerManagerService.h
@@ -20,7 +20,7 @@
#include "JNIHelp.h"
#include "jni.h"
-#include <ui/PowerManager.h>
+#include <androidfw/PowerManager.h>
namespace android {
diff --git a/services/surfaceflinger/LayerScreenshot.cpp b/services/surfaceflinger/LayerScreenshot.cpp
index c127fa6..c7cf46e 100644
--- a/services/surfaceflinger/LayerScreenshot.cpp
+++ b/services/surfaceflinger/LayerScreenshot.cpp
@@ -70,6 +70,8 @@
glBindTexture(GL_TEXTURE_2D, mTextureName);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+ glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
mTexCoords[0] = 0; mTexCoords[1] = v;
mTexCoords[2] = 0; mTexCoords[3] = 0;
mTexCoords[4] = u; mTexCoords[5] = 0;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 40717f4..9e3f548 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -1922,6 +1922,8 @@
glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, vtx);
@@ -2094,6 +2096,8 @@
glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer(2, GL_FLOAT, 0, vtx);
diff --git a/services/surfaceflinger/tests/resize/resize.cpp b/services/surfaceflinger/tests/resize/resize.cpp
index 56b2a8f..7f3f064 100644
--- a/services/surfaceflinger/tests/resize/resize.cpp
+++ b/services/surfaceflinger/tests/resize/resize.cpp
@@ -39,7 +39,7 @@
// create a client to surfaceflinger
sp<SurfaceComposerClient> client = new SurfaceComposerClient();
- sp<Surface> surface = client->createSurface(getpid(), 0, 160, 240,
+ sp<Surface> surface = client->createSurface(0, 160, 240,
PIXEL_FORMAT_RGB_565);
diff --git a/services/surfaceflinger/tests/surface/surface.cpp b/services/surfaceflinger/tests/surface/surface.cpp
index 8e1c3fe..9c15f9b 100644
--- a/services/surfaceflinger/tests/surface/surface.cpp
+++ b/services/surfaceflinger/tests/surface/surface.cpp
@@ -38,7 +38,7 @@
sp<SurfaceComposerClient> client = new SurfaceComposerClient();
sp<SurfaceControl> surfaceControl = client->createSurface(
- getpid(), 0, 160, 240, PIXEL_FORMAT_RGB_565);
+ 0, 160, 240, PIXEL_FORMAT_RGB_565);
SurfaceComposerClient::openGlobalTransaction();
surfaceControl->setLayer(100000);
SurfaceComposerClient::closeGlobalTransaction();
diff --git a/test-runner/src/android/test/mock/MockContext.java b/test-runner/src/android/test/mock/MockContext.java
index 674c0b7..5fab2bb 100644
--- a/test-runner/src/android/test/mock/MockContext.java
+++ b/test-runner/src/android/test/mock/MockContext.java
@@ -267,6 +267,12 @@
throw new UnsupportedOperationException();
}
+ /** @hide */
+ @Override
+ public void sendBroadcast(Intent intent, int userId) {
+ throw new UnsupportedOperationException();
+ }
+
@Override
public void sendBroadcast(Intent intent, String receiverPermission) {
throw new UnsupportedOperationException();
diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml
index 3904c21..ed78daa3 100644
--- a/tests/HwAccelerationTest/AndroidManifest.xml
+++ b/tests/HwAccelerationTest/AndroidManifest.xml
@@ -568,6 +568,15 @@
</activity>
<activity
+ android:name="PathsCacheActivity"
+ android:label="_PathsCache">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <activity
android:name="PointsActivity"
android:label="_Points">
<intent-filter>
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/PathsCacheActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/PathsCacheActivity.java
new file mode 100644
index 0000000..b8ad823
--- /dev/null
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/PathsCacheActivity.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2010 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 com.android.test.hwui;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+
+import java.util.ArrayList;
+import java.util.Random;
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class PathsCacheActivity extends Activity {
+ private Path mPath;
+
+ private final Random mRandom = new Random();
+ private final ArrayList<Path> mPathList = new ArrayList<Path>();
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ mPath = makePath();
+
+ final PathsView view = new PathsView(this);
+ setContentView(view);
+ }
+
+ private Path makePath() {
+ Path path = new Path();
+ buildPath(path);
+ return path;
+ }
+
+ private void buildPath(Path path) {
+ path.moveTo(0.0f, 0.0f);
+ path.cubicTo(0.0f, 0.0f, 100.0f, 150.0f, 100.0f, 200.0f);
+ path.cubicTo(100.0f, 200.0f, 50.0f, 300.0f, -80.0f, 200.0f);
+ path.cubicTo(-80.0f, 200.0f, 100.0f, 200.0f, 200.0f, 0.0f);
+ }
+
+ public class PathsView extends View {
+ private final Paint mMediumPaint;
+
+ public PathsView(Context c) {
+ super(c);
+
+ mMediumPaint = new Paint();
+ mMediumPaint.setAntiAlias(true);
+ mMediumPaint.setColor(0xe00000ff);
+ mMediumPaint.setStrokeWidth(10.0f);
+ mMediumPaint.setStyle(Paint.Style.STROKE);
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+
+ Log.d("OpenGLRenderer", "Start frame");
+
+ canvas.drawARGB(255, 255, 255, 255);
+
+ canvas.save();
+ canvas.translate(550.0f, 60.0f);
+ canvas.drawPath(mPath, mMediumPaint);
+
+ mPath.reset();
+ buildPath(mPath);
+
+ canvas.translate(30.0f, 30.0f);
+ canvas.drawPath(mPath, mMediumPaint);
+ canvas.drawPath(mPath, mMediumPaint);
+
+ canvas.restore();
+
+// Path path = makePath();
+// int r = mRandom.nextInt(10);
+// if (r == 5 || r == 3) {
+// mPathList.add(path);
+// } else if (r == 9) {
+// mPathList.clear();
+// }
+//
+// canvas.save();
+// canvas.translate(550.0f + mRandom.nextInt(50), 60.0f + mRandom.nextInt(50));
+// canvas.drawPath(path, mMediumPaint);
+// canvas.restore();
+//
+ invalidate();
+ }
+ }
+}
diff --git a/tests/backup/Android.mk b/tests/backup/Android.mk
index 31e2ec5..88794c2 100644
--- a/tests/backup/Android.mk
+++ b/tests/backup/Android.mk
@@ -24,7 +24,7 @@
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := backup_helper_test
LOCAL_MODULE_PATH := $(TARGET_OUT_DATA_APPS)
-LOCAL_SHARED_LIBRARIES := libutils
+LOCAL_SHARED_LIBRARIES := libandroidfw libutils
include $(BUILD_EXECUTABLE)
diff --git a/tests/backup/backup_helper_test.cpp b/tests/backup/backup_helper_test.cpp
index 04358ad..b5f6ff5 100644
--- a/tests/backup/backup_helper_test.cpp
+++ b/tests/backup/backup_helper_test.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include <utils/BackupHelpers.h>
+#include <androidfw/BackupHelpers.h>
#include <stdio.h>
#include <string.h>
diff --git a/tools/aapt/AaptAssets.h b/tools/aapt/AaptAssets.h
index 1c653e1..5924952 100644
--- a/tools/aapt/AaptAssets.h
+++ b/tools/aapt/AaptAssets.h
@@ -7,14 +7,14 @@
#define __AAPT_ASSETS_H
#include <stdlib.h>
-#include <utils/AssetManager.h>
+#include <androidfw/AssetManager.h>
+#include <androidfw/ResourceTypes.h>
#include <utils/KeyedVector.h>
-#include <utils/String8.h>
-#include <utils/ResourceTypes.h>
+#include <utils/RefBase.h>
#include <utils/SortedVector.h>
#include <utils/String8.h>
+#include <utils/String8.h>
#include <utils/Vector.h>
-#include <utils/RefBase.h>
#include "ZipFile.h"
#include "Bundle.h"
diff --git a/tools/aapt/Android.mk b/tools/aapt/Android.mk
index cb55a9c..d0a81dc 100644
--- a/tools/aapt/Android.mk
+++ b/tools/aapt/Android.mk
@@ -38,6 +38,7 @@
#LOCAL_WHOLE_STATIC_LIBRARIES :=
LOCAL_STATIC_LIBRARIES := \
libhost \
+ libandroidfw \
libutils \
libcutils \
libexpat \
diff --git a/tools/aapt/Images.cpp b/tools/aapt/Images.cpp
index ffbe875..6402e3c 100644
--- a/tools/aapt/Images.cpp
+++ b/tools/aapt/Images.cpp
@@ -8,7 +8,7 @@
#include "Images.h"
-#include <utils/ResourceTypes.h>
+#include <androidfw/ResourceTypes.h>
#include <utils/ByteOrder.h>
#include <png.h>
diff --git a/tools/aapt/ResourceTable.cpp b/tools/aapt/ResourceTable.cpp
index 7a0499c..0c0b2ea 100644
--- a/tools/aapt/ResourceTable.cpp
+++ b/tools/aapt/ResourceTable.cpp
@@ -9,8 +9,8 @@
#include "XMLNode.h"
#include "ResourceFilter.h"
+#include <androidfw/ResourceTypes.h>
#include <utils/ByteOrder.h>
-#include <utils/ResourceTypes.h>
#include <stdarg.h>
#define NOISY(x) //x
diff --git a/tools/aapt/StringPool.h b/tools/aapt/StringPool.h
index 255bdbf..86044ed 100644
--- a/tools/aapt/StringPool.h
+++ b/tools/aapt/StringPool.h
@@ -10,7 +10,7 @@
#include "Main.h"
#include "AaptAssets.h"
-#include <utils/ResourceTypes.h>
+#include <androidfw/ResourceTypes.h>
#include <utils/String16.h>
#include <utils/TextOutput.h>
diff --git a/tools/aapt/ZipFile.cpp b/tools/aapt/ZipFile.cpp
index 0705be3..8057068 100644
--- a/tools/aapt/ZipFile.cpp
+++ b/tools/aapt/ZipFile.cpp
@@ -20,7 +20,7 @@
#define LOG_TAG "zip"
-#include <utils/ZipUtils.h>
+#include <androidfw/ZipUtils.h>
#include <utils/Log.h>
#include "ZipFile.h"
diff --git a/tools/aidl/Type.cpp b/tools/aidl/Type.cpp
index 42e1226..d572af6 100755
--- a/tools/aidl/Type.cpp
+++ b/tools/aidl/Type.cpp
@@ -123,7 +123,7 @@
RPC_DATA_TYPE = new RpcDataType();
NAMES.Add(RPC_DATA_TYPE);
- RPC_ERROR_TYPE = new UserDataType("com.android.athome.rpc", "RpcError",
+ RPC_ERROR_TYPE = new UserDataType("android.support.place.rpc", "RpcError",
true, __FILE__, __LINE__);
NAMES.Add(RPC_ERROR_TYPE);
@@ -1234,7 +1234,7 @@
// ================================================================
RpcDataType::RpcDataType()
- :UserDataType("com.android.athome.rpc", "RpcData", true, true, true)
+ :UserDataType("android.support.place.rpc", "RpcData", true, true, true)
{
}
diff --git a/tools/aidl/generate_java_rpc.cpp b/tools/aidl/generate_java_rpc.cpp
index ecff3a1..e5fa076 100644
--- a/tools/aidl/generate_java_rpc.cpp
+++ b/tools/aidl/generate_java_rpc.cpp
@@ -7,26 +7,26 @@
Type* SERVICE_CONTEXT_TYPE = new Type("android.content",
"Context", Type::BUILT_IN, false, false, false);
-Type* PRESENTER_BASE_TYPE = new Type("com.android.athome.connector",
+Type* PRESENTER_BASE_TYPE = new Type("android.support.place.connector",
"EventListener", Type::BUILT_IN, false, false, false);
-Type* PRESENTER_LISTENER_BASE_TYPE = new Type("com.android.athome.connector",
+Type* PRESENTER_LISTENER_BASE_TYPE = new Type("android.support.place.connector",
"EventListener.Listener", Type::BUILT_IN, false, false, false);
-Type* RPC_BROKER_TYPE = new Type("com.android.athome.connector", "Broker",
+Type* RPC_BROKER_TYPE = new Type("android.support.place.connector", "Broker",
Type::BUILT_IN, false, false, false);
Type* RPC_CONTAINER_TYPE = new Type("com.android.athome.connector", "ConnectorContainer",
Type::BUILT_IN, false, false, false);
Type* PLACE_INFO_TYPE = new Type("android.support.place.connector", "PlaceInfo",
Type::BUILT_IN, false, false, false);
// TODO: Just use Endpoint, so this works for all endpoints.
-Type* RPC_CONNECTOR_TYPE = new Type("com.android.athome.connector", "Connector",
+Type* RPC_CONNECTOR_TYPE = new Type("android.support.place.connector", "Connector",
Type::BUILT_IN, false, false, false);
-Type* RPC_ENDPOINT_INFO_TYPE = new UserDataType("com.android.athome.rpc",
+Type* RPC_ENDPOINT_INFO_TYPE = new UserDataType("android.support.place.rpc",
"EndpointInfo", true, __FILE__, __LINE__);
-Type* RPC_RESULT_HANDLER_TYPE = new UserDataType("com.android.athome.rpc", "RpcResultHandler",
+Type* RPC_RESULT_HANDLER_TYPE = new UserDataType("android.support.place.rpc", "RpcResultHandler",
true, __FILE__, __LINE__);
-Type* RPC_ERROR_LISTENER_TYPE = new Type("com.android.athome.rpc", "RpcErrorHandler",
+Type* RPC_ERROR_LISTENER_TYPE = new Type("android.support.place.rpc", "RpcErrorHandler",
Type::BUILT_IN, false, false, false);
-Type* RPC_CONTEXT_TYPE = new UserDataType("com.android.athome.rpc", "RpcContext", true,
+Type* RPC_CONTEXT_TYPE = new UserDataType("android.support.place.rpc", "RpcContext", true,
__FILE__, __LINE__);
static void generate_create_from_data(Type* t, StatementBlock* addTo, const string& key,
diff --git a/tools/layoutlib/bridge/src/android/view/AttachInfo_Accessor.java b/tools/layoutlib/bridge/src/android/view/AttachInfo_Accessor.java
index 96de51c..97d9969 100644
--- a/tools/layoutlib/bridge/src/android/view/AttachInfo_Accessor.java
+++ b/tools/layoutlib/bridge/src/android/view/AttachInfo_Accessor.java
@@ -29,7 +29,7 @@
public static void setAttachInfo(View view) {
AttachInfo info = new AttachInfo(new BridgeWindowSession(), new BridgeWindow(),
- new Handler(), null);
+ new ViewRootImpl(view.getContext()), new Handler(), null);
info.mHasWindowFocus = true;
info.mWindowVisibility = View.VISIBLE;
info.mInTouchMode = false; // this is so that we can display selections.
diff --git a/tools/makekeycodes/makekeycodes.cpp b/tools/makekeycodes/makekeycodes.cpp
index 16df774..6ffbfb8 100644
--- a/tools/makekeycodes/makekeycodes.cpp
+++ b/tools/makekeycodes/makekeycodes.cpp
@@ -1,5 +1,21 @@
+/*
+ * Copyright (C) 2012 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.
+ */
+
#include <stdio.h>
-#include <ui/KeycodeLabels.h>
+#include <androidfw/KeycodeLabels.h>
int
main(int argc, char** argv)
diff --git a/tools/obbtool/Android.mk b/tools/obbtool/Android.mk
index 72a9858..dd57ae6 100644
--- a/tools/obbtool/Android.mk
+++ b/tools/obbtool/Android.mk
@@ -19,6 +19,7 @@
LOCAL_STATIC_LIBRARIES := \
libutils \
+ libandroidfw \
libcutils
ifeq ($(HOST_OS),linux)
diff --git a/tools/obbtool/Main.cpp b/tools/obbtool/Main.cpp
index 932dbec..b2152e8 100644
--- a/tools/obbtool/Main.cpp
+++ b/tools/obbtool/Main.cpp
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include <utils/ObbFile.h>
+#include <androidfw/ObbFile.h>
#include <utils/String8.h>
#include <getopt.h>
diff --git a/tools/validatekeymaps/Android.mk b/tools/validatekeymaps/Android.mk
index 1368a07..fce2e93 100644
--- a/tools/validatekeymaps/Android.mk
+++ b/tools/validatekeymaps/Android.mk
@@ -18,7 +18,7 @@
#LOCAL_C_INCLUDES +=
LOCAL_STATIC_LIBRARIES := \
- libui \
+ libandroidfw \
libutils \
libcutils
diff --git a/tools/validatekeymaps/Main.cpp b/tools/validatekeymaps/Main.cpp
index 8ab9b6a..3cc2467 100644
--- a/tools/validatekeymaps/Main.cpp
+++ b/tools/validatekeymaps/Main.cpp
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-#include <ui/KeyCharacterMap.h>
-#include <ui/KeyLayoutMap.h>
-#include <ui/VirtualKeyMap.h>
+#include <androidfw/KeyCharacterMap.h>
+#include <androidfw/KeyLayoutMap.h>
+#include <androidfw/VirtualKeyMap.h>
#include <utils/PropertyMap.h>
#include <utils/String8.h>
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 0134456..1b64f3e 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -1754,7 +1754,9 @@
* If we've exceeded the maximum number of retries for DHCP
* to a given network, disable the network
*/
- if (++mReconnectCount > getMaxDhcpRetries()) {
+ int maxRetries = getMaxDhcpRetries();
+ // maxRetries == 0 means keep trying forever
+ if (maxRetries > 0 && ++mReconnectCount > maxRetries) {
loge("Failed " +
mReconnectCount + " times, Disabling " + mLastNetworkId);
mWifiConfigStore.disableNetwork(mLastNetworkId,