Merge "Support more MPEG4-LATM audio functionality."
diff --git a/core/java/android/app/KeyguardManager.java b/core/java/android/app/KeyguardManager.java
index e3d8e20..1e8743c 100644
--- a/core/java/android/app/KeyguardManager.java
+++ b/core/java/android/app/KeyguardManager.java
@@ -117,6 +117,40 @@
}
/**
+ * isKeyguardLocked
+ *
+ * Return whether the keyguard is currently locked.
+ *
+ * @return true if in keyguard is locked.
+ *
+ * @hide
+ */
+ public boolean isKeyguardLocked() {
+ try {
+ return mWM.isKeyguardSecure();
+ } catch (RemoteException ex) {
+ return false;
+ }
+ }
+
+ /**
+ * isKeyguardSecure
+ *
+ * Return whether the keyguard requires a password to unlock.
+ *
+ * @return true if in keyguard is secure.
+ *
+ * @hide
+ */
+ public boolean isKeyguardSecure() {
+ try {
+ return mWM.isKeyguardSecure();
+ } catch (RemoteException ex) {
+ return false;
+ }
+ }
+
+ /**
* If keyguard screen is showing or in restricted key input mode (i.e. in
* keyguard password emergency screen). When in such mode, certain keys,
* such as the Home key and the right soft keys, don't work.
diff --git a/core/java/android/app/ListActivity.java b/core/java/android/app/ListActivity.java
index d49968f..2162521 100644
--- a/core/java/android/app/ListActivity.java
+++ b/core/java/android/app/ListActivity.java
@@ -43,7 +43,7 @@
* <p>
* Optionally, your custom view can contain another view object of any type to
* display when the list view is empty. This "empty list" notifier must have an
- * id "android:empty". Note that when an empty view is present, the list view
+ * id "android:id/empty". Note that when an empty view is present, the list view
* will be hidden when there is no data to display.
* <p>
* The following code demonstrates an (ugly) custom screen layout. It has a list
@@ -59,14 +59,14 @@
* android:paddingLeft="8dp"
* android:paddingRight="8dp">
*
- * <ListView android:id="@id/android:list"
+ * <ListView android:id="@android:id/list"
* android:layout_width="match_parent"
* android:layout_height="match_parent"
* android:background="#00FF00"
* android:layout_weight="1"
* android:drawSelectorOnTop="false"/>
*
- * <TextView android:id="@id/android:empty"
+ * <TextView android:id="@android:id/empty"
* android:layout_width="match_parent"
* android:layout_height="match_parent"
* android:background="#FF0000"
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index 4656e15..1f4fe80 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -1049,6 +1049,9 @@
} else if (profile == BluetoothProfile.A2DP) {
BluetoothA2dp a2dp = new BluetoothA2dp(context, listener);
return true;
+ } else if (profile == BluetoothProfile.INPUT_DEVICE) {
+ BluetoothInputDevice iDev = new BluetoothInputDevice(context, listener);
+ return true;
} else {
return false;
}
diff --git a/core/java/android/bluetooth/BluetoothDeviceProfileState.java b/core/java/android/bluetooth/BluetoothDeviceProfileState.java
index 6ec347f..116a068 100644
--- a/core/java/android/bluetooth/BluetoothDeviceProfileState.java
+++ b/core/java/android/bluetooth/BluetoothDeviceProfileState.java
@@ -136,17 +136,17 @@
newState == BluetoothProfile.STATE_DISCONNECTED) {
sendMessage(TRANSITION_TO_STABLE);
}
- } else if (action.equals(BluetoothInputDevice.ACTION_INPUT_DEVICE_STATE_CHANGED)) {
- int newState = intent.getIntExtra(BluetoothInputDevice.EXTRA_INPUT_DEVICE_STATE, 0);
+ } else if (action.equals(BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED)) {
+ int newState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, 0);
int oldState =
- intent.getIntExtra(BluetoothInputDevice.EXTRA_PREVIOUS_INPUT_DEVICE_STATE, 0);
+ intent.getIntExtra(BluetoothProfile.EXTRA_PREVIOUS_STATE, 0);
- if (oldState == BluetoothInputDevice.STATE_CONNECTED &&
- newState == BluetoothInputDevice.STATE_DISCONNECTED) {
+ if (oldState == BluetoothProfile.STATE_CONNECTED &&
+ newState == BluetoothProfile.STATE_DISCONNECTED) {
sendMessage(DISCONNECT_HID_INCOMING);
}
- if (newState == BluetoothInputDevice.STATE_CONNECTED ||
- newState == BluetoothInputDevice.STATE_DISCONNECTED) {
+ if (newState == BluetoothProfile.STATE_CONNECTED ||
+ newState == BluetoothProfile.STATE_DISCONNECTED) {
sendMessage(TRANSITION_TO_STABLE);
}
} else if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)) {
@@ -194,7 +194,7 @@
filter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
filter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
- filter.addAction(BluetoothInputDevice.ACTION_INPUT_DEVICE_STATE_CHANGED);
+ filter.addAction(BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED);
filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
mContext.registerReceiver(mBroadcastReceiver, filter);
@@ -286,7 +286,7 @@
sendMessage(DISCONNECT_A2DP_OUTGOING);
deferMessage(message);
break;
- } else if (mService.getInputDeviceState(mDevice) !=
+ } else if (mService.getInputDeviceConnectionState(mDevice) !=
BluetoothInputDevice.STATE_DISCONNECTED) {
sendMessage(DISCONNECT_HID_OUTGOING);
deferMessage(message);
diff --git a/core/java/android/bluetooth/BluetoothInputDevice.java b/core/java/android/bluetooth/BluetoothInputDevice.java
index a70de59..df212a8 100644
--- a/core/java/android/bluetooth/BluetoothInputDevice.java
+++ b/core/java/android/bluetooth/BluetoothInputDevice.java
@@ -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.
@@ -27,91 +27,88 @@
import java.util.ArrayList;
import java.util.List;
+
/**
- * Public API for controlling the Bluetooth HID (Input Device) Profile
+ * This class provides the public APIs to control the Bluetooth Input
+ * Device Profile.
*
- * BluetoothInputDevice is a proxy object used to make calls to Bluetooth Service
- * which handles the HID profile.
+ *<p>BluetoothInputDevice is a proxy object for controlling the Bluetooth
+ * Service via IPC. Use {@link BluetoothAdapter#getProfileProxy} to get
+ * the BluetoothInputDevice proxy object.
*
- * Creating a BluetoothInputDevice object will initiate a binding with the
- * Bluetooth service. Users of this object should call close() when they
- * are finished, so that this proxy object can unbind from the service.
- *
- * Currently the Bluetooth service runs in the system server and this
- * proxy object will be immediately bound to the service on construction.
- *
- * @hide
+ *<p>Each method is protected with its appropriate permission.
+ *@hide
*/
-public final class BluetoothInputDevice {
+public final class BluetoothInputDevice implements BluetoothProfile {
private static final String TAG = "BluetoothInputDevice";
private static final boolean DBG = false;
- /** int extra for ACTION_INPUT_DEVICE_STATE_CHANGED */
- public static final String EXTRA_INPUT_DEVICE_STATE =
- "android.bluetooth.inputdevice.extra.INPUT_DEVICE_STATE";
- /** int extra for ACTION_INPUT_DEVICE_STATE_CHANGED */
- public static final String EXTRA_PREVIOUS_INPUT_DEVICE_STATE =
- "android.bluetooth.inputdevice.extra.PREVIOUS_INPUT_DEVICE_STATE";
-
- /** Indicates the state of an input device has changed.
- * This intent will always contain EXTRA_INPUT_DEVICE_STATE,
- * EXTRA_PREVIOUS_INPUT_DEVICE_STATE and BluetoothDevice.EXTRA_DEVICE
- * extras.
+ /**
+ * Intent used to broadcast the change in connection state of the Input
+ * Device profile.
+ *
+ * <p>This intent will have 3 extras:
+ * <ul>
+ * <li> {@link #EXTRA_STATE} - The current state of the profile. </li>
+ * <li> {@link #EXTRA_PREVIOUS_STATE}- The previous state of the profile.</li>
+ * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
+ * </ul>
+ *
+ * <p>{@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} can be any of
+ * {@link #STATE_DISCONNECTED}, {@link #STATE_CONNECTING},
+ * {@link #STATE_CONNECTED}, {@link #STATE_DISCONNECTING}.
+ *
+ * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to
+ * receive.
*/
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
- public static final String ACTION_INPUT_DEVICE_STATE_CHANGED =
- "android.bluetooth.inputdevice.action.INPUT_DEVICE_STATE_CHANGED";
-
- public static final int STATE_DISCONNECTED = 0;
- public static final int STATE_CONNECTING = 1;
- public static final int STATE_CONNECTED = 2;
- public static final int STATE_DISCONNECTING = 3;
-
- /**
- * Auto connection, incoming and outgoing connection are allowed at this
- * priority level.
- */
- public static final int PRIORITY_AUTO_CONNECT = 1000;
- /**
- * Incoming and outgoing connection are allowed at this priority level
- */
- public static final int PRIORITY_ON = 100;
- /**
- * Connections to the device are not allowed at this priority level.
- */
- public static final int PRIORITY_OFF = 0;
- /**
- * Default priority level when the device is unpaired.
- */
- public static final int PRIORITY_UNDEFINED = -1;
+ public static final String ACTION_CONNECTION_STATE_CHANGED =
+ "android.bluetooth.input.profile.action.CONNECTION_STATE_CHANGED";
/**
* Return codes for the connect and disconnect Bluez / Dbus calls.
+ * @hide
*/
public static final int INPUT_DISCONNECT_FAILED_NOT_CONNECTED = 5000;
+ /**
+ * @hide
+ */
public static final int INPUT_CONNECT_FAILED_ALREADY_CONNECTED = 5001;
+ /**
+ * @hide
+ */
public static final int INPUT_CONNECT_FAILED_ATTEMPT_FAILED = 5002;
+ /**
+ * @hide
+ */
public static final int INPUT_OPERATION_GENERIC_FAILURE = 5003;
+ /**
+ * @hide
+ */
public static final int INPUT_OPERATION_SUCCESS = 5004;
- private final IBluetooth mService;
- private final Context mContext;
+ private ServiceListener mServiceListener;
+ private BluetoothAdapter mAdapter;
+ private IBluetooth mService;
/**
* Create a BluetoothInputDevice proxy object for interacting with the local
- * Bluetooth Service which handle the HID profile.
- * @param c Context
+ * Bluetooth Service which handles the InputDevice profile
+ *
*/
- public BluetoothInputDevice(Context c) {
- mContext = c;
-
+ /*package*/ BluetoothInputDevice(Context mContext, ServiceListener l) {
IBinder b = ServiceManager.getService(BluetoothAdapter.BLUETOOTH_SERVICE);
+ mServiceListener = l;
+ mAdapter = BluetoothAdapter.getDefaultAdapter();
if (b != null) {
mService = IBluetooth.Stub.asInterface(b);
+ if (mServiceListener != null) {
+ mServiceListener.onServiceConnected(BluetoothProfile.INPUT_DEVICE, this);
+ }
} else {
Log.w(TAG, "Bluetooth Service not available!");
@@ -121,130 +118,151 @@
}
}
- /** Initiate a connection to an Input device.
- *
- * This function returns false on error and true if the connection
- * attempt is being made.
- *
- * Listen for INPUT_DEVICE_STATE_CHANGED_ACTION to find out when the
- * connection is completed.
- * @param device Remote BT device.
- * @return false on immediate error, true otherwise
- * @hide
+ /**
+ * {@inheritDoc}
+ * @hide
*/
- public boolean connectInputDevice(BluetoothDevice device) {
- if (DBG) log("connectInputDevice(" + device + ")");
- try {
- return mService.connectInputDevice(device);
- } catch (RemoteException e) {
- Log.e(TAG, "", e);
- return false;
+ public boolean connect(BluetoothDevice device) {
+ if (DBG) log("connect(" + device + ")");
+ if (mService != null && isEnabled() &&
+ isValidDevice(device)) {
+ try {
+ return mService.connectInputDevice(device);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return false;
+ }
}
- }
-
- /** Initiate disconnect from an Input Device.
- * This function return false on error and true if the disconnection
- * attempt is being made.
- *
- * Listen for INPUT_DEVICE_STATE_CHANGED_ACTION to find out when
- * disconnect is completed.
- *
- * @param device Remote BT device.
- * @return false on immediate error, true otherwise
- * @hide
- */
- public boolean disconnectInputDevice(BluetoothDevice device) {
- if (DBG) log("disconnectInputDevice(" + device + ")");
- try {
- return mService.disconnectInputDevice(device);
- } catch (RemoteException e) {
- Log.e(TAG, "", e);
- return false;
- }
- }
-
- /** Check if a specified InputDevice is connected.
- *
- * @param device Remote BT device.
- * @return True if connected , false otherwise and on error.
- * @hide
- */
- public boolean isInputDeviceConnected(BluetoothDevice device) {
- if (DBG) log("isInputDeviceConnected(" + device + ")");
- int state = getInputDeviceState(device);
- if (state == STATE_CONNECTED) return true;
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
return false;
}
- /** Check if any Input Device is connected.
- *
- * @return List of devices, empty List on error.
+ /**
+ * {@inheritDoc}
* @hide
*/
- public List<BluetoothDevice> getConnectedInputDevices() {
- if (DBG) log("getConnectedInputDevices()");
- try {
- return mService.getConnectedInputDevices();
- } catch (RemoteException e) {
- Log.e(TAG, "", e);
- return new ArrayList<BluetoothDevice>();
+ public boolean disconnect(BluetoothDevice device) {
+ if (DBG) log("disconnect(" + device + ")");
+ if (mService != null && isEnabled() &&
+ isValidDevice(device)) {
+ try {
+ return mService.disconnectInputDevice(device);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return false;
+ }
}
- }
-
- /** Get the state of an Input Device.
- *
- * @param device Remote BT device.
- * @return The current state of the Input Device
- * @hide
- */
- public int getInputDeviceState(BluetoothDevice device) {
- if (DBG) log("getInputDeviceState(" + device + ")");
- try {
- return mService.getInputDeviceState(device);
- } catch (RemoteException e) {
- Log.e(TAG, "", e);
- return STATE_DISCONNECTED;
- }
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ return false;
}
/**
- * Set priority of an input device.
- *
- * Priority is a non-negative integer. Priority can take the following
- * values:
- * {@link PRIORITY_ON}, {@link PRIORITY_OFF}, {@link PRIORITY_AUTO_CONNECT}
- *
- * @param device Paired device.
- * @param priority Integer priority
- * @return true if priority is set, false on error
+ * {@inheritDoc}
*/
- public boolean setInputDevicePriority(BluetoothDevice device, int priority) {
- if (DBG) log("setInputDevicePriority(" + device + ", " + priority + ")");
- try {
- return mService.setInputDevicePriority(device, priority);
- } catch (RemoteException e) {
- Log.e(TAG, "", e);
- return false;
+ public List<BluetoothDevice> getConnectedDevices() {
+ if (DBG) log("getConnectedDevices()");
+ if (mService != null && isEnabled()) {
+ try {
+ return mService.getConnectedInputDevices();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return new ArrayList<BluetoothDevice>();
+ }
}
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ return new ArrayList<BluetoothDevice>();
}
/**
- * Get the priority associated with an Input Device.
- *
- * @param device Input Device
- * @return non-negative priority, or negative error code on error.
+ * {@inheritDoc}
*/
- public int getInputDevicePriority(BluetoothDevice device) {
- if (DBG) log("getInputDevicePriority(" + device + ")");
- try {
- return mService.getInputDevicePriority(device);
- } catch (RemoteException e) {
- Log.e(TAG, "", e);
- return PRIORITY_OFF;
+ public List<BluetoothDevice> getDevicesMatchingConnectionStates(int[] states) {
+ if (DBG) log("getDevicesMatchingStates()");
+ if (mService != null && isEnabled()) {
+ try {
+ return mService.getInputDevicesMatchingConnectionStates(states);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return new ArrayList<BluetoothDevice>();
+ }
}
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ return new ArrayList<BluetoothDevice>();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int getConnectionState(BluetoothDevice device) {
+ if (DBG) log("getState(" + device + ")");
+ if (mService != null && isEnabled()
+ && isValidDevice(device)) {
+ try {
+ return mService.getInputDeviceConnectionState(device);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return BluetoothProfile.STATE_DISCONNECTED;
+ }
+ }
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ return BluetoothProfile.STATE_DISCONNECTED;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @hide
+ */
+ public boolean setPriority(BluetoothDevice device, int priority) {
+ if (DBG) log("setPriority(" + device + ", " + priority + ")");
+ if (mService != null && isEnabled()
+ && isValidDevice(device)) {
+ if (priority != BluetoothProfile.PRIORITY_OFF &&
+ priority != BluetoothProfile.PRIORITY_ON) {
+ return false;
+ }
+ try {
+ return mService.setInputDevicePriority(device, priority);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return false;
+ }
+ }
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ * @hide
+ */
+ public int getPriority(BluetoothDevice device) {
+ if (DBG) log("getPriority(" + device + ")");
+ if (mService != null && isEnabled()
+ && isValidDevice(device)) {
+ try {
+ return mService.getInputDevicePriority(device);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Stack:" + Log.getStackTraceString(new Throwable()));
+ return BluetoothProfile.PRIORITY_OFF;
+ }
+ }
+ if (mService == null) Log.w(TAG, "Proxy not attached to service");
+ return BluetoothProfile.PRIORITY_OFF;
+ }
+
+ private boolean isEnabled() {
+ if (mAdapter.getState() == BluetoothAdapter.STATE_ON) return true;
+ return false;
+ }
+
+ private boolean isValidDevice(BluetoothDevice device) {
+ if (device == null) return false;
+
+ if (BluetoothAdapter.checkBluetoothAddress(device.getAddress())) return true;
+ return false;
}
private static void log(String msg) {
- Log.d(TAG, msg);
+ Log.d(TAG, msg);
}
}
diff --git a/core/java/android/bluetooth/BluetoothProfile.java b/core/java/android/bluetooth/BluetoothProfile.java
index ef80195d..1ffee72 100644
--- a/core/java/android/bluetooth/BluetoothProfile.java
+++ b/core/java/android/bluetooth/BluetoothProfile.java
@@ -62,6 +62,11 @@
* A2DP profile.
*/
public static final int A2DP = 2;
+ /**
+ * Input Device Profile
+ * @hide
+ */
+ public static final int INPUT_DEVICE = 3;
/**
* Default priority for devices that we try to auto-connect to and
diff --git a/core/java/android/bluetooth/BluetoothProfileState.java b/core/java/android/bluetooth/BluetoothProfileState.java
index 3f36926..18060a0 100644
--- a/core/java/android/bluetooth/BluetoothProfileState.java
+++ b/core/java/android/bluetooth/BluetoothProfileState.java
@@ -72,10 +72,10 @@
newState == BluetoothProfile.STATE_DISCONNECTED)) {
sendMessage(TRANSITION_TO_STABLE);
}
- } else if (action.equals(BluetoothInputDevice.ACTION_INPUT_DEVICE_STATE_CHANGED)) {
- int newState = intent.getIntExtra(BluetoothInputDevice.EXTRA_INPUT_DEVICE_STATE, 0);
- if (mProfile == HID && (newState == BluetoothInputDevice.STATE_CONNECTED ||
- newState == BluetoothInputDevice.STATE_DISCONNECTED)) {
+ } else if (action.equals(BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED)) {
+ int newState = intent.getIntExtra(BluetoothProfile.EXTRA_STATE, 0);
+ if (mProfile == HID && (newState == BluetoothProfile.STATE_CONNECTED ||
+ newState == BluetoothProfile.STATE_DISCONNECTED)) {
sendMessage(TRANSITION_TO_STABLE);
}
} else if (action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)) {
@@ -96,7 +96,7 @@
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED);
filter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED);
- filter.addAction(BluetoothInputDevice.ACTION_INPUT_DEVICE_STATE_CHANGED);
+ filter.addAction(BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED);
filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
context.registerReceiver(mBroadcastReceiver, filter);
}
diff --git a/core/java/android/bluetooth/IBluetooth.aidl b/core/java/android/bluetooth/IBluetooth.aidl
index f3e73cf..69fb06a 100644
--- a/core/java/android/bluetooth/IBluetooth.aidl
+++ b/core/java/android/bluetooth/IBluetooth.aidl
@@ -85,7 +85,8 @@
boolean connectInputDevice(in BluetoothDevice device);
boolean disconnectInputDevice(in BluetoothDevice device);
List<BluetoothDevice> getConnectedInputDevices();
- int getInputDeviceState(in BluetoothDevice device);
+ List<BluetoothDevice> getInputDevicesMatchingConnectionStates(in int[] states);
+ int getInputDeviceConnectionState(in BluetoothDevice device);
boolean setInputDevicePriority(in BluetoothDevice device, int priority);
int getInputDevicePriority(in BluetoothDevice device);
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 85f64d0..81eb09c 100755
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -115,7 +115,7 @@
private CompatibilityInfo mCompatibilityInfo;
private Display mDefaultDisplay;
- private static final LongSparseArray<Object> EMPTY_ARRAY = new LongSparseArray<Object>() {
+ private static final LongSparseArray<Object> EMPTY_ARRAY = new LongSparseArray<Object>(0) {
@Override
public void put(long k, Object o) {
throw new UnsupportedOperationException();
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index 3316ea5..c0b3cc8 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -57,6 +57,7 @@
private final BluetoothService mBluetoothService;
private final BluetoothAdapter mAdapter;
private BluetoothA2dp mA2dp;
+ private BluetoothInputDevice mInputDevice;
private final Context mContext;
// The WakeLock is used for bringing up the LCD during a pairing request
// from remote device when Android is in Suspend state.
@@ -125,15 +126,24 @@
/*package*/ void getProfileProxy() {
mAdapter.getProfileProxy(mContext, mProfileServiceListener, BluetoothProfile.A2DP);
+ mAdapter.getProfileProxy(mContext, mProfileServiceListener, BluetoothProfile.INPUT_DEVICE);
}
private BluetoothProfile.ServiceListener mProfileServiceListener =
new BluetoothProfile.ServiceListener() {
public void onServiceConnected(int profile, BluetoothProfile proxy) {
- mA2dp = (BluetoothA2dp) proxy;
+ if (profile == BluetoothProfile.A2DP) {
+ mA2dp = (BluetoothA2dp) proxy;
+ } else if (profile == BluetoothProfile.INPUT_DEVICE) {
+ mInputDevice = (BluetoothInputDevice) proxy;
+ }
}
public void onServiceDisconnected(int profile) {
- mA2dp = null;
+ if (profile == BluetoothProfile.A2DP) {
+ mA2dp = null;
+ } else if (profile == BluetoothProfile.INPUT_DEVICE) {
+ mInputDevice = null;
+ }
}
};
@@ -651,10 +661,9 @@
} else {
Log.i(TAG, "Rejecting incoming A2DP / AVRCP connection from " + address);
}
- } else if (BluetoothUuid.isInputDevice(uuid) && !isOtherInputDeviceConnected(address)) {
- BluetoothInputDevice inputDevice = new BluetoothInputDevice(mContext);
- authorized = inputDevice.getInputDevicePriority(device) >
- BluetoothInputDevice.PRIORITY_OFF;
+ } else if (mInputDevice != null && BluetoothUuid.isInputDevice(uuid)) {
+ // We can have more than 1 input device connected.
+ authorized = mInputDevice.getPriority(device) > BluetoothInputDevice.PRIORITY_OFF;
if (authorized) {
Log.i(TAG, "Allowing incoming HID connection from " + address);
} else {
@@ -669,18 +678,6 @@
return authorized;
}
- private boolean isOtherInputDeviceConnected(String address) {
- List<BluetoothDevice> devices =
- mBluetoothService.lookupInputDevicesMatchingStates(new int[] {
- BluetoothInputDevice.STATE_CONNECTING,
- BluetoothInputDevice.STATE_CONNECTED});
-
- for (BluetoothDevice device : devices) {
- if (!device.getAddress().equals(address)) return true;
- }
- return false;
- }
-
private boolean onAgentOutOfBandDataAvailable(String objectPath) {
if (!mBluetoothService.isEnabled()) return false;
@@ -758,7 +755,7 @@
boolean connected = false;
BluetoothDevice device = mAdapter.getRemoteDevice(address);
- int state = mBluetoothService.getInputDeviceState(device);
+ int state = mBluetoothService.getInputDeviceConnectionState(device);
if (state == BluetoothInputDevice.STATE_CONNECTING) {
if (result == BluetoothInputDevice.INPUT_CONNECT_FAILED_ALREADY_CONNECTED) {
connected = true;
diff --git a/core/java/android/server/BluetoothInputProfileHandler.java b/core/java/android/server/BluetoothInputProfileHandler.java
index 7ffa5ae..cdc0f2d 100644
--- a/core/java/android/server/BluetoothInputProfileHandler.java
+++ b/core/java/android/server/BluetoothInputProfileHandler.java
@@ -64,7 +64,7 @@
BluetoothDeviceProfileState state) {
String objectPath = mBluetoothService.getObjectPathFromAddress(device.getAddress());
if (objectPath == null ||
- getInputDeviceState(device) != BluetoothInputDevice.STATE_DISCONNECTED ||
+ getInputDeviceConnectionState(device) != BluetoothInputDevice.STATE_DISCONNECTED ||
getInputDevicePriority(device) == BluetoothInputDevice.PRIORITY_OFF) {
return false;
}
@@ -92,7 +92,7 @@
BluetoothDeviceProfileState state) {
String objectPath = mBluetoothService.getObjectPathFromAddress(device.getAddress());
if (objectPath == null ||
- getInputDeviceState(device) == BluetoothInputDevice.STATE_DISCONNECTED) {
+ getInputDeviceConnectionState(device) == BluetoothInputDevice.STATE_DISCONNECTED) {
return false;
}
if (state != null) {
@@ -115,7 +115,7 @@
return true;
}
- synchronized int getInputDeviceState(BluetoothDevice device) {
+ synchronized int getInputDeviceConnectionState(BluetoothDevice device) {
if (mInputDevices.get(device) == null) {
return BluetoothInputDevice.STATE_DISCONNECTED;
}
@@ -128,6 +128,11 @@
return devices;
}
+ synchronized List<BluetoothDevice> getInputDevicesMatchingConnectionStates(int[] states) {
+ List<BluetoothDevice> devices = lookupInputDevicesMatchingStates(states);
+ return devices;
+ }
+
synchronized int getInputDevicePriority(BluetoothDevice device) {
return Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.getBluetoothInputDevicePriorityKey(device.getAddress()),
@@ -147,7 +152,7 @@
List<BluetoothDevice> inputDevices = new ArrayList<BluetoothDevice>();
for (BluetoothDevice device: mInputDevices.keySet()) {
- int inputDeviceState = getInputDeviceState(device);
+ int inputDeviceState = getInputDeviceConnectionState(device);
for (int state : states) {
if (state == inputDeviceState) {
inputDevices.add(device);
@@ -178,10 +183,10 @@
setInputDevicePriority(device, BluetoothInputDevice.PRIORITY_AUTO_CONNECT);
}
- Intent intent = new Intent(BluetoothInputDevice.ACTION_INPUT_DEVICE_STATE_CHANGED);
+ Intent intent = new Intent(BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED);
intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);
- intent.putExtra(BluetoothInputDevice.EXTRA_PREVIOUS_INPUT_DEVICE_STATE, prevState);
- intent.putExtra(BluetoothInputDevice.EXTRA_INPUT_DEVICE_STATE, state);
+ intent.putExtra(BluetoothInputDevice.EXTRA_PREVIOUS_STATE, prevState);
+ intent.putExtra(BluetoothInputDevice.EXTRA_STATE, state);
mContext.sendBroadcast(intent, BluetoothService.BLUETOOTH_PERM);
debugLog("InputDevice state : device: " + device + " State:" + prevState + "->" + state);
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index a295de5..70aaf0a 100644
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -31,6 +31,7 @@
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothDeviceProfileState;
import android.bluetooth.BluetoothHeadset;
+import android.bluetooth.BluetoothInputDevice;
import android.bluetooth.BluetoothPan;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothProfileState;
@@ -83,6 +84,7 @@
private int mNativeData;
private BluetoothEventLoop mEventLoop;
private BluetoothHeadset mBluetoothHeadset;
+ private BluetoothInputDevice mInputDevice;
private boolean mIsAirplaneSensitive;
private boolean mIsAirplaneToggleable;
private int mBluetoothState;
@@ -2078,6 +2080,8 @@
mAdapter.getProfileProxy(mContext,
mBluetoothProfileServiceListener, BluetoothProfile.HEADSET);
+ mAdapter.getProfileProxy(mContext,
+ mBluetoothProfileServiceListener, BluetoothProfile.INPUT_DEVICE);
pw.println("\n--Known devices--");
for (String address : mDeviceProperties.keySet()) {
@@ -2119,8 +2123,17 @@
}
}
- // Rather not do this from here, but no-where else and I need this
- // dump
+ dumpHeadsetProfile(pw);
+ dumpInputDeviceProfile(pw);
+
+ pw.println("\n--Application Service Records--");
+ for (Integer handle : mServiceRecordToPid.keySet()) {
+ Integer pid = mServiceRecordToPid.get(handle);
+ pw.println("\tpid " + pid + " handle " + Integer.toHexString(handle));
+ }
+ }
+
+ private void dumpHeadsetProfile(PrintWriter pw) {
pw.println("\n--Headset Service--");
if (mBluetoothHeadset != null) {
List<BluetoothDevice> deviceList = mBluetoothHeadset.getConnectedDevices();
@@ -2158,24 +2171,60 @@
pw.println("SCO audio connected to device:" + device);
}
}
-
- mAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mBluetoothHeadset);
}
+ mAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mBluetoothHeadset);
+ }
- pw.println("\n--Application Service Records--");
- for (Integer handle : mServiceRecordToPid.keySet()) {
- Integer pid = mServiceRecordToPid.get(handle);
- pw.println("\tpid " + pid + " handle " + Integer.toHexString(handle));
+ private void dumpInputDeviceProfile(PrintWriter pw) {
+ pw.println("\n--Bluetooth Service- Input Device Profile");
+ if (mInputDevice != null) {
+ List<BluetoothDevice> deviceList = mInputDevice.getConnectedDevices();
+ if (deviceList.size() == 0) {
+ pw.println("\nNo input devices connected--");
+ } else {
+ pw.println("\nNumber of connected devices:" + deviceList.size());
+ BluetoothDevice device = deviceList.get(0);
+ pw.println("getConnectedDevices[0] = " + device);
+ pw.println("Priority of Connected device = " + mInputDevice.getPriority(device));
+
+ switch (mInputDevice.getConnectionState(device)) {
+ case BluetoothInputDevice.STATE_CONNECTING:
+ pw.println("getConnectionState() = STATE_CONNECTING");
+ break;
+ case BluetoothInputDevice.STATE_CONNECTED:
+ pw.println("getConnectionState() = STATE_CONNECTED");
+ break;
+ case BluetoothInputDevice.STATE_DISCONNECTING:
+ pw.println("getConnectionState() = STATE_DISCONNECTING");
+ break;
+ }
+ }
+ deviceList.clear();
+ deviceList = mInputDevice.getDevicesMatchingConnectionStates(new int[] {
+ BluetoothProfile.STATE_CONNECTED, BluetoothProfile.STATE_DISCONNECTED});
+ pw.println("--Connected and Disconnected input devices");
+ for (BluetoothDevice device: deviceList) {
+ pw.println(device);
+ }
}
+ mAdapter.closeProfileProxy(BluetoothProfile.INPUT_DEVICE, mBluetoothHeadset);
}
private BluetoothProfile.ServiceListener mBluetoothProfileServiceListener =
new BluetoothProfile.ServiceListener() {
public void onServiceConnected(int profile, BluetoothProfile proxy) {
- mBluetoothHeadset = (BluetoothHeadset) proxy;
- }
+ if (profile == BluetoothProfile.HEADSET) {
+ mBluetoothHeadset = (BluetoothHeadset) proxy;
+ } else if (profile == BluetoothProfile.INPUT_DEVICE) {
+ mInputDevice = (BluetoothInputDevice) proxy;
+ }
+ }
public void onServiceDisconnected(int profile) {
- mBluetoothHeadset = null;
+ if (profile == BluetoothProfile.HEADSET) {
+ mBluetoothHeadset = null;
+ } else if (profile == BluetoothProfile.INPUT_DEVICE) {
+ mInputDevice = null;
+ }
}
};
@@ -2311,9 +2360,9 @@
return mBluetoothInputProfileHandler.disconnectInputDeviceInternal(device);
}
- public synchronized int getInputDeviceState(BluetoothDevice device) {
+ public synchronized int getInputDeviceConnectionState(BluetoothDevice device) {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
- return mBluetoothInputProfileHandler.getInputDeviceState(device);
+ return mBluetoothInputProfileHandler.getInputDeviceConnectionState(device);
}
@@ -2322,6 +2371,13 @@
return mBluetoothInputProfileHandler.getConnectedInputDevices();
}
+ public synchronized List<BluetoothDevice> getInputDevicesMatchingConnectionStates(
+ int[] states) {
+ mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
+ return mBluetoothInputProfileHandler.getInputDevicesMatchingConnectionStates(states);
+ }
+
+
public synchronized int getInputDevicePriority(BluetoothDevice device) {
mContext.enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission");
return mBluetoothInputProfileHandler.getInputDevicePriority(device);
diff --git a/core/java/android/util/AttributeSet.java b/core/java/android/util/AttributeSet.java
index 82592b9..470526c 100644
--- a/core/java/android/util/AttributeSet.java
+++ b/core/java/android/util/AttributeSet.java
@@ -56,10 +56,53 @@
* identifier associated with a particular XML attribute name.
*/
public interface AttributeSet {
+ /**
+ * Returns the number of attributes available in the set.
+ *
+ * @return A positive integer, or 0 if the set is empty.
+ */
public int getAttributeCount();
+
+ /**
+ * Returns the name of the specified attribute.
+ *
+ * @param index Index of the desired attribute, 0...count-1.
+ *
+ * @return A String containing the name of the attribute, or null if the
+ * attribute cannot be found.
+ */
public String getAttributeName(int index);
+
+ /**
+ * Returns the value of the specified attribute as a string representation.
+ *
+ * @param index Index of the desired attribute, 0...count-1.
+ *
+ * @return A String containing the value of the attribute, or null if the
+ * attribute cannot be found.
+ */
public String getAttributeValue(int index);
+
+ /**
+ * Returns the value of the specified attribute as a string representation.
+ * The lookup is performed using the attribute name.
+ *
+ * @param namespace The namespace of the attribute to get the value from.
+ * @param name The name of the attribute to get the value from.
+ *
+ * @return A String containing the value of the attribute, or null if the
+ * attribute cannot be found.
+ */
public String getAttributeValue(String namespace, String name);
+
+ /**
+ * Returns a description of the current position of the attribute set.
+ * For instance, if the attribute set is loaded from an XML document,
+ * the position description could indicate the current line number.
+ *
+ * @return A string representation of the current position in the set,
+ * may be null.
+ */
public String getPositionDescription();
/**
@@ -80,7 +123,8 @@
/**
* Return the index of the value of 'attribute' in the list 'options'.
- *
+ *
+ * @param namespace Namespace of attribute to retrieve.
* @param attribute Name of attribute to retrieve.
* @param options List of strings whose values we are checking against.
* @param defaultValue Value returned if attribute doesn't exist or no
@@ -94,6 +138,7 @@
/**
* Return the boolean value of 'attribute'.
*
+ * @param namespace Namespace of attribute to retrieve.
* @param attribute The attribute to retrieve.
* @param defaultValue What to return if the attribute isn't found.
*
@@ -111,6 +156,7 @@
* "@package:type/resource"); the other method returns a resource
* identifier that identifies the name of the attribute.
*
+ * @param namespace Namespace of attribute to retrieve.
* @param attribute The attribute to retrieve.
* @param defaultValue What to return if the attribute isn't found.
*
@@ -122,6 +168,7 @@
/**
* Return the integer value of 'attribute'.
*
+ * @param namespace Namespace of attribute to retrieve.
* @param attribute The attribute to retrieve.
* @param defaultValue What to return if the attribute isn't found.
*
@@ -135,6 +182,7 @@
* unsigned value. In particular, the formats 0xn...n and #n...n are
* handled.
*
+ * @param namespace Namespace of attribute to retrieve.
* @param attribute The attribute to retrieve.
* @param defaultValue What to return if the attribute isn't found.
*
@@ -146,6 +194,7 @@
/**
* Return the float value of 'attribute'.
*
+ * @param namespace Namespace of attribute to retrieve.
* @param attribute The attribute to retrieve.
* @param defaultValue What to return if the attribute isn't found.
*
@@ -165,8 +214,7 @@
*
* @return Index in to 'options' or defaultValue.
*/
- public int getAttributeListValue(int index,
- String[] options, int defaultValue);
+ public int getAttributeListValue(int index, String[] options, int defaultValue);
/**
* Return the boolean value of attribute at 'index'.
@@ -176,8 +224,7 @@
*
* @return Resulting value.
*/
- public boolean getAttributeBooleanValue(int index,
- boolean defaultValue);
+ public boolean getAttributeBooleanValue(int index, boolean defaultValue);
/**
* Return the value of attribute at 'index' as a resource identifier.
@@ -193,8 +240,7 @@
*
* @return Resulting value.
*/
- public int getAttributeResourceValue(int index,
- int defaultValue);
+ public int getAttributeResourceValue(int index, int defaultValue);
/**
* Return the integer value of attribute at 'index'.
@@ -204,8 +250,7 @@
*
* @return Resulting value.
*/
- public int getAttributeIntValue(int index,
- int defaultValue);
+ public int getAttributeIntValue(int index, int defaultValue);
/**
* Return the integer value of attribute at 'index' that is formatted as an
@@ -217,8 +262,7 @@
*
* @return Resulting value.
*/
- public int getAttributeUnsignedIntValue(int index,
- int defaultValue);
+ public int getAttributeUnsignedIntValue(int index, int defaultValue);
/**
* Return the float value of attribute at 'index'.
@@ -228,8 +272,7 @@
*
* @return Resulting value.
*/
- public float getAttributeFloatValue(int index,
- float defaultValue);
+ public float getAttributeFloatValue(int index, float defaultValue);
/**
* Return the value of the "id" attribute or null if there is not one.
@@ -266,4 +309,3 @@
*/
public int getStyleAttribute();
}
-
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 51653df..dd8242a 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -100,6 +100,8 @@
void disableKeyguard(IBinder token, String tag);
void reenableKeyguard(IBinder token);
void exitKeyguardSecurely(IOnKeyguardExitResult callback);
+ boolean isKeyguardLocked();
+ boolean isKeyguardSecure();
boolean inKeyguardRestrictedInputMode();
void closeSystemDialogs(String reason);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index eefce06..ae06888 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -6665,7 +6665,14 @@
* view specifying how it should be arranged. There are many subclasses of
* ViewGroup.LayoutParams, and these correspond to the different subclasses
* of ViewGroup that are responsible for arranging their children.
- * @return The LayoutParams associated with this view
+ *
+ * This method may return null if this View is not attached to a parent
+ * ViewGroup or {@link #setLayoutParams(android.view.ViewGroup.LayoutParams)}
+ * was not invoked successfully. When a View is attached to a parent
+ * ViewGroup, this method must not return null.
+ *
+ * @return The LayoutParams associated with this view, or null if no
+ * parameters have been set yet
*/
@ViewDebug.ExportedProperty(deepExport = true, prefix = "layout_")
public ViewGroup.LayoutParams getLayoutParams() {
@@ -6679,11 +6686,11 @@
* correspond to the different subclasses of ViewGroup that are responsible
* for arranging their children.
*
- * @param params the layout parameters for this view
+ * @param params The layout parameters for this view, cannot be null
*/
public void setLayoutParams(ViewGroup.LayoutParams params) {
if (params == null) {
- throw new NullPointerException("params == null");
+ throw new NullPointerException("Layout parameters cannot be null");
}
mLayoutParams = params;
requestLayout();
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index ad06902..be68cb9 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -754,6 +754,24 @@
void exitKeyguardSecurely(OnKeyguardExitResult callback);
/**
+ * isKeyguardLocked
+ *
+ * Return whether the keyguard is currently locked.
+ *
+ * @return true if in keyguard is locked.
+ */
+ public boolean isKeyguardLocked();
+
+ /**
+ * isKeyguardSecure
+ *
+ * Return whether the keyguard requires a password to unlock.
+ *
+ * @return true if in keyguard is secure.
+ */
+ public boolean isKeyguardSecure();
+
+ /**
* inKeyguardRestrictedKeyInputMode
*
* if keyguard screen is showing or in restricted key input mode (i.e. in
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 74e6628..d9f050b 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -5531,6 +5531,8 @@
ted.mPoints[0] = new Point(contentX, contentY);
ted.mMetaState = ev.getMetaState();
ted.mReprocess = mDeferTouchProcess;
+ ted.mNativeLayer = nativeScrollableLayer(
+ contentX, contentY, ted.mNativeLayerRect, null);
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
if (mDeferTouchProcess) {
// still needs to set them for compute deltaX/Y
@@ -5575,6 +5577,8 @@
ted.mPoints[0] = new Point(contentX, contentY);
ted.mMetaState = ev.getMetaState();
ted.mReprocess = mDeferTouchProcess;
+ ted.mNativeLayer = mScrollingLayer;
+ ted.mNativeLayerRect.set(mScrollingLayerRect);
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
mLastSentTouchTime = eventTime;
if (mDeferTouchProcess) {
@@ -5754,6 +5758,8 @@
ted.mPoints[0] = new Point(contentX, contentY);
ted.mMetaState = ev.getMetaState();
ted.mReprocess = mDeferTouchProcess;
+ ted.mNativeLayer = mScrollingLayer;
+ ted.mNativeLayerRect.set(mScrollingLayerRect);
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
}
mLastTouchUpTime = eventTime;
@@ -5773,6 +5779,9 @@
ted.mPoints[0] = new Point(contentX, contentY);
ted.mMetaState = ev.getMetaState();
ted.mReprocess = mDeferTouchProcess;
+ ted.mNativeLayer = nativeScrollableLayer(
+ contentX, contentY,
+ ted.mNativeLayerRect, null);
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
} else if (mPreventDefault != PREVENT_DEFAULT_YES){
mZoomManager.handleDoubleTap(mLastTouchX, mLastTouchY);
@@ -6004,6 +6013,8 @@
ted.mPoints = new Point[1];
ted.mPoints[0] = new Point(x, y);
ted.mAction = MotionEvent.ACTION_CANCEL;
+ ted.mNativeLayer = nativeScrollableLayer(
+ x, y, ted.mNativeLayerRect, null);
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
mPreventDefault = PREVENT_DEFAULT_IGNORE;
}
@@ -6643,8 +6654,9 @@
// mLastTouchX and mLastTouchY are the point in the current viewport
int contentX = viewToContentX(mLastTouchX + mScrollX);
int contentY = viewToContentY(mLastTouchY + mScrollY);
- Rect rect = new Rect(contentX - mNavSlop, contentY - mNavSlop,
- contentX + mNavSlop, contentY + mNavSlop);
+ int slop = viewToContentDimension(mNavSlop);
+ Rect rect = new Rect(contentX - slop, contentY - slop,
+ contentX + slop, contentY + slop);
nativeSelectBestAt(rect);
mInitialHitTestResult = hitTestResult(null);
}
@@ -6718,7 +6730,8 @@
}
int x = viewToContentX((int) event.getX() + mWebTextView.getLeft());
int y = viewToContentY((int) event.getY() + mWebTextView.getTop());
- nativeMotionUp(x, y, mNavSlop);
+ int slop = viewToContentDimension(mNavSlop);
+ nativeMotionUp(x, y, slop);
}
/**
@@ -6741,6 +6754,7 @@
// mLastTouchX and mLastTouchY are the point in the current viewport
int contentX = viewToContentX(mLastTouchX + mScrollX);
int contentY = viewToContentY(mLastTouchY + mScrollY);
+ int slop = viewToContentDimension(mNavSlop);
if (getSettings().supportTouchOnly()) {
removeTouchHighlight(false);
WebViewCore.TouchUpData touchUpData = new WebViewCore.TouchUpData();
@@ -6748,7 +6762,7 @@
// it used when processing GET_TOUCH_HIGHLIGHT_RECTS
touchUpData.mMoveGeneration = 0;
mWebViewCore.sendMessage(EventHub.TOUCH_UP, touchUpData);
- } else if (nativePointInNavCache(contentX, contentY, mNavSlop)) {
+ } else if (nativePointInNavCache(contentX, contentY, slop)) {
WebViewCore.MotionUpData motionUpData = new WebViewCore
.MotionUpData();
motionUpData.mFrame = nativeCacheHitFramePointer();
@@ -6764,7 +6778,8 @@
}
private void doMotionUp(int contentX, int contentY) {
- if (nativeMotionUp(contentX, contentY, mNavSlop) && mLogEvent) {
+ int slop = viewToContentDimension(mNavSlop);
+ if (nativeMotionUp(contentX, contentY, slop) && mLogEvent) {
EventLog.writeEvent(EventLogTags.BROWSER_SNAP_CENTER);
}
if (nativeHasCursorNode() && !nativeCursorIsTextInput()) {
@@ -6777,7 +6792,8 @@
* plugin. Otherwise a NULL rectangle is returned.
*/
Rect getPluginBounds(int x, int y) {
- if (nativePointInNavCache(x, y, mNavSlop) && nativeCacheHitIsPlugin()) {
+ int slop = viewToContentDimension(mNavSlop);
+ if (nativePointInNavCache(x, y, slop) && nativeCacheHitIsPlugin()) {
return nativeCacheHitNodeBounds();
} else {
return null;
@@ -7161,6 +7177,9 @@
// simplicity for now, we don't set it.
ted.mMetaState = 0;
ted.mReprocess = mDeferTouchProcess;
+ ted.mNativeLayer = nativeScrollableLayer(
+ ted.mPoints[0].x, ted.mPoints[0].y,
+ ted.mNativeLayerRect, null);
mWebViewCore.sendMessage(EventHub.TOUCH_EVENT, ted);
} else if (mPreventDefault != PREVENT_DEFAULT_YES) {
mTouchMode = TOUCH_DONE_MODE;
@@ -8033,6 +8052,8 @@
touchUpData.mNode = node;
touchUpData.mX = x;
touchUpData.mY = y;
+ touchUpData.mNativeLayer = nativeScrollableLayer(
+ x, y, touchUpData.mNativeLayerRect, null);
mWebViewCore.sendMessage(EventHub.TOUCH_UP, touchUpData);
}
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index da4ce43..fb0f61c 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -778,6 +778,8 @@
int mNode;
int mX;
int mY;
+ int mNativeLayer;
+ Rect mNativeLayerRect = new Rect();
}
static class TouchHighlightData {
@@ -821,6 +823,8 @@
int mMetaState;
boolean mReprocess;
MotionEvent mMotionEvent;
+ int mNativeLayer;
+ Rect mNativeLayerRect = new Rect();
}
static class GeolocationPermissionsData {
@@ -1304,6 +1308,10 @@
case TOUCH_UP:
TouchUpData touchUpData = (TouchUpData) msg.obj;
+ if (touchUpData.mNativeLayer != 0) {
+ nativeScrollLayer(touchUpData.mNativeLayer,
+ touchUpData.mNativeLayerRect);
+ }
nativeTouchUp(touchUpData.mMoveGeneration,
touchUpData.mFrame, touchUpData.mNode,
touchUpData.mX, touchUpData.mY);
@@ -1318,6 +1326,10 @@
xArray[c] = ted.mPoints[c].x;
yArray[c] = ted.mPoints[c].y;
}
+ if (ted.mNativeLayer != 0) {
+ nativeScrollLayer(ted.mNativeLayer,
+ ted.mNativeLayerRect);
+ }
Message.obtain(
mWebView.mPrivateHandler,
WebView.PREVENT_TOUCH_ID,
@@ -2702,4 +2714,5 @@
int slop);
private native void nativeAutoFillForm(int queryId);
+ private native void nativeScrollLayer(int layer, Rect rect);
}
diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java
index a84df16..0383b5c 100644
--- a/core/java/android/widget/GridView.java
+++ b/core/java/android/widget/GridView.java
@@ -37,14 +37,46 @@
*
* <p>See the <a href="{@docRoot}resources/tutorials/views/hello-gridview.html">Grid
* View tutorial</a>.</p>
+ *
+ * @attr ref android.R.styleable#GridView_horizontalSpacing
+ * @attr ref android.R.styleable#GridView_verticalSpacing
+ * @attr ref android.R.styleable#GridView_stretchMode
+ * @attr ref android.R.styleable#GridView_columnWidth
+ * @attr ref android.R.styleable#GridView_numColumns
+ * @attr ref android.R.styleable#GridView_gravity
*/
@RemoteView
public class GridView extends AbsListView {
+ /**
+ * Disables stretching.
+ *
+ * @see #setStretchMode(int)
+ */
public static final int NO_STRETCH = 0;
+ /**
+ * Stretches the spacing between columns.
+ *
+ * @see #setStretchMode(int)
+ */
public static final int STRETCH_SPACING = 1;
+ /**
+ * Stretches columns.
+ *
+ * @see #setStretchMode(int)
+ */
public static final int STRETCH_COLUMN_WIDTH = 2;
+ /**
+ * Stretches the spacing between columns. The spacing is uniform.
+ *
+ * @see #setStretchMode(int)
+ */
public static final int STRETCH_SPACING_UNIFORM = 3;
-
+
+ /**
+ * Creates as many columns as can fit on screen.
+ *
+ * @see #setNumColumns(int)
+ */
public static final int AUTO_FIT = -1;
private int mNumColumns = AUTO_FIT;
diff --git a/core/jni/android_bluetooth_BluetoothAudioGateway.cpp b/core/jni/android_bluetooth_BluetoothAudioGateway.cpp
index bf23650..acf858a 100755
--- a/core/jni/android_bluetooth_BluetoothAudioGateway.cpp
+++ b/core/jni/android_bluetooth_BluetoothAudioGateway.cpp
@@ -89,40 +89,40 @@
#endif
static void classInitNative(JNIEnv* env, jclass clazz) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
/* in */
field_mNativeData = get_field(env, clazz, "mNativeData", "I");
- field_mHandsfreeAgRfcommChannel =
+ field_mHandsfreeAgRfcommChannel =
get_field(env, clazz, "mHandsfreeAgRfcommChannel", "I");
- field_mHeadsetAgRfcommChannel =
+ field_mHeadsetAgRfcommChannel =
get_field(env, clazz, "mHeadsetAgRfcommChannel", "I");
/* out */
- field_mConnectingHeadsetAddress =
- get_field(env, clazz,
+ field_mConnectingHeadsetAddress =
+ get_field(env, clazz,
"mConnectingHeadsetAddress", "Ljava/lang/String;");
- field_mConnectingHeadsetRfcommChannel =
+ field_mConnectingHeadsetRfcommChannel =
get_field(env, clazz, "mConnectingHeadsetRfcommChannel", "I");
- field_mConnectingHeadsetSocketFd =
+ field_mConnectingHeadsetSocketFd =
get_field(env, clazz, "mConnectingHeadsetSocketFd", "I");
- field_mConnectingHandsfreeAddress =
- get_field(env, clazz,
+ field_mConnectingHandsfreeAddress =
+ get_field(env, clazz,
"mConnectingHandsfreeAddress", "Ljava/lang/String;");
- field_mConnectingHandsfreeRfcommChannel =
+ field_mConnectingHandsfreeRfcommChannel =
get_field(env, clazz, "mConnectingHandsfreeRfcommChannel", "I");
- field_mConnectingHandsfreeSocketFd =
+ field_mConnectingHandsfreeSocketFd =
get_field(env, clazz, "mConnectingHandsfreeSocketFd", "I");
- field_mTimeoutRemainingMs =
+ field_mTimeoutRemainingMs =
get_field(env, clazz, "mTimeoutRemainingMs", "I");
#endif
}
static void initializeNativeDataNative(JNIEnv* env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = (native_data_t *)calloc(1, sizeof(native_data_t));
if (NULL == nat) {
@@ -150,7 +150,7 @@
}
static void cleanupNativeDataNative(JNIEnv* env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
if (nat) {
@@ -165,7 +165,7 @@
static int set_nb(int sk, bool nb) {
int flags = fcntl(sk, F_GETFL);
if (flags < 0) {
- LOGE("Can't get socket flags with fcntl(): %s (%d)",
+ LOGE("Can't get socket flags with fcntl(): %s (%d)",
strerror(errno), errno);
close(sk);
return -1;
@@ -255,7 +255,7 @@
static jboolean waitForHandsfreeConnectNative(JNIEnv* env, jobject object,
jint timeout_ms) {
-// LOGV(__FUNCTION__);
+// LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
env->SetIntField(object, field_mTimeoutRemainingMs, timeout_ms);
@@ -264,11 +264,11 @@
native_data_t *nat = get_native_data(env, object);
#if USE_ACCEPT_DIRECTLY
if (nat->hf_ag_rfcomm_channel > 0) {
- LOGI("Setting HF AG server socket to RFCOMM port %d!",
+ LOGI("Setting HF AG server socket to RFCOMM port %d!",
nat->hf_ag_rfcomm_channel);
struct timeval tv;
int len = sizeof(tv);
- if (getsockopt(nat->hf_ag_rfcomm_channel,
+ if (getsockopt(nat->hf_ag_rfcomm_channel,
SOL_SOCKET, SO_RCVTIMEO, &tv, &len) < 0) {
LOGE("getsockopt(%d, SOL_SOCKET, SO_RCVTIMEO): %s (%d)",
nat->hf_ag_rfcomm_channel,
@@ -276,12 +276,12 @@
errno);
return JNI_FALSE;
}
- LOGI("Current HF AG server socket RCVTIMEO is (%d(s), %d(us))!",
+ LOGI("Current HF AG server socket RCVTIMEO is (%d(s), %d(us))!",
(int)tv.tv_sec, (int)tv.tv_usec);
if (timeout_ms >= 0) {
tv.tv_sec = timeout_ms / 1000;
tv.tv_usec = 1000 * (timeout_ms % 1000);
- if (setsockopt(nat->hf_ag_rfcomm_channel,
+ if (setsockopt(nat->hf_ag_rfcomm_channel,
SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
LOGE("setsockopt(%d, SOL_SOCKET, SO_RCVTIMEO): %s (%d)",
nat->hf_ag_rfcomm_channel,
@@ -289,11 +289,11 @@
errno);
return JNI_FALSE;
}
- LOGI("Changed HF AG server socket RCVTIMEO to (%d(s), %d(us))!",
+ LOGI("Changed HF AG server socket RCVTIMEO to (%d(s), %d(us))!",
(int)tv.tv_sec, (int)tv.tv_usec);
}
- if (!do_accept(env, object, nat->hf_ag_rfcomm_sock,
+ if (!do_accept(env, object, nat->hf_ag_rfcomm_sock,
field_mConnectingHandsfreeSocketFd,
field_mConnectingHandsfreeAddress,
field_mConnectingHandsfreeRfcommChannel))
@@ -309,13 +309,13 @@
FD_ZERO(&rset);
int cnt = 0;
if (nat->hf_ag_rfcomm_channel > 0) {
- LOGI("Setting HF AG server socket to RFCOMM port %d!",
+ LOGI("Setting HF AG server socket to RFCOMM port %d!",
nat->hf_ag_rfcomm_channel);
cnt++;
FD_SET(nat->hf_ag_rfcomm_sock, &rset);
}
if (nat->hs_ag_rfcomm_channel > 0) {
- LOGI("Setting HS AG server socket to RFCOMM port %d!",
+ LOGI("Setting HS AG server socket to RFCOMM port %d!",
nat->hs_ag_rfcomm_channel);
cnt++;
FD_SET(nat->hs_ag_rfcomm_sock, &rset);
@@ -330,7 +330,7 @@
to.tv_sec = timeout_ms / 1000;
to.tv_usec = 1000 * (timeout_ms % 1000);
}
- n = select(MAX(nat->hf_ag_rfcomm_sock,
+ n = select(MAX(nat->hf_ag_rfcomm_sock,
nat->hs_ag_rfcomm_sock) + 1,
&rset,
NULL,
@@ -354,7 +354,7 @@
return JNI_FALSE;
}
- n = on_accept_set_fields(env, object,
+ n = on_accept_set_fields(env, object,
&rset, nat->hf_ag_rfcomm_sock,
field_mConnectingHandsfreeSocketFd,
field_mConnectingHandsfreeAddress,
@@ -371,7 +371,7 @@
struct pollfd fds[2];
int cnt = 0;
if (nat->hf_ag_rfcomm_channel > 0) {
-// LOGI("Setting HF AG server socket %d to RFCOMM port %d!",
+// LOGI("Setting HF AG server socket %d to RFCOMM port %d!",
// nat->hf_ag_rfcomm_sock,
// nat->hf_ag_rfcomm_channel);
fds[cnt].fd = nat->hf_ag_rfcomm_sock;
@@ -379,7 +379,7 @@
cnt++;
}
if (nat->hs_ag_rfcomm_channel > 0) {
-// LOGI("Setting HS AG server socket %d to RFCOMM port %d!",
+// LOGI("Setting HS AG server socket %d to RFCOMM port %d!",
// nat->hs_ag_rfcomm_sock,
// nat->hs_ag_rfcomm_channel);
fds[cnt].fd = nat->hs_ag_rfcomm_sock;
@@ -411,7 +411,7 @@
if (fds[cnt].fd == nat->hf_ag_rfcomm_sock) {
if (fds[cnt].revents & (POLLIN | POLLPRI | POLLOUT)) {
LOGI("Accepting HF connection.\n");
- err += do_accept(env, object, fds[cnt].fd,
+ err += do_accept(env, object, fds[cnt].fd,
field_mConnectingHandsfreeSocketFd,
field_mConnectingHandsfreeAddress,
field_mConnectingHandsfreeRfcommChannel);
@@ -421,7 +421,7 @@
else if (fds[cnt].fd == nat->hs_ag_rfcomm_sock) {
if (fds[cnt].revents & (POLLIN | POLLPRI | POLLOUT)) {
LOGI("Accepting HS connection.\n");
- err += do_accept(env, object, fds[cnt].fd,
+ err += do_accept(env, object, fds[cnt].fd,
field_mConnectingHeadsetSocketFd,
field_mConnectingHeadsetAddress,
field_mConnectingHeadsetRfcommChannel);
@@ -444,7 +444,7 @@
}
static jboolean setUpListeningSocketsNative(JNIEnv* env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
@@ -509,7 +509,7 @@
private native void tearDownListeningSocketsNative();
*/
static void tearDownListeningSocketsNative(JNIEnv *env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
diff --git a/core/jni/android_bluetooth_BluetoothSocket.cpp b/core/jni/android_bluetooth_BluetoothSocket.cpp
index 31ebf8c..b87f7c4 100644
--- a/core/jni/android_bluetooth_BluetoothSocket.cpp
+++ b/core/jni/android_bluetooth_BluetoothSocket.cpp
@@ -66,7 +66,7 @@
static void initSocketFromFdNative(JNIEnv *env, jobject obj, jint fd) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
struct asocket *s = asocket_init(fd);
@@ -85,7 +85,7 @@
static void initSocketNative(JNIEnv *env, jobject obj) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
int fd;
int lm = 0;
@@ -161,7 +161,7 @@
static void connectNative(JNIEnv *env, jobject obj) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
int ret;
jint type;
@@ -240,7 +240,7 @@
/* Returns errno instead of throwing, so java can check errno */
static int bindListenNative(JNIEnv *env, jobject obj) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
jint type;
socklen_t addr_sz;
@@ -307,7 +307,7 @@
static jobject acceptNative(JNIEnv *env, jobject obj, int timeout) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
int fd;
jint type;
@@ -380,7 +380,7 @@
static jint availableNative(JNIEnv *env, jobject obj) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
int available;
struct asocket *s = get_socketData(env, obj);
@@ -403,7 +403,7 @@
static jint readNative(JNIEnv *env, jobject obj, jbyteArray jb, jint offset,
jint length) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
int ret;
jbyte *b;
@@ -446,7 +446,7 @@
static jint writeNative(JNIEnv *env, jobject obj, jbyteArray jb, jint offset,
jint length) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
int ret;
jbyte *b;
@@ -488,7 +488,7 @@
static void abortNative(JNIEnv *env, jobject obj) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
struct asocket *s = get_socketData(env, obj);
if (!s)
@@ -504,7 +504,7 @@
static void destroyNative(JNIEnv *env, jobject obj) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
struct asocket *s = get_socketData(env, obj);
int fd = s->fd;
diff --git a/core/jni/android_bluetooth_HeadsetBase.cpp b/core/jni/android_bluetooth_HeadsetBase.cpp
index 4e9fbaf..bbf1ae5 100644
--- a/core/jni/android_bluetooth_HeadsetBase.cpp
+++ b/core/jni/android_bluetooth_HeadsetBase.cpp
@@ -180,7 +180,7 @@
#endif
static void classInitNative(JNIEnv* env, jclass clazz) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
field_mNativeData = get_field(env, clazz, "mNativeData", "I");
field_mAddress = get_field(env, clazz, "mAddress", "Ljava/lang/String;");
@@ -191,7 +191,7 @@
static void initializeNativeDataNative(JNIEnv* env, jobject object,
jint socketFd) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = (native_data_t *)calloc(1, sizeof(native_data_t));
if (NULL == nat) {
@@ -213,7 +213,7 @@
}
static void cleanupNativeDataNative(JNIEnv* env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat =
(native_data_t *)env->GetIntField(object, field_mNativeData);
@@ -226,7 +226,7 @@
static jboolean connectNative(JNIEnv *env, jobject obj)
{
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
int lm;
struct sockaddr_rc addr;
@@ -278,7 +278,7 @@
}
static jint connectAsyncNative(JNIEnv *env, jobject obj) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
struct sockaddr_rc addr;
native_data_t *nat = get_native_data(env, obj);
@@ -357,7 +357,7 @@
static jint waitForAsyncConnectNative(JNIEnv *env, jobject obj,
jint timeout_ms) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
struct sockaddr_rc addr;
native_data_t *nat = get_native_data(env, obj);
@@ -463,7 +463,7 @@
}
static void disconnectNative(JNIEnv *env, jobject obj) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, obj);
if (nat->rfcomm_sock >= 0) {
diff --git a/core/jni/android_server_BluetoothA2dpService.cpp b/core/jni/android_server_BluetoothA2dpService.cpp
index 8c795af..1851ad6 100644
--- a/core/jni/android_server_BluetoothA2dpService.cpp
+++ b/core/jni/android_server_BluetoothA2dpService.cpp
@@ -61,7 +61,7 @@
* Return false if dbus is down, or another serious error (out of memory)
*/
static bool initNative(JNIEnv* env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
nat = (native_data_t *)calloc(1, sizeof(native_data_t));
if (NULL == nat) {
@@ -88,7 +88,7 @@
static void cleanupNative(JNIEnv* env, jobject object) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
if (nat) {
dbus_connection_close(nat->conn);
env->DeleteGlobalRef(nat->me);
@@ -101,7 +101,7 @@
static jobjectArray getSinkPropertiesNative(JNIEnv *env, jobject object,
jstring path) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
if (nat) {
DBusMessage *msg, *reply;
DBusError err;
@@ -132,7 +132,7 @@
static jboolean connectSinkNative(JNIEnv *env, jobject object, jstring path) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
if (nat) {
const char *c_path = env->GetStringUTFChars(path, NULL);
int len = env->GetStringLength(path) + 1;
@@ -153,7 +153,7 @@
static jboolean disconnectSinkNative(JNIEnv *env, jobject object,
jstring path) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
if (nat) {
const char *c_path = env->GetStringUTFChars(path, NULL);
@@ -171,7 +171,7 @@
static jboolean suspendSinkNative(JNIEnv *env, jobject object,
jstring path) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
if (nat) {
const char *c_path = env->GetStringUTFChars(path, NULL);
bool ret = dbus_func_args_async(env, nat->conn, -1, NULL, NULL, nat,
@@ -187,7 +187,7 @@
static jboolean resumeSinkNative(JNIEnv *env, jobject object,
jstring path) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
if (nat) {
const char *c_path = env->GetStringUTFChars(path, NULL);
bool ret = dbus_func_args_async(env, nat->conn, -1, NULL, NULL, nat,
@@ -203,7 +203,7 @@
static jboolean avrcpVolumeUpNative(JNIEnv *env, jobject object,
jstring path) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
if (nat) {
const char *c_path = env->GetStringUTFChars(path, NULL);
bool ret = dbus_func_args_async(env, nat->conn, -1, NULL, NULL, nat,
@@ -219,7 +219,7 @@
static jboolean avrcpVolumeDownNative(JNIEnv *env, jobject object,
jstring path) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
if (nat) {
const char *c_path = env->GetStringUTFChars(path, NULL);
bool ret = dbus_func_args_async(env, nat->conn, -1, NULL, NULL, nat,
@@ -278,7 +278,7 @@
}
void onConnectSinkResult(DBusMessage *msg, void *user, void *n) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = (native_data_t *)n;
const char *path = (const char *)user;
diff --git a/core/jni/android_server_BluetoothEventLoop.cpp b/core/jni/android_server_BluetoothEventLoop.cpp
index fd12c2d7..afaade8 100644
--- a/core/jni/android_server_BluetoothEventLoop.cpp
+++ b/core/jni/android_server_BluetoothEventLoop.cpp
@@ -88,7 +88,7 @@
#endif
static void classInitNative(JNIEnv* env, jclass clazz) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
method_onPropertyChanged = env->GetMethodID(clazz, "onPropertyChanged",
@@ -147,7 +147,7 @@
}
static void initializeNativeDataNative(JNIEnv* env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = (native_data_t *)calloc(1, sizeof(native_data_t));
if (NULL == nat) {
@@ -175,7 +175,7 @@
}
static void cleanupNativeDataNative(JNIEnv* env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat =
(native_data_t *)env->GetIntField(object, field_mNativeData);
@@ -216,7 +216,7 @@
}
static jboolean setUpEventLoop(native_data_t *nat) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
if (nat != NULL && nat->conn != NULL) {
dbus_threads_init_default();
@@ -395,7 +395,7 @@
}
static void tearDownEventLoop(native_data_t *nat) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
if (nat != NULL && nat->conn != NULL) {
DBusMessage *msg, *reply;
@@ -1229,7 +1229,7 @@
#ifdef HAVE_BLUETOOTH
void onCreatePairedDeviceResult(DBusMessage *msg, void *user, void *n) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = (native_data_t *)n;
const char *address = (const char *)user;
@@ -1298,7 +1298,7 @@
}
void onCreateDeviceResult(DBusMessage *msg, void *user, void *n) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = (native_data_t *)n;
const char *address= (const char *)user;
@@ -1328,7 +1328,7 @@
}
void onDiscoverServicesResult(DBusMessage *msg, void *user, void *n) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = (native_data_t *)n;
const char *path = (const char *)user;
@@ -1354,7 +1354,7 @@
}
void onGetDeviceServiceChannelResult(DBusMessage *msg, void *user, void *n) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
const char *address = (const char *) user;
native_data_t *nat = (native_data_t *) n;
@@ -1387,7 +1387,7 @@
}
void onInputDeviceConnectionResult(DBusMessage *msg, void *user, void *n) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = (native_data_t *)n;
const char *path = (const char *)user;
@@ -1426,7 +1426,7 @@
}
void onPanDeviceConnectionResult(DBusMessage *msg, void *user, void *n) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = (native_data_t *)n;
const char *path = (const char *)user;
diff --git a/core/jni/android_server_BluetoothService.cpp b/core/jni/android_server_BluetoothService.cpp
index bf0504f..158e475 100644
--- a/core/jni/android_server_BluetoothService.cpp
+++ b/core/jni/android_server_BluetoothService.cpp
@@ -1,16 +1,16 @@
/*
** Copyright 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
+** 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
+** 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
+** 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.
*/
@@ -93,7 +93,7 @@
#endif
static void classInitNative(JNIEnv* env, jclass clazz) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
field_mNativeData = get_field(env, clazz, "mNativeData", "I");
field_mEventLoop = get_field(env, clazz, "mEventLoop",
@@ -105,7 +105,7 @@
* Return false if dbus is down, or another serious error (out of memory)
*/
static bool initializeNativeDataNative(JNIEnv* env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = (native_data_t *)calloc(1, sizeof(native_data_t));
if (NULL == nat) {
@@ -144,7 +144,7 @@
// This function is called when the adapter is enabled.
static jboolean setupNativeDataNative(JNIEnv* env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat =
(native_data_t *)env->GetIntField(object, field_mNativeData);
@@ -167,7 +167,7 @@
}
static jboolean tearDownNativeDataNative(JNIEnv *env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat =
(native_data_t *)env->GetIntField(object, field_mNativeData);
@@ -181,7 +181,7 @@
}
static void cleanupNativeDataNative(JNIEnv* env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat =
(native_data_t *)env->GetIntField(object, field_mNativeData);
@@ -193,7 +193,7 @@
}
static jstring getAdapterPathNative(JNIEnv *env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
if (nat) {
@@ -205,7 +205,7 @@
static jboolean startDiscoveryNative(JNIEnv *env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
DBusMessage *msg = NULL;
DBusMessage *reply = NULL;
@@ -251,7 +251,7 @@
}
static void stopDiscoveryNative(JNIEnv *env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
DBusMessage *msg = NULL;
DBusMessage *reply = NULL;
@@ -297,7 +297,7 @@
}
static jbyteArray readAdapterOutOfBandDataNative(JNIEnv *env, jobject object) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
DBusError err;
@@ -338,7 +338,7 @@
static jboolean createPairedDeviceNative(JNIEnv *env, jobject object,
jstring address, jint timeout_ms) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
@@ -374,7 +374,7 @@
static jboolean createPairedDeviceOutOfBandNative(JNIEnv *env, jobject object,
jstring address, jint timeout_ms) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
@@ -411,7 +411,7 @@
jstring path,
jstring pattern, jint attr_id) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = get_native_data(env, object);
jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
struct event_loop_native_data_t *eventLoopNat =
@@ -437,7 +437,7 @@
static jboolean cancelDeviceCreationNative(JNIEnv *env, jobject object,
jstring address) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
jboolean result = JNI_FALSE;
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
@@ -469,7 +469,7 @@
}
static jboolean removeDeviceNative(JNIEnv *env, jobject object, jstring object_path) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
if (nat) {
@@ -492,7 +492,7 @@
static jint enableNative(JNIEnv *env, jobject object) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
return bt_enable();
#endif
return -1;
@@ -500,7 +500,7 @@
static jint disableNative(JNIEnv *env, jobject object) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
return bt_disable();
#endif
return -1;
@@ -508,7 +508,7 @@
static jint isEnabledNative(JNIEnv *env, jobject object) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
return bt_is_enabled();
#endif
return -1;
@@ -518,7 +518,7 @@
jstring address, bool confirm,
int nativeData) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = get_native_data(env, object);
if (nat) {
DBusMessage *msg = (DBusMessage *)nativeData;
@@ -549,7 +549,7 @@
static jboolean setPasskeyNative(JNIEnv *env, jobject object, jstring address,
int passkey, int nativeData) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = get_native_data(env, object);
if (nat) {
DBusMessage *msg = (DBusMessage *)nativeData;
@@ -576,7 +576,7 @@
static jboolean setRemoteOutOfBandDataNative(JNIEnv *env, jobject object, jstring address,
jbyteArray hash, jbyteArray randomizer, int nativeData) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = get_native_data(env, object);
if (nat) {
DBusMessage *msg = (DBusMessage *)nativeData;
@@ -610,7 +610,7 @@
static jboolean setPinNative(JNIEnv *env, jobject object, jstring address,
jstring pin, int nativeData) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = get_native_data(env, object);
if (nat) {
DBusMessage *msg = (DBusMessage *)nativeData;
@@ -640,7 +640,7 @@
static jboolean cancelPairingUserInputNative(JNIEnv *env, jobject object,
jstring address, int nativeData) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = get_native_data(env, object);
if (nat) {
DBusMessage *msg = (DBusMessage *)nativeData;
@@ -666,7 +666,7 @@
jstring path)
{
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = get_native_data(env, object);
if (nat) {
DBusMessage *msg, *reply;
@@ -705,7 +705,7 @@
static jobjectArray getAdapterPropertiesNative(JNIEnv *env, jobject object) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = get_native_data(env, object);
if (nat) {
DBusMessage *msg, *reply;
@@ -741,7 +741,7 @@
static jboolean setAdapterPropertyNative(JNIEnv *env, jobject object, jstring key,
void *value, jint type) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = get_native_data(env, object);
if (nat) {
DBusMessage *msg;
@@ -808,7 +808,7 @@
static jboolean setDevicePropertyNative(JNIEnv *env, jobject object, jstring path,
jstring key, void *value, jint type) {
#ifdef HAVE_BLUETOOTH
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
native_data_t *nat = get_native_data(env, object);
if (nat) {
DBusMessage *reply, *msg;
@@ -863,7 +863,7 @@
static jboolean createDeviceNative(JNIEnv *env, jobject object,
jstring address) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
@@ -894,7 +894,7 @@
static jboolean discoverServicesNative(JNIEnv *env, jobject object,
jstring path, jstring pattern) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
@@ -955,7 +955,7 @@
static jintArray addReservedServiceRecordsNative(JNIEnv *env, jobject object,
jintArray uuids) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
DBusMessage *reply = NULL;
@@ -979,7 +979,7 @@
static jboolean removeReservedServiceRecordsNative(JNIEnv *env, jobject object,
jintArray handles) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
jint *values = env->GetIntArrayElements(handles, NULL);
@@ -1002,7 +1002,7 @@
static jint addRfcommServiceRecordNative(JNIEnv *env, jobject object,
jstring name, jlong uuidMsb, jlong uuidLsb, jshort channel) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
if (nat) {
@@ -1027,7 +1027,7 @@
}
static jboolean removeServiceRecordNative(JNIEnv *env, jobject object, jint handle) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
if (nat) {
@@ -1045,7 +1045,7 @@
static jboolean setLinkTimeoutNative(JNIEnv *env, jobject object, jstring object_path,
jint num_slots) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
if (nat) {
@@ -1064,7 +1064,7 @@
}
static jboolean connectInputDeviceNative(JNIEnv *env, jobject object, jstring path) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
@@ -1092,7 +1092,7 @@
static jboolean disconnectInputDeviceNative(JNIEnv *env, jobject object,
jstring path) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
jobject eventLoop = env->GetObjectField(object, field_mEventLoop);
@@ -1120,7 +1120,7 @@
static jboolean setBluetoothTetheringNative(JNIEnv *env, jobject object, jboolean value,
jstring src_role, jstring bridge) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
native_data_t *nat = get_native_data(env, object);
if (nat) {
@@ -1155,7 +1155,7 @@
static jboolean connectPanDeviceNative(JNIEnv *env, jobject object, jstring path,
jstring dstRole) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
LOGE("connectPanDeviceNative");
native_data_t *nat = get_native_data(env, object);
@@ -1187,7 +1187,7 @@
static jboolean disconnectPanDeviceNative(JNIEnv *env, jobject object,
jstring path) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
LOGE("disconnectPanDeviceNative");
native_data_t *nat = get_native_data(env, object);
@@ -1217,7 +1217,7 @@
static jboolean disconnectPanServerDeviceNative(JNIEnv *env, jobject object,
jstring path, jstring address,
jstring iface) {
- LOGV(__FUNCTION__);
+ LOGV("%s", __FUNCTION__);
#ifdef HAVE_BLUETOOTH
LOGE("disconnectPanServerDeviceNative");
native_data_t *nat = get_native_data(env, object);
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 6f37dc0..d9eccd6 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2256,18 +2256,29 @@
<attr name="unselectedAlpha" format="float" />
</declare-styleable>
<declare-styleable name="GridView">
+ <!-- Defines the default horizontal spacing between columns. -->
<attr name="horizontalSpacing" format="dimension" />
+ <!-- Defines the default vertical spacing between rows. -->
<attr name="verticalSpacing" format="dimension" />
+ <!-- Defines how columns should stretch to fill the available empty space, if any. -->
<attr name="stretchMode">
+ <!-- Stretching is disabled. -->
<enum name="none" value="0"/>
+ <!-- The spacing between each column is stretched. -->
<enum name="spacingWidth" value="1" />
+ <!-- Each column is stretched equally. -->
<enum name="columnWidth" value="2" />
+ <!-- The spacing between each column is uniformly stretched.. -->
<enum name="spacingWidthUniform" value="3" />
</attr>
+ <!-- Specifies the fixed width for each column. -->
<attr name="columnWidth" format="dimension" />
+ <!-- Defines how many columns to show. -->
<attr name="numColumns" format="integer" min="0">
+ <!-- Display as many columns as possible to fill the available space. -->
<enum name="auto_fit" value="-1" />
</attr>
+ <!-- Specifies the gravity within each cell. -->
<attr name="gravity" />
</declare-styleable>
<declare-styleable name="ImageSwitcher">
diff --git a/core/tests/coretests/src/android/bluetooth/BluetoothStressTest.java b/core/tests/coretests/src/android/bluetooth/BluetoothStressTest.java
index 96b028a..672f252 100644
--- a/core/tests/coretests/src/android/bluetooth/BluetoothStressTest.java
+++ b/core/tests/coretests/src/android/bluetooth/BluetoothStressTest.java
@@ -250,8 +250,8 @@
for (int i = 0; i < iterations; i++) {
mTestUtils.writeOutput("connectInput iteration " + (i + 1) + " of " + iterations);
- mTestUtils.connectInput(adapter, device);
- mTestUtils.disconnectInput(adapter, device);
+ mTestUtils.connectProfile(adapter, device, BluetoothProfile.INPUT_DEVICE);
+ mTestUtils.disconnectProfile(adapter, device, BluetoothProfile.INPUT_DEVICE);
}
mTestUtils.unpair(adapter, device);
diff --git a/core/tests/coretests/src/android/bluetooth/BluetoothTestUtils.java b/core/tests/coretests/src/android/bluetooth/BluetoothTestUtils.java
index effed76..35210e5 100644
--- a/core/tests/coretests/src/android/bluetooth/BluetoothTestUtils.java
+++ b/core/tests/coretests/src/android/bluetooth/BluetoothTestUtils.java
@@ -238,6 +238,9 @@
case BluetoothProfile.HEADSET:
mConnectionAction = BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED;
break;
+ case BluetoothProfile.INPUT_DEVICE:
+ mConnectionAction = BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED;
+ break;
default:
mConnectionAction = null;
}
@@ -270,47 +273,6 @@
}
}
- private class ConnectInputReceiver extends FlagReceiver {
- private static final int STATE_DISCONNECTED_FLAG = 1;
- private static final int STATE_CONNECTING_FLAG = 1 << 1;
- private static final int STATE_CONNECTED_FLAG = 1 << 2;
- private static final int STATE_DISCONNECTING_FLAG = 1 << 3;
-
- private BluetoothDevice mDevice;
-
- public ConnectInputReceiver(BluetoothDevice device, int expectedFlags) {
- super(expectedFlags);
-
- mDevice = device;
- }
-
- @Override
- public void onReceive(Context context, Intent intent) {
- if (!mDevice.equals(intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE))) {
- return;
- }
-
- if (BluetoothInputDevice.ACTION_INPUT_DEVICE_STATE_CHANGED.equals(intent.getAction())) {
- int state = intent.getIntExtra(BluetoothInputDevice.EXTRA_INPUT_DEVICE_STATE, -1);
- assertNotSame(-1, state);
- switch (state) {
- case BluetoothInputDevice.STATE_DISCONNECTED:
- setFiredFlag(STATE_DISCONNECTED_FLAG);
- break;
- case BluetoothInputDevice.STATE_CONNECTING:
- setFiredFlag(STATE_CONNECTING_FLAG);
- break;
- case BluetoothInputDevice.STATE_CONNECTED:
- setFiredFlag(STATE_CONNECTED_FLAG);
- break;
- case BluetoothInputDevice.STATE_DISCONNECTING:
- setFiredFlag(STATE_DISCONNECTING_FLAG);
- break;
- }
- }
- }
- }
-
private class ConnectPanReceiver extends FlagReceiver {
private static final int STATE_DISCONNECTED_FLAG = 1;
private static final int STATE_CONNECTING_FLAG = 1 << 1;
@@ -366,6 +328,9 @@
case BluetoothProfile.HEADSET:
mHeadset = (BluetoothHeadset) proxy;
break;
+ case BluetoothProfile.INPUT_DEVICE:
+ mInput = (BluetoothInputDevice) proxy;
+ break;
}
}
}
@@ -379,6 +344,9 @@
case BluetoothProfile.HEADSET:
mHeadset = null;
break;
+ case BluetoothProfile.INPUT_DEVICE:
+ mInput = null;
+ break;
}
}
}
@@ -393,6 +361,7 @@
private Context mContext;
private BluetoothA2dp mA2dp;
private BluetoothHeadset mHeadset;
+ private BluetoothInputDevice mInput;
/**
* Creates a utility instance for testing Bluetooth.
@@ -1078,142 +1047,6 @@
}
/**
- * Connects the local device with a remote HID device and checks to make sure that the profile
- * is connected and that the correct actions were broadcast.
- *
- * @param adapter The BT adapter.
- * @param device The remote device.
- */
- public void connectInput(BluetoothAdapter adapter, BluetoothDevice device) {
- int mask = (ConnectInputReceiver.STATE_CONNECTING_FLAG
- | ConnectInputReceiver.STATE_CONNECTED_FLAG);
- long start = -1;
-
- if (!adapter.isEnabled()) {
- fail(String.format("connectInput() bluetooth not enabled: device=%s", device));
- }
-
- if (!adapter.getBondedDevices().contains(device)) {
- fail(String.format("connectInput() device not paired: device=%s", device));
- }
-
- BluetoothInputDevice inputDevice = new BluetoothInputDevice(mContext);
- assertNotNull(inputDevice);
- ConnectInputReceiver receiver = getConnectInputReceiver(device, mask);
-
- int state = inputDevice.getInputDeviceState(device);
- switch (state) {
- case BluetoothInputDevice.STATE_CONNECTED:
- removeReceiver(receiver);
- return;
- case BluetoothInputDevice.STATE_CONNECTING:
- mask = 0; // Don't check for received intents since we might have missed them.
- break;
- case BluetoothInputDevice.STATE_DISCONNECTED:
- case BluetoothInputDevice.STATE_DISCONNECTING:
- start = System.currentTimeMillis();
- assertTrue(inputDevice.connectInputDevice(device));
- break;
- default:
- removeReceiver(receiver);
- fail(String.format("connectInput() invalid state: device=%s, state=%d", device,
- state));
- }
-
- long s = System.currentTimeMillis();
- while (System.currentTimeMillis() - s < CONNECT_DISCONNECT_PROFILE_TIMEOUT) {
- state = inputDevice.getInputDeviceState(device);
- if (state == BluetoothInputDevice.STATE_CONNECTED
- && (receiver.getFiredFlags() & mask) == mask) {
- long finish = receiver.getCompletedTime();
- if (start != -1 && finish != -1) {
- writeOutput(String.format("connectInput() completed in %d ms: device=%s",
- (finish - start), device));
- } else {
- writeOutput(String.format("connectInput() completed: device=%s", device));
- }
- removeReceiver(receiver);
- return;
- }
- sleep(POLL_TIME);
- }
-
- int firedFlags = receiver.getFiredFlags();
- removeReceiver(receiver);
- fail(String.format("connectInput() timeout: device=%s, state=%d (expected %d), "
- + "flags=0x%x (expected 0x%s)", device, state, BluetoothInputDevice.STATE_CONNECTED,
- firedFlags, mask));
- }
-
- /**
- * Disconnects the local device with a remote HID device and checks to make sure that the
- * profile is connected and that the correct actions were broadcast.
- *
- * @param adapter The BT adapter.
- * @param device The remote device.
- */
- public void disconnectInput(BluetoothAdapter adapter, BluetoothDevice device) {
- int mask = (ConnectInputReceiver.STATE_DISCONNECTING_FLAG
- | ConnectInputReceiver.STATE_DISCONNECTED_FLAG);
- long start = -1;
-
- if (!adapter.isEnabled()) {
- fail(String.format("disconnectInput() bluetooth not enabled: device=%s", device));
- }
-
- if (!adapter.getBondedDevices().contains(device)) {
- fail(String.format("disconnectInput() device not paired: device=%s", device));
- }
-
- BluetoothInputDevice inputDevice = new BluetoothInputDevice(mContext);
- assertNotNull(inputDevice);
- ConnectInputReceiver receiver = getConnectInputReceiver(device, mask);
-
- int state = inputDevice.getInputDeviceState(device);
- switch (state) {
- case BluetoothInputDevice.STATE_CONNECTED:
- case BluetoothInputDevice.STATE_CONNECTING:
- start = System.currentTimeMillis();
- assertTrue(inputDevice.disconnectInputDevice(device));
- break;
- case BluetoothInputDevice.STATE_DISCONNECTED:
- removeReceiver(receiver);
- return;
- case BluetoothInputDevice.STATE_DISCONNECTING:
- mask = 0; // Don't check for received intents since we might have missed them.
- break;
- default:
- removeReceiver(receiver);
- fail(String.format("disconnectInput() invalid state: device=%s, state=%d", device,
- state));
- }
-
- long s = System.currentTimeMillis();
- while (System.currentTimeMillis() - s < CONNECT_DISCONNECT_PROFILE_TIMEOUT) {
- state = inputDevice.getInputDeviceState(device);
- if (state == BluetoothInputDevice.STATE_DISCONNECTED
- && (receiver.getFiredFlags() & mask) == mask) {
- long finish = receiver.getCompletedTime();
- if (start != -1 && finish != -1) {
- writeOutput(String.format("disconnectInput() completed in %d ms: device=%s",
- (finish - start), device));
- } else {
- writeOutput(String.format("disconnectInput() completed: device=%s", device));
- }
- removeReceiver(receiver);
- return;
- }
- sleep(POLL_TIME);
- }
-
- int firedFlags = receiver.getFiredFlags();
- removeReceiver(receiver);
- fail(String.format("disconnectInput() timeout: device=%s, state=%d (expected %d), "
- + "flags=0x%x (expected 0x%s)", device, state,
- BluetoothInputDevice.STATE_DISCONNECTED, firedFlags, mask));
- }
-
- /**
* Connects the PANU to a remote NAP and checks to make sure that the PANU is connected and that
* the correct actions were broadcast.
*
@@ -1478,21 +1311,14 @@
int expectedFlags) {
String[] actions = {
BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED,
- BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED};
+ BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED,
+ BluetoothInputDevice.ACTION_CONNECTION_STATE_CHANGED};
ConnectProfileReceiver receiver = new ConnectProfileReceiver(device, profile,
expectedFlags);
addReceiver(receiver, actions);
return receiver;
}
- private ConnectInputReceiver getConnectInputReceiver(BluetoothDevice device,
- int expectedFlags) {
- String[] actions = {BluetoothInputDevice.ACTION_INPUT_DEVICE_STATE_CHANGED};
- ConnectInputReceiver receiver = new ConnectInputReceiver(device, expectedFlags);
- addReceiver(receiver, actions);
- return receiver;
- }
-
private ConnectPanReceiver getConnectPanReceiver(BluetoothDevice device, int role,
int expectedFlags) {
String[] actions = {BluetoothPan.ACTION_PAN_STATE_CHANGED};
@@ -1511,15 +1337,20 @@
long s = System.currentTimeMillis();
switch (profile) {
case BluetoothProfile.A2DP:
- while (mA2dp != null && System.currentTimeMillis() - s < CONNECT_PROXY_TIMEOUT) {
+ while (mA2dp == null && System.currentTimeMillis() - s < CONNECT_PROXY_TIMEOUT) {
sleep(POLL_TIME);
}
return mA2dp;
case BluetoothProfile.HEADSET:
- while (mHeadset != null && System.currentTimeMillis() - s < CONNECT_PROXY_TIMEOUT) {
+ while (mHeadset == null && System.currentTimeMillis() - s < CONNECT_PROXY_TIMEOUT) {
sleep(POLL_TIME);
}
return mHeadset;
+ case BluetoothProfile.INPUT_DEVICE:
+ while (mInput == null && System.currentTimeMillis() - s < CONNECT_PROXY_TIMEOUT) {
+ sleep(POLL_TIME);
+ }
+ return mInput;
default:
return null;
}
diff --git a/media/java/android/media/videoeditor/Transition.java b/media/java/android/media/videoeditor/Transition.java
index 95f002c..3e8fe94 100755
--- a/media/java/android/media/videoeditor/Transition.java
+++ b/media/java/android/media/videoeditor/Transition.java
@@ -173,6 +173,7 @@
mDurationMs = durationMs;
invalidate();
+ mNativeHelper.setGeneratePreview(true);
}
/**
diff --git a/media/libmedia/mediarecorder.cpp b/media/libmedia/mediarecorder.cpp
index fd575fe..0100a17 100644
--- a/media/libmedia/mediarecorder.cpp
+++ b/media/libmedia/mediarecorder.cpp
@@ -298,6 +298,17 @@
return INVALID_OPERATION;
}
+ // It appears that if an invalid file descriptor is passed through
+ // binder calls, the server-side of the inter-process function call
+ // is skipped. As a result, the check at the server-side to catch
+ // the invalid file descritpor never gets invoked. This is to workaround
+ // this issue by checking the file descriptor first before passing
+ // it through binder call.
+ if (fd < 0) {
+ LOGE("Invalid file descriptor: %d", fd);
+ return BAD_VALUE;
+ }
+
status_t ret = mMediaRecorder->setOutputFile(fd, offset, length);
if (OK != ret) {
LOGV("setOutputFile failed: %d", ret);
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkPerfTestRunner.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkPerfTestRunner.java
index eaaa798..988b229 100755
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkPerfTestRunner.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaFrameworkPerfTestRunner.java
@@ -17,7 +17,8 @@
package com.android.mediaframeworktest;
import com.android.mediaframeworktest.performance.MediaPlayerPerformance;
-
+/*Video Editor performance Test cases*/
+import com.android.mediaframeworktest.performance.VideoEditorPerformance;
import junit.framework.TestSuite;
import android.test.InstrumentationTestRunner;
@@ -26,7 +27,7 @@
/**
* Instrumentation Test Runner for all MediaPlayer tests.
- *
+ *
* Running all tests:
*
* adb shell am instrument \
@@ -40,6 +41,8 @@
public TestSuite getAllTests() {
TestSuite suite = new InstrumentationTestSuite(this);
suite.addTestSuite(MediaPlayerPerformance.class);
+ /*Video Editor performance Test cases*/
+ suite.addTestSuite(VideoEditorPerformance.class);
return suite;
}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaPlayerStressTestRunner.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaPlayerStressTestRunner.java
index 5438061..0cd784c 100755
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaPlayerStressTestRunner.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/MediaPlayerStressTestRunner.java
@@ -19,6 +19,8 @@
import android.test.InstrumentationTestRunner;
import android.test.InstrumentationTestSuite;
import com.android.mediaframeworktest.stress.MediaPlayerStressTest;
+/** Import for Video Editor Stress Test cases*/
+import com.android.mediaframeworktest.stress.VideoEditorStressTest;
import junit.framework.TestSuite;
@@ -28,6 +30,8 @@
public TestSuite getAllTests() {
TestSuite suite = new InstrumentationTestSuite(this);
suite.addTestSuite(MediaPlayerStressTest.class);
+ /** Video Editor Stress Test cases*/
+ suite.addTestSuite(VideoEditorStressTest.class);
return suite;
}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/VideoEditorPreviewTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/VideoEditorPreviewTest.java
index bd0a838..9a7f4f2 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/VideoEditorPreviewTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/functional/VideoEditorPreviewTest.java
@@ -95,7 +95,7 @@
private boolean previewStop;
/* Minimum waiting time for Semaphore to wait for release */
- private final long minWaitingTime = 1000;
+ private final long minWaitingTime = 3000;
// Declares the annotation for Preview Test Cases
public @interface Preview {
@@ -473,8 +473,8 @@
mVideoEditorHelper.checkProgressCBValues(progressValues);
final SurfaceHolder surfaceHolder =
MediaFrameworkTest.mSurfaceView.getHolder();
-
- long waitingTime = minWaitingTime + 10000;
+ /* As transition takes more time buffer of 10 sec is added */
+ long waitingTime = minWaitingTime + 10000 + 10000;
blockTillPreviewCompletes.acquire();
try {
@@ -691,31 +691,34 @@
long waitingTime = minWaitingTime + mVideoEditor.getDuration();
+
blockTillPreviewCompletes.acquire();
+ final String fileName = mVideoEditor.getPath() + "\test.3gp";
+ final int height = MediaProperties.HEIGHT_480;
+ final int bitrate = MediaProperties.BITRATE_512K;
+
+ try {
+ mVideoEditor.export(fileName, height, bitrate,
+ new ExportProgressListener() {
+ public void onProgress(VideoEditor ve,
+ String outFileName,int progress) {
+
+ }
+ });
+ } catch (IOException e) {
+ assertTrue("UnExpected Error in Export" +
+ e.toString(), false);
+ }
final SurfaceHolder surfaceHolder =
MediaFrameworkTest.mSurfaceView.getHolder();
try {
+
mVideoEditor.startPreview(surfaceHolder, 5000, -1, false, 1,
new PreviewProgressListener() {
- final String fileName = mVideoEditor.getPath() + "\test.3gp";
- final int height = MediaProperties.HEIGHT_360;
- final int bitrate = MediaProperties.BITRATE_512K;
+
public void onProgress(VideoEditor videoEditor, long timeMs,
OverlayData overlayData) {
- if (timeMs >= 10000)
- try {
- videoEditor.export(fileName, height, bitrate,
- new ExportProgressListener() {
- public void onProgress(VideoEditor ve,
- String outFileName,int progress) {
-
- }
- });
- } catch (IOException e) {
- assertTrue("UnExpected Error in Export" +
- e.toString(), false);
- }
}
public void onStart(VideoEditor videoEditor) {
setPreviewStart();
@@ -725,10 +728,10 @@
blockTillPreviewCompletes.release();
}
});
+
} catch (Exception e) {
blockTillPreviewCompletes.release();
}
-
blockTillPreviewCompletes.tryAcquire(waitingTime, TimeUnit.MILLISECONDS);
mVideoEditor.stopPreview();
assertTrue("Preview Failed to start", previewStart);
@@ -837,31 +840,7 @@
mVideoEditor.renderPreviewFrame(surfaceHolder, 7000,
overlayData1));
- long waitingTime = minWaitingTime + (mVideoEditor.getDuration() - 5000);
-
- blockTillPreviewCompletes.acquire();
- try {
- mVideoEditor.startPreview(surfaceHolder, 5000, -1, false, 1,
- new PreviewProgressListener() {
- public void onProgress(VideoEditor videoEditor, long timeMs,
- OverlayData overlayData) {
- }
- public void onStart(VideoEditor videoEditor) {
- setPreviewStart();
- }
- public void onStop(VideoEditor videoEditor) {
- setPreviewStop();
- blockTillPreviewCompletes.release();
- }
- });
- } catch (Exception e) {
- blockTillPreviewCompletes.release();
- }
- blockTillPreviewCompletes.tryAcquire(waitingTime, TimeUnit.MILLISECONDS);
- mVideoEditor.stopPreview();
- assertTrue("Preview Failed to start", previewStart);
- assertTrue("Preview Failed to stop", previewStop);
- blockTillPreviewCompletes.release();
+ validatePreviewProgress(5000, -1, false, mVideoEditor.getDuration());
}
/**
@@ -1142,20 +1121,19 @@
duration = mVideoEditor.getDuration();
/* RenderPreviewFrame returns -1 to indicate last frame */
try {
- assertEquals("Render preview Frame at item duration", -1,
- mVideoEditor.renderPreviewFrame(surfaceHolder, duration,
- overlayData1));
- } catch ( Exception e) {
- assertTrue (" Render Preview Frame without generate", false);
- }
- duration = mVideoEditor.getDuration() + 1000;
- try {
mVideoEditor.renderPreviewFrame(surfaceHolder, duration,
overlayData1);
} catch ( IllegalStateException e) {
flagForException = true;
}
+ assertTrue (" Render Preview Frame without generate", flagForException);
+ duration = mVideoEditor.getDuration() + 1000;
+ try {
+ mVideoEditor.renderPreviewFrame(surfaceHolder, duration,
+ overlayData1);
+ } catch ( IllegalArgumentException e) {
+ flagForException = true;
+ }
assertTrue (" Preview time greater than duration", flagForException);
}
-
}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/VideoEditorPerformance.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/VideoEditorPerformance.java
new file mode 100644
index 0000000..4481d00
--- /dev/null
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/performance/VideoEditorPerformance.java
@@ -0,0 +1,1086 @@
+/*
+ * 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 com.android.mediaframeworktest.performance;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.Writer;
+
+import android.graphics.Bitmap;
+import android.graphics.Rect;
+import android.media.videoeditor.AudioTrack;
+import android.media.videoeditor.EffectColor;
+import android.media.videoeditor.EffectKenBurns;
+import android.media.videoeditor.MediaImageItem;
+import android.media.videoeditor.MediaItem;
+import android.media.videoeditor.MediaProperties;
+import android.media.videoeditor.MediaVideoItem;
+import android.media.videoeditor.OverlayFrame;
+import android.media.videoeditor.Transition;
+import android.media.videoeditor.TransitionCrossfade;
+import android.media.videoeditor.TransitionAlpha;
+import android.media.videoeditor.TransitionFadeBlack;
+import android.media.videoeditor.TransitionSliding;
+import android.media.videoeditor.VideoEditor;
+import android.os.Environment;
+import android.test.ActivityInstrumentationTestCase;
+import android.media.videoeditor.VideoEditor.MediaProcessingProgressListener;
+import android.os.Environment;
+import android.os.SystemClock;
+import android.test.ActivityInstrumentationTestCase;
+import android.media.videoeditor.VideoEditor.ExportProgressListener;
+
+import android.util.Log;
+
+import com.android.mediaframeworktest.MediaFrameworkTest;
+import android.test.suitebuilder.annotation.LargeTest;
+import com.android.mediaframeworktest.VideoEditorHelper;
+
+/**
+ * Junit / Instrumentation - performance measurement for media player and
+ * recorder
+ */
+public class VideoEditorPerformance extends
+ ActivityInstrumentationTestCase<MediaFrameworkTest> {
+
+ private final String TAG = "VideoEditorPerformance";
+
+ private final String PROJECT_LOCATION = VideoEditorHelper.PROJECT_LOCATION_COMMON;
+
+ private final String INPUT_FILE_PATH = VideoEditorHelper.INPUT_FILE_PATH_COMMON;
+
+ private final String VIDEOEDITOR_OUTPUT = PROJECT_LOCATION +
+ "VideoEditorPerformance.txt";
+
+ public VideoEditorPerformance() {
+ super("com.android.mediaframeworktest", MediaFrameworkTest.class);
+ }
+
+ private final String PROJECT_CLASS_NAME =
+ "android.media.videoeditor.VideoEditorImpl";
+ private VideoEditor mVideoEditor;
+ private VideoEditorHelper mVideoEditorHelper;
+
+ @Override
+ protected void setUp() throws Exception {
+ // setup for each test case.
+ super.setUp();
+ mVideoEditorHelper = new VideoEditorHelper();
+ // Create a random String which will be used as project path, where all
+ // project related files will be stored.
+ final String projectPath =
+ mVideoEditorHelper.createRandomFile(PROJECT_LOCATION);
+ mVideoEditor = mVideoEditorHelper.createVideoEditor(projectPath);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ mVideoEditorHelper.destroyVideoEditor(mVideoEditor);
+ // Clean the directory created as project path
+ mVideoEditorHelper.deleteProject(new File(mVideoEditor.getPath()));
+ System.gc();
+ super.tearDown();
+ }
+
+ private void writeTimingInfo(String testCaseName, String[] information)
+ throws Exception {
+ File outFile = new File(VIDEOEDITOR_OUTPUT);
+ Writer output = new BufferedWriter(new FileWriter(outFile, true));
+ output.write(testCaseName + "\n\t");
+ for (int i = 0; i < information.length; i++) {
+ output.write(information[i]);
+ }
+ output.write("\n\n");
+ output.close();
+ }
+
+ private final int NUM_OF_ITERATIONS=20;
+
+ private float calculateTimeTaken(long beginTime, int numIterations)
+ throws Exception {
+ final long duration2 = SystemClock.uptimeMillis();
+ final long durationToCreateMediaItem = (duration2 - beginTime);
+ final float timeTaken1 = (float)durationToCreateMediaItem *
+ 1.0f/(float)numIterations;
+ return (timeTaken1);
+ }
+
+ private void createVideoItems(MediaVideoItem[] mediaVideoItem,
+ String videoItemFileName, int renderingMode, int startTime, int endTime) throws Exception {
+ for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
+ try {
+ mediaVideoItem[i] = new MediaVideoItem(mVideoEditor, "m" + i,
+ videoItemFileName, renderingMode);
+ mediaVideoItem[i].setExtractBoundaries(startTime, endTime);
+ } catch (Exception e1) {
+ assertTrue(
+ "Can not create an object of Video Item with file name = "
+ + videoItemFileName + "------ID:m" + i + " Issue = "
+ + e1.toString(), false);
+ }
+ }
+ }
+
+ private void addVideoItems(MediaVideoItem[] mediaVideoItem) throws Exception {
+ for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
+ try {
+ mVideoEditor.addMediaItem(mediaVideoItem[i]);
+ } catch (Exception e1) {
+ assertTrue(
+ "Can not add an object of Video Item with ID:m" + i +
+ " Issue = " + e1.toString(), false);
+ }
+ }
+ }
+
+ private void removeVideoItems(MediaVideoItem[] mediaVideoItem) throws Exception {
+ for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
+ try {
+ mVideoEditor.removeMediaItem(mediaVideoItem[i].getId());
+ } catch (Exception e1) {
+ assertTrue(
+ "Can not Remove an object of Video Item with ID:m" + i +
+ " Issue = " + e1.toString(), false);
+ }
+ }
+ }
+
+ private void createImageItems(MediaImageItem[] mIi,
+ String imageItemFileName, int renderingMode, int duration) throws Exception {
+ for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
+ try {
+ mIi[i] = new MediaImageItem(mVideoEditor, "m" + i,
+ imageItemFileName, duration, renderingMode);
+ } catch (Exception e1) {
+ assertTrue( " Cannot create Image Item", false);
+ }
+ }
+ }
+
+ private void addImageItems(MediaImageItem[] mIi) throws Exception {
+ for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
+ try {
+ mVideoEditor.addMediaItem(mIi[i]);
+ } catch (Exception e1) {
+ assertTrue("Cannot add Image item", false);
+ }
+ }
+ }
+
+ private void removeImageItems(MediaImageItem[] mIi) throws Exception {
+ for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
+ try {
+ mVideoEditor.removeMediaItem(mIi[i].getId());
+ } catch (Exception e1) {
+ assertTrue("Cannot remove image item", false);
+ }
+ }
+ }
+ /**
+ * To test the performance of adding and removing the video media item
+ *
+ * @throws Exception
+ */
+ // TODO : remove PRF_001
+ @LargeTest
+ public void testPerformanceAddRemoveVideoItem() throws Exception {
+ final String videoItemFileName = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
+ final int videoItemStartTime = 0;
+ final int videoItemEndTime = 5000;
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String[] loggingInfo = new String[3];
+ final MediaVideoItem[] mediaVideoItem =
+ new MediaVideoItem[NUM_OF_ITERATIONS];
+ float timeTaken = 0.0f;
+ long startTime = 0;
+
+ /** Time Take for creation of Media Video Item */
+ startTime = SystemClock.uptimeMillis();
+ createVideoItems(mediaVideoItem, videoItemFileName, renderingMode,
+ videoItemStartTime, videoItemEndTime);
+
+ timeTaken = calculateTimeTaken (startTime, NUM_OF_ITERATIONS);
+ loggingInfo[0] = "Time taken to Create Media Video Item\t" +
+ timeTaken;
+
+ /** Time Take for Addition of Media Video Item */
+ startTime = SystemClock.uptimeMillis();
+ addVideoItems(mediaVideoItem);
+ timeTaken = calculateTimeTaken (startTime, NUM_OF_ITERATIONS);
+ loggingInfo[1] = "\n\tTime taken to Add Media Video Item\t"
+ + timeTaken;
+
+ /** Time Take for Removal of Media Video Item */
+ startTime = SystemClock.uptimeMillis();
+ removeVideoItems(mediaVideoItem);
+ timeTaken = calculateTimeTaken (startTime, NUM_OF_ITERATIONS);
+ loggingInfo[2] = "\n\tTime taken to remove Media Video Item\t"
+ + timeTaken;
+
+ writeTimingInfo("testPerformanceAddRemoveVideoItem (in mSec)", loggingInfo);
+ }
+
+ /**
+ * To test the performance of adding and removing the image media item
+ *
+ * @throws Exception
+ */
+ // TODO : remove PRF_002
+ @LargeTest
+ public void testPerformanceAddRemoveImageItem() throws Exception {
+ final String imageItemFileName = INPUT_FILE_PATH + "IMG_1600x1200.jpg";
+ final int imageItemDuration = 0;
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String[] loggingInfo = new String[3];
+ final MediaImageItem[] mediaImageItem =
+ new MediaImageItem[NUM_OF_ITERATIONS];
+ float timeTaken = 0.0f;
+
+ long beginTime = SystemClock.uptimeMillis();
+ createImageItems(mediaImageItem, imageItemFileName, renderingMode,
+ imageItemDuration);
+ timeTaken = calculateTimeTaken(beginTime, NUM_OF_ITERATIONS);
+ loggingInfo[0] = "Time taken to Create Media Image Item\t" +
+ timeTaken;
+
+ beginTime = SystemClock.uptimeMillis();
+ addImageItems(mediaImageItem);
+ timeTaken = calculateTimeTaken(beginTime, NUM_OF_ITERATIONS);
+ loggingInfo[1] = "\n\tTime taken to add Media Image Item\t" +
+ timeTaken;
+
+ beginTime = SystemClock.uptimeMillis();
+ removeImageItems(mediaImageItem);
+ timeTaken = calculateTimeTaken(beginTime, NUM_OF_ITERATIONS);
+ loggingInfo[2] = "\n\tTime taken to remove Media Image Item\t"
+ + timeTaken;
+
+ writeTimingInfo("testPerformanceAddRemoveImageItem (in mSec)",
+ loggingInfo);
+ }
+
+ /**
+ * To test the performance of adding and removing the transition
+ *
+ * @throws Exception
+ */
+ // TODO : remove PRF_003
+ @LargeTest
+ public void testPerformanceAddRemoveTransition() throws Exception {
+ final String videoItemFileName1 = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
+ final int videoItemStartTime1 = 0;
+ final int videoItemEndTime1 = 20000;
+ final String videoItemFileName2 = INPUT_FILE_PATH
+ + "MPEG4_SP_640x480_15fps_512kbps_AACLC_48khz_132kbps_s_0_26.mp4";
+ final int videoItemStartTime2 = 0;
+ final int videoItemEndTime2 = 20000;
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final int transitionDuration = 5000;
+ final int transitionBehavior = Transition.BEHAVIOR_MIDDLE_FAST;
+ final String[] loggingInfo = new String[3];
+ float timeTaken = 0.0f;
+
+ final MediaVideoItem[] mediaVideoItem =
+ new MediaVideoItem[(NUM_OF_ITERATIONS *10) + 1];
+
+ for (int i = 0; i < (NUM_OF_ITERATIONS *10); i+=2) {
+ try {
+ mediaVideoItem[i] = new MediaVideoItem(mVideoEditor, "m" + i,
+ videoItemFileName1, renderingMode);
+ mediaVideoItem[i+1] = new MediaVideoItem(mVideoEditor,
+ "m" + (i+1), videoItemFileName2, renderingMode);
+ mediaVideoItem[i].setExtractBoundaries(videoItemStartTime1,
+ videoItemEndTime1);
+ mediaVideoItem[i+1].setExtractBoundaries(videoItemStartTime2,
+ videoItemEndTime2);
+ } catch (Exception e1) {
+ assertTrue("Can not create Video Object Item with file name = "
+ + e1.toString(), false);
+ }
+ mVideoEditor.addMediaItem(mediaVideoItem[i]);
+ mVideoEditor.addMediaItem(mediaVideoItem[i+1]);
+ }
+ mediaVideoItem[(NUM_OF_ITERATIONS *10)] = new MediaVideoItem(mVideoEditor,
+ "m" + (NUM_OF_ITERATIONS *10), videoItemFileName1, renderingMode);
+ mediaVideoItem[(NUM_OF_ITERATIONS *10)].setExtractBoundaries(
+ videoItemStartTime1, videoItemEndTime1);
+ mVideoEditor.addMediaItem(mediaVideoItem[(NUM_OF_ITERATIONS *10)]);
+ final TransitionCrossfade tranCrossfade[] =
+ new TransitionCrossfade[(NUM_OF_ITERATIONS *10)];
+
+ long beginTime = SystemClock.uptimeMillis();
+ for (int i = 0; i < (NUM_OF_ITERATIONS *10); i++) {
+ tranCrossfade[i] = new TransitionCrossfade("transition" + i,
+ mediaVideoItem[i], mediaVideoItem[i+1], transitionDuration,
+ transitionBehavior);
+ }
+ timeTaken = calculateTimeTaken(beginTime, (NUM_OF_ITERATIONS * 10));
+ loggingInfo[0] = "Time taken to Create CrossFade Transition\t" +
+ timeTaken;
+
+ beginTime = SystemClock.uptimeMillis();
+ for (int i = 0; i < (NUM_OF_ITERATIONS *10); i++) {
+ mVideoEditor.addTransition(tranCrossfade[i]);
+ }
+ timeTaken = calculateTimeTaken(beginTime, (NUM_OF_ITERATIONS * 10));
+ loggingInfo[1] = "\n\tTime taken to add CrossFade Transition\t" +
+ timeTaken;
+
+ beginTime = SystemClock.uptimeMillis();
+ for (int i = 0; i < (NUM_OF_ITERATIONS *10); i++) {
+ assertEquals("Removing Transitions", tranCrossfade[i], mVideoEditor
+ .removeTransition(tranCrossfade[i].getId()));
+ }
+ timeTaken = calculateTimeTaken(beginTime, (NUM_OF_ITERATIONS * 10));
+ loggingInfo[2] = "\n\tTime taken to remove CrossFade Transition\t" +
+ timeTaken;
+
+ writeTimingInfo("testPerformanceAddRemoveTransition (in mSec)", loggingInfo);
+ }
+
+ /**
+ * To test performance of Export
+ *
+ * @throws Exception
+ */
+ // TODO : remove PRF_004
+ @LargeTest
+ public void testPerformanceExport() throws Exception {
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final int outHeight = MediaProperties.HEIGHT_480;
+ final int outBitrate = MediaProperties.BITRATE_256K;
+ final int outVcodec = MediaProperties.VCODEC_H264BP;
+ final String[] loggingInfo = new String[1];
+ final String outFilename = mVideoEditorHelper
+ .createRandomFile(mVideoEditor.getPath() + "/") + ".3gp";
+ final String videoItemFileName1 = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_12Mbps_AACLC_44.1khz_64kbps_s_1_17.mp4";
+ final String imageItemFileName1 = INPUT_FILE_PATH + "IMG_1600x1200.jpg";
+ final String videoItemFileName2 = INPUT_FILE_PATH +
+ "H264_BP_640x480_15fps_1200Kbps_AACLC_48KHz_32kbps_m_1_17.3gp";
+ final String imageItemFileName2 = INPUT_FILE_PATH + "IMG_176x144.jpg";
+ final String videoItemFileName3 = INPUT_FILE_PATH +
+ "MPEG4_SP_720x480_30fps_280kbps_AACLC_48kHz_161kbps_s_0_26.mp4";
+ final String overlayFile = INPUT_FILE_PATH + "IMG_640x480_Overlay1.png";
+ final String audioTrackFilename = INPUT_FILE_PATH +
+ "AMRNB_8KHz_12.2Kbps_m_1_17.3gp";
+ final String maskFilename = INPUT_FILE_PATH +
+ "TransitionSpiral_QVGA.jpg";
+
+ final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor,
+ "m1", videoItemFileName1, renderingMode);
+ mediaItem1.setExtractBoundaries(0, 20000);
+ mVideoEditor.addMediaItem(mediaItem1);
+
+ final MediaImageItem mediaItem2 = new MediaImageItem(mVideoEditor,
+ "m2", imageItemFileName1, 10000, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem2);
+
+ final MediaVideoItem mediaItem3 = new MediaVideoItem(mVideoEditor,
+ "m3", videoItemFileName2, renderingMode);
+ mediaItem3.setExtractBoundaries(0, 20000);
+ mVideoEditor.addMediaItem(mediaItem3);
+
+ final MediaImageItem mediaItem4 = new MediaImageItem(mVideoEditor,
+ "m4", imageItemFileName2, 10000, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem4);
+
+ final MediaVideoItem mediaItem5 = new MediaVideoItem(mVideoEditor,
+ "m5", videoItemFileName3, renderingMode);
+ mediaItem5.setExtractBoundaries(0, 20000);
+ mVideoEditor.addMediaItem(mediaItem5);
+ /**
+ * 7.Add TransitionAlpha, Apply this Transition as Begin for Media Item 1
+ * with duration = 2 sec behavior = BEHAVIOR_LINEAR, mask file name =
+ * TransitionSpiral_QVGA.jpg , blending percent = 50%, invert = true;
+ * */
+ final TransitionAlpha transition1 =
+ mVideoEditorHelper.createTAlpha("transition1", null, mediaItem1,
+ 2000, Transition.BEHAVIOR_LINEAR, maskFilename, 50, true);
+ mVideoEditor.addTransition(transition1);
+
+ /**
+ * 8.Add Transition Sliding between MediaItem 2 and 3 ,
+ * Sliding Direction = DIRECTION_RIGHT_OUT_LEFT_IN,
+ * behavior = BEHAVIOR_MIDDLE_FAST and duration = 4sec
+ * */
+ final TransitionSliding transition2And3 =
+ mVideoEditorHelper.createTSliding("transition2", mediaItem2,
+ mediaItem3, 4000, Transition.BEHAVIOR_MIDDLE_FAST,
+ TransitionSliding.DIRECTION_RIGHT_OUT_LEFT_IN);
+ mVideoEditor.addTransition(transition2And3);
+
+ /**
+ * 9.Add Transition Crossfade between Media Item 3 and 4,
+ * behavior = BEHAVIOR_MIDDLE_SLOW, duration = 3.5 sec
+ * */
+ final TransitionCrossfade transition3And4 =
+ mVideoEditorHelper.createTCrossFade("transition3", mediaItem3,
+ mediaItem4, 3500, Transition.BEHAVIOR_MIDDLE_SLOW);
+ mVideoEditor.addTransition(transition3And4);
+
+ /**
+ * 10.Add Transition Fadeblack between Media Item 4 and 5,
+ * behavior = BEHAVIOR_SPEED_DOWN, duration = 3.5 sec
+ * */
+ final TransitionFadeBlack transition4And5 =
+ mVideoEditorHelper.createTFadeBlack("transition4", mediaItem4,
+ mediaItem5, 3500, Transition.BEHAVIOR_SPEED_DOWN);
+ mVideoEditor.addTransition(transition4And5);
+
+ /**
+ * 11.Add Effect 1 type="TYPE_SEPIA" to the MediaItem 1,
+ * start time=1sec and duration =4secs
+ * */
+ final EffectColor effectColor1 = mVideoEditorHelper.createEffectItem(
+ mediaItem1, "effect1", 1000, 4000, EffectColor.TYPE_SEPIA, 0);
+ mediaItem1.addEffect(effectColor1);
+
+ /**
+ * 12.Add Overlay 1 to the MediaItem 3: Frame Overlay with start time = 1 sec
+ * duration = 4 sec with item = IMG_640x480_Overlay1.png
+ * */
+ final Bitmap mBitmap = mVideoEditorHelper.getBitmap(overlayFile, 640,
+ 480);
+ final OverlayFrame overlayFrame =
+ mVideoEditorHelper.createOverlay(mediaItem3, "overlay",
+ mBitmap, 1000, 4000);
+ mediaItem3.addOverlay(overlayFrame);
+ /**
+ * 13.Add Effect 2 type="TYPE_NEGATIVE" to the MediaItem 2,
+ * start time=8sec and duration =2secs
+ * */
+ final EffectColor effectColor2 = mVideoEditorHelper.createEffectItem(
+ mediaItem2, "effect2", 8000, 2000, EffectColor.TYPE_NEGATIVE, 0);
+ mediaItem2.addEffect(effectColor2);
+ /**
+ * 14.Add Effect 3 type="TYPE_COLOR" to the MediaItem 3, color param = "PINK",
+ * start time=5 sec and duration =3secs
+ * */
+ final EffectColor effectColor3 = mVideoEditorHelper.createEffectItem(
+ mediaItem3, "effect3", 5000, 3000, EffectColor.TYPE_COLOR,
+ EffectColor.PINK);
+ mediaItem3.addEffect(effectColor3);
+ /**
+ * 15.Add Effect 4 type="TYPE_FIFTIES" to the MediaItem 4,
+ * start time=2 sec and duration =1secs
+ * */
+ final EffectColor effectColor4 = mVideoEditorHelper.createEffectItem(
+ mediaItem4, "effect4", 2000, 1000, EffectColor.TYPE_FIFTIES, 0);
+ mediaItem4.addEffect(effectColor4);
+ /**
+ * 16.Add KenBurnsEffect for MediaItem 4 with
+ * duration = 3 sec and startTime = 4 sec
+ * StartRect
+ * left = org_height/3 ; top = org_width/3
+ * bottom = org_width/2 ; right = org_height/2
+ * EndRect
+ * left = 0 ; top = 0
+ * bottom = org_height; right = org_width
+ * */
+
+ final Rect startRect = new Rect((mediaItem4.getHeight() / 3),
+ (mediaItem4.getWidth() / 3), (mediaItem4.getHeight() / 2),
+ (mediaItem4.getWidth() / 2));
+ final Rect endRect = new Rect(0, 0, mediaItem4.getWidth(),
+ mediaItem4.getHeight());
+ final EffectKenBurns kbEffectOnMediaItem = new EffectKenBurns(
+ mediaItem4, "KBOnM2", startRect, endRect,4000 , 3000);
+ mediaItem4.addEffect(kbEffectOnMediaItem);
+
+ /** 17.Add Audio Track,Set extract boundaries o to 10 sec.
+ * */
+ final AudioTrack audioTrack = mVideoEditorHelper.createAudio(
+ mVideoEditor, "audioTrack", audioTrackFilename);
+ mVideoEditor.addAudioTrack(audioTrack);
+ /** 18.Enable Looping for Audio Track.
+ * */
+ audioTrack.enableLoop();
+ float timeTaken = 0.0f;
+ final long beginTime = SystemClock.uptimeMillis();
+ try {
+ mVideoEditor.export(outFilename, outHeight, outBitrate,
+ new ExportProgressListener() {
+ public void onProgress(VideoEditor ve,
+ String outFileName, int progress) {
+ }
+ });
+ } catch (Exception e) {
+ assertTrue("Error in Export" + e.toString(), false);
+ }
+ mVideoEditorHelper.checkDeleteExistingFile(outFilename);
+
+ timeTaken = calculateTimeTaken(beginTime, 1);
+ loggingInfo[0] = "Time taken to do ONE export of storyboard duration\t"
+ + mVideoEditor.getDuration() + " is :\t" + timeTaken;
+
+ writeTimingInfo("testPerformanceExport (in mSec)", loggingInfo);
+ mVideoEditorHelper.deleteProject(new File(mVideoEditor.getPath()));
+ }
+
+
+ /**
+ * To test the performance of thumbnail extraction
+ *
+ * @throws Exception
+ */
+ // TODO : remove PRF_005
+ @LargeTest
+ public void testPerformanceThumbnailVideoItem() throws Exception {
+ final String videoItemFileName = INPUT_FILE_PATH
+ + "MPEG4_SP_640x480_15fps_512kbps_AACLC_48khz_132kbps_s_0_26.mp4";
+ final int videoItemStartTime = 0;
+ final int videoItemEndTime = 20000;
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String[] loggingInfo = new String[1];
+
+ final MediaVideoItem mediaVideoItem = new MediaVideoItem(mVideoEditor,
+ "m1", videoItemFileName, renderingMode);
+ mediaVideoItem.setExtractBoundaries(videoItemStartTime,
+ videoItemEndTime);
+
+ float timeTaken = 0.0f;
+ long beginTime = SystemClock.uptimeMillis();
+ for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
+ mediaVideoItem.getThumbnail(mediaVideoItem.getWidth() / 2,
+ mediaVideoItem.getHeight() / 2, i);
+ }
+ timeTaken = calculateTimeTaken(beginTime, NUM_OF_ITERATIONS);
+ loggingInfo[0] = "Duration taken to get Video Thumbnails\t" +
+ timeTaken;
+
+ writeTimingInfo("testPerformanceThumbnailVideoItem (in mSec)", loggingInfo);
+ }
+
+ /**
+ * To test the performance of adding and removing the overlay to media item
+ *
+ * @throws Exception
+ */
+ // TODO : remove PRF_006
+ @LargeTest
+ public void testPerformanceOverlayVideoItem() throws Exception {
+ final String videoItemFileName1 = INPUT_FILE_PATH +
+ "MPEG4_SP_640x480_15fps_512kbps_AACLC_48khz_132kbps_s_0_26.mp4";
+ final int videoItemStartTime1 = 0;
+ final int videoItemEndTime1 = 10000;
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String overlayFilename = INPUT_FILE_PATH
+ + "IMG_640x480_Overlay1.png";
+ final int overlayStartTime = 1000;
+ final int overlayDuration = 5000;
+
+ final String[] loggingInfo = new String[2];
+ MediaVideoItem mediaVideoItem = null;
+
+ try {
+ mediaVideoItem = new MediaVideoItem(mVideoEditor, "m0",
+ videoItemFileName1, renderingMode);
+ mediaVideoItem.setExtractBoundaries(videoItemStartTime1,
+ videoItemEndTime1);
+ } catch (Exception e1) {
+ assertTrue("Can not create Video Item with file name = "
+ + e1.toString(), false);
+ }
+ final OverlayFrame overlayFrame[] = new OverlayFrame[NUM_OF_ITERATIONS];
+ final Bitmap mBitmap = mVideoEditorHelper.getBitmap(overlayFilename,
+ 640, 480);
+ float timeTaken = 0.0f;
+ long beginTime = SystemClock.uptimeMillis();
+ for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
+ overlayFrame[i] = new OverlayFrame(mediaVideoItem, "overlay" + i,
+ mBitmap, overlayStartTime, overlayDuration);
+ mediaVideoItem.addOverlay(overlayFrame[i]);
+ }
+ timeTaken = calculateTimeTaken(beginTime, NUM_OF_ITERATIONS);
+ loggingInfo[0] = "Time taken to add & create Overlay\t" + timeTaken;
+
+ beginTime = SystemClock.uptimeMillis();
+ for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
+ assertEquals("Removing Overlays", overlayFrame[i],
+ mediaVideoItem.removeOverlay((overlayFrame[i].getId())));
+ }
+ timeTaken = calculateTimeTaken(beginTime, NUM_OF_ITERATIONS);
+ loggingInfo[1] = "\n\tTime taken to remove Overlay\t" +
+ timeTaken;
+
+ writeTimingInfo("testPerformanceOverlayVideoItem (in mSec)", loggingInfo);
+ }
+
+ /**
+ * To test the performance of get properties of a Video media item
+ *
+ * @throws Exception
+ */
+ // TODO : remove PRF_007
+ @LargeTest
+ public void testPerformanceVideoItemProperties() throws Exception {
+ final String videoItemFileName1 = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
+ final int videoItemStartTime1 = 0;
+ final int videoItemEndTime1 = 10100;
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final int aspectRatio = MediaProperties.ASPECT_RATIO_3_2;
+ final int fileType = MediaProperties.FILE_MP4;
+ final int videoCodecType = MediaProperties.VCODEC_H264BP;
+ final int duration = 77366;
+ final int videoBitrate = 3169971;
+ final int fps = 30;
+ final int videoProfile = MediaProperties.H264_PROFILE_0_LEVEL_1_3;
+ final int width = 1080;
+ final int height = MediaProperties.HEIGHT_720;
+ float timeTaken = 0.0f;
+ final String[] loggingInfo = new String[1];
+ final MediaVideoItem mediaVideoItem = new MediaVideoItem(mVideoEditor,
+ "m0", videoItemFileName1, renderingMode);
+ mediaVideoItem.setExtractBoundaries(videoItemStartTime1,
+ videoItemEndTime1);
+ long beginTime = SystemClock.uptimeMillis();
+ for (int i = 0; i < (NUM_OF_ITERATIONS*10); i++) {
+ try {
+ assertEquals("Aspect Ratio Mismatch",
+ aspectRatio, mediaVideoItem.getAspectRatio());
+ assertEquals("File Type Mismatch",
+ fileType, mediaVideoItem.getFileType());
+ assertEquals("VideoCodec Mismatch",
+ videoCodecType, mediaVideoItem.getVideoType());
+ assertEquals("duration Mismatch",
+ duration, mediaVideoItem.getDuration());
+ assertEquals("Video Profile ",
+ videoProfile, mediaVideoItem.getVideoProfile());
+ assertEquals("Video height ",
+ height, mediaVideoItem.getHeight());
+ assertEquals("Video width ",
+ width, mediaVideoItem.getWidth());
+ } catch (Exception e1) {
+ assertTrue("Can not create Video Item with file name = "
+ + e1.toString(), false);
+ }
+ }
+ timeTaken = calculateTimeTaken(beginTime, (NUM_OF_ITERATIONS*10));
+ loggingInfo[0] = "Time taken to get Media Properties\t"
+ + timeTaken;
+ writeTimingInfo("testPerformanceVideoItemProperties:", loggingInfo);
+ }
+
+ /**
+ * To test the performance of generatePreview : with Transitions
+ *
+ * @throws Exception
+ */
+ // TODO : remove PRF_008
+ @LargeTest
+ public void testPerformanceGeneratePreviewWithTransitions()
+ throws Exception {
+ final String videoItemFileName = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
+ final String imageItemFileName = INPUT_FILE_PATH +
+ "IMG_1600x1200.jpg";
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final int transitionBehavior = Transition.BEHAVIOR_MIDDLE_FAST;
+ long averageTime = 0;
+ final String[] loggingInfo = new String[1];
+
+ final MediaVideoItem mediaVideoItem = new MediaVideoItem(mVideoEditor,
+ "mediaItem1", videoItemFileName, renderingMode);
+ mediaVideoItem.setExtractBoundaries(0, 10000);
+ mVideoEditor.addMediaItem(mediaVideoItem);
+
+ final MediaImageItem mediaImageItem = new MediaImageItem(mVideoEditor,
+ "mediaItem2", imageItemFileName, 10000, renderingMode);
+ mVideoEditor.addMediaItem(mediaImageItem);
+
+ final TransitionCrossfade transitionCrossFade = new TransitionCrossfade(
+ "transitionCrossFade", mediaVideoItem, mediaImageItem,
+ 5000, transitionBehavior);
+ mVideoEditor.addTransition(transitionCrossFade);
+
+ for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
+ final long duration1 = SystemClock.uptimeMillis();
+ mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
+ public void onProgress(Object item, int action, int progress) {
+ }
+ });
+ final long duration2 = SystemClock.uptimeMillis();
+ mVideoEditor.removeTransition(transitionCrossFade.getId());
+ mVideoEditor.addTransition(transitionCrossFade);
+ averageTime += (duration2 - duration1);
+ }
+ final long durationToAddObjects = averageTime;
+ final float timeTaken = (float)durationToAddObjects *
+ 1.0f/(float)NUM_OF_ITERATIONS;
+ loggingInfo[0] = "Time taken to Generate Preview with transition\t"
+ + timeTaken;
+ writeTimingInfo("testPerformanceGeneratePreviewWithTransitions:",
+ loggingInfo);
+ }
+
+ /**
+ * To test the performance of generatePreview : with KenBurn
+ *
+ * @throws Exception
+ */
+ // TODO : remove PRF_009
+ @LargeTest
+ public void testPerformanceWithKenBurn() throws Exception {
+ final String videoItemFileName = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
+ final String imageItemFileName = INPUT_FILE_PATH +
+ "IMG_1600x1200.jpg";
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ long averageTime = 0;
+ final String[] loggingInfo = new String[1];
+ final MediaVideoItem mediaVideoItem = new MediaVideoItem(mVideoEditor,
+ "mediaItem1", videoItemFileName, renderingMode);
+ mediaVideoItem.setExtractBoundaries(0, 10000);
+ mVideoEditor.addMediaItem(mediaVideoItem);
+
+ final MediaImageItem mediaImageItem = new MediaImageItem(mVideoEditor,
+ "mediaItem2", imageItemFileName, 10000, renderingMode);
+ mVideoEditor.addMediaItem(mediaImageItem);
+
+ final Rect startRect = new Rect((mediaImageItem.getHeight() / 3),
+ (mediaImageItem.getWidth() / 3), (mediaImageItem.getHeight() / 2),
+ (mediaImageItem.getWidth() / 2));
+ final Rect endRect = new Rect(0, 0, mediaImageItem.getWidth(),
+ mediaImageItem.getHeight());
+ final EffectKenBurns kbEffectOnMediaItem =
+ new EffectKenBurns(mediaImageItem, "KBOnM2", startRect, endRect,
+ 500, 3000);
+ mediaImageItem.addEffect(kbEffectOnMediaItem);
+
+ for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
+ final long duration1 = SystemClock.uptimeMillis();
+ mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
+ public void onProgress(Object item, int action, int progress) {
+ }
+ });
+ final long duration2 = SystemClock.uptimeMillis();
+ mediaImageItem.removeEffect(kbEffectOnMediaItem.getId());
+ mediaImageItem.addEffect(kbEffectOnMediaItem);
+ averageTime += duration2 - duration1;
+ }
+
+ final long durationToAddObjects = (averageTime);
+ final float timeTaken = (float)durationToAddObjects *
+ 1.0f/(float)NUM_OF_ITERATIONS;
+ loggingInfo[0] = "Time taken to Generate KenBurn Effect \t"
+ + timeTaken;
+ writeTimingInfo("testPerformanceWithKenBurn", loggingInfo);
+ }
+
+ /**
+ * To test the performance of generatePreview : with Transitions and
+ * Effect,Overlapping scenario
+ *
+ * @throws Exception
+ */
+ // TODO : remove PRF_010
+ @LargeTest
+ public void testPerformanceEffectOverlappingTransition() throws Exception {
+ final String videoItemFileName1 = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
+ final String videoItemFileName2 = INPUT_FILE_PATH
+ + "MPEG4_SP_640x480_15fps_512kbps_AACLC_48khz_132kbps_s_0_26.mp4";
+ final int videoStartTime1 = 0;
+ final int videoEndTime1 = 10000;
+ final int videoStartTime2 = 0;
+ final int videoEndTime2 = 10000;
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final int transitionDuration = 5000;
+ final int transitionBehavior = Transition.BEHAVIOR_MIDDLE_FAST;
+ final int effectItemStartTime = 5000;
+ final int effectItemDurationTime = 5000;
+ final int effectType = EffectColor.TYPE_COLOR;
+ final int effectColorType = EffectColor.GREEN;
+ long averageDuration = 0;
+
+ final String[] loggingInfo = new String[1];
+ final MediaVideoItem mediaVideoItem1 = new MediaVideoItem(mVideoEditor,
+ "mediaItem1", videoItemFileName1, renderingMode);
+ mediaVideoItem1.setExtractBoundaries(videoStartTime1, videoEndTime1);
+ mVideoEditor.addMediaItem(mediaVideoItem1);
+
+ final MediaVideoItem mediaVideoItem2 = new MediaVideoItem(mVideoEditor,
+ "mediaItem2", videoItemFileName2, renderingMode);
+ mediaVideoItem2.setExtractBoundaries(videoStartTime2, videoEndTime2);
+ mVideoEditor.addMediaItem(mediaVideoItem2);
+
+ final TransitionCrossfade transitionCrossFade = new TransitionCrossfade(
+ "transitionCrossFade", mediaVideoItem1, mediaVideoItem2,
+ transitionDuration, transitionBehavior);
+ mVideoEditor.addTransition(transitionCrossFade);
+
+ final EffectColor effectColor = new EffectColor(mediaVideoItem1,
+ "effect", effectItemStartTime, effectItemDurationTime, effectType,
+ effectColorType);
+ mediaVideoItem1.addEffect(effectColor);
+
+ for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
+ final long duration1 = SystemClock.uptimeMillis();
+ mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
+ public void onProgress(Object item, int action, int progress) {
+ }
+ });
+ final long duration2 = SystemClock.uptimeMillis();
+ mVideoEditor.removeTransition(transitionCrossFade.getId());
+ mVideoEditor.addTransition(transitionCrossFade);
+ averageDuration += (duration2 - duration1);
+ }
+ SystemClock.uptimeMillis();
+ final long durationToAddObjects = (averageDuration);
+ final float timeTaken = (float)durationToAddObjects *
+ 1.0f/(float)NUM_OF_ITERATIONS;
+ loggingInfo[0] =
+ "Time taken to testPerformanceEffectOverlappingTransition\t"
+ + timeTaken;
+ writeTimingInfo("testPerformanceEffectOverlappingTransition:",
+ loggingInfo);
+ }
+
+ /**
+ * To test creation of story board with Transition and Two Effects, Effect
+ * overlapping transitions
+ *
+ * @throws Exception
+ */
+ // TODO : remove PRF_011
+ @LargeTest
+ public void testPerformanceTransitionWithEffectOverlapping() throws Exception {
+ final String videoItemFileName1 = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
+ final String videoItemFileName2 = INPUT_FILE_PATH
+ + "MPEG4_SP_640x480_15fps_512kbps_AACLC_48khz_132kbps_s_0_26.mp4";
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final int transitionDuration = 5000;
+ final int transitionBehavior = Transition.BEHAVIOR_MIDDLE_FAST;
+ final int effectItemStartTime1 = 5000;
+ final int effectItemDurationTime1 = 5000;
+ final int effectType1 = EffectColor.TYPE_COLOR;
+ final int effectColorType1 = EffectColor.GREEN;
+ final int effectItemStartTime2 = 5000;
+ final int effectItemDurationTime2 = 5000;
+ final int effectType2 = EffectColor.TYPE_COLOR;
+ final int effectColorType2 = EffectColor.GREEN;
+ int averageTime = 0;
+ final String[] loggingInfo = new String[1];
+
+ final MediaVideoItem mediaVideoItem1 = new MediaVideoItem(mVideoEditor,
+ "mediaItem1", videoItemFileName1, renderingMode);
+ mVideoEditor.addMediaItem(mediaVideoItem1);
+
+ final MediaVideoItem mediaVideoItem2 = new MediaVideoItem(mVideoEditor,
+ "mediaItem2", videoItemFileName2, renderingMode);
+ mVideoEditor.addMediaItem(mediaVideoItem2);
+
+ final TransitionCrossfade transitionCrossFade = new TransitionCrossfade(
+ "transitionCrossFade", mediaVideoItem1, mediaVideoItem2,
+ transitionDuration, transitionBehavior);
+ mVideoEditor.addTransition(transitionCrossFade);
+
+ final EffectColor effectColor1 = new EffectColor(mediaVideoItem1,
+ "effect1", effectItemStartTime1, effectItemDurationTime1,
+ effectType1, effectColorType1);
+ mediaVideoItem1.addEffect(effectColor1);
+
+ final EffectColor effectColor2 = new EffectColor(mediaVideoItem2,
+ "effect2", effectItemStartTime2, effectItemDurationTime2,
+ effectType2, effectColorType2);
+ mediaVideoItem2.addEffect(effectColor2);
+
+ for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
+ final long duration1 = SystemClock.uptimeMillis();
+ mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
+ public void onProgress(Object item, int action, int progress) {
+ }
+ });
+ final long duration2 = SystemClock.uptimeMillis();
+ mVideoEditor.removeTransition(transitionCrossFade.getId());
+ mVideoEditor.addTransition(transitionCrossFade);
+ averageTime += duration2 - duration1;
+ }
+ final long durationToAddObjects = (averageTime);
+ final float timeTaken = (float)durationToAddObjects *
+ 1.0f/(float)NUM_OF_ITERATIONS;
+ loggingInfo[0] = "Time taken to TransitionWithEffectOverlapping\t"
+ + timeTaken;
+ writeTimingInfo("testPerformanceTransitionWithEffectOverlapping",
+ loggingInfo);
+ }
+
+ /**
+ *To test ThumbnailList for H264
+ */
+ // TODO : TC_PRF_12
+ @LargeTest
+ public void testThumbnailH264NonIFrame() throws Exception {
+ final String videoItemFilename = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
+ final int outWidth = 1080;
+ final int outHeight = 720;
+ final int atTime = 2400;
+ long durationToAddObjects = 0;
+ int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String[] loggingInfo = new String[1];
+ final MediaVideoItem mediaVideoItem = new MediaVideoItem(mVideoEditor,
+ "m1", videoItemFilename, renderingMode);
+ assertNotNull("MediaVideoItem", mediaVideoItem);
+
+ for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
+ final long duration1 = SystemClock.uptimeMillis();
+ mediaVideoItem.getThumbnail(outWidth, outHeight, atTime + i);
+ final long duration2 = SystemClock.uptimeMillis();
+ durationToAddObjects += (duration2 - duration1);
+ }
+ final float timeTaken = (float)durationToAddObjects *
+ 1.0f/(float)NUM_OF_ITERATIONS;
+ loggingInfo[0] = "Time taken for Thumbnail generation \t"
+ + timeTaken;
+ writeTimingInfo("testThumbnailH264NonIFrame", loggingInfo);
+ }
+
+ /**
+ *To test ThumbnailList for H264
+ */
+ // TODO : TC_PRF_13
+ @LargeTest
+ public void testThumbnailH264AnIFrame() throws Exception {
+ final String videoItemFilename = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
+ final int outWidth = 1080;
+ final int outHeight = 720;
+ final int atTime = 3000;
+ int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String[] loggingInfo = new String[1];
+ long durationToAddObjects = 0;
+
+ final MediaVideoItem mediaVideoItem = new MediaVideoItem(mVideoEditor,
+ "m1", videoItemFilename, renderingMode);
+ assertNotNull("MediaVideoItem", mediaVideoItem);
+
+ for (int i = 0; i < NUM_OF_ITERATIONS; i++) {
+ final long duration1 = SystemClock.uptimeMillis();
+ mediaVideoItem.getThumbnail(outWidth, outHeight, atTime + i);
+ final long duration2 = SystemClock.uptimeMillis();
+ durationToAddObjects += (duration2 - duration1);
+ }
+ final float timeTaken = (float)durationToAddObjects *
+ 1.0f/(float)NUM_OF_ITERATIONS;
+ loggingInfo[0] = "Time taken Thumbnail generation \t"
+ + timeTaken;
+ writeTimingInfo("testThumbnailH264AnIFrame", loggingInfo);
+ }
+
+ /**
+ * To test the performance : With an audio track
+ *
+ * @throws Exception
+ */
+ // TODO : remove PRF_014
+ @LargeTest
+ public void testPerformanceWithAudioTrack() throws Exception {
+ final String videoItemFileName1 = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
+ final String audioFilename1 = INPUT_FILE_PATH +
+ "AACLC_44.1kHz_256kbps_s_1_17.mp4";
+ final String audioFilename2 = INPUT_FILE_PATH +
+ "AMRNB_8KHz_12.2Kbps_m_1_17.3gp";
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final int audioVolume = 50;
+ final String[] loggingInfo = new String[2];
+ float timeTaken = 0.0f;
+
+ final MediaVideoItem mediaVideoItem = new MediaVideoItem(mVideoEditor,
+ "mediaItem1", videoItemFileName1, renderingMode);
+ mVideoEditor.addMediaItem(mediaVideoItem);
+
+ final AudioTrack audioTrack1 = new AudioTrack(mVideoEditor,
+ "Audio Track1", audioFilename1);
+ audioTrack1.disableDucking();
+ audioTrack1.setVolume(audioVolume);
+ mVideoEditor.addAudioTrack(audioTrack1);
+
+ long beginTime = SystemClock.uptimeMillis();
+ mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
+ public void onProgress(Object item, int action, int progress) {
+ }
+ });
+ timeTaken = calculateTimeTaken(beginTime, 1);
+ loggingInfo[0] = "Time taken for 1st Audio Track (AACLC)\t"
+ + timeTaken;
+
+ final AudioTrack audioTrack2 = new AudioTrack(mVideoEditor,
+ "Audio Track2", audioFilename2);
+ audioTrack2.enableLoop();
+
+ beginTime = SystemClock.uptimeMillis();
+ mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
+ public void onProgress(Object item, int action, int progress) {
+ }
+ });
+ timeTaken = calculateTimeTaken(beginTime, 1);
+ loggingInfo[1] = "\n\tTime taken for 2nd Audio Track(AMRNB)\t"
+ + timeTaken;
+
+ writeTimingInfo("testPerformanceWithAudioTrack", loggingInfo);
+ }
+
+ /**
+ * To test the performance of adding and removing the
+ * image media item with 640 x 480
+ *
+ * @throws Exception
+ */
+ // TODO : remove PRF_015
+ @LargeTest
+ public void testPerformanceAddRemoveImageItem640x480() throws Exception {
+ final String imageItemFileName = INPUT_FILE_PATH + "IMG_640x480.jpg";
+ final int imageItemDuration = 0;
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String[] loggingInfo = new String[3];
+
+ float timeTaken = 0.0f;
+
+ final MediaImageItem[] mediaImageItem =
+ new MediaImageItem[NUM_OF_ITERATIONS];
+ long beginTime = SystemClock.uptimeMillis();
+ createImageItems(mediaImageItem, imageItemFileName, renderingMode,
+ imageItemDuration);
+ timeTaken = calculateTimeTaken(beginTime, NUM_OF_ITERATIONS);
+ loggingInfo[0] = "Time taken to Create Media Image Item (640x480)\t"
+ + timeTaken;
+
+ beginTime = SystemClock.uptimeMillis();
+ addImageItems(mediaImageItem);
+ timeTaken = calculateTimeTaken(beginTime, NUM_OF_ITERATIONS);
+ loggingInfo[1] = "\n\tTime taken to add Media Image Item (640x480)\t"
+ + timeTaken;
+
+ beginTime = SystemClock.uptimeMillis();
+ removeImageItems(mediaImageItem);
+ timeTaken = calculateTimeTaken(beginTime, NUM_OF_ITERATIONS);
+ loggingInfo[2] = "\n\tTime taken to remove Media Image Item (640x480)\t"
+ + timeTaken;
+ writeTimingInfo("testPerformanceAddRemoveImageItem640x480 (in mSec)", loggingInfo);
+ }
+
+
+}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/VideoEditorStressTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/VideoEditorStressTest.java
new file mode 100755
index 0000000..0e70dd3
--- /dev/null
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/stress/VideoEditorStressTest.java
@@ -0,0 +1,1317 @@
+/*
+ * 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 com.android.mediaframeworktest.stress;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.FileWriter;
+import java.io.Writer;
+import java.util.List;
+
+import android.graphics.Bitmap;
+import android.graphics.Rect;
+import android.media.videoeditor.AudioTrack;
+import android.media.videoeditor.EffectColor;
+import android.media.videoeditor.EffectKenBurns;
+import android.media.videoeditor.MediaImageItem;
+import android.media.videoeditor.MediaItem;
+import android.media.videoeditor.MediaProperties;
+import android.media.videoeditor.MediaVideoItem;
+import android.media.videoeditor.OverlayFrame;
+import android.media.videoeditor.Transition;
+import android.media.videoeditor.TransitionCrossfade;
+import android.media.videoeditor.TransitionAlpha;
+import android.media.videoeditor.TransitionFadeBlack;
+import android.media.videoeditor.TransitionSliding;
+import android.media.videoeditor.VideoEditor;
+import android.os.Environment;
+import android.test.ActivityInstrumentationTestCase;
+import android.media.videoeditor.VideoEditor.MediaProcessingProgressListener;
+import android.os.Environment;
+import android.os.SystemClock;
+import android.test.ActivityInstrumentationTestCase;
+import android.media.videoeditor.VideoEditor.ExportProgressListener;
+import android.media.videoeditor.VideoEditorFactory;
+import android.media.videoeditor.ExtractAudioWaveformProgressListener;
+
+import android.os.Debug;
+import android.util.Log;
+
+import com.android.mediaframeworktest.MediaFrameworkTest;
+import android.test.suitebuilder.annotation.LargeTest;
+import com.android.mediaframeworktest.VideoEditorHelper;
+
+/**
+ * Junit / Instrumentation - performance measurement for media player and
+ * recorder
+ */
+public class VideoEditorStressTest
+ extends ActivityInstrumentationTestCase<MediaFrameworkTest> {
+
+ private final String TAG = "VideoEditorPerformance";
+
+ private final String PROJECT_LOCATION = VideoEditorHelper.PROJECT_LOCATION_COMMON;
+
+ private final String INPUT_FILE_PATH = VideoEditorHelper.INPUT_FILE_PATH_COMMON;
+
+ private final String VIDEOEDITOR_OUTPUT = PROJECT_LOCATION +
+ "VideoEditorStressMemOutput.txt";
+
+ private long BeginJavaMemory;
+ private long AfterJavaMemory;
+
+ private long BeginNativeMemory;
+ private long AfterNativeMemory;
+
+ public VideoEditorStressTest() {
+ super("com.android.mediaframeworktest", MediaFrameworkTest.class);
+ new File(VIDEOEDITOR_OUTPUT).delete();
+ }
+
+ private final String PROJECT_CLASS_NAME =
+ "android.media.videoeditor.VideoEditorImpl";
+ private VideoEditor mVideoEditor;
+ private VideoEditorHelper mVideoEditorHelper;
+
+ @Override
+ protected void setUp() throws Exception {
+ // setup for each test case.
+ super.setUp();
+ mVideoEditorHelper = new VideoEditorHelper();
+ // Create a random String which will be used as project path, where all
+ // project related files will be stored.
+ final String projectPath =
+ mVideoEditorHelper.createRandomFile(PROJECT_LOCATION);
+ mVideoEditor = mVideoEditorHelper.createVideoEditor(projectPath);
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ mVideoEditorHelper.destroyVideoEditor(mVideoEditor);
+ // Clean the directory created as project path
+ mVideoEditorHelper.deleteProject(new File(mVideoEditor.getPath()));
+ System.gc();
+ super.tearDown();
+ }
+
+ private void writeTimingInfo(String[] information)
+ throws Exception {
+ File outFile = new File(VIDEOEDITOR_OUTPUT);
+ Writer output = new BufferedWriter(new FileWriter(outFile, true));
+ for (int i = 0; i < information.length; i++) {
+ output.write(information[i]);
+ }
+ output.close();
+ }
+
+ private void writeTestCaseHeader(String testCaseName)
+ throws Exception {
+ File outFile = new File(VIDEOEDITOR_OUTPUT);
+ Writer output = new BufferedWriter(new FileWriter(outFile, true));
+ output.write("\n\n" + testCaseName + "\n");
+ output.close();
+ }
+
+ private void getBeginMemory() throws Exception {
+ System.gc();
+ Thread.sleep(2500);
+ BeginNativeMemory = Debug.getNativeHeapAllocatedSize();
+ }
+ private void getAfterMemory_updateLog(String[] loggingInfo, boolean when,
+ int iteration)
+ throws Exception {
+ System.gc();
+ Thread.sleep(2500);
+ AfterNativeMemory = Debug.getNativeHeapAllocatedSize();
+ if(when == false){
+ loggingInfo[0] = "\n Before Remove: iteration No.= " + iteration +
+ "\t " + (AfterNativeMemory - BeginNativeMemory);
+ } else {
+ loggingInfo[0] = "\n After Remove: iteration No.= " + iteration +
+ "\t " + (AfterNativeMemory - BeginNativeMemory);
+ }
+ writeTimingInfo(loggingInfo);
+ }
+
+ /**
+ * To stress test MediaItem(Video Item) adding functionality
+ *
+ * @throws Exception
+ */
+ // TODO : remove TC_STR_001
+ @LargeTest
+ public void testStressAddRemoveVideoItem() throws Exception {
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+
+ final String videoItemFileName1 = INPUT_FILE_PATH +
+ "H264_BP_176x144_15fps_144kbps_AMRNB_8kHz_12.2kbps_m_1_17.3gp";
+ final String videoItemFileName2 = INPUT_FILE_PATH +
+ "MPEG4_SP_720x480_30fps_280kbps_AACLC_48kHz_96kbps_s_0_21.mp4";
+ final String videoItemFileName3 = INPUT_FILE_PATH +
+ "H263_profile0_176x144_15fps_128kbps_1_35.3gp";
+ final String videoItemFileName4 = INPUT_FILE_PATH +
+ "MPEG4_SP_640x480_15fps_1200kbps_AACLC_48khz_64kbps_m_1_17.3gp";
+ final String[] loggingInfo = new String[1];
+ writeTestCaseHeader("testStressAddRemoveVideoItem");
+ int i = 0;
+ getBeginMemory();
+
+ for ( i = 0; i < 50; i++) {
+ if (i % 4 == 0) {
+ final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor,
+ "m1" + i, videoItemFileName1, renderingMode);
+ mediaItem1.setExtractBoundaries(0, 5000);
+ mVideoEditor.addMediaItem(mediaItem1);
+ }
+ if (i % 4 == 1) {
+ final MediaVideoItem mediaItem2 = new MediaVideoItem(mVideoEditor,
+ "m2" + i, videoItemFileName2, renderingMode);
+ mediaItem2.setExtractBoundaries(0, 10000);
+ mVideoEditor.addMediaItem(mediaItem2);
+ }
+ if (i % 4 == 2) {
+ final MediaVideoItem mediaItem3 = new MediaVideoItem(mVideoEditor,
+ "m3" + i, videoItemFileName3, renderingMode);
+ mediaItem3.setExtractBoundaries(30000, 45000);
+ mVideoEditor.addMediaItem(mediaItem3);
+ }
+ if (i % 4 == 3) {
+ final MediaVideoItem mediaItem4 = new MediaVideoItem(mVideoEditor,
+ "m4" + i, videoItemFileName4, renderingMode);
+ mediaItem4.setExtractBoundaries(10000, 30000);
+ mVideoEditor.addMediaItem(mediaItem4);
+ }
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+ }
+ getAfterMemory_updateLog(loggingInfo, false, i);
+
+ /** Remove items and check for memory leak if any */
+ getBeginMemory();
+ for ( i = 0; i < 50; i++) {
+ if (i % 4 == 0) {
+ mVideoEditor.removeMediaItem("m1" + i);
+ }
+ if (i % 4 == 1) {
+ mVideoEditor.removeMediaItem("m2" + i);
+ }
+ if (i % 4 == 2) {
+ mVideoEditor.removeMediaItem("m3" + i);
+ }
+ if (i % 4 == 3) {
+ mVideoEditor.removeMediaItem("m4" + i);
+ }
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+ }
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+
+ /**
+ * To stress test MediaItem(Image Item) adding functionality
+ *
+ * @throws Exception
+ */
+ // TODO : remove TC_STR_002
+ @LargeTest
+ public void testStressAddRemoveImageItem() throws Exception {
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String ImageItemFileName1 = INPUT_FILE_PATH +
+ "IMG_1600x1200.jpg";
+ final String ImageItemFileName2 = INPUT_FILE_PATH +
+ "IMG_640x480.jpg";
+ final String ImageItemFileName3 = INPUT_FILE_PATH +
+ "IMG_320x240.jpg";
+ final String ImageItemFileName4 = INPUT_FILE_PATH +
+ "IMG_176x144.jpg";
+ final String[] loggingInfo = new String[1];
+ int i = 0;
+ writeTestCaseHeader("testStressAddRemoveImageItem");
+ getBeginMemory();
+ for ( i = 0; i < 50; i++) {
+ if (i % 4 == 0) {
+ final MediaImageItem mediaItem1 = new MediaImageItem(mVideoEditor,
+ "m1"+ i, ImageItemFileName1, 5000, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem1);
+ }
+ if (i % 4 == 1) {
+ final MediaImageItem mediaItem2 = new MediaImageItem(mVideoEditor,
+ "m2"+ i, ImageItemFileName2, 10000, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem2);
+ }
+ if (i % 4 == 2) {
+ final MediaImageItem mediaItem3 = new MediaImageItem(mVideoEditor,
+ "m3"+ i, ImageItemFileName3, 15000, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem3);
+ }
+ if (i % 4 == 3) {
+ final MediaImageItem mediaItem4 = new MediaImageItem(mVideoEditor,
+ "m4"+ i, ImageItemFileName4, 20000, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem4);
+ }
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+ }
+ getAfterMemory_updateLog(loggingInfo, false, i);
+
+ /** Remove items and check for memory leak if any */
+ getBeginMemory();
+ for ( i = 0; i < 50; i++) {
+ if (i % 4 == 0) {
+ mVideoEditor.removeMediaItem("m1"+i);
+ }
+ if (i % 4 == 1) {
+ mVideoEditor.removeMediaItem("m2"+i);
+ }
+ if (i % 4 == 2) {
+ mVideoEditor.removeMediaItem("m3"+i);
+ }
+ if (i % 4 == 3) {
+ mVideoEditor.removeMediaItem("m4"+i);
+ }
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+ }
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+
+ /**
+ * To stress test transition
+ *
+ * @throws Exception
+ */
+ // TODO : remove TC_STR_003
+ @LargeTest
+ public void testStressAddRemoveTransition() throws Exception {
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String VideoItemFileName1 = INPUT_FILE_PATH +
+ "H264_BP_800x480_15fps_512kbps_1_17.mp4";
+ final String ImageItemFileName2 = INPUT_FILE_PATH +
+ "IMG_1600x1200.jpg";
+ final String VideoItemFileName3 = INPUT_FILE_PATH +
+ "MPEG4_SP_640x480_15fps_512kbps_AACLC_48khz_132kbps_s_0_26.mp4";
+ final String maskFilename = INPUT_FILE_PATH +
+ "TransitionSpiral_QVGA.jpg";
+ final String[] loggingInfo = new String[1];
+ int i = 0;
+ writeTestCaseHeader("testStressAddRemoveTransition");
+ getBeginMemory();
+ for ( i = 0; i < 50; i++) {
+ if (i % 4 == 0) {
+ final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor,
+ "m1"+i, VideoItemFileName1, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem1);
+ mediaItem1.setExtractBoundaries(0, 10000);
+ final TransitionCrossfade tranCrossfade =
+ new TransitionCrossfade("transCF" + i, null,
+ mediaItem1, 5000, Transition.BEHAVIOR_MIDDLE_FAST);
+ mVideoEditor.addTransition(tranCrossfade);
+ }
+ if (i % 4 == 1) {
+ final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor,
+ "m1"+i, VideoItemFileName1, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem1);
+ mediaItem1.setExtractBoundaries(0, 10000);
+
+ final MediaImageItem mediaItem2 = new MediaImageItem(mVideoEditor,
+ "m2" +i, ImageItemFileName2, 10000, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem2);
+
+ final TransitionAlpha transitionAlpha =
+ mVideoEditorHelper.createTAlpha("transAlpha" + i, mediaItem1,
+ mediaItem2, 5000, Transition.BEHAVIOR_SPEED_UP,
+ maskFilename, 10, false);
+ transitionAlpha.setDuration(4000);
+ mVideoEditor.addTransition(transitionAlpha);
+ }
+ if (i % 4 == 2) {
+ final MediaImageItem mediaItem2 = new MediaImageItem(mVideoEditor,
+ "m2" + i, ImageItemFileName2, 10000, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem2);
+
+ final MediaVideoItem mediaItem3 = new MediaVideoItem(mVideoEditor,
+ "m3" + i, VideoItemFileName3, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem3);
+
+ mediaItem3.setExtractBoundaries(0, 10000);
+ final TransitionAlpha transitionAlpha =
+ mVideoEditorHelper.createTAlpha("transAlpha" + i, mediaItem2,
+ mediaItem3, 5000, Transition.BEHAVIOR_SPEED_UP,
+ maskFilename, 10, false);
+ transitionAlpha.setDuration(4000);
+ mVideoEditor.addTransition(transitionAlpha);
+
+ mediaItem3.setExtractBoundaries(0, 6000);
+
+ final TransitionSliding transition2And3 =
+ mVideoEditorHelper.createTSliding("transSlide" +i, mediaItem2,
+ mediaItem3, 3000, Transition.BEHAVIOR_MIDDLE_FAST,
+ TransitionSliding.DIRECTION_LEFT_OUT_RIGHT_IN);
+ mVideoEditor.addTransition(transition2And3);
+ }
+ if (i % 4 == 3) {
+ final MediaVideoItem mediaItem3 = new MediaVideoItem(mVideoEditor,
+ "m3" + i, VideoItemFileName3, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem3);
+ mediaItem3.setExtractBoundaries(0, 5000);
+
+ final TransitionFadeBlack transition3 =
+ mVideoEditorHelper.createTFadeBlack("transFB" +i, mediaItem3,
+ null, 2500, Transition.BEHAVIOR_SPEED_UP);
+ transition3.setDuration(500);
+ mVideoEditor.addTransition(transition3);
+ }
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+ }
+ getAfterMemory_updateLog(loggingInfo, false, i);
+
+ /** Remove items and check for memory leak if any */
+ getBeginMemory();
+ for ( i = 0; i < 50; i++) {
+ if (i % 4 == 0) {
+ mVideoEditor.removeTransition("transCF" + i);
+ mVideoEditor.removeMediaItem("m1" + i);
+ }
+ if (i % 4 == 1) {
+ mVideoEditor.removeTransition("transAlpha" + i);
+ mVideoEditor.removeMediaItem("m1" + i);
+ mVideoEditor.removeMediaItem("m2" + i);
+ }
+ if (i % 4 == 2) {
+ mVideoEditor.removeTransition("transSlide" +i);
+ mVideoEditor.removeMediaItem("m2" + i);
+ mVideoEditor.removeMediaItem("m3" + i);
+ }
+ if (i % 4 == 3) {
+ mVideoEditor.removeMediaItem("m3" + i);
+ }
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+ }
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+
+ /**
+ * To stress test overlay
+ *
+ * @throws Exception
+ */
+ // TODO : remove TC_STR_004
+ @LargeTest
+ public void testStressAddRemoveOverlay() throws Exception {
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String VideoItemFileName1 = INPUT_FILE_PATH +
+ "MPEG4_SP_640x480_15fps_512kbps_AACLC_48khz_132kbps_s_0_26.mp4";
+ final String ImageItemFileName2 = INPUT_FILE_PATH +
+ "IMG_640x480.jpg";
+ final String OverlayFile3 = INPUT_FILE_PATH +
+ "IMG_640x480_Overlay1.png";
+ final String OverlayFile4 = INPUT_FILE_PATH +
+ "IMG_640x480_Overlay2.png";
+ final String[] loggingInfo = new String[1];
+ int i = 0;
+ final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor,
+ "m1", VideoItemFileName1, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem1);
+
+ final MediaImageItem mediaItem2 = new MediaImageItem(mVideoEditor,
+ "m2", ImageItemFileName2, 10000, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem2);
+ writeTestCaseHeader("testStressAddRemoveOverlay");
+ getBeginMemory();
+ for ( i = 0; i < 50; i++) {
+ if (i % 3 == 0) {
+ mediaItem1.setExtractBoundaries(0, 10000);
+ final Bitmap mBitmap = mVideoEditorHelper.getBitmap(
+ OverlayFile3, 640, 480);
+ final OverlayFrame overlayFrame =
+ mVideoEditorHelper.createOverlay(mediaItem1, "overlay" + i,
+ mBitmap, 1000, 5000);
+ mediaItem1.addOverlay(overlayFrame);
+ mediaItem1.removeOverlay("overlay"+i);
+ }
+ if (i % 3 == 1) {
+ final Bitmap mBitmap = mVideoEditorHelper.getBitmap(
+ OverlayFile4, 640, 480);
+ final OverlayFrame overlayFrame =
+ mVideoEditorHelper.createOverlay(mediaItem2, "overlay" + i,
+ mBitmap, 1000, 5000);
+ mediaItem2.addOverlay(overlayFrame);
+ mediaItem2.removeOverlay("overlay"+i);
+ }
+ if (i % 3 == 2) {
+ mediaItem1.setExtractBoundaries(0, 10000);
+ final Bitmap mBitmap = mVideoEditorHelper.getBitmap(
+ OverlayFile4, 640, 480);
+ final OverlayFrame overlayFrame =
+ mVideoEditorHelper.createOverlay(mediaItem1, "overlay" + i,
+ mBitmap, 0, mediaItem1.getDuration());
+ mediaItem1.addOverlay(overlayFrame);
+ mediaItem1.removeOverlay("overlay"+i);
+ }
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+ }
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+
+ /**
+ * To stress test Effects
+ *
+ * @throws Exception
+ */
+ // TODO : remove TC_STR_005
+ @LargeTest
+ public void testStressAddRemoveEffects() throws Exception {
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String VideoItemFileName1 = INPUT_FILE_PATH +
+ "MPEG4_SP_640x480_15fps_1200kbps_AACLC_48khz_64kbps_m_1_17.3gp";
+ final String ImageItemFileName2 = INPUT_FILE_PATH +
+ "IMG_1600x1200.jpg";
+ final String[] loggingInfo = new String[1];
+ final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor,
+ "m1", VideoItemFileName1, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem1);
+ final MediaImageItem mediaItem2 = new MediaImageItem(mVideoEditor,
+ "m2", ImageItemFileName2, 10000, renderingMode);
+ int i = 0;
+ mVideoEditor.addMediaItem(mediaItem2);
+ writeTestCaseHeader("testStressAddRemoveEffects");
+ getBeginMemory();
+ for ( i = 0; i < 50; i++) {
+ if (i % 5 == 0) {
+ mediaItem1.setExtractBoundaries(10000, 30000);
+ final EffectColor effectColor1 =
+ mVideoEditorHelper.createEffectItem(mediaItem1, "effect1"+i,
+ 10000, (mediaItem1.getTimelineDuration()-1000),
+ EffectColor.TYPE_COLOR, EffectColor.GREEN);
+ mediaItem1.addEffect(effectColor1);
+ }
+ if (i % 5 == 1) {
+ mediaItem2.setDuration(20000);
+ final EffectColor effectColor1 =
+ mVideoEditorHelper.createEffectItem(mediaItem2, "effect1"+i,
+ 0, 4000, EffectColor.TYPE_GRADIENT, EffectColor.GRAY);
+ mediaItem2.addEffect(effectColor1);
+ }
+ if (i % 5 == 2) {
+ mediaItem1.setExtractBoundaries(10000, 30000);
+ final EffectColor effectColor1 =
+ mVideoEditorHelper.createEffectItem(mediaItem1, "effect1"+i,
+ (mediaItem1.getTimelineDuration() - 4000), 4000,
+ EffectColor.TYPE_SEPIA, 0);
+ mediaItem1.addEffect(effectColor1);
+ }
+ if (i % 5 == 3) {
+ mediaItem2.setDuration(20000);
+ final EffectColor effectColor1 =
+ mVideoEditorHelper.createEffectItem(mediaItem2, "effect1"+i,
+ 10000, 4000, EffectColor.TYPE_NEGATIVE, 0);
+ mediaItem2.addEffect(effectColor1);
+ }
+ if (i % 5 == 4) {
+ mediaItem2.setDuration(20000);
+ final Rect startRect = new Rect((mediaItem2.getHeight() / 3),
+ (mediaItem2.getWidth() / 3), (mediaItem2.getHeight() / 2),
+ (mediaItem2.getWidth() / 2));
+ final Rect endRect = new Rect(0, 0, mediaItem2.getWidth(),
+ mediaItem2.getHeight());
+ final EffectKenBurns kbEffectOnMediaItem = new EffectKenBurns(
+ mediaItem2, "KBOnM2" + i, startRect, endRect, 500,
+ (mediaItem2.getDuration() - 500));
+ mediaItem2.addEffect(kbEffectOnMediaItem);
+ }
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+ }
+ getAfterMemory_updateLog(loggingInfo, false, i);
+
+ /** Remove items and check for memory leak if any */
+ getBeginMemory();
+ for ( i = 0; i < 50; i++) {
+ if (i % 5 == 0) {
+ mediaItem1.removeEffect("effect1"+i);
+ }
+ if (i % 5 == 1) {
+ mediaItem1.removeEffect("effect1"+i);
+ }
+ if (i % 5 == 2) {
+ mediaItem1.removeEffect("effect1"+i);
+ }
+ if (i % 5 == 3) {
+ mediaItem1.removeEffect("effect1"+i);
+ }
+ if (i % 5 == 4) {
+ mediaItem1.removeEffect("KBOnM2"+i);
+ }
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+ }
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+
+ /**
+ * This method will test thumbnail list extraction in a loop = 200 for Video
+ * Item
+ *
+ * @throws Exception
+ */
+ // TODO : remove TC_STR_006
+ @LargeTest
+ public void testStressThumbnailVideoItem() throws Exception {
+ final String videoItemFileName = INPUT_FILE_PATH
+ + "H264_BP_640x480_15fps_1200Kbps_AACLC_48KHz_64kps_m_0_27.3gp";
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String[] loggingInfo = new String[1];
+ int i = 0;
+ final MediaVideoItem mediaVideoItem = new MediaVideoItem(mVideoEditor,
+ "m1", videoItemFileName, renderingMode);
+ writeTestCaseHeader("testStressThumbnailVideoItem");
+ getBeginMemory();
+ for ( i = 0; i < 50; i++) {
+ if (i % 4 == 0) {
+ final Bitmap[] thumbNails =
+ mediaVideoItem.getThumbnailList(mediaVideoItem.getWidth()*3,
+ mediaVideoItem.getHeight()*2, i, 5000, 2);
+ // Recycle this Bitmap array
+ for (int i1 = 0; i1 < thumbNails.length; i1++) {
+ thumbNails[i1].recycle();
+ }
+ }
+ if (i % 4 == 1) {
+ final Bitmap[] thumbNails =
+ mediaVideoItem.getThumbnailList(mediaVideoItem.getWidth()/2,
+ mediaVideoItem.getHeight() * 3, i, 5000, 2);
+ // Recycle this Bitmap array
+ for (int i1 = 0; i1 < thumbNails.length; i1++) {
+ thumbNails[i1].recycle();
+ }
+ }
+ if (i % 4 == 2) {
+ final Bitmap[] thumbNails =
+ mediaVideoItem.getThumbnailList(mediaVideoItem.getWidth()*2,
+ mediaVideoItem.getHeight() / 3, i, 5000, 2);
+ // Recycle this Bitmap array
+ for (int i1 = 0; i1 < thumbNails.length; i1++) {
+ thumbNails[i1].recycle();
+ }
+ }
+ if (i % 4 == 3) {
+ final Bitmap[] thumbNails =
+ mediaVideoItem.getThumbnailList(mediaVideoItem.getWidth(),
+ mediaVideoItem.getHeight(), i, 5000, 2);
+ // Recycle this Bitmap array
+ for (int i1 = 0; i1 < thumbNails.length; i1++) {
+ thumbNails[i1].recycle();
+ }
+ }
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+ }
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+
+ /**
+ * To stress test media properties
+ *
+ * @throws Exception
+ */
+ // TODO : remove TC_STR_007
+ @LargeTest
+ public void testStressMediaProperties() throws Exception {
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String VideoItemFileName1 = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
+ final String ImageItemFileName2 = INPUT_FILE_PATH +
+ "IMG_640x480.jpg";
+ final String AudioItemFileName3 = INPUT_FILE_PATH +
+ "AACLC_44.1kHz_256kbps_s_1_17.mp4";
+ final String[] loggingInfo = new String[1];
+ int i = 0;
+ final int videoAspectRatio = MediaProperties.ASPECT_RATIO_3_2;
+ final int videoFileType = MediaProperties.FILE_MP4;
+ final int videoCodecType = MediaProperties.VCODEC_H264BP;
+ final int videoDuration = 77366;
+ final int videoProfile = MediaProperties.H264_PROFILE_0_LEVEL_1_3;
+ final int videoHeight = MediaProperties.HEIGHT_720;
+ final int videoWidth = 1080;
+
+ final int imageAspectRatio = MediaProperties.ASPECT_RATIO_4_3;
+ final int imageFileType = MediaProperties.FILE_JPEG;
+ final int imageWidth = 640;
+ final int imageHeight = MediaProperties.HEIGHT_480;
+
+ final int audioDuration = 77554;
+ final int audioCodecType = MediaProperties.ACODEC_AAC_LC;
+ final int audioSamplingFrequency = 44100;
+ final int audioChannel = 2;
+ writeTestCaseHeader("testStressMediaProperties");
+ getBeginMemory();
+ for ( i = 0; i < 50; i++) {
+ if (i % 3 == 0) {
+ final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor,
+ "m1" + i, VideoItemFileName1, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem1);
+ mediaItem1.setExtractBoundaries(0, 20000);
+ assertEquals("Aspect Ratio Mismatch",
+ videoAspectRatio, mediaItem1.getAspectRatio());
+ assertEquals("File Type Mismatch",
+ videoFileType, mediaItem1.getFileType());
+ assertEquals("VideoCodec Mismatch",
+ videoCodecType, mediaItem1.getVideoType());
+ assertEquals("duration Mismatch",
+ videoDuration, mediaItem1.getDuration());
+ assertEquals("Video Profile ",
+ videoProfile, mediaItem1.getVideoProfile());
+ assertEquals("Video height ",
+ videoHeight, mediaItem1.getHeight());
+ assertEquals("Video width ",
+ videoWidth, mediaItem1.getWidth());
+ mVideoEditor.removeMediaItem("m1" + i);
+ }
+ if (i % 3 == 1) {
+ final MediaImageItem mediaItem2 = new MediaImageItem(mVideoEditor,
+ "m2" + i, ImageItemFileName2, 10000, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem2);
+ assertEquals("Aspect Ratio Mismatch",
+ imageAspectRatio, mediaItem2.getAspectRatio());
+ assertEquals("File Type Mismatch",
+ imageFileType, mediaItem2.getFileType());
+ assertEquals("Image height",
+ imageHeight, mediaItem2.getHeight());
+ assertEquals("Image width",
+ imageWidth, mediaItem2.getWidth());
+ mVideoEditor.removeMediaItem("m2" + i);
+ }
+ if (i % 3 == 2) {
+ final AudioTrack mediaItem3 = new AudioTrack(mVideoEditor,
+ "m3" + i, AudioItemFileName3);
+ mVideoEditor.addAudioTrack(mediaItem3);
+ assertEquals("AudioType Mismatch", audioCodecType,
+ mediaItem3.getAudioType());
+ assertEquals("Audio Sampling", audioSamplingFrequency,
+ mediaItem3.getAudioSamplingFrequency());
+ assertEquals("Audio Channels",
+ audioChannel, mediaItem3.getAudioChannels());
+ assertEquals("duration Mismatch", audioDuration,
+ mediaItem3.getDuration());
+ mVideoEditor.removeAudioTrack("m3" + i);
+ }
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+ }
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+
+ /**
+ * To stress test insert and move of mediaitems
+ *
+ * @throws Exception
+ */
+ // TODO : remove TC_STR_008
+ @LargeTest
+ public void testStressInsertMovieItems() throws Exception {
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String VideoItemFileName1 = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
+ final String VideoItemFileName2 = INPUT_FILE_PATH +
+ "H264_BP_800x480_15fps_512kbps_1_17.mp4";
+ final String VideoItemFileName3 = INPUT_FILE_PATH +
+ "MPEG4_SP_640x480_15fps_1200kbps_AACLC_48khz_64kbps_m_1_17.3gp";
+ final String[] loggingInfo = new String[1];
+ int i = 0;
+ writeTestCaseHeader("testStressInsertMoveItems");
+
+ final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor,
+ "m1", VideoItemFileName1, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem1);
+ mediaItem1.setExtractBoundaries(0, 10000);
+
+ final MediaVideoItem mediaItem2 = new MediaVideoItem(mVideoEditor,
+ "m2", VideoItemFileName2, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem2);
+ mediaItem2.setExtractBoundaries(0, 15000);
+
+ getBeginMemory();
+ for ( i = 0; i < 50; i++) {
+ final MediaVideoItem mediaItem3 = new MediaVideoItem(mVideoEditor,
+ "m3" + i, VideoItemFileName3, renderingMode);
+ mediaItem3.setExtractBoundaries(0, 15000);
+ mVideoEditor.insertMediaItem(mediaItem3, "m1");
+ mVideoEditor.moveMediaItem("m2", "m3" + i);
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+ }
+ getAfterMemory_updateLog(loggingInfo, false, i);
+
+ /** Remove items and check for memory leak if any */
+ getBeginMemory();
+ for ( i = 0; i < 50; i++) {
+ mVideoEditor.removeMediaItem("m3" + i);
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+ }
+ mVideoEditor.removeMediaItem("m2");
+ mVideoEditor.removeMediaItem("m1");
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+
+ /**
+ * To stress test : load and save
+ *
+ * @throws Exception
+ */
+ // TODO : remove TC_STR_009
+ @LargeTest
+ public void testStressLoadAndSave() throws Exception {
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String VideoItemFileName1 = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
+ final String VideoItemFileName2 = INPUT_FILE_PATH +
+ "H264_BP_800x480_15fps_512kbps_1_17.mp4";
+ final String VideoItemFileName3 = INPUT_FILE_PATH +
+ "MPEG4_SP_640x480_15fps_1200kbps_AACLC_48khz_64kbps_m_1_17.3gp";
+ final String ImageItemFileName4 = INPUT_FILE_PATH +
+ "IMG_640x480.jpg";
+ final String ImageItemFileName5 = INPUT_FILE_PATH +
+ "IMG_176x144.jpg";
+ final String OverlayFile6 = INPUT_FILE_PATH +
+ "IMG_640x480_Overlay1.png";
+ final String[] loggingInfo = new String[1];
+ int i = 0;
+ final String[] projectPath = new String[10];
+ writeTestCaseHeader("testStressLoadAndSave");
+ getBeginMemory();
+ for( i=0; i < 10; i++){
+
+ projectPath[i] =
+ mVideoEditorHelper.createRandomFile(PROJECT_LOCATION);
+ final VideoEditor mVideoEditor1 =
+ mVideoEditorHelper.createVideoEditor(projectPath[i]);
+
+ final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor1,
+ "m1", VideoItemFileName1, renderingMode);
+ mVideoEditor1.addMediaItem(mediaItem1);
+ mediaItem1.setExtractBoundaries(0, 10000);
+
+ final MediaVideoItem mediaItem2 = new MediaVideoItem(mVideoEditor1,
+ "m2", VideoItemFileName2, renderingMode);
+ mVideoEditor1.addMediaItem(mediaItem2);
+ mediaItem2.setExtractBoundaries(mediaItem2.getDuration()/4,
+ mediaItem2.getDuration()/2);
+
+ final MediaVideoItem mediaItem3 = new MediaVideoItem(mVideoEditor1,
+ "m3", VideoItemFileName3, renderingMode);
+ mVideoEditor1.addMediaItem(mediaItem3);
+ mediaItem3.setExtractBoundaries(mediaItem3.getDuration()/2,
+ mediaItem3.getDuration());
+
+ final MediaImageItem mediaItem4 = new MediaImageItem(mVideoEditor1,
+ "m4", ImageItemFileName4, 5000, renderingMode);
+ mVideoEditor1.addMediaItem(mediaItem4);
+
+ final MediaImageItem mediaItem5 = new MediaImageItem(mVideoEditor1,
+ "m5", ImageItemFileName5, 5000, renderingMode);
+ mVideoEditor1.addMediaItem(mediaItem5);
+
+ final EffectColor effectColor1 =
+ mVideoEditorHelper.createEffectItem(mediaItem3, "effect1",
+ 10000, 2000, EffectColor.TYPE_COLOR, EffectColor.GREEN);
+ mediaItem3.addEffect(effectColor1);
+
+ final Bitmap mBitmap = mVideoEditorHelper.getBitmap(OverlayFile6,
+ 640, 480);
+ final OverlayFrame overlayFrame =
+ mVideoEditorHelper.createOverlay(mediaItem4, "overlay",
+ mBitmap, 4000, 1000);
+ mediaItem4.addOverlay(overlayFrame);
+
+ final TransitionCrossfade tranCrossfade =
+ new TransitionCrossfade("transCF", mediaItem1,
+ mediaItem2, 5000, Transition.BEHAVIOR_MIDDLE_FAST);
+ mVideoEditor1.addTransition(tranCrossfade);
+
+ final EffectColor effectColor2 =
+ mVideoEditorHelper.createEffectItem(mediaItem4, "effect2", 0,
+ mediaItem4.getDuration(), EffectColor.TYPE_COLOR,
+ EffectColor.PINK);
+ mediaItem4.addEffect(effectColor2);
+
+ mVideoEditor1.generatePreview(new MediaProcessingProgressListener() {
+ public void onProgress(Object item, int action, int progress) {
+ }
+ });
+
+ mVideoEditor1.save();
+ mVideoEditor1.release();
+
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+ getAfterMemory_updateLog(loggingInfo, false, i);
+
+ /** Remove items and check for memory leak if any */
+ getBeginMemory();
+ for( i=0; i<10; i++){
+ final VideoEditor mVideoEditor1b =
+ VideoEditorFactory.load(projectPath[i], true);
+ List<MediaItem> mediaList = mVideoEditor1b.getAllMediaItems();
+ assertEquals("Media Item List Size", 5, mediaList.size());
+
+ mediaList.get(3).removeEffect("effect1");
+ mediaList.get(3).removeEffect("effect2");
+ mediaList.get(2).removeOverlay("overlay");
+ mVideoEditor1b.removeTransition("transCF");
+ mVideoEditor1b.removeMediaItem("m5");
+ mVideoEditor1b.removeMediaItem("m4");
+ mVideoEditor1b.removeMediaItem("m3");
+ mVideoEditor1b.removeMediaItem("m2");
+ mVideoEditor1b.removeMediaItem("m1");
+ mVideoEditor1b.release();
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+
+ /**
+ * To stress test : Multiple Export
+ *
+ * @throws Exception
+ */
+ // TODO : remove TC_STR_010
+ @LargeTest
+ public void testStressMultipleExport() throws Exception {
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String VideoItemFileName1 = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
+ final String VideoItemFileName2 = INPUT_FILE_PATH +
+ "H264_BP_800x480_15fps_512kbps_1_17.mp4";
+ final String[] loggingInfo = new String[1];
+ final String outFilename = mVideoEditorHelper.createRandomFile(
+ mVideoEditor.getPath() + "/") + ".3gp";
+ int i = 0;
+ writeTestCaseHeader("testStressMultipleExport");
+ getBeginMemory();
+ final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor,
+ "m1", VideoItemFileName1, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem1);
+ mediaItem1.setExtractBoundaries(0, 10000);
+
+ final MediaVideoItem mediaItem2 = new MediaVideoItem(mVideoEditor,
+ "m2", VideoItemFileName2, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem2);
+ mediaItem2.setExtractBoundaries(0, 15000);
+
+ for ( i = 0; i < 50; i++) {
+ if(i%4 ==0){
+ final int aspectRatio = MediaProperties.ASPECT_RATIO_4_3;
+ mVideoEditor.setAspectRatio(aspectRatio);
+ mVideoEditor.export(outFilename, MediaProperties.HEIGHT_480,
+ MediaProperties.BITRATE_256K,MediaProperties.ACODEC_AAC_LC,
+ MediaProperties.VCODEC_H263,
+ new ExportProgressListener() {
+ public void onProgress(VideoEditor ve, String outFileName,
+ int progress) {
+ }
+ });
+ }
+ if(i%4 ==1){
+ final int aspectRatio = MediaProperties.ASPECT_RATIO_5_3;
+ mVideoEditor.setAspectRatio(aspectRatio);
+ mVideoEditor.export(outFilename, MediaProperties.HEIGHT_144,
+ MediaProperties.BITRATE_384K,MediaProperties.ACODEC_AAC_LC,
+ MediaProperties.VCODEC_MPEG4,
+ new ExportProgressListener() {
+ public void onProgress(VideoEditor ve, String outFileName,
+ int progress) {
+ }
+ });
+ }
+ if(i%4 ==2){
+ final int aspectRatio = MediaProperties.ASPECT_RATIO_11_9;
+ mVideoEditor.setAspectRatio(aspectRatio);
+ mVideoEditor.export(outFilename, MediaProperties.HEIGHT_144,
+ MediaProperties.BITRATE_512K,MediaProperties.ACODEC_AAC_LC,
+ MediaProperties.VCODEC_H264BP,
+ new ExportProgressListener() {
+ public void onProgress(VideoEditor ve, String outFileName,
+ int progress) {
+ }
+ });
+ }
+ if(i%4 ==3){
+ final int aspectRatio = MediaProperties.ASPECT_RATIO_3_2;
+ mVideoEditor.setAspectRatio(aspectRatio);
+ mVideoEditor.export(outFilename, MediaProperties.HEIGHT_480,
+ MediaProperties.BITRATE_800K,MediaProperties.ACODEC_AAC_LC,
+ MediaProperties.VCODEC_H264BP,
+ new ExportProgressListener() {
+ public void onProgress(VideoEditor ve, String outFileName,
+ int progress) {
+ }
+ });
+ }
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+ }
+ getAfterMemory_updateLog(loggingInfo, false, i);
+
+ /** Remove items and check for memory leak if any */
+ getBeginMemory();
+ mVideoEditor.removeMediaItem("m2");
+ mVideoEditor.removeMediaItem("m1");
+
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+
+ /**
+ * To stress test Media Item,Overlays,Transitions and Ken Burn
+ *
+ * @throws Exception
+ */
+ // TODO : remove TC_STR_011
+ @LargeTest
+ public void testStressOverlayTransKenBurn() throws Exception {
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String VideoItemFileName1 = INPUT_FILE_PATH +
+ "H264_BP_640x480_30fps_256kbps_1_17.mp4";
+ final String ImageItemFileName2 = INPUT_FILE_PATH +
+ "IMG_640x480.jpg";
+ final String OverlayFile3 = INPUT_FILE_PATH +
+ "IMG_640x480_Overlay1.png";
+ final String audioFilename4 = INPUT_FILE_PATH +
+ "AACLC_44.1kHz_256kbps_s_1_17.mp4";
+ int i = 0;
+ final String[] loggingInfo = new String[1];
+ writeTestCaseHeader("testStressOverlayTransKenBurn");
+ getBeginMemory();
+ for ( i = 0; i < 10; i++) {
+ final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor,
+ "m1" + i, VideoItemFileName1, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem1);
+ mediaItem1.setExtractBoundaries(0, 10000);
+
+ final MediaImageItem mediaItem2 = new MediaImageItem(mVideoEditor,
+ "m2" + i, ImageItemFileName2, 10000, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem2);
+
+ final EffectColor effectColor1 =
+ mVideoEditorHelper.createEffectItem(mediaItem1, "effect1"+i,
+ (mediaItem1.getDuration() - 4000), 4000,
+ EffectColor.TYPE_SEPIA, 0);
+ mediaItem1.addEffect(effectColor1);
+
+ final TransitionCrossfade tranCrossfade =
+ new TransitionCrossfade("transCF" + i, mediaItem1,
+ mediaItem2, 4000, Transition.BEHAVIOR_MIDDLE_FAST);
+ mVideoEditor.addTransition(tranCrossfade);
+
+ final Bitmap mBitmap = mVideoEditorHelper.getBitmap(OverlayFile3,
+ 640, 480);
+ final OverlayFrame overlayFrame =
+ mVideoEditorHelper.createOverlay(mediaItem1, "overlay" + i,
+ mBitmap, 1000, 5000);
+ mediaItem1.addOverlay(overlayFrame);
+
+ final Rect startRect = new Rect((mediaItem2.getHeight() / 3),
+ (mediaItem2.getWidth() / 3), (mediaItem2.getHeight() / 2),
+ (mediaItem2.getWidth() / 2));
+ final Rect endRect = new Rect(0, 0, mediaItem2.getWidth(),
+ mediaItem2.getHeight());
+
+ final EffectKenBurns kbEffectOnMediaItem = new EffectKenBurns(
+ mediaItem2, "KBOnM2" + i, startRect, endRect, 500,
+ (mediaItem2.getDuration()-500));
+ mediaItem2.addEffect(kbEffectOnMediaItem);
+
+ if(i == 5) {
+ final AudioTrack audioTrack1 = new AudioTrack(mVideoEditor,
+ "Audio Track1", audioFilename4);
+ mVideoEditor.addAudioTrack(audioTrack1);
+ }
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+ getAfterMemory_updateLog(loggingInfo, false, i);
+
+ /** Remove items and check for memory leak if any */
+ getBeginMemory();
+ for ( i = 0; i < 10; i++) {
+ MediaImageItem m2 = (MediaImageItem)mVideoEditor.getMediaItem("m2"+i);
+ MediaVideoItem m1 = (MediaVideoItem)mVideoEditor.getMediaItem("m1"+i);
+ m2.removeEffect("KBOnM2" + i);
+ m1.removeOverlay("overlay" + i);
+ mVideoEditor.removeTransition("transCF" + i);
+ m1.removeEffect("effect1" + i);
+ mVideoEditor.removeMediaItem("m2" + i);
+ mVideoEditor.removeMediaItem("m1" + i);
+ if(i == 5) {
+ mVideoEditor.removeAudioTrack("Audio Track1");
+ }
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+
+ /**
+ * To test the performance : With an audio track with Video
+ *
+ * @throws Exception
+ */
+ // TODO : remove TC_STR_012
+ @LargeTest
+ public void testStressAudioTrackVideo() throws Exception {
+ final String videoItemFileName1 = INPUT_FILE_PATH +
+ "H264_BP_1080x720_30fps_800kbps_1_17.mp4";
+ final String audioFilename1 = INPUT_FILE_PATH +
+ "AACLC_44.1kHz_256kbps_s_1_17.mp4";
+ final String audioFilename2 = INPUT_FILE_PATH +
+ "AMRNB_8KHz_12.2Kbps_m_1_17.3gp";
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final int audioVolume = 50;
+ final String[] loggingInfo = new String[1];
+ int i = 1;
+ writeTestCaseHeader("testStressAudioTrackVideo");
+ getBeginMemory();
+ final MediaVideoItem mediaVideoItem = new MediaVideoItem(mVideoEditor,
+ "mediaItem1", videoItemFileName1, renderingMode);
+ mVideoEditor.addMediaItem(mediaVideoItem);
+
+ final AudioTrack audioTrack1 = new AudioTrack(mVideoEditor,
+ "Audio Track1", audioFilename1);
+ audioTrack1.disableDucking();
+ audioTrack1.setVolume(audioVolume);
+ mVideoEditor.addAudioTrack(audioTrack1);
+
+ mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
+ public void onProgress(Object item, int action, int progress) {
+ }
+ });
+
+ mVideoEditor.removeAudioTrack("Audio Track1");
+
+ final AudioTrack audioTrack2 = new AudioTrack(mVideoEditor,
+ "Audio Track2", audioFilename2);
+ audioTrack2.enableLoop();
+
+ mVideoEditor.generatePreview(new MediaProcessingProgressListener() {
+ public void onProgress(Object item, int action, int progress) {
+ }
+ });
+ getAfterMemory_updateLog(loggingInfo, false, i);
+
+ /** Remove items and check for memory leak if any */
+ getBeginMemory();
+ mVideoEditor.removeMediaItem("mediaItem1");
+
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+
+ /**
+ * To Test Stress : Story Board creation with out preview or export
+ *
+ * @throws Exception
+ */
+ // TODO : remove TC_STR_013
+ @LargeTest
+ public void testStressStoryBoard() throws Exception {
+ final String videoItemFileName1 = INPUT_FILE_PATH +
+ "MPEG4_SP_720x480_30fps_280kbps_AACLC_48kHz_161kbps_s_0_26.mp4";
+ final String videoItemFileName2 = INPUT_FILE_PATH +
+ "MPEG4_SP_854x480_15fps_256kbps_AACLC_16khz_48kbps_s_0_26.mp4";
+ final String videoItemFileName3= INPUT_FILE_PATH +
+ "MPEG4_SP_640x480_15fps_512kbps_AACLC_48khz_132kbps_s_0_26.mp4";
+ final String imageItemFileName4 = INPUT_FILE_PATH +
+ "IMG_1600x1200.jpg";
+ final String imageItemFileName5 = INPUT_FILE_PATH +
+ "IMG_176x144.jpg";
+ final String audioFilename6 = INPUT_FILE_PATH +
+ "AMRNB_8KHz_12.2Kbps_m_1_17.3gp";
+ final String audioFilename7 = INPUT_FILE_PATH +
+ "AACLC_44.1kHz_256kbps_s_1_17.mp4";
+
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final int audioVolume = 50;
+ final String[] loggingInfo = new String[1];
+ int i = 1;
+
+ writeTestCaseHeader("testStressStoryBoard");
+ getBeginMemory();
+ final MediaVideoItem mediaItem1 = new MediaVideoItem(mVideoEditor,
+ "m1", videoItemFileName1, renderingMode);
+ mediaItem1.setExtractBoundaries(0, 10000);
+ mVideoEditor.addMediaItem(mediaItem1);
+
+ final MediaVideoItem mediaItem2 = new MediaVideoItem(mVideoEditor,
+ "m2", videoItemFileName2, renderingMode);
+ mediaItem2.setExtractBoundaries(mediaItem2.getDuration()/4,
+ mediaItem2.getDuration()/2);
+ mVideoEditor.addMediaItem(mediaItem2);
+
+ final MediaVideoItem mediaItem3 = new MediaVideoItem(mVideoEditor,
+ "m3", videoItemFileName3, renderingMode);
+ mediaItem3.setExtractBoundaries(mediaItem3.getDuration()/2,
+ mediaItem3.getDuration());
+ mVideoEditor.addMediaItem(mediaItem3);
+
+ final MediaImageItem mediaItem4 = new MediaImageItem(mVideoEditor,
+ "m4", imageItemFileName4, 5000, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem4);
+
+ final MediaImageItem mediaItem5 = new MediaImageItem(mVideoEditor,
+ "m5", imageItemFileName5, 5000, renderingMode);
+ mVideoEditor.addMediaItem(mediaItem5);
+
+ final TransitionCrossfade tranCrossfade =
+ new TransitionCrossfade("transCF", mediaItem2, mediaItem3, 2500,
+ Transition.BEHAVIOR_MIDDLE_FAST);
+ mVideoEditor.addTransition(tranCrossfade);
+
+ final TransitionCrossfade tranCrossfade1 =
+ new TransitionCrossfade("transCF1", mediaItem3, mediaItem4, 2500,
+ Transition.BEHAVIOR_MIDDLE_FAST);
+ mVideoEditor.addTransition(tranCrossfade1);
+
+ final AudioTrack audioTrack1 = new AudioTrack(mVideoEditor,
+ "Audio Track1", audioFilename6);
+ mVideoEditor.addAudioTrack(audioTrack1);
+
+ mVideoEditor.removeAudioTrack("Audio Track1");
+ final AudioTrack audioTrack2 = new AudioTrack(mVideoEditor,
+ "Audio Track2", audioFilename7);
+ mVideoEditor.addAudioTrack(audioTrack2);
+ audioTrack2.enableLoop();
+ getAfterMemory_updateLog(loggingInfo, false, i);
+
+ /** Remove items and check for memory leak if any */
+ getBeginMemory();
+ mVideoEditor.removeAudioTrack("Audio Track2");
+ mVideoEditor.removeTransition("transCF");
+ mVideoEditor.removeTransition("transCF1");
+ mVideoEditor.removeMediaItem("m5");
+ mVideoEditor.removeMediaItem("m4");
+ mVideoEditor.removeMediaItem("m3");
+ mVideoEditor.removeMediaItem("m2");
+ mVideoEditor.removeMediaItem("m1");
+
+ getAfterMemory_updateLog(loggingInfo, true, i);
+ }
+
+ /**
+ * To test the performance : With an audio track Only
+ *
+ * @throws Exception
+ */
+ // TODO : remove TC_STR_014
+ @LargeTest
+ public void testStressAudioTrackOnly() throws Exception {
+
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String AudioItemFileName1 = INPUT_FILE_PATH +
+ "AACLC_44.1kHz_256kbps_s_1_17.mp4";
+ final String[] loggingInfo = new String[1];
+ int i = 0;
+ writeTestCaseHeader("testStressAudioTrackOnly");
+ getBeginMemory();
+ for ( i = 0; i < 50; i++) {
+ final AudioTrack mediaItem1 = new AudioTrack(mVideoEditor,
+ "m1" + i, AudioItemFileName1);
+ mVideoEditor.addAudioTrack(mediaItem1);
+ mediaItem1.enableLoop();
+ mVideoEditor.removeAudioTrack("m1" + i);
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+ }
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+
+ /**
+ * This method will test thumbnail list extraction in a loop = 200 for Image
+ * Item
+ *
+ * @throws Exception
+ */
+ // TODO : remove TC_STR_016 -- New Test Case
+ @LargeTest
+ public void testStressThumbnailImageItem() throws Exception {
+ final String imageItemFileName = INPUT_FILE_PATH + "IMG_640x480.jpg";
+ final int renderingMode = MediaItem.RENDERING_MODE_BLACK_BORDER;
+ final String[] loggingInfo = new String[1];
+ int i = 0;
+ final MediaImageItem mediaImageItem = new MediaImageItem(mVideoEditor,
+ "m1", imageItemFileName, 5000, renderingMode);
+ writeTestCaseHeader("testStressThumbnailImageItem");
+ getBeginMemory();
+ for ( i = 0; i < 50; i++) {
+ if (i % 4 == 0) {
+ final Bitmap[] thumbNails = mediaImageItem.getThumbnailList(
+ mediaImageItem.getWidth() / 2 ,
+ mediaImageItem.getHeight() / 2, i, 5000, 2);
+ // Recycle this Bitmap array
+ for (int i1 = 0; i1 < thumbNails.length; i1++) {
+ thumbNails[i1].recycle();
+ }
+ }
+ if (i % 4 == 1) {
+ final Bitmap[] thumbNails = mediaImageItem.getThumbnailList(
+ mediaImageItem.getWidth() / 2,
+ mediaImageItem.getHeight() * 3, i, 5000, 2);
+ // Recycle this Bitmap array
+ for (int i1 = 0; i1 < thumbNails.length; i1++) {
+ thumbNails[i1].recycle();
+ }
+ }
+ if (i % 4 == 2) {
+ final Bitmap[] thumbNails = mediaImageItem.getThumbnailList(
+ mediaImageItem.getWidth() * 2,
+ mediaImageItem.getHeight() / 3, i, 5000, 2);
+ // Recycle this Bitmap array
+ for (int i1 = 0; i1 < thumbNails.length; i1++) {
+ thumbNails[i1].recycle();
+ }
+ }
+ if (i % 4 == 3) {
+ final Bitmap[] thumbNails = mediaImageItem.getThumbnailList(
+ mediaImageItem.getWidth(),
+ mediaImageItem.getHeight(), i, 5000, 2);
+ // Recycle this Bitmap array
+ for (int i1 = 0; i1 < thumbNails.length; i1++) {
+ thumbNails[i1].recycle();
+ }
+ }
+ if (i % 10 == 0) {
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+ }
+ getAfterMemory_updateLog(loggingInfo, false, i);
+ }
+}
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 156391e..84588b7 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -2438,6 +2438,17 @@
return mKeyguardMediator.isShowingAndNotHidden();
}
+
+ /** {@inheritDoc} */
+ public boolean isKeyguardLocked() {
+ return keyguardOn();
+ }
+
+ /** {@inheritDoc} */
+ public boolean isKeyguardSecure() {
+ return mKeyguardMediator.isSecure();
+ }
+
/** {@inheritDoc} */
public boolean inKeyguardRestrictedKeyInputMode() {
return mKeyguardMediator.isInputRestricted();
@@ -2463,6 +2474,15 @@
public int rotationForOrientationLw(int orientation, int lastRotation,
boolean displayEnabled) {
+ if (false) {
+ Slog.v(TAG, "rotationForOrientationLw(orient="
+ + orientation + ", last=" + lastRotation
+ + "); user=" + mUserRotation + " "
+ + ((mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED)
+ ? "USER_ROTATION_LOCKED" : "")
+ );
+ }
+
if (mPortraitRotation < 0) {
// Initialize the rotation angles for each orientation once.
Display d = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
@@ -2581,15 +2601,15 @@
// User rotation: to be used when all else fails in assigning an orientation to the device
public void setUserRotationMode(int mode, int rot) {
ContentResolver res = mContext.getContentResolver();
- mUserRotationMode = mode;
+
+ // mUserRotationMode and mUserRotation will be assigned by the content observer
if (mode == WindowManagerPolicy.USER_ROTATION_LOCKED) {
- mUserRotation = rot;
- Settings.System.putInt(res,
- Settings.System.ACCELEROMETER_ROTATION,
- 0);
Settings.System.putInt(res,
Settings.System.USER_ROTATION,
rot);
+ Settings.System.putInt(res,
+ Settings.System.ACCELEROMETER_ROTATION,
+ 0);
} else {
Settings.System.putInt(res,
Settings.System.ACCELEROMETER_ROTATION,
@@ -2907,7 +2927,7 @@
pw.print(" mDeskDockRotation="); pw.println(mDeskDockRotation);
pw.print(prefix); pw.print("mUserRotationMode="); pw.print(mUserRotationMode);
pw.print(" mUserRotation="); pw.print(mUserRotation);
- pw.print("mAllowAllRotations="); pw.println(mAllowAllRotations);
+ pw.print(" mAllowAllRotations="); pw.println(mAllowAllRotations);
pw.print(prefix); pw.print("mAccelerometerDefault="); pw.print(mAccelerometerDefault);
pw.print(" mCurrentAppOrientation="); pw.println(mCurrentAppOrientation);
pw.print(prefix); pw.print("mCarDockEnablesAccelerometer=");
diff --git a/services/java/com/android/server/UsbService.java b/services/java/com/android/server/UsbService.java
index af4c425..1bc203e 100644
--- a/services/java/com/android/server/UsbService.java
+++ b/services/java/com/android/server/UsbService.java
@@ -44,7 +44,11 @@
import java.util.HashMap;
/**
- * <p>UsbService monitors for changes to USB state.
+ * UsbService monitors for changes to USB state.
+ * This includes code for both USB host support (where the android device is the host)
+ * as well as USB device support (android device is connected to a USB host).
+ * Accessory mode is a special case of USB device mode, where the android device is
+ * connected to a USB host that supports the android accessory protocol.
*/
class UsbService extends IUsbManager.Stub {
private static final String TAG = UsbService.class.getSimpleName();
@@ -63,7 +67,9 @@
private static final String USB_COMPOSITE_CLASS_PATH =
"/sys/class/usb_composite";
- private static final int MSG_UPDATE = 0;
+ private static final int MSG_UPDATE_STATE = 0;
+ private static final int MSG_FUNCTION_ENABLED = 1;
+ private static final int MSG_FUNCTION_DISABLED = 2;
// Delay for debouncing USB disconnects.
// We often get rapid connect/disconnect events when enabling USB functions,
@@ -79,7 +85,6 @@
private int mLastConfiguration = -1;
// lists of enabled and disabled USB functions (for USB device mode)
- // synchronize on mEnabledFunctions when using either of these lists
private final ArrayList<String> mEnabledFunctions = new ArrayList<String>();
private final ArrayList<String> mDisabledFunctions = new ArrayList<String>();
@@ -90,26 +95,48 @@
private final String[] mHostBlacklist;
private boolean mSystemReady;
+
private UsbAccessory mCurrentAccessory;
+ // functions to restore after exiting accessory mode
+ private final ArrayList<String> mAccessoryRestoreFunctions = new ArrayList<String>();
private final Context mContext;
+ private final Object mLock = new Object();
- private final void functionEnabled(String function, boolean enabled) {
- synchronized (mEnabledFunctions) {
- if (enabled) {
- if (!mEnabledFunctions.contains(function)) {
- mEnabledFunctions.add(function);
+ /*
+ * Handles USB function enable/disable events (device mode)
+ */
+ private final void functionEnabledLocked(String function, boolean enabled) {
+ boolean enteringAccessoryMode =
+ (enabled && UsbManager.USB_FUNCTION_ACCESSORY.equals(function));
+
+ if (enteringAccessoryMode) {
+ // keep a list of functions to reenable after exiting accessory mode
+ mAccessoryRestoreFunctions.clear();
+ int count = mEnabledFunctions.size();
+ for (int i = 0; i < count; i++) {
+ String f = mEnabledFunctions.get(i);
+ // RNDIS should not be restored and adb is handled automatically
+ if (!UsbManager.USB_FUNCTION_RNDIS.equals(f) &&
+ !UsbManager.USB_FUNCTION_ADB.equals(f) &&
+ !UsbManager.USB_FUNCTION_ACCESSORY.equals(f)) {
+ mAccessoryRestoreFunctions.add(f);
}
- mDisabledFunctions.remove(function);
- } else {
- if (!mDisabledFunctions.contains(function)) {
- mDisabledFunctions.add(function);
- }
- mEnabledFunctions.remove(function);
}
}
+ if (enabled) {
+ if (!mEnabledFunctions.contains(function)) {
+ mEnabledFunctions.add(function);
+ }
+ mDisabledFunctions.remove(function);
+ } else {
+ if (!mDisabledFunctions.contains(function)) {
+ mDisabledFunctions.add(function);
+ }
+ mEnabledFunctions.remove(function);
+ }
- if (enabled && UsbManager.USB_FUNCTION_ACCESSORY.equals(function)) {
+ if (enteringAccessoryMode) {
String[] strings = nativeGetAccessoryStrings();
if (strings != null) {
Log.d(TAG, "entering USB accessory mode");
@@ -136,6 +163,9 @@
}
}
+ /*
+ * Listens for uevent messages from the kernel to monitor the USB state (device mode)
+ */
private final UEventObserver mUEventObserver = new UEventObserver() {
@Override
public void onUEvent(UEventObserver.UEvent event) {
@@ -143,7 +173,7 @@
Slog.v(TAG, "USB UEVENT: " + event.toString());
}
- synchronized (this) {
+ synchronized (mLock) {
String name = event.get("SWITCH_NAME");
String state = event.get("SWITCH_STATE");
if (name != null && state != null) {
@@ -172,8 +202,11 @@
if (function != null && enabledStr != null) {
// Note: we do not broadcast a change when a function is enabled or disabled.
// We just record the state change for the next broadcast.
- boolean enabled = "1".equals(enabledStr);
- functionEnabled(function, enabled);
+ int what = ("1".equals(enabledStr) ?
+ MSG_FUNCTION_ENABLED : MSG_FUNCTION_DISABLED);
+ Message msg = Message.obtain(mHandler, what);
+ msg.obj = function;
+ mHandler.sendMessage(msg);
}
}
}
@@ -197,6 +230,7 @@
private final void init() {
char[] buffer = new char[1024];
+ // Read initial USB state (device mode)
mConfiguration = -1;
try {
FileReader file = new FileReader(USB_CONNECTED_PATH);
@@ -217,21 +251,20 @@
if (mConfiguration < 0)
return;
+ // Read initial list of enabled and disabled functions (device mode)
try {
- synchronized (mEnabledFunctions) {
- File[] files = new File(USB_COMPOSITE_CLASS_PATH).listFiles();
- for (int i = 0; i < files.length; i++) {
- File file = new File(files[i], "enable");
- FileReader reader = new FileReader(file);
- int len = reader.read(buffer, 0, 1024);
- reader.close();
- int value = Integer.valueOf((new String(buffer, 0, len)).trim());
- String functionName = files[i].getName();
- if (value == 1) {
- mEnabledFunctions.add(functionName);
- } else {
- mDisabledFunctions.add(functionName);
- }
+ File[] files = new File(USB_COMPOSITE_CLASS_PATH).listFiles();
+ for (int i = 0; i < files.length; i++) {
+ File file = new File(files[i], "enable");
+ FileReader reader = new FileReader(file);
+ int len = reader.read(buffer, 0, 1024);
+ reader.close();
+ int value = Integer.valueOf((new String(buffer, 0, len)).trim());
+ String functionName = files[i].getName();
+ if (value == 1) {
+ mEnabledFunctions.add(functionName);
+ } else {
+ mDisabledFunctions.add(functionName);
}
}
} catch (FileNotFoundException e) {
@@ -251,6 +284,7 @@
return false;
}
+ /* returns true if the USB device should not be accessible by applications (host mode) */
private boolean isBlackListed(int clazz, int subClass, int protocol) {
// blacklist hubs
if (clazz == UsbConstants.USB_CLASS_HUB) return true;
@@ -264,7 +298,7 @@
return false;
}
- // called from JNI in monitorUsbHostBus()
+ /* Called from JNI in monitorUsbHostBus() to report new USB devices (host mode) */
private void usbDeviceAdded(String deviceName, int vendorID, int productID,
int deviceClass, int deviceSubclass, int deviceProtocol,
/* array of quintuples containing id, class, subclass, protocol
@@ -279,7 +313,7 @@
return;
}
- synchronized (mDevices) {
+ synchronized (mLock) {
if (mDevices.get(deviceName) != null) {
Log.w(TAG, "device already on mDevices list: " + deviceName);
return;
@@ -338,9 +372,9 @@
}
}
- // called from JNI in monitorUsbHostBus()
+ /* Called from JNI in monitorUsbHostBus to report USB device removal (host mode) */
private void usbDeviceRemoved(String deviceName) {
- synchronized (mDevices) {
+ synchronized (mLock) {
UsbDevice device = mDevices.remove(deviceName);
if (device != null) {
Intent intent = new Intent(UsbManager.ACTION_USB_DEVICE_DETACHED);
@@ -363,7 +397,7 @@
}
void systemReady() {
- synchronized (this) {
+ synchronized (mLock) {
if (mContext.getResources().getBoolean(
com.android.internal.R.bool.config_hasUsbHostSupport)) {
// start monitoring for connected USB devices
@@ -375,21 +409,27 @@
}
}
+ /*
+ * Sends a message to update the USB connected and configured state (device mode).
+ * If delayed is true, then we add a small delay in sending the message to debounce
+ * the USB connection when enabling USB tethering.
+ */
private final void update(boolean delayed) {
- mHandler.removeMessages(MSG_UPDATE);
- mHandler.sendEmptyMessageDelayed(MSG_UPDATE, delayed ? UPDATE_DELAY : 0);
+ mHandler.removeMessages(MSG_UPDATE_STATE);
+ mHandler.sendEmptyMessageDelayed(MSG_UPDATE_STATE, delayed ? UPDATE_DELAY : 0);
}
- /* Returns a list of all currently attached USB devices */
+ /* Returns a list of all currently attached USB devices (host mdoe) */
public void getDeviceList(Bundle devices) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_USB, null);
- synchronized (mDevices) {
+ synchronized (mLock) {
for (String name : mDevices.keySet()) {
devices.putParcelable(name, mDevices.get(name));
}
}
}
+ /* Opens the specified USB device (host mode) */
public ParcelFileDescriptor openDevice(String deviceName) {
if (isBlackListed(deviceName)) {
throw new SecurityException("USB device is on a restricted bus");
@@ -403,34 +443,37 @@
return nativeOpenDevice(deviceName);
}
+ /* returns the currently attached USB accessory (device mode) */
public UsbAccessory getCurrentAccessory() {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_USB, null);
return mCurrentAccessory;
}
+ /* opens the currently attached USB accessory (device mode) */
public ParcelFileDescriptor openAccessory() {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.ACCESS_USB, null);
return nativeOpenAccessory();
}
+ /*
+ * This handler is for deferred handling of events related to device mode and accessories.
+ */
private final Handler mHandler = new Handler() {
- private void addEnabledFunctions(Intent intent) {
- synchronized (mEnabledFunctions) {
+ private void addEnabledFunctionsLocked(Intent intent) {
// include state of all USB functions in our extras
- for (int i = 0; i < mEnabledFunctions.size(); i++) {
- intent.putExtra(mEnabledFunctions.get(i), UsbManager.USB_FUNCTION_ENABLED);
- }
- for (int i = 0; i < mDisabledFunctions.size(); i++) {
- intent.putExtra(mDisabledFunctions.get(i), UsbManager.USB_FUNCTION_DISABLED);
- }
+ for (int i = 0; i < mEnabledFunctions.size(); i++) {
+ intent.putExtra(mEnabledFunctions.get(i), UsbManager.USB_FUNCTION_ENABLED);
+ }
+ for (int i = 0; i < mDisabledFunctions.size(); i++) {
+ intent.putExtra(mDisabledFunctions.get(i), UsbManager.USB_FUNCTION_DISABLED);
}
}
@Override
public void handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_UPDATE:
- synchronized (this) {
+ synchronized (mLock) {
+ switch (msg.what) {
+ case MSG_UPDATE_STATE:
if (mConnected != mLastConnected || mConfiguration != mLastConfiguration) {
if (mConnected == 0 && mCurrentAccessory != null) {
// turn off accessory mode when we are disconnected
@@ -438,6 +481,14 @@
UsbManager.USB_FUNCTION_ACCESSORY, false)) {
Log.d(TAG, "exited USB accessory mode");
+ // restore previously enabled functions
+ for (String function : mAccessoryRestoreFunctions) {
+ if (UsbManager.setFunctionEnabled(function, true)) {
+ Log.e(TAG, "could not reenable function " + function);
+ }
+ }
+ mAccessoryRestoreFunctions.clear();
+
Intent intent = new Intent(
UsbManager.ACTION_USB_ACCESSORY_DETACHED);
intent.putExtra(UsbManager.EXTRA_ACCESSORY, mCurrentAccessory);
@@ -468,17 +519,23 @@
intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING);
intent.putExtra(UsbManager.USB_CONNECTED, mConnected != 0);
intent.putExtra(UsbManager.USB_CONFIGURATION, mConfiguration);
- addEnabledFunctions(intent);
+ addEnabledFunctionsLocked(intent);
mContext.sendStickyBroadcast(intent);
}
- }
- break;
+ break;
+ case MSG_FUNCTION_ENABLED:
+ case MSG_FUNCTION_DISABLED:
+ functionEnabledLocked((String)msg.obj, msg.what == MSG_FUNCTION_ENABLED);
+ break;
+ }
}
}
};
+ // host support
private native void monitorUsbHostBus();
private native ParcelFileDescriptor nativeOpenDevice(String deviceName);
+ // accessory support
private native String[] nativeGetAccessoryStrings();
private native ParcelFileDescriptor nativeOpenAccessory();
}
diff --git a/services/java/com/android/server/wm/InputMonitor.java b/services/java/com/android/server/wm/InputMonitor.java
index 34f3618..b1833c4 100644
--- a/services/java/com/android/server/wm/InputMonitor.java
+++ b/services/java/com/android/server/wm/InputMonitor.java
@@ -1,6 +1,19 @@
-/**
- *
+/*
+ * 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.server.wm;
import android.graphics.Rect;
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index a598ce9..b7cc324 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -4410,6 +4410,14 @@
return mPolicy.inKeyguardRestrictedKeyInputMode();
}
+ public boolean isKeyguardLocked() {
+ return mPolicy.isKeyguardLocked();
+ }
+
+ public boolean isKeyguardSecure() {
+ return mPolicy.isKeyguardSecure();
+ }
+
public void closeSystemDialogs(String reason) {
synchronized(mWindowMap) {
for (int i=mWindows.size()-1; i>=0; i--) {
@@ -4822,21 +4830,25 @@
public void freezeRotation() {
if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
- "setRotation()")) {
+ "freezeRotation()")) {
throw new SecurityException("Requires SET_ORIENTATION permission");
}
+ if (DEBUG_ORIENTATION) Slog.v(TAG, "freezeRotation: mRotation=" + mRotation);
+
mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_LOCKED, mRotation);
setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false, 0);
}
public void thawRotation() {
if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
- "setRotation()")) {
+ "thawRotation()")) {
throw new SecurityException("Requires SET_ORIENTATION permission");
}
- mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_FREE, 0);
+ if (DEBUG_ORIENTATION) Slog.v(TAG, "thawRotation: mRotation=" + mRotation);
+
+ mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_FREE, 777); // rot not used
setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false, 0);
}