diff options
38 files changed, 760 insertions, 246 deletions
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java index 479b70ad951f..3fb17362f4c1 100644 --- a/cmds/am/src/com/android/commands/am/Am.java +++ b/cmds/am/src/com/android/commands/am/Am.java @@ -157,6 +157,11 @@ public class Am { String value = nextArgRequired(); intent.putExtra(key, Integer.valueOf(value)); hasIntentInfo = true; + } else if (opt.equals("--eu")) { + String key = nextArgRequired(); + String value = nextArgRequired(); + intent.putExtra(key, Uri.parse(value)); + hasIntentInfo = true; } else if (opt.equals("--eia")) { String key = nextArgRequired(); String value = nextArgRequired(); @@ -1119,6 +1124,7 @@ public class Am { " [--ez <EXTRA_KEY> <EXTRA_BOOLEAN_VALUE> ...]\n" + " [--ei <EXTRA_KEY> <EXTRA_INT_VALUE> ...]\n" + " [--el <EXTRA_KEY> <EXTRA_LONG_VALUE> ...]\n" + + " [--eu <EXTRA_KEY> <EXTRA_URI_VALUE> ...]\n" + " [--eia <EXTRA_KEY> <EXTRA_INT_VALUE>[,<EXTRA_INT_VALUE...]]\n" + " [--ela <EXTRA_KEY> <EXTRA_LONG_VALUE>[,<EXTRA_LONG_VALUE...]]\n" + " [-n <COMPONENT>] [-f <FLAGS>]\n" + diff --git a/core/java/android/bluetooth/BluetoothHealth.java b/core/java/android/bluetooth/BluetoothHealth.java index 52efc071ce6c..0a01dcf80e1d 100644 --- a/core/java/android/bluetooth/BluetoothHealth.java +++ b/core/java/android/bluetooth/BluetoothHealth.java @@ -16,7 +16,6 @@ package android.bluetooth; -import android.annotation.SdkConstant; import android.content.Context; import android.os.IBinder; import android.os.ParcelFileDescriptor; @@ -67,9 +66,6 @@ public final class BluetoothHealth implements BluetoothProfile { */ public static final int CHANNEL_TYPE_ANY = 12; - private final ArrayList<BluetoothHealthAppConfiguration> mAppConfigs = - new ArrayList<BluetoothHealthAppConfiguration>(); - /** * Register an application configuration that acts as a Health SINK. * This is the configuration that will be used to communicate with health devices @@ -86,7 +82,7 @@ public final class BluetoothHealth implements BluetoothProfile { * @return If true, callback will be called. */ public boolean registerSinkAppConfiguration(String name, int dataType, - IBluetoothHealthCallback callback) { + BluetoothHealthCallback callback) { if (!isEnabled() || name == null) return false; if (DBG) log("registerSinkApplication(" + name + ":" + dataType + ")"); @@ -111,18 +107,18 @@ public final class BluetoothHealth implements BluetoothProfile { * @hide */ public boolean registerAppConfiguration(String name, int dataType, int role, - int channelType, IBluetoothHealthCallback callback) { + int channelType, BluetoothHealthCallback callback) { boolean result = false; if (!isEnabled() || !checkAppParam(name, role, channelType, callback)) return result; if (DBG) log("registerApplication(" + name + ":" + dataType + ")"); + BluetoothHealthCallbackWrapper wrapper = new BluetoothHealthCallbackWrapper(callback); BluetoothHealthAppConfiguration config = - new BluetoothHealthAppConfiguration(name, dataType, role, channelType, - callback); + new BluetoothHealthAppConfiguration(name, dataType, role, channelType); if (mService != null) { try { - result = mService.registerAppConfiguration(config); + result = mService.registerAppConfiguration(config, wrapper); } catch (RemoteException e) { Log.e(TAG, e.toString()); } @@ -130,8 +126,6 @@ public final class BluetoothHealth implements BluetoothProfile { Log.w(TAG, "Proxy not attached to service"); if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable())); } - - if (result) mAppConfigs.add(config); return result; } @@ -147,7 +141,7 @@ public final class BluetoothHealth implements BluetoothProfile { */ public boolean unregisterAppConfiguration(BluetoothHealthAppConfiguration config) { boolean result = false; - if (mService != null && isEnabled() && isValidAppConfig(config)) { + if (mService != null && isEnabled() && config != null) { try { result = mService.unregisterAppConfiguration(config); } catch (RemoteException e) { @@ -157,26 +151,26 @@ public final class BluetoothHealth implements BluetoothProfile { Log.w(TAG, "Proxy not attached to service"); if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable())); } - if (result) mAppConfigs.remove(config); + return result; } /** * Connect to a health device which has the {@link #SOURCE_ROLE}. - * This is an asynchrnous call. If this function returns true, the callback + * This is an asynchronous call. If this function returns true, the callback * associated with the application configuration will be called. * * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * * @param device The remote Bluetooth device. - * @param config The application configuration which has been registed using - * {@link #registerSinkAppConfiguration(String, int, IBluetoothHealthCallback) } + * @param config The application configuration which has been registered using + * {@link #registerSinkAppConfiguration(String, int, BluetoothHealthCallback) } * @return If true, the callback associated with the application config will be called. */ public boolean connectChannelToSource(BluetoothDevice device, BluetoothHealthAppConfiguration config) { if (mService != null && isEnabled() && isValidDevice(device) && - isValidAppConfig(config)) { + config != null) { try { return mService.connectChannelToSource(device, config); } catch (RemoteException e) { @@ -197,15 +191,15 @@ public final class BluetoothHealth implements BluetoothProfile { *<p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * * @param device The remote Bluetooth device. - * @param config The application configuration which has been registed using - * {@link #registerSinkAppConfiguration(String, int, IBluetoothHealthCallback) } + * @param config The application configuration which has been registered using + * {@link #registerSinkAppConfiguration(String, int, BluetoothHealthCallback) } * @return If true, the callback associated with the application config will be called. * @hide */ public boolean connectChannelToSink(BluetoothDevice device, BluetoothHealthAppConfiguration config, int channelType) { if (mService != null && isEnabled() && isValidDevice(device) && - isValidAppConfig(config)) { + config != null) { try { return mService.connectChannelToSink(device, config, channelType); } catch (RemoteException e) { @@ -226,8 +220,8 @@ public final class BluetoothHealth implements BluetoothProfile { *<p>Requires {@link android.Manifest.permission#BLUETOOTH} permission. * * @param device The remote Bluetooth device. - * @param config The application configuration which has been registed using - * {@link #registerSinkAppConfiguration(String, int, IBluetoothHealthCallback) } + * @param config The application configuration which has been registered using + * {@link #registerSinkAppConfiguration(String, int, BluetoothHealthCallback) } * @param fd The file descriptor that was associated with the channel. * @return If true, the callback associated with the application config will be called. * @hide @@ -235,7 +229,7 @@ public final class BluetoothHealth implements BluetoothProfile { public boolean disconnectChannel(BluetoothDevice device, BluetoothHealthAppConfiguration config, ParcelFileDescriptor fd) { if (mService != null && isEnabled() && isValidDevice(device) && - isValidAppConfig(config)) { + config != null) { try { return mService.disconnectChannel(device, config, fd); } catch (RemoteException e) { @@ -262,7 +256,7 @@ public final class BluetoothHealth implements BluetoothProfile { public ParcelFileDescriptor getMainChannelFd(BluetoothDevice device, BluetoothHealthAppConfiguration config) { if (mService != null && isEnabled() && isValidDevice(device) && - isValidAppConfig(config)) { + config != null) { try { return mService.getMainChannelFd(device, config); } catch (RemoteException e) { @@ -290,6 +284,7 @@ public final class BluetoothHealth implements BluetoothProfile { * {@link #STATE_CONNECTED}, {@link #STATE_CONNECTING}, * {@link #STATE_DISCONNECTED}, {@link #STATE_DISCONNECTING} */ + @Override public int getConnectionState(BluetoothDevice device) { if (mService != null && isEnabled() && isValidDevice(device)) { try { @@ -317,6 +312,7 @@ public final class BluetoothHealth implements BluetoothProfile { * local adapter. * @return List of devices. The list will be empty on error. */ + @Override public List<BluetoothDevice> getConnectedDevices() { if (mService != null && isEnabled()) { try { @@ -348,6 +344,7 @@ public final class BluetoothHealth implements BluetoothProfile { * {@link #STATE_DISCONNECTED}, {@link #STATE_DISCONNECTING}, * @return List of devices. The list will be empty on error. */ + @Override public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) { if (mService != null && isEnabled()) { try { @@ -361,6 +358,27 @@ public final class BluetoothHealth implements BluetoothProfile { return new ArrayList<BluetoothDevice>(); } + private static class BluetoothHealthCallbackWrapper extends IBluetoothHealthCallback.Stub { + private BluetoothHealthCallback mCallback; + + public BluetoothHealthCallbackWrapper(BluetoothHealthCallback callback) { + mCallback = callback; + } + + @Override + public void onHealthAppConfigurationStatusChange(BluetoothHealthAppConfiguration config, + int status) { + mCallback.onHealthAppConfigurationStatusChange(config, status); + } + + @Override + public void onHealthChannelStateChange(BluetoothHealthAppConfiguration config, + BluetoothDevice device, int prevState, int newState, + ParcelFileDescriptor fd) { + mCallback.onHealthChannelStateChange(config, device, prevState, newState, fd); + } + } + /** Health Channel Connection State - Disconnected */ public static final int STATE_CHANNEL_DISCONNECTED = 0; /** Health Channel Connection State - Connecting */ @@ -379,7 +397,6 @@ public final class BluetoothHealth implements BluetoothProfile { /** Health App Configuration un-registration failure */ public static final int APPLICATION_UNREGISTRATION_FAILURE = 3; - private Context mContext; private ServiceListener mServiceListener; private IBluetooth mService; BluetoothAdapter mAdapter; @@ -420,14 +437,8 @@ public final class BluetoothHealth implements BluetoothProfile { return false; } - private boolean isValidAppConfig(BluetoothHealthAppConfiguration config) { - if (!mAppConfigs.isEmpty() && mAppConfigs.contains(config)) return true; - log("Not a valid config: " + config); - return false; - } - private boolean checkAppParam(String name, int role, int channelType, - IBluetoothHealthCallback callback) { + BluetoothHealthCallback callback) { if (name == null || (role != SOURCE_ROLE && role != SINK_ROLE) || (channelType != CHANNEL_TYPE_RELIABLE && channelType != CHANNEL_TYPE_STREAMING && diff --git a/core/java/android/bluetooth/BluetoothHealthAppConfiguration.java b/core/java/android/bluetooth/BluetoothHealthAppConfiguration.java index b87aea591383..7020249c4ccc 100644 --- a/core/java/android/bluetooth/BluetoothHealthAppConfiguration.java +++ b/core/java/android/bluetooth/BluetoothHealthAppConfiguration.java @@ -17,7 +17,6 @@ package android.bluetooth; -import android.os.IBinder; import android.os.Parcel; import android.os.Parcelable; @@ -34,21 +33,18 @@ public final class BluetoothHealthAppConfiguration implements Parcelable { private final int mDataType; private final int mRole; private final int mChannelType; - private final IBluetoothHealthCallback mCallback; /** * Constructor to register the SINK role * * @param name Friendly name associated with the application configuration * @param dataType Data Type of the remote Bluetooth Health device - * @param callback Callback associated with the application configuration. */ - BluetoothHealthAppConfiguration(String name, int dataType, IBluetoothHealthCallback callback) { + BluetoothHealthAppConfiguration(String name, int dataType) { mName = name; mDataType = dataType; mRole = BluetoothHealth.SINK_ROLE; mChannelType = BluetoothHealth.CHANNEL_TYPE_ANY; - mCallback = callback; } /** @@ -56,17 +52,15 @@ public final class BluetoothHealthAppConfiguration implements Parcelable { * * @param name Friendly name associated with the application configuration * @param dataType Data Type of the remote Bluetooth Health device - * @param role {@link BluetoothHealth.SOURCE_ROLE} or - * {@link BluetoothHealth.SINK_ROLE} - * @param callback Callback associated with the application configuration. + * @param role {@link BluetoothHealth#SOURCE_ROLE} or + * {@link BluetoothHealth#SINK_ROLE} */ - BluetoothHealthAppConfiguration(String name, int dataType, int role, int channelType, - IBluetoothHealthCallback callback) { + BluetoothHealthAppConfiguration(String name, int dataType, int role, int + channelType) { mName = name; mDataType = dataType; mRole = role; mChannelType = channelType; - mCallback = callback; } @Override @@ -77,8 +71,7 @@ public final class BluetoothHealthAppConfiguration implements Parcelable { return mName.equals(config.getName()) && mDataType == config.getDataType() && mRole == config.getRole() && - mChannelType == config.getChannelType() && - mCallback.equals(config.getCallback()); + mChannelType == config.getChannelType(); } return false; } @@ -90,7 +83,6 @@ public final class BluetoothHealthAppConfiguration implements Parcelable { result = 31 * result + mDataType; result = 31 * result + mRole; result = 31 * result + mChannelType; - result = 31 * result + (mCallback != null ? mCallback.hashCode() : 0); return result; } @@ -98,9 +90,10 @@ public final class BluetoothHealthAppConfiguration implements Parcelable { public String toString() { return "BluetoothHealthAppConfiguration [mName = " + mName + ",mDataType = " + mDataType + ", mRole = " + mRole + ",mChannelType = " + - mChannelType + ",callback=" + mCallback +"]"; + mChannelType + "]"; } + @Override public int describeContents() { return 0; } @@ -144,37 +137,31 @@ public final class BluetoothHealthAppConfiguration implements Parcelable { return mChannelType; } - /** - * Return the callback associated with this application configuration. - * - * @return IBluetoothHealthCallback - */ - public IBluetoothHealthCallback getCallback() { - return mCallback; - } - public static final Parcelable.Creator<BluetoothHealthAppConfiguration> CREATOR = new Parcelable.Creator<BluetoothHealthAppConfiguration>() { + @Override public BluetoothHealthAppConfiguration createFromParcel(Parcel in) { String name = in.readString(); int type = in.readInt(); int role = in.readInt(); int channelType = in.readInt(); - IBluetoothHealthCallback callback = - IBluetoothHealthCallback.Stub.asInterface(in.readStrongBinder()); - return new BluetoothHealthAppConfiguration(name, type, role, channelType, - callback); + return new BluetoothHealthAppConfiguration(name, type, role, + channelType); } + + @Override public BluetoothHealthAppConfiguration[] newArray(int size) { return new BluetoothHealthAppConfiguration[size]; } }; + @Override public void writeToParcel(Parcel out, int flags) { out.writeString(mName); out.writeInt(mDataType); out.writeInt(mRole); out.writeInt(mChannelType); - out.writeStrongInterface(mCallback); } + + } diff --git a/core/java/android/bluetooth/BluetoothHealthCallback.java b/core/java/android/bluetooth/BluetoothHealthCallback.java new file mode 100644 index 000000000000..0d11bb544681 --- /dev/null +++ b/core/java/android/bluetooth/BluetoothHealthCallback.java @@ -0,0 +1,42 @@ +/* + * 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. + */ + + +package android.bluetooth; + +import android.os.ParcelFileDescriptor; +import android.util.Log; + +/** + * This class is used for all the {@link BluetoothHealth} callbacks. + * @hide + */ +public abstract class BluetoothHealthCallback { + + private static final String TAG = "BluetoothHealthCallback"; + + public void onHealthAppConfigurationStatusChange(BluetoothHealthAppConfiguration config, + int status) { + Log.d(TAG, "onHealthAppConfigurationStatusChange: " + config + " Status:" + status); + } + + public void onHealthChannelStateChange(BluetoothHealthAppConfiguration config, + BluetoothDevice device, int prevState, int newState, + ParcelFileDescriptor fd) { + Log.d(TAG, "onHealthChannelStateChange: " + config + " Device:" + device + + "PrevState:" + prevState + "NewState:" + newState + "FileDescriptor:" + fd); + } +} diff --git a/core/java/android/bluetooth/IBluetooth.aidl b/core/java/android/bluetooth/IBluetooth.aidl index 6ca6c2e1037e..183772d62aad 100644 --- a/core/java/android/bluetooth/IBluetooth.aidl +++ b/core/java/android/bluetooth/IBluetooth.aidl @@ -17,6 +17,7 @@ package android.bluetooth; import android.bluetooth.IBluetoothCallback; +import android.bluetooth.IBluetoothHealthCallback; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHealthAppConfiguration; import android.os.ParcelUuid; @@ -102,7 +103,8 @@ interface IBluetooth boolean disconnectPanDevice(in BluetoothDevice device); // HDP profile APIs - boolean registerAppConfiguration(in BluetoothHealthAppConfiguration config); + boolean registerAppConfiguration(in BluetoothHealthAppConfiguration config, + in IBluetoothHealthCallback callback); boolean unregisterAppConfiguration(in BluetoothHealthAppConfiguration config); boolean connectChannelToSource(in BluetoothDevice device, in BluetoothHealthAppConfiguration config); boolean connectChannelToSink(in BluetoothDevice device, in BluetoothHealthAppConfiguration config, diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java index 269e50eb3f81..5b1f563a29d9 100644 --- a/core/java/android/os/Process.java +++ b/core/java/android/os/Process.java @@ -270,13 +270,12 @@ public class Process { * @param targetSdkVersion The target SDK version for the app. * @param zygoteArgs Additional arguments to supply to the zygote process. * - * @return int If > 0 the pid of the new process; if 0 the process is - * being emulated by a thread + * @return An object that describes the result of the attempt to start the process. * @throws RuntimeException on fatal start failure * * {@hide} */ - public static final int start(final String processClass, + public static final ProcessStartResult start(final String processClass, final String niceName, int uid, int gid, int[] gids, int debugFlags, int targetSdkVersion, @@ -376,14 +375,11 @@ public class Process { * and returns the child's pid. Please note: the present implementation * replaces newlines in the argument list with spaces. * @param args argument list - * @return PID of new child process + * @return An object that describes the result of the attempt to start the process. * @throws ZygoteStartFailedEx if process start failed for any reason */ - private static int zygoteSendArgsAndGetPid(ArrayList<String> args) + private static ProcessStartResult zygoteSendArgsAndGetResult(ArrayList<String> args) throws ZygoteStartFailedEx { - - int pid; - openZygoteSocketIfNeeded(); try { @@ -394,7 +390,8 @@ public class Process { * b) a number of newline-separated argument strings equal to count * * After the zygote process reads these it will write the pid of - * the child or -1 on failure. + * the child or -1 on failure, followed by boolean to + * indicate whether a wrapper process was used. */ sZygoteWriter.write(Integer.toString(args.size())); @@ -414,11 +411,13 @@ public class Process { sZygoteWriter.flush(); // Should there be a timeout on this? - pid = sZygoteInputStream.readInt(); - - if (pid < 0) { + ProcessStartResult result = new ProcessStartResult(); + result.pid = sZygoteInputStream.readInt(); + if (result.pid < 0) { throw new ZygoteStartFailedEx("fork() failed"); } + result.usingWrapper = sZygoteInputStream.readBoolean(); + return result; } catch (IOException ex) { try { if (sZygoteSocket != null) { @@ -433,8 +432,6 @@ public class Process { throw new ZygoteStartFailedEx(ex); } - - return pid; } /** @@ -449,18 +446,16 @@ public class Process { * @param debugFlags Additional flags. * @param targetSdkVersion The target SDK version for the app. * @param extraArgs Additional arguments to supply to the zygote process. - * @return PID + * @return An object that describes the result of the attempt to start the process. * @throws ZygoteStartFailedEx if process start failed for any reason */ - private static int startViaZygote(final String processClass, + private static ProcessStartResult startViaZygote(final String processClass, final String niceName, final int uid, final int gid, final int[] gids, int debugFlags, int targetSdkVersion, String[] extraArgs) throws ZygoteStartFailedEx { - int pid; - synchronized(Process.class) { ArrayList<String> argsForZygote = new ArrayList<String>(); @@ -516,15 +511,9 @@ public class Process { argsForZygote.add(arg); } } - - pid = zygoteSendArgsAndGetPid(argsForZygote); - } - if (pid <= 0) { - throw new ZygoteStartFailedEx("zygote start failed:" + pid); + return zygoteSendArgsAndGetResult(argsForZygote); } - - return pid; } /** @@ -808,4 +797,21 @@ public class Process { * @hide */ public static final native long getPss(int pid); + + /** + * Specifies the outcome of having started a process. + * @hide + */ + public static final class ProcessStartResult { + /** + * The PID of the newly started process. + * Always >= 0. (If the start failed, an exception will have been thrown instead.) + */ + public int pid; + + /** + * True if the process was started with a wrapper attached. + */ + public boolean usingWrapper; + } } diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java index 61deea429460..9c12a44c81f3 100644 --- a/core/java/android/provider/ContactsContract.java +++ b/core/java/android/provider/ContactsContract.java @@ -135,14 +135,6 @@ public final class ContactsContract { public static final String ALLOW_PROFILE = "allow_profile"; /** - * A query parameter key used to specify the package that is requesting a query. - * This is used for restricting data based on package name. - * - * @hide - */ - public static final String REQUESTING_PACKAGE_PARAM_KEY = "requesting_package"; - - /** * Query parameter that should be used by the client to access a specific * {@link Directory}. The parameter value should be the _ID of the corresponding * directory, e.g. @@ -271,8 +263,6 @@ public final class ContactsContract { * <li>The URI authority is replaced with the corresponding {@link #DIRECTORY_AUTHORITY}.</li> * <li>The {@code accountName=} and {@code accountType=} parameters are added or * replaced using the corresponding {@link #ACCOUNT_TYPE} and {@link #ACCOUNT_NAME} values.</li> - * <li>If the URI is missing a ContactsContract.REQUESTING_PACKAGE_PARAM_KEY - * parameter, this parameter is added.</li> * </ul> * </p> * <p> @@ -1881,15 +1871,6 @@ public final class ContactsContract { public static final String CONTACT_ID = "contact_id"; /** - * Flag indicating that this {@link RawContacts} entry and its children have - * been restricted to specific platform apps. - * <P>Type: INTEGER (boolean)</P> - * - * @hide until finalized in future platform release - */ - public static final String IS_RESTRICTED = "is_restricted"; - - /** * The aggregation mode for this contact. * <P>Type: INTEGER</P> */ @@ -2537,7 +2518,6 @@ public final class ContactsContract { DatabaseUtils.cursorLongToContentValuesIfPresent(cursor, cv, DELETED); DatabaseUtils.cursorLongToContentValuesIfPresent(cursor, cv, CONTACT_ID); DatabaseUtils.cursorLongToContentValuesIfPresent(cursor, cv, STARRED); - DatabaseUtils.cursorIntToContentValuesIfPresent(cursor, cv, IS_RESTRICTED); DatabaseUtils.cursorIntToContentValuesIfPresent(cursor, cv, NAME_VERIFIED); android.content.Entity contact = new android.content.Entity(cv); @@ -3814,27 +3794,6 @@ public final class ContactsContract { /** * <p> - * If {@link #FOR_EXPORT_ONLY} is explicitly set to "1", returned Cursor toward - * Data.CONTENT_URI contains only exportable data. - * </p> - * <p> - * This flag is useful (currently) only for vCard exporter in Contacts app, which - * needs to exclude "un-exportable" data from available data to export, while - * Contacts app itself has priviledge to access all data including "un-exportable" - * ones and providers return all of them regardless of the callers' intention. - * </p> - * <p> - * Type: INTEGER - * </p> - * - * @hide Maybe available only in Eclair and not really ready for public use. - * TODO: remove, or implement this feature completely. As of now (Eclair), - * we only use this flag in queryEntities(), not query(). - */ - public static final String FOR_EXPORT_ONLY = "for_export_only"; - - /** - * <p> * Build a {@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI} * style {@link Uri} for the parent {@link android.provider.ContactsContract.Contacts} * entry of the given {@link ContactsContract.Data} entry. diff --git a/core/java/android/server/BluetoothHealthProfileHandler.java b/core/java/android/server/BluetoothHealthProfileHandler.java index 7f862e023caf..105ff332ed04 100644 --- a/core/java/android/server/BluetoothHealthProfileHandler.java +++ b/core/java/android/server/BluetoothHealthProfileHandler.java @@ -20,15 +20,12 @@ import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHealth; import android.bluetooth.BluetoothHealthAppConfiguration; -import android.bluetooth.BluetoothHealth; -import android.bluetooth.BluetoothInputDevice; +import android.bluetooth.IBluetoothHealthCallback; import android.content.Context; -import android.content.Intent; import android.os.Handler; import android.os.Message; import android.os.ParcelFileDescriptor; import android.os.RemoteException; -import android.provider.Settings; import android.util.Log; import java.util.ArrayList; @@ -36,10 +33,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map.Entry; -import java.io.FileDescriptor; -import java.io.FileInputStream; -import java.io.IOException; - /** * This handles all the operations on the Bluetooth Health profile. * All functions are called by BluetoothService, as Bluetooth Service @@ -58,6 +51,7 @@ final class BluetoothHealthProfileHandler { private ArrayList<HealthChannel> mHealthChannels; private HashMap <BluetoothHealthAppConfiguration, String> mHealthAppConfigs; private HashMap <BluetoothDevice, Integer> mHealthDevices; + private HashMap <BluetoothHealthAppConfiguration, IBluetoothHealthCallback> mCallbacks; private static final int MESSAGE_REGISTER_APPLICATION = 0; private static final int MESSAGE_UNREGISTER_APPLICATION = 1; @@ -103,6 +97,7 @@ final class BluetoothHealthProfileHandler { } if (path == null) { + mCallbacks.remove(registerApp); callHealthApplicationStatusCallback(registerApp, BluetoothHealth.APPLICATION_REGISTRATION_FAILURE); } else { @@ -118,6 +113,7 @@ final class BluetoothHealthProfileHandler { boolean result = mBluetoothService.unregisterHealthApplicationNative( mHealthAppConfigs.get(unregisterApp)); if (result) { + mCallbacks.remove(unregisterApp); callHealthApplicationStatusCallback(unregisterApp, BluetoothHealth.APPLICATION_UNREGISTRATION_SUCCESS); } else { @@ -149,6 +145,7 @@ final class BluetoothHealthProfileHandler { mHealthAppConfigs = new HashMap<BluetoothHealthAppConfiguration, String>(); mHealthChannels = new ArrayList<HealthChannel>(); mHealthDevices = new HashMap<BluetoothDevice, Integer>(); + mCallbacks = new HashMap<BluetoothHealthAppConfiguration, IBluetoothHealthCallback>(); } static synchronized BluetoothHealthProfileHandler getInstance(Context context, @@ -157,10 +154,12 @@ final class BluetoothHealthProfileHandler { return sInstance; } - boolean registerAppConfiguration(BluetoothHealthAppConfiguration config) { + boolean registerAppConfiguration(BluetoothHealthAppConfiguration config, + IBluetoothHealthCallback callback) { Message msg = mHandler.obtainMessage(MESSAGE_REGISTER_APPLICATION); msg.obj = config; mHandler.sendMessage(msg); + mCallbacks.put(config, callback); return true; } @@ -442,11 +441,11 @@ final class BluetoothHealthProfileHandler { debugLog("Health Device Callback: " + device + " State Change: " + prevState + "->" + state); - try { - config.getCallback().onHealthChannelStateChange(config, device, prevState, - state, fd); - } catch (RemoteException e) { - errorLog("Error while making health channel state change callback: " + e); + IBluetoothHealthCallback callback = mCallbacks.get(config); + if (callback != null) { + try { + callback.onHealthChannelStateChange(config, device, prevState, state, fd); + } catch (RemoteException e) {} } } @@ -454,10 +453,11 @@ final class BluetoothHealthProfileHandler { BluetoothHealthAppConfiguration config, int status) { debugLog("Health Device Application: " + config + " State Change: status:" + status); - try { - config.getCallback().onHealthAppConfigurationStatusChange(config, status); - } catch (RemoteException e) { - errorLog("Error while making health app registration state change callback: " + e); + IBluetoothHealthCallback callback = mCallbacks.get(config); + if (callback != null) { + try { + callback.onHealthAppConfigurationStatusChange(config, status); + } catch (RemoteException e) {} } } @@ -526,19 +526,19 @@ final class BluetoothHealthProfileHandler { List<HealthChannel> chan; switch (currDeviceState) { case BluetoothHealth.STATE_DISCONNECTED: - updateAndsendIntent(device, currDeviceState, newDeviceState); + updateAndSendIntent(device, currDeviceState, newDeviceState); break; case BluetoothHealth.STATE_CONNECTING: // Channel got connected. if (newDeviceState == BluetoothHealth.STATE_CONNECTED) { - updateAndsendIntent(device, currDeviceState, newDeviceState); + updateAndSendIntent(device, currDeviceState, newDeviceState); } else { // Channel got disconnected chan = findChannelByStates(device, new int [] { BluetoothHealth.STATE_CHANNEL_CONNECTING, BluetoothHealth.STATE_CHANNEL_DISCONNECTING}); if (chan.isEmpty()) { - updateAndsendIntent(device, currDeviceState, newDeviceState); + updateAndSendIntent(device, currDeviceState, newDeviceState); } } break; @@ -548,22 +548,23 @@ final class BluetoothHealthProfileHandler { BluetoothHealth.STATE_CHANNEL_CONNECTING, BluetoothHealth.STATE_CHANNEL_CONNECTED}); if (chan.isEmpty()) { - updateAndsendIntent(device, currDeviceState, newDeviceState); + updateAndSendIntent(device, currDeviceState, newDeviceState); } + break; case BluetoothHealth.STATE_DISCONNECTING: // Channel got disconnected. chan = findChannelByStates(device, new int [] { BluetoothHealth.STATE_CHANNEL_CONNECTING, BluetoothHealth.STATE_CHANNEL_DISCONNECTING}); if (chan.isEmpty()) { - updateAndsendIntent(device, currDeviceState, newDeviceState); + updateAndSendIntent(device, currDeviceState, newDeviceState); } break; } } } - private void updateAndsendIntent(BluetoothDevice device, int prevDeviceState, + private void updateAndSendIntent(BluetoothDevice device, int prevDeviceState, int newDeviceState) { mHealthDevices.put(device, newDeviceState); mBluetoothService.sendConnectionStateChange(device, prevDeviceState, newDeviceState); diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java index 9839f763e479..b23e3ce314cf 100644..100755 --- a/core/java/android/server/BluetoothService.java +++ b/core/java/android/server/BluetoothService.java @@ -24,8 +24,6 @@ package android.server; -import com.android.internal.app.IBatteryStats; - import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothClass; import android.bluetooth.BluetoothDevice; @@ -40,6 +38,7 @@ import android.bluetooth.BluetoothSocket; import android.bluetooth.BluetoothUuid; import android.bluetooth.IBluetooth; import android.bluetooth.IBluetoothCallback; +import android.bluetooth.IBluetoothHealthCallback; import android.content.BroadcastReceiver; import android.content.ContentResolver; import android.content.Context; @@ -58,6 +57,8 @@ import android.provider.Settings; import android.util.Log; import android.util.Pair; +import com.android.internal.app.IBatteryStats; + import java.io.BufferedInputStream; import java.io.BufferedReader; import java.io.BufferedWriter; @@ -2111,11 +2112,12 @@ public class BluetoothService extends IBluetooth.Stub { /**** Handlers for Health Device Profile ****/ // TODO: All these need to be converted to a state machine. - public boolean registerAppConfiguration(BluetoothHealthAppConfiguration config) { + public boolean registerAppConfiguration(BluetoothHealthAppConfiguration config, + IBluetoothHealthCallback callback) { mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); synchronized (mBluetoothHealthProfileHandler) { - return mBluetoothHealthProfileHandler.registerAppConfiguration(config); + return mBluetoothHealthProfileHandler.registerAppConfiguration(config, callback); } } diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java index 1638c740f13e..011e44c5157c 100644 --- a/core/java/android/view/HardwareRenderer.java +++ b/core/java/android/view/HardwareRenderer.java @@ -128,10 +128,19 @@ public abstract class HardwareRenderer { abstract void updateSurface(SurfaceHolder holder) throws Surface.OutOfResourcesException; /** - * Invoked whenever the size of the target surface changes. This will - * not be invoked when the surface is first created. + * This method should be invoked whenever the current hardware renderer + * context should be reset. */ - abstract void preapareSurfaceForResize(); + abstract void invalidate(); + + /** + * This method should be invoked to ensure the hardware renderer is in + * valid state (for instance, to ensure the correct EGL context is bound + * to the current thread.) + * + * @return true if the renderer is now valid, false otherwise + */ + abstract boolean validate(); /** * Setup the hardware renderer for drawing. This is called whenever the @@ -629,11 +638,16 @@ public abstract class HardwareRenderer { } @Override - void preapareSurfaceForResize() { + void invalidate() { // Cancels any existing buffer to ensure we'll get a buffer // of the right size before we call eglSwapBuffers sEgl.eglMakeCurrent(sEglDisplay, EGL10.EGL_NO_SURFACE, - EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT); + EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT); + } + + @Override + boolean validate() { + return checkCurrent() != SURFACE_STATE_ERROR; } @Override @@ -662,7 +676,7 @@ public abstract class HardwareRenderer { attachInfo.mDrawingTime = SystemClock.uptimeMillis(); view.mPrivateFlags |= View.DRAWN; - + final int surfaceState = checkCurrent(); if (surfaceState != SURFACE_STATE_ERROR) { // We had to change the current surface and/or context, redraw everything @@ -723,10 +737,21 @@ public abstract class HardwareRenderer { } } } - + + /** + * Ensures the currnet EGL context is the one we expect. + * + * @return {@link #SURFACE_STATE_ERROR} if the correct EGL context cannot be made current, + * {@link #SURFACE_STATE_UPDATED} if the EGL context was changed or + * {@link #SURFACE_STATE_SUCCESS} if the EGL context was the correct one + */ private int checkCurrent() { - // TODO: Don't check the current context when we have one per UI thread - // TODO: Use a threadlocal flag to know whether the surface has changed + if (sEglThread != Thread.currentThread()) { + throw new IllegalStateException("Hardware acceleration can only be used with a " + + "single UI thread.\nOriginal thread: " + sEglThread + "\n" + + "Current thread: " + Thread.currentThread()); + } + if (!sEglContext.equals(sEgl.eglGetCurrentContext()) || !mEglSurface.equals(sEgl.eglGetCurrentSurface(EGL10.EGL_DRAW))) { if (!sEgl.eglMakeCurrent(sEglDisplay, mEglSurface, mEglSurface, sEglContext)) { diff --git a/core/java/android/view/ViewAncestor.java b/core/java/android/view/ViewAncestor.java index b4f323c9647d..1dcbc26c53f9 100644 --- a/core/java/android/view/ViewAncestor.java +++ b/core/java/android/view/ViewAncestor.java @@ -901,6 +901,7 @@ public final class ViewAncestor extends Handler implements ViewParent, !mAttachInfo.mTurnOffWindowResizeAnim && mAttachInfo.mHardwareRenderer != null && mAttachInfo.mHardwareRenderer.isEnabled() && + mAttachInfo.mHardwareRenderer.validate() && lp != null && !PixelFormat.formatHasAlpha(lp.format)) { disposeResizeBuffer(); @@ -1314,10 +1315,10 @@ public final class ViewAncestor extends Handler implements ViewParent, if (hwInitialized || ((windowShouldResize || params != null) && mAttachInfo.mHardwareRenderer != null && mAttachInfo.mHardwareRenderer.isEnabled())) { + mAttachInfo.mHardwareRenderer.setup(mWidth, mHeight); if (!hwInitialized) { - mAttachInfo.mHardwareRenderer.preapareSurfaceForResize(); + mAttachInfo.mHardwareRenderer.invalidate(); } - mAttachInfo.mHardwareRenderer.setup(mWidth, mHeight); } if (!mStopped) { diff --git a/core/java/android/webkit/ZoomManager.java b/core/java/android/webkit/ZoomManager.java index 7d3f3138c469..49ea9445e46f 100644 --- a/core/java/android/webkit/ZoomManager.java +++ b/core/java/android/webkit/ZoomManager.java @@ -344,6 +344,8 @@ class ZoomManager { public final void setInitialScaleInPercent(int scaleInPercent) { mInitialScale = scaleInPercent * 0.01f; + mActualScale = mInitialScale > 0 ? mInitialScale : mDefaultScale; + mInvActualScale = 1 / mActualScale; } public final float computeScaleWithLimits(float scale) { diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java index a3b779542169..9af7e96fd7ac 100644 --- a/core/java/com/android/internal/os/ZygoteConnection.java +++ b/core/java/com/android/internal/os/ZygoteConnection.java @@ -900,6 +900,7 @@ class ZygoteConnection { } } + boolean usingWrapper = false; if (pipeFd != null && pid > 0) { DataInputStream is = new DataInputStream(new FileInputStream(pipeFd)); int innerPid = -1; @@ -924,6 +925,7 @@ class ZygoteConnection { if (parentPid > 0) { Log.i(TAG, "Wrapped process has pid " + innerPid); pid = innerPid; + usingWrapper = true; } else { Log.w(TAG, "Wrapped process reported a pid that is not a child of " + "the process that we forked: childPid=" + pid @@ -934,6 +936,7 @@ class ZygoteConnection { try { mSocketOutStream.writeInt(pid); + mSocketOutStream.writeBoolean(usingWrapper); } catch (IOException ex) { Log.e(TAG, "Error reading from command socket", ex); return true; diff --git a/core/jni/android_server_BluetoothService.cpp b/core/jni/android_server_BluetoothService.cpp index 1166ae426bc5..86e7cc0bf135 100644 --- a/core/jni/android_server_BluetoothService.cpp +++ b/core/jni/android_server_BluetoothService.cpp @@ -1396,7 +1396,6 @@ static jstring registerSinkHealthApplicationNative(JNIEnv *env, jobject object, LOG_AND_FREE_DBUS_ERROR(&err); } } else { - LOGE("--_Call made getting the patch..."); if (!dbus_message_get_args(reply, &err, DBUS_TYPE_OBJECT_PATH, &c_path, DBUS_TYPE_INVALID)) { @@ -1405,7 +1404,6 @@ static jstring registerSinkHealthApplicationNative(JNIEnv *env, jobject object, } } else { path = env->NewStringUTF(c_path); - LOGE("----Path is %s", c_path); } dbus_message_unref(reply); } @@ -1459,7 +1457,6 @@ static jboolean createChannelNative(JNIEnv *env, jobject object, const char *c_device_path = env->GetStringUTFChars(devicePath, NULL); const char *c_app_path = env->GetStringUTFChars(appPath, NULL); const char *c_config = env->GetStringUTFChars(config, NULL); - LOGE("Params...%s, %s, %s \n", c_device_path, c_app_path, c_config); DBusMessage *reply = dbus_func_args(env, nat->conn, c_device_path, @@ -1531,7 +1528,6 @@ static jstring getMainChannelNative(JNIEnv *env, jobject object, jstring deviceP DBusError err; dbus_error_init(&err); - LOGE("---Args %s", c_device_path); DBusMessage *reply = dbus_func_args(env, nat->conn, c_device_path, DBUS_HEALTH_DEVICE_IFACE, "GetProperties", @@ -1566,8 +1562,6 @@ static jstring getChannelApplicationNative(JNIEnv *env, jobject object, jstring DBusError err; dbus_error_init(&err); - LOGE("---Args %s", c_channel_path); - DBusMessage *reply = dbus_func_args(env, nat->conn, c_channel_path, DBUS_HEALTH_CHANNEL_IFACE, "GetProperties", @@ -1596,7 +1590,6 @@ static jstring getChannelApplicationNative(JNIEnv *env, jobject object, jstring if (!strcmp(c_name, "Application")) { path = (jstring) env->GetObjectArrayElement(str_array, i+1); - LOGE("----Path is %s", env->GetStringUTFChars(path, NULL)); env->ReleaseStringUTFChars(name, c_name); return path; } @@ -1655,13 +1648,11 @@ static jobject getChannelFdNative(JNIEnv *env, jobject object, jstring channelPa fd = dbus_returns_unixfd(env, reply); if (fd == -1) return NULL; - LOGE("---got fd %d\n", fd); // Create FileDescriptor object jobject fileDesc = jniCreateFileDescriptor(env, fd); if (fileDesc == NULL) { // FileDescriptor constructor has thrown an exception releaseChannelFdNative(env, object, channelPath); - LOGE("---File Desc is null"); return NULL; } diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java index 625419218a8a..12e5ada5c673 100644 --- a/graphics/java/android/renderscript/Allocation.java +++ b/graphics/java/android/renderscript/Allocation.java @@ -155,6 +155,14 @@ public class Allocation extends BaseObj { } } + + private int getIDSafe() { + if (mAdaptedAllocation != null) { + return mAdaptedAllocation.getID(); + } + return getID(); + } + private void updateCacheInfo(Type t) { mCurrentDimX = t.getX(); mCurrentDimY = t.getY(); @@ -262,7 +270,7 @@ public class Allocation extends BaseObj { throw new RSIllegalArgumentException("Source must be exactly one usage type."); } mRS.validate(); - mRS.nAllocationSyncAll(getID(), srcLocation); + mRS.nAllocationSyncAll(getIDSafe(), srcLocation); } public void copyFrom(BaseObj[] d) { @@ -480,7 +488,7 @@ public class Allocation extends BaseObj { " does not match component size " + eSize + "."); } - mRS.nAllocationElementData1D(getID(), xoff, mSelectedLOD, + mRS.nAllocationElementData1D(getIDSafe(), xoff, mSelectedLOD, component_number, data, data.length); } @@ -527,7 +535,7 @@ public class Allocation extends BaseObj { public void copy1DRangeFromUnchecked(int off, int count, int[] d) { int dataSize = mType.mElement.getSizeBytes() * count; data1DChecks(off, count, d.length * 4, dataSize); - mRS.nAllocationData1D(getID(), off, mSelectedLOD, count, d, dataSize); + mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize); } /** * Copy part of an allocation from an array. This variant is @@ -541,7 +549,7 @@ public class Allocation extends BaseObj { public void copy1DRangeFromUnchecked(int off, int count, short[] d) { int dataSize = mType.mElement.getSizeBytes() * count; data1DChecks(off, count, d.length * 2, dataSize); - mRS.nAllocationData1D(getID(), off, mSelectedLOD, count, d, dataSize); + mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize); } /** * Copy part of an allocation from an array. This variant is @@ -555,7 +563,7 @@ public class Allocation extends BaseObj { public void copy1DRangeFromUnchecked(int off, int count, byte[] d) { int dataSize = mType.mElement.getSizeBytes() * count; data1DChecks(off, count, d.length, dataSize); - mRS.nAllocationData1D(getID(), off, mSelectedLOD, count, d, dataSize); + mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize); } /** * Copy part of an allocation from an array. This variant is @@ -569,7 +577,7 @@ public class Allocation extends BaseObj { public void copy1DRangeFromUnchecked(int off, int count, float[] d) { int dataSize = mType.mElement.getSizeBytes() * count; data1DChecks(off, count, d.length * 4, dataSize); - mRS.nAllocationData1D(getID(), off, mSelectedLOD, count, d, dataSize); + mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, d, dataSize); } /** @@ -638,7 +646,7 @@ public class Allocation extends BaseObj { * be copied. */ public void copy1DRangeFrom(int off, int count, Allocation data, int dataOff) { - mRS.nAllocationData2D(getID(), off, 0, + mRS.nAllocationData2D(getIDSafe(), off, 0, mSelectedLOD, mSelectedFace.mID, count, 1, data.getID(), dataOff, 0, data.mSelectedLOD, data.mSelectedFace.mID); @@ -674,28 +682,28 @@ public class Allocation extends BaseObj { public void copy2DRangeFrom(int xoff, int yoff, int w, int h, byte[] data) { mRS.validate(); validate2DRange(xoff, yoff, w, h); - mRS.nAllocationData2D(getID(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, + mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, w, h, data, data.length); } public void copy2DRangeFrom(int xoff, int yoff, int w, int h, short[] data) { mRS.validate(); validate2DRange(xoff, yoff, w, h); - mRS.nAllocationData2D(getID(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, + mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, w, h, data, data.length * 2); } public void copy2DRangeFrom(int xoff, int yoff, int w, int h, int[] data) { mRS.validate(); validate2DRange(xoff, yoff, w, h); - mRS.nAllocationData2D(getID(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, + mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, w, h, data, data.length * 4); } public void copy2DRangeFrom(int xoff, int yoff, int w, int h, float[] data) { mRS.validate(); validate2DRange(xoff, yoff, w, h); - mRS.nAllocationData2D(getID(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, + mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, w, h, data, data.length * 4); } @@ -715,7 +723,7 @@ public class Allocation extends BaseObj { Allocation data, int dataXoff, int dataYoff) { mRS.validate(); validate2DRange(xoff, yoff, w, h); - mRS.nAllocationData2D(getID(), xoff, yoff, + mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, w, h, data.getID(), dataXoff, dataYoff, data.mSelectedLOD, data.mSelectedFace.mID); @@ -734,10 +742,16 @@ public class Allocation extends BaseObj { mRS.validate(); validateBitmapFormat(data); validate2DRange(xoff, yoff, data.getWidth(), data.getHeight()); - mRS.nAllocationData2D(getID(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, data); + mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, data); } + /** + * Copy from the Allocation into a Bitmap. The bitmap must + * match the dimensions of the Allocation. + * + * @param b The bitmap to be set from the Allocation. + */ public void copyTo(Bitmap b) { mRS.validate(); validateBitmapFormat(b); @@ -745,24 +759,52 @@ public class Allocation extends BaseObj { mRS.nAllocationCopyToBitmap(getID(), b); } + /** + * Copy from the Allocation into a byte array. The array must + * be at least as large as the Allocation. The allocation must + * be of an 8 bit elemental type. + * + * @param d The array to be set from the Allocation. + */ public void copyTo(byte[] d) { validateIsInt8(); mRS.validate(); mRS.nAllocationRead(getID(), d); } + /** + * Copy from the Allocation into a short array. The array must + * be at least as large as the Allocation. The allocation must + * be of an 16 bit elemental type. + * + * @param d The array to be set from the Allocation. + */ public void copyTo(short[] d) { validateIsInt16(); mRS.validate(); mRS.nAllocationRead(getID(), d); } + /** + * Copy from the Allocation into a int array. The array must be + * at least as large as the Allocation. The allocation must be + * of an 32 bit elemental type. + * + * @param d The array to be set from the Allocation. + */ public void copyTo(int[] d) { validateIsInt32(); mRS.validate(); mRS.nAllocationRead(getID(), d); } + /** + * Copy from the Allocation into a float array. The array must + * be at least as large as the Allocation. The allocation must + * be of an 32 bit float elemental type. + * + * @param d The array to be set from the Allocation. + */ public void copyTo(float[] d) { validateIsFloat32(); mRS.validate(); diff --git a/graphics/java/android/renderscript/AllocationAdapter.java b/graphics/java/android/renderscript/AllocationAdapter.java index ca5246ac4b1d..d38f2df37e15 100644 --- a/graphics/java/android/renderscript/AllocationAdapter.java +++ b/graphics/java/android/renderscript/AllocationAdapter.java @@ -31,7 +31,8 @@ public class AllocationAdapter extends Allocation { } int getID() { - return mAdaptedAllocation.getID(); + throw new RSInvalidStateException( + "This operation is not supported with adapters at this time."); } /** diff --git a/include/gui/SurfaceTextureClient.h b/include/gui/SurfaceTextureClient.h index 6ce44fcac731..9db736424293 100644 --- a/include/gui/SurfaceTextureClient.h +++ b/include/gui/SurfaceTextureClient.h @@ -65,6 +65,8 @@ private: int dispatchDisconnect(va_list args); int dispatchSetBufferCount(va_list args); int dispatchSetBuffersGeometry(va_list args); + int dispatchSetBuffersDimensions(va_list args); + int dispatchSetBuffersFormat(va_list args); int dispatchSetBuffersTransform(va_list args); int dispatchSetBuffersTimestamp(va_list args); int dispatchSetCrop(va_list args); @@ -73,7 +75,8 @@ private: int connect(int api); int disconnect(int api); int setBufferCount(int bufferCount); - int setBuffersGeometry(int w, int h, int format); + int setBuffersDimensions(int w, int h); + int setBuffersFormat(int format); int setBuffersTransform(int transform); int setBuffersTimestamp(int64_t timestamp); int setCrop(Rect const* rect); diff --git a/libs/gui/SurfaceTextureClient.cpp b/libs/gui/SurfaceTextureClient.cpp index b9b2310c7f55..e203035ee969 100644 --- a/libs/gui/SurfaceTextureClient.cpp +++ b/libs/gui/SurfaceTextureClient.cpp @@ -254,6 +254,12 @@ int SurfaceTextureClient::perform(int operation, va_list args) case NATIVE_WINDOW_SET_BUFFERS_TIMESTAMP: res = dispatchSetBuffersTimestamp(args); break; + case NATIVE_WINDOW_SET_BUFFERS_DIMENSIONS: + res = dispatchSetBuffersDimensions(args); + break; + case NATIVE_WINDOW_SET_BUFFERS_FORMAT: + res = dispatchSetBuffersFormat(args); + break; default: res = NAME_NOT_FOUND; break; @@ -290,7 +296,22 @@ int SurfaceTextureClient::dispatchSetBuffersGeometry(va_list args) { int w = va_arg(args, int); int h = va_arg(args, int); int f = va_arg(args, int); - return setBuffersGeometry(w, h, f); + int err = setBuffersDimensions(w, h); + if (err != 0) { + return err; + } + return setBuffersFormat(f); +} + +int SurfaceTextureClient::dispatchSetBuffersDimensions(va_list args) { + int w = va_arg(args, int); + int h = va_arg(args, int); + return setBuffersDimensions(w, h); +} + +int SurfaceTextureClient::dispatchSetBuffersFormat(va_list args) { + int f = va_arg(args, int); + return setBuffersFormat(f); } int SurfaceTextureClient::dispatchSetBuffersTransform(va_list args) { @@ -390,12 +411,12 @@ int SurfaceTextureClient::setBufferCount(int bufferCount) return err; } -int SurfaceTextureClient::setBuffersGeometry(int w, int h, int format) +int SurfaceTextureClient::setBuffersDimensions(int w, int h) { - LOGV("SurfaceTextureClient::setBuffersGeometry"); + LOGV("SurfaceTextureClient::setBuffersDimensions"); Mutex::Autolock lock(mMutex); - if (w<0 || h<0 || format<0) + if (w<0 || h<0) return BAD_VALUE; if ((w && !h) || (!w && h)) @@ -403,7 +424,6 @@ int SurfaceTextureClient::setBuffersGeometry(int w, int h, int format) mReqWidth = w; mReqHeight = h; - mReqFormat = format; status_t err = mSurfaceTexture->setCrop(Rect(0, 0)); LOGE_IF(err, "ISurfaceTexture::setCrop(...) returned %s", strerror(-err)); @@ -411,6 +431,19 @@ int SurfaceTextureClient::setBuffersGeometry(int w, int h, int format) return err; } +int SurfaceTextureClient::setBuffersFormat(int format) +{ + LOGV("SurfaceTextureClient::setBuffersFormat"); + Mutex::Autolock lock(mMutex); + + if (format<0) + return BAD_VALUE; + + mReqFormat = format; + + return NO_ERROR; +} + int SurfaceTextureClient::setBuffersTransform(int transform) { LOGV("SurfaceTextureClient::setBuffersTransform"); diff --git a/libs/ui/FramebufferNativeWindow.cpp b/libs/ui/FramebufferNativeWindow.cpp index 4393504236e5..9c10c754ba0a 100644 --- a/libs/ui/FramebufferNativeWindow.cpp +++ b/libs/ui/FramebufferNativeWindow.cpp @@ -299,6 +299,7 @@ int FramebufferNativeWindow::perform(ANativeWindow* window, { switch (operation) { case NATIVE_WINDOW_SET_USAGE: + case NATIVE_WINDOW_SET_BUFFERS_FORMAT: case NATIVE_WINDOW_CONNECT: case NATIVE_WINDOW_DISCONNECT: break; diff --git a/libs/utils/VectorImpl.cpp b/libs/utils/VectorImpl.cpp index 289c826d3eb6..87ae3d51f1ee 100644 --- a/libs/utils/VectorImpl.cpp +++ b/libs/utils/VectorImpl.cpp @@ -290,7 +290,7 @@ void VectorImpl::clear() void* VectorImpl::editItemLocation(size_t index) { LOG_ASSERT(index<capacity(), - "[%p] itemLocation: index=%d, capacity=%d, count=%d", + "[%p] editItemLocation: index=%d, capacity=%d, count=%d", this, (int)index, (int)capacity(), (int)mCount); void* buffer = editArrayImpl(); @@ -302,7 +302,7 @@ void* VectorImpl::editItemLocation(size_t index) const void* VectorImpl::itemLocation(size_t index) const { LOG_ASSERT(index<capacity(), - "[%p] editItemLocation: index=%d, capacity=%d, count=%d", + "[%p] itemLocation: index=%d, capacity=%d, count=%d", this, (int)index, (int)capacity(), (int)mCount); const void* buffer = arrayImpl(); diff --git a/media/libeffects/factory/EffectsFactory.c b/media/libeffects/factory/EffectsFactory.c index a3e76d92daac..a9689bcad839 100644 --- a/media/libeffects/factory/EffectsFactory.c +++ b/media/libeffects/factory/EffectsFactory.c @@ -130,10 +130,43 @@ int Effect_GetDescriptor(effect_handle_t self, return ret; } +int Effect_ProcessReverse(effect_handle_t self, audio_buffer_t *inBuffer, audio_buffer_t *outBuffer) +{ + int ret = init(); + if (ret < 0) { + return ret; + } + effect_entry_t *fx = (effect_entry_t *)self; + pthread_mutex_lock(&gLibLock); + if (fx->lib == NULL) { + pthread_mutex_unlock(&gLibLock); + return -EPIPE; + } + pthread_mutex_lock(&fx->lib->lock); + pthread_mutex_unlock(&gLibLock); + + if ((*fx->subItfe)->process_reverse != NULL) { + ret = (*fx->subItfe)->process_reverse(fx->subItfe, inBuffer, outBuffer); + } else { + ret = -ENOSYS; + } + pthread_mutex_unlock(&fx->lib->lock); + return ret; +} + + const struct effect_interface_s gInterface = { Effect_Process, Effect_Command, - Effect_GetDescriptor + Effect_GetDescriptor, + NULL +}; + +const struct effect_interface_s gInterfaceWithReverse = { + Effect_Process, + Effect_Command, + Effect_GetDescriptor, + Effect_ProcessReverse }; ///////////////////////////////////////////////// @@ -266,7 +299,13 @@ int EffectCreate(effect_uuid_t *uuid, int32_t sessionId, int32_t ioId, effect_ha // add entry to effect list fx = (effect_entry_t *)malloc(sizeof(effect_entry_t)); fx->subItfe = itfe; - fx->itfe = (struct effect_interface_s *)&gInterface; + if ((*itfe)->process_reverse != NULL) { + fx->itfe = (struct effect_interface_s *)&gInterfaceWithReverse; + LOGV("EffectCreate() gInterfaceWithReverse"); + } else { + fx->itfe = (struct effect_interface_s *)&gInterface; + LOGV("EffectCreate() gInterface"); + } fx->lib = l; e = (list_elem_t *)malloc(sizeof(list_elem_t)); diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp index 21c451f9d9e7..efa1c45fa300 100644 --- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp +++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp @@ -3231,7 +3231,8 @@ int Effect_getDescriptor(effect_handle_t self, const struct effect_interface_s gLvmEffectInterface = { Effect_process, Effect_command, - Effect_getDescriptor + Effect_getDescriptor, + NULL, }; /* end gLvmEffectInterface */ audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = { diff --git a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp index 2727375822ba..663f8ff04c2e 100755 --- a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp +++ b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp @@ -2134,7 +2134,8 @@ int Reverb_getDescriptor(effect_handle_t self, const struct effect_interface_s gReverbInterface = { Reverb_process, Reverb_command, - Reverb_getDescriptor + Reverb_getDescriptor, + NULL, }; /* end gReverbInterface */ audio_effect_library_t AUDIO_EFFECT_LIBRARY_INFO_SYM = { diff --git a/media/libeffects/testlibs/EffectEqualizer.cpp b/media/libeffects/testlibs/EffectEqualizer.cpp index c2ffce5058b2..b22ebec73121 100644 --- a/media/libeffects/testlibs/EffectEqualizer.cpp +++ b/media/libeffects/testlibs/EffectEqualizer.cpp @@ -736,7 +736,8 @@ extern "C" int Equalizer_getDescriptor(effect_handle_t self, const struct effect_interface_s gEqualizerInterface = { Equalizer_process, Equalizer_command, - Equalizer_getDescriptor + Equalizer_getDescriptor, + NULL }; diff --git a/media/libeffects/testlibs/EffectReverb.c b/media/libeffects/testlibs/EffectReverb.c index 02762c959c6c..405f908cc848 100644 --- a/media/libeffects/testlibs/EffectReverb.c +++ b/media/libeffects/testlibs/EffectReverb.c @@ -27,7 +27,8 @@ const struct effect_interface_s gReverbInterface = { Reverb_Process, Reverb_Command, - Reverb_GetDescriptor + Reverb_GetDescriptor, + NULL }; // Google auxiliary environmental reverb UUID: 1f0ae2e0-4ef7-11df-bc09-0002a5d5c51b diff --git a/media/libeffects/visualizer/EffectVisualizer.cpp b/media/libeffects/visualizer/EffectVisualizer.cpp index aeebd4db9193..3c3af8f343af 100644 --- a/media/libeffects/visualizer/EffectVisualizer.cpp +++ b/media/libeffects/visualizer/EffectVisualizer.cpp @@ -450,7 +450,8 @@ int Visualizer_getDescriptor(effect_handle_t self, const struct effect_interface_s gVisualizerInterface = { Visualizer_process, Visualizer_command, - Visualizer_getDescriptor + Visualizer_getDescriptor, + NULL, }; diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp index b11db324ddb3..ddad2d323fce 100644 --- a/opengl/libs/EGL/egl.cpp +++ b/opengl/libs/EGL/egl.cpp @@ -31,6 +31,7 @@ #include <cutils/properties.h> #include <cutils/memory.h> +#include <utils/CallStack.h> #include <utils/String8.h> #include "egldefs.h" @@ -147,6 +148,10 @@ static int gl_no_context() { if (egl_tls_t::logNoContextCall()) { LOGE("call to OpenGL ES API with no current context " "(logged once per thread)"); + LOGE("call stack before error:"); + CallStack stack; + stack.update(); + stack.dump(); } return 0; } diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp index 7d5d01084fc5..ba5d29a17db1 100644 --- a/opengl/libs/EGL/eglApi.cpp +++ b/opengl/libs/EGL/eglApi.cpp @@ -367,7 +367,12 @@ EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config, if (cnx->egl.eglGetConfigAttrib(iDpy, iConfig, EGL_NATIVE_VISUAL_ID, &format)) { if (format != 0) { - native_window_set_buffers_geometry(window, 0, 0, format); + int err = native_window_set_buffers_format(window, format); + if (err != 0) { + LOGE("error setting native window pixel format: %s (%d)", + strerror(-err), err); + return setError(EGL_BAD_NATIVE_WINDOW, EGL_NO_SURFACE); + } } } diff --git a/opengl/specs/EGL_ANDROID_blob_cache.txt b/opengl/specs/EGL_ANDROID_blob_cache.txt new file mode 100644 index 000000000000..55dc9004a1fd --- /dev/null +++ b/opengl/specs/EGL_ANDROID_blob_cache.txt @@ -0,0 +1,208 @@ +Name + + ANDROID_blob_cache + +Name Strings + + EGL_ANDROID_blob_cache + +Contributors + + Jamie Gennis + +Contact + + Jamie Gennis, Google Inc. (jgennis 'at' google.com) + +Status + + Draft. + +Version + + Version 1, April 22, 2011 + +Number + + EGL Extension #XXX + +Dependencies + + Requires EGL 1.0 + + This extension is written against the wording of the EGL 1.4 Specification + +Overview + + Shader compilation and optimization has been a troublesome aspect of OpenGL + programming for a long time. It can consume seconds of CPU cycles during + application start-up. Additionally, state-based re-compiles done + internally by the drivers add an unpredictable element to application + performance tuning, often leading to occasional pauses in otherwise smooth + animations. + + This extension provides a mechanism through which client API + implementations may cache shader binaries after they are compiled. It may + then retrieve those cached shaders during subsequent executions of the same + program. The management of the cache is handled by the application (or + middleware), allowing it to be tuned to a particular platform or + environment. + + While the focus of this extension is on providing a persistent cache for + shader binaries, it may also be useful for caching other data. This is + perfectly acceptable, but the guarantees provided (or lack thereof) were + designed around the shader use case. + + Note that although this extension is written as if the application + implements the caching functionality, on the Android OS it is implemented + as part of the Android EGL module. This extension is not exposed to + applications on Android, but will be used automatically in every + application that uses EGL if it is supported by the underlying + device-specific EGL implementation. + +New Types + + /* + * EGLsizei is a signed integer type for representing the size of a memory + * buffer. + */ + #include <khrplatform.h> + typedef khronos_ssize_t EGLsizei; + + /* + * EGLSetBlobFunc is a pointer to an application-provided function that a + * client API implementation may use to insert a key/value pair into the + * cache. + */ + typedef void (*EGLSetBlobFunc) (const void* key, EGLsizei keySize, + const void* value, EGLsizei valueSize) + + /* + * EGLGetBlobFunc is a pointer to an application-provided function that a + * client API implementation may use to retrieve a cached value from the + * cache. + */ + typedef EGLsizei (*EGLGetBlobFunc) (const void* key, EGLsizei keySize, + void* value, EGLsizei valueSize) + +New Procedures and Functions + + void eglSetBlobCacheFuncs(EGLDisplay dpy, + EGLSetBlobFunc set, + EGLGetBlobFunc get); + +New Tokens + + None. + +Changes to Chapter 3 of the EGL 1.4 Specification (EGL Functions and Errors) + + Add a new subsection after Section 3.8, page 50 + (Synchronization Primitives) + + "3.9 Persistent Caching + + In order to facilitate persistent caching of internal client API state that + is slow to compute or collect, the application may specify callback + function pointers through which the client APIs can request data be cached + and retrieved. The command + + void eglSetBlobCacheFuncs(EGLDisplay dpy, + EGLSetBlobFunc set, EGLGetBlobFunc get); + + sets the callback function pointers that client APIs associated with + display <dpy> can use to interact with caching functionality provided by + the application. <set> points to a function that inserts a new value into + the cache and associates it with the given key. <get> points to a function + that retrieves from the cache the value associated with a given key. The + semantics of these callback functions are described in Section 3.9.1 (Cache + Operations). + + Cache functions may only be specified once during the lifetime of an + EGLDisplay. The <set> and <get> functions may be called at any time and + from any thread from the time at which eglSetBlobCacheFuncs is called until + the time that the last resource associated with <dpy> is deleted and <dpy> + itself is terminated. Concurrent calls to these functions from different + threads is also allowed. + + If eglSetBlobCacheFuncs generates an error then all client APIs must behave + as though eglSetBlobCacheFuncs was not called for the display <dpy>. If + <set> or <get> is NULL then an EGL_BAD_PARAMETER error is generated. If a + successful eglSetBlobCacheFuncs call was already made for <dpy> and the + display has not since been terminated then an EGL_BAD_PARAMETER error is + generated. + + 3.9.1 Cache Operations + + To insert a new binary value into the cache and associate it with a given + key, a client API implementation can call the application-provided callback + function + + void (*set) (const void* key, EGLsizei keySize, const void* value, + EGLsizei valueSize) + + <key> and <value> are pointers to the beginning of the key and value, + respectively, that are to be inserted. <keySize> and <valueSize> specify + the size in bytes of the data pointed to by <key> and <value>, + respectively. + + No guarantees are made as to whether a given key/value pair is present in + the cache after the set call. If a different value has been associated + with the given key in the past then it is undefined which value, if any, is + associated with the key after the set call. Note that while there are no + guarantees, the cache implementation should attempt to cache the most + recently set value for a given key. + + To retrieve the binary value associated with a given key from the cache, a + client API implementation can call the application-provided callback + function + + EGLsizei (*get) (const void* key, EGLsizei keySize, void* value, + EGLsizei valueSize) + + <key> is a pointer to the beginning of the key. <keySize> specifies the + size in bytes of the binary key pointed to by <key>. If the cache contains + a value associated with the given key then the size of that binary value in + bytes is returned. Otherwise 0 is returned. + + If the cache contains a value for the given key and its size in bytes is + less than or equal to <valueSize> then the value is written to the memory + pointed to by <value>. Otherwise nothing is written to the memory pointed + to by <value>. + +Issues + + 1. How should errors be handled in the callback functions? + + RESOLVED: No guarantees are made about the presence of values in the cache, + so there should not be a need to return error information to the client API + implementation. The cache implementation can simply drop a value if it + encounters an error during the 'set' callback. Similarly, it can simply + return 0 if it encouters an error in a 'get' callback. + + 2. When a client API driver gets updated, that may need to invalidate + previously cached entries. How can the driver handle this situation? + + RESPONSE: There are a number of ways the driver can handle this situation. + The recommended way is to include the driver version in all cache keys. + That way each driver version will use a set of cache keys that are unique + to that version, and conflicts should never occur. Updating the driver + could then leave a number of values in the cache that will never be + requested again. If needed, the cache implementation can handle those + values in some way, but the driver does not need to take any special + action. + + 3. How much data can be stored in the cache? + + RESPONSE: This is entirely dependent upon the cache implementation. + Presumably it will be tuned to store enough data to be useful, but not + enough to become problematic. :) + +Revision History + +#2 (Jamie Gennis, April 25, 2011) + - Swapped the order of the size and pointer arguments to the get and set + functions. + +#1 (Jamie Gennis, April 22, 2011) + - Initial draft. diff --git a/opengl/specs/EGL_ANDROID_recordable.txt b/opengl/specs/EGL_ANDROID_recordable.txt new file mode 100644 index 000000000000..cf44465198d7 --- /dev/null +++ b/opengl/specs/EGL_ANDROID_recordable.txt @@ -0,0 +1,113 @@ +Name + + ANDROID_recordable + +Name Strings + + EGL_ANDROID_recordable + +Contributors + + Jamie Gennis + +Contact + + Jamie Gennis, Google Inc. (jgennis 'at' google.com) + +Status + + Draft. + +Version + + Version 1, July 8, 2011 + +Number + + EGL Extension #XXX + +Dependencies + + Requires EGL 1.0 + + This extension is written against the wording of the EGL 1.4 Specification + +Overview + + Android supports a number of different ANativeWindow implementations that + can be used to create an EGLSurface. One implementation, which records the + rendered image as a video each time eglSwapBuffers gets called, may have + some device-specific restrictions. Because of this, some EGLConfigs may be + incompatible with these ANativeWindows. This extension introduces a new + boolean EGLConfig attribute that indicates whether the EGLConfig supports + rendering to an ANativeWindow that records images to a video. + +New Types + + None. + +New Procedures and Functions + + None. + +New Tokens + + Accepted by the <attribute> parameter of eglGetConfigAttrib and + the <attrib_list> parameter of eglChooseConfig: + + EGL_RECORDABLE_ANDROID 0xXXXX + +Changes to Chapter 3 of the EGL 1.4 Specification (EGL Functions and Errors) + + Section 3.4, Configuration Management, add a row to Table 3.1. + + Attribute Type Notes + ---------------------- ------- -------------------------- + EGL_RECORDABLE_ANDROID boolean whether video recording is + supported + + Section 3.4, Configuration Management, add a row to Table 3.4. + + Attribute Default Selection Sort Sort + Criteria Order Priority + ---------------------- ------------- --------- ----- -------- + EGL_RECORDABLE_ANDROID EGL_DONT_CARE Exact None + + Section 3.4, Configuration Management, add a paragraph at the end of the + subsection titled Other EGLConfig Attribute Descriptions. + + EGL_RECORDABLE_ANDROID is a boolean indicating whether the config may + be used to create an EGLSurface from an ANativeWindow that is a video + recorder as indicated by the NATIVE_WINDOW_IS_VIDEO_RECORDER query on + the ANativeWindow. + + Section 3.4.1, Querying Configurations, change the last paragraph as follow + + EGLConfigs are not sorted with respect to the parameters + EGL_BIND_TO_TEXTURE_RGB, EGL_BIND_TO_TEXTURE_RGBA, EGL_CONFORMANT, + EGL_LEVEL, EGL_NATIVE_RENDERABLE, EGL_MAX_SWAP_INTERVAL, + EGL_MIN_SWAP_INTERVAL, EGL_RENDERABLE_TYPE, EGL_SURFACE_TYPE, + EGL_TRANSPARENT_TYPE, EGL_TRANSPARENT_RED_VALUE, + EGL_TRANSPARENT_GREEN_VALUE, EGL_TRANSPARENT_BLUE_VALUE, and + EGL_RECORDABLE_ANDROID. + +Issues + + 1. Should this functionality be exposed as a new attribute or as a bit in + the EGL_SURFACE_TYPE bitfield? + + RESOLVED: It should be a new attribute. It does not make sense to use up a + bit in the limit-size bitfield for a platform-specific extension. + + 2. How should the new attribute affect the sorting of EGLConfigs? + + RESOLVED: It should not affect sorting. Some implementations may not have + any drawback associated with using a recordable EGLConfig. Such + implementations should not have to double-up some of their configs to one sort earlier than . + Implementations that do have drawbacks can use the existing caveat + mechanism to report this drawback to the client. + +Revision History + +#1 (Jamie Gennis, July 8, 2011) + - Initial draft. diff --git a/opengl/specs/README b/opengl/specs/README new file mode 100644 index 000000000000..2fa258777f7f --- /dev/null +++ b/opengl/specs/README @@ -0,0 +1,12 @@ +This directory contains OpenGL ES and EGL extension specifications that have +been or are being defined for Android. + +The table below tracks usage of EGL enumerant values that have been reserved +for use by Android extensions. + + Value Extension +---------------- ---------------------------------- +0x3140 EGL_ANDROID_image_native_buffer +0x3141 (unused) +0x3142 EGL_ANDROID_recordable +0x3143 - 0x314F (unused) diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java index 826ac92e3ab1..dedbe5d70f8f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java @@ -785,7 +785,7 @@ public class PhoneStatusBarPolicy { int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR); mBluetoothEnabled = state == BluetoothAdapter.STATE_ON; } else if (action.equals(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED)) { - int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, + int state = intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE, BluetoothAdapter.STATE_DISCONNECTED); if (state == BluetoothAdapter.STATE_CONNECTED) { iconId = R.drawable.stat_sys_data_bluetooth_connected; diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp index 10b9083549f2..da9b55ccd2a3 100644 --- a/services/input/InputDispatcher.cpp +++ b/services/input/InputDispatcher.cpp @@ -3154,11 +3154,9 @@ void InputDispatcher::setInputWindows(const Vector<InputWindow>& inputWindows) { mLastHoverWindow = NULL; } - mWindows.clear(); - // Loop over new windows and rebuild the necessary window pointers for // tracking focus and touch. - mWindows.appendVector(inputWindows); + mWindows = inputWindows; size_t numWindows = mWindows.size(); for (size_t i = 0; i < numWindows; i++) { @@ -4560,8 +4558,7 @@ void InputDispatcher::TouchState::copyFrom(const TouchState& other) { split = other.split; deviceId = other.deviceId; source = other.source; - windows.clear(); - windows.appendVector(other.windows); + windows = other.windows; } void InputDispatcher::TouchState::addOrUpdateWindow(const InputWindow* window, diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index d5e8730c836b..8501163e82a7 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -208,6 +208,12 @@ public final class ActivityManagerService extends ActivityManagerNative // before we decide it's never going to come up for real. static final int PROC_START_TIMEOUT = 10*1000; + // How long we wait for a launched process to attach to the activity manager + // before we decide it's never going to come up for real, when the process was + // started with a wrapper for instrumentation (such as Valgrind) because it + // could take much longer than usual. + static final int PROC_START_TIMEOUT_WITH_WRAPPER = 300*1000; + // How long to wait after going idle before forcing apps to GC. static final int GC_TIMEOUT = 5*1000; @@ -1950,9 +1956,13 @@ public final class ActivityManagerService extends ActivityManagerNative if ("1".equals(SystemProperties.get("debug.assert"))) { debugFlags |= Zygote.DEBUG_ENABLE_ASSERT; } - int pid = Process.start("android.app.ActivityThread", + + // Start the process. It will either succeed and return a result containing + // the PID of the new process, or else throw a RuntimeException. + Process.ProcessStartResult startResult = Process.start("android.app.ActivityThread", app.processName, uid, uid, gids, debugFlags, app.info.targetSdkVersion, null); + BatteryStatsImpl bs = app.batteryStats.getBatteryStats(); synchronized (bs) { if (bs.isOnBattery()) { @@ -1960,12 +1970,12 @@ public final class ActivityManagerService extends ActivityManagerNative } } - EventLog.writeEvent(EventLogTags.AM_PROC_START, pid, uid, + EventLog.writeEvent(EventLogTags.AM_PROC_START, startResult.pid, uid, app.processName, hostingType, hostingNameStr != null ? hostingNameStr : ""); if (app.persistent) { - Watchdog.getInstance().processStarted(app.processName, pid); + Watchdog.getInstance().processStarted(app.processName, startResult.pid); } StringBuilder buf = mStringBuilder; @@ -1979,7 +1989,7 @@ public final class ActivityManagerService extends ActivityManagerNative buf.append(hostingNameStr); } buf.append(": pid="); - buf.append(pid); + buf.append(startResult.pid); buf.append(" uid="); buf.append(uid); buf.append(" gids={"); @@ -1992,21 +2002,15 @@ public final class ActivityManagerService extends ActivityManagerNative } buf.append("}"); Slog.i(TAG, buf.toString()); - if (pid > 0) { - app.pid = pid; - app.removed = false; - synchronized (mPidsSelfLocked) { - this.mPidsSelfLocked.put(pid, app); - Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); - msg.obj = app; - mHandler.sendMessageDelayed(msg, PROC_START_TIMEOUT); - } - } else { - app.pid = 0; - RuntimeException e = new RuntimeException( - "Failure starting process " + app.processName - + ": returned pid=" + pid); - Slog.e(TAG, e.getMessage(), e); + app.pid = startResult.pid; + app.usingWrapper = startResult.usingWrapper; + app.removed = false; + synchronized (mPidsSelfLocked) { + this.mPidsSelfLocked.put(startResult.pid, app); + Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); + msg.obj = app; + mHandler.sendMessageDelayed(msg, startResult.usingWrapper + ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); } } catch (RuntimeException e) { // XXX do better error recovery. diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java index 090e26b0fc95..73ffafb66ec1 100644 --- a/services/java/com/android/server/am/ActivityRecord.java +++ b/services/java/com/android/server/am/ActivityRecord.java @@ -658,12 +658,12 @@ final class ActivityRecord extends IApplicationToken.Stub { public long getKeyDispatchingTimeout() { synchronized(service) { ActivityRecord r = getWaitingHistoryRecordLocked(); - if (r == null || r.app == null - || r.app.instrumentationClass == null) { - return ActivityManagerService.KEY_DISPATCHING_TIMEOUT; + if (r != null && r.app != null + && (r.app.instrumentationClass != null || r.app.usingWrapper)) { + return ActivityManagerService.INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; } - - return ActivityManagerService.INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT; + + return ActivityManagerService.KEY_DISPATCHING_TIMEOUT; } } diff --git a/services/java/com/android/server/am/ProcessRecord.java b/services/java/com/android/server/am/ProcessRecord.java index 3968f6635a57..da83e7d029d2 100644 --- a/services/java/com/android/server/am/ProcessRecord.java +++ b/services/java/com/android/server/am/ProcessRecord.java @@ -78,6 +78,7 @@ class ProcessRecord { IInstrumentationWatcher instrumentationWatcher; // who is waiting Bundle instrumentationArguments;// as given to us ComponentName instrumentationResultClass;// copy of instrumentationClass + boolean usingWrapper; // Set to true when process was launched with a wrapper attached BroadcastRecord curReceiver;// receiver currently running in the app long lastWakeTime; // How long proc held wake lock at last check long lastCpuTime; // How long proc has run CPU at last check diff --git a/services/java/com/android/server/connectivity/Tethering.java b/services/java/com/android/server/connectivity/Tethering.java index 6bb79499d9b7..d7d4b0346795 100644 --- a/services/java/com/android/server/connectivity/Tethering.java +++ b/services/java/com/android/server/connectivity/Tethering.java @@ -221,8 +221,6 @@ public class Tethering extends INetworkManagementEventObserver.Stub { } public void interfaceLinkStateChanged(String iface, boolean up) { - if (DEBUG) Log.d(TAG, "interfaceLinkStateChanged " + iface + ", " + up); - interfaceStatusChanged(iface, up); } private boolean isUsb(String iface) { diff --git a/services/java/com/android/server/usb/UsbDeviceManager.java b/services/java/com/android/server/usb/UsbDeviceManager.java index 1ab570a7a7f7..86b3d364ab02 100644 --- a/services/java/com/android/server/usb/UsbDeviceManager.java +++ b/services/java/com/android/server/usb/UsbDeviceManager.java @@ -251,19 +251,18 @@ public class UsbDeviceManager { public UsbHandler() { try { + // persist.sys.usb.config should never be unset. But if it is, set it to "adb" + // so we have a chance of debugging what happened. + mDefaultFunctions = SystemProperties.get("persist.sys.usb.config", "adb"); // sanity check the sys.usb.config system property // this may be necessary if we crashed while switching USB configurations String config = SystemProperties.get("sys.usb.config", "none"); - if (config.equals("none")) { - String persistConfig = SystemProperties.get("persist.sys.usb.config", "none"); - Slog.w(TAG, "resetting config to persistent property: " + persistConfig); - SystemProperties.set("sys.usb.config", persistConfig); + if (!config.equals(mDefaultFunctions)) { + Slog.w(TAG, "resetting config to persistent property: " + mDefaultFunctions); + SystemProperties.set("sys.usb.config", mDefaultFunctions); } - // Read initial USB state - mCurrentFunctions = FileUtils.readTextFile( - new File(FUNCTIONS_PATH), 0, null).trim(); - mDefaultFunctions = mCurrentFunctions; + mCurrentFunctions = mDefaultFunctions; String state = FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim(); updateState(state); mAdbEnabled = containsFunction(mCurrentFunctions, UsbManager.USB_FUNCTION_ADB); @@ -621,6 +620,16 @@ public class UsbDeviceManager { pw.println(" mConnected: " + mConnected); pw.println(" mConfigured: " + mConfigured); pw.println(" mCurrentAccessory: " + mCurrentAccessory); + try { + pw.println(" Kernel state: " + + FileUtils.readTextFile(new File(STATE_PATH), 0, null).trim()); + pw.println(" Kernel function list: " + + FileUtils.readTextFile(new File(FUNCTIONS_PATH), 0, null).trim()); + pw.println(" Mass storage backing file: " + + FileUtils.readTextFile(new File(MASS_STORAGE_FILE_PATH), 0, null).trim()); + } catch (IOException e) { + pw.println("IOException: " + e); + } } } |