diff options
21 files changed, 768 insertions, 77 deletions
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java index 9e72c1b39732..c502e6fc0498 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -2417,6 +2417,7 @@ public class Activity extends ContextThemeWrapper */ public boolean onMenuOpened(int featureId, Menu menu) { if (featureId == Window.FEATURE_ACTION_BAR) { + initActionBar(); if (mActionBar != null) { mActionBar.dispatchMenuVisibilityChanged(true); } else { diff --git a/core/java/android/app/backup/WallpaperBackupHelper.java b/core/java/android/app/backup/WallpaperBackupHelper.java index d70b3d37ee8b..65397117fc4d 100644 --- a/core/java/android/app/backup/WallpaperBackupHelper.java +++ b/core/java/android/app/backup/WallpaperBackupHelper.java @@ -21,6 +21,8 @@ import android.content.Context; import android.graphics.BitmapFactory; import android.os.ParcelFileDescriptor; import android.util.Slog; +import android.view.Display; +import android.view.WindowManager; import java.io.File; @@ -65,6 +67,13 @@ public class WallpaperBackupHelper extends FileBackupHelperBase implements Backu mDesiredMinWidth = (double) wpm.getDesiredMinimumWidth(); mDesiredMinHeight = (double) wpm.getDesiredMinimumHeight(); + if (mDesiredMinWidth <= 0 || mDesiredMinHeight <= 0) { + WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); + Display d = wm.getDefaultDisplay(); + mDesiredMinWidth = d.getWidth(); + mDesiredMinHeight = d.getHeight(); + } + if (DEBUG) { Slog.d(TAG, "dmW=" + mDesiredMinWidth + " dmH=" + mDesiredMinHeight); } diff --git a/core/java/android/view/ViewPropertyAnimator.java b/core/java/android/view/ViewPropertyAnimator.java index 27e7db13b395..1d56e9daf0d3 100644 --- a/core/java/android/view/ViewPropertyAnimator.java +++ b/core/java/android/view/ViewPropertyAnimator.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. @@ -33,11 +33,11 @@ import java.util.Set; * more convenient syntax to animate a specific property, then ViewPropertyAnimator might be * more well-suited to the task. * - * <p>This class could provide better performance for several simultaneous animations, because - * it will optimize invalidatesionto take place only once for several properties instead of each - * aniamted property independently causing its own invalidation. Also, the syntax of using this + * <p>This class may provide better performance for several simultaneous animations, because + * it will optimize invalidate calls to take place only once for several properties instead of each + * animated property independently causing its own invalidation. Also, the syntax of using this * class could be easier to use because the caller need only tell the View object which - * property to animate, and the value to animate either to or by, and this calss handles the + * property to animate, and the value to animate either to or by, and this class handles the * details of configuring the underlying Animator class and starting it.</p> * * <p>This class is not constructed by the caller, but rather by the View whose properties @@ -103,7 +103,7 @@ public class ViewPropertyAnimator { /** * Constants used to associate a property being requested and the mechanism used to set - * the property (this calss calls directly into View to set the properties in question). + * the property (this class calls directly into View to set the properties in question). */ private static final int NONE = 0x0000; private static final int TRANSLATION_X = 0x0001; @@ -260,7 +260,7 @@ public class ViewPropertyAnimator { /** * This method will cause the View's <code>x</code> property to be animated to the - * specifed value. + * specified value. Animations already running on the property will be canceled. * * @param value The value to be animated to. * @see View#setX(float) @@ -273,7 +273,7 @@ public class ViewPropertyAnimator { /** * This method will cause the View's <code>x</code> property to be animated by the - * specifed value. + * specified value. Animations already running on the property will be canceled. * * @param value The amount to be animated by, as an offset from the current value. * @see View#setX(float) @@ -286,7 +286,7 @@ public class ViewPropertyAnimator { /** * This method will cause the View's <code>y</code> property to be animated to the - * specifed value. + * specified value. Animations already running on the property will be canceled. * * @param value The value to be animated to. * @see View#setY(float) @@ -299,7 +299,7 @@ public class ViewPropertyAnimator { /** * This method will cause the View's <code>y</code> property to be animated by the - * specifed value. + * specified value. Animations already running on the property will be canceled. * * @param value The amount to be animated by, as an offset from the current value. * @see View#setY(float) @@ -312,7 +312,7 @@ public class ViewPropertyAnimator { /** * This method will cause the View's <code>rotation</code> property to be animated to the - * specifed value. + * specified value. Animations already running on the property will be canceled. * * @param value The value to be animated to. * @see View#setRotation(float) @@ -325,7 +325,7 @@ public class ViewPropertyAnimator { /** * This method will cause the View's <code>rotation</code> property to be animated by the - * specifed value. + * specified value. Animations already running on the property will be canceled. * * @param value The amount to be animated by, as an offset from the current value. * @see View#setRotation(float) @@ -338,7 +338,7 @@ public class ViewPropertyAnimator { /** * This method will cause the View's <code>rotationX</code> property to be animated to the - * specifed value. + * specified value. Animations already running on the property will be canceled. * * @param value The value to be animated to. * @see View#setRotationX(float) @@ -351,7 +351,7 @@ public class ViewPropertyAnimator { /** * This method will cause the View's <code>rotationX</code> property to be animated by the - * specifed value. + * specified value. Animations already running on the property will be canceled. * * @param value The amount to be animated by, as an offset from the current value. * @see View#setRotationX(float) @@ -364,7 +364,7 @@ public class ViewPropertyAnimator { /** * This method will cause the View's <code>rotationY</code> property to be animated to the - * specifed value. + * specified value. Animations already running on the property will be canceled. * * @param value The value to be animated to. * @see View#setRotationY(float) @@ -377,7 +377,7 @@ public class ViewPropertyAnimator { /** * This method will cause the View's <code>rotationY</code> property to be animated by the - * specifed value. + * specified value. Animations already running on the property will be canceled. * * @param value The amount to be animated by, as an offset from the current value. * @see View#setRotationY(float) @@ -390,7 +390,7 @@ public class ViewPropertyAnimator { /** * This method will cause the View's <code>translationX</code> property to be animated to the - * specifed value. + * specified value. Animations already running on the property will be canceled. * * @param value The value to be animated to. * @see View#setTranslationX(float) @@ -403,7 +403,7 @@ public class ViewPropertyAnimator { /** * This method will cause the View's <code>translationX</code> property to be animated by the - * specifed value. + * specified value. Animations already running on the property will be canceled. * * @param value The amount to be animated by, as an offset from the current value. * @see View#setTranslationX(float) @@ -416,7 +416,7 @@ public class ViewPropertyAnimator { /** * This method will cause the View's <code>translationY</code> property to be animated to the - * specifed value. + * specified value. Animations already running on the property will be canceled. * * @param value The value to be animated to. * @see View#setTranslationY(float) @@ -429,7 +429,7 @@ public class ViewPropertyAnimator { /** * This method will cause the View's <code>translationY</code> property to be animated by the - * specifed value. + * specified value. Animations already running on the property will be canceled. * * @param value The amount to be animated by, as an offset from the current value. * @see View#setTranslationY(float) @@ -442,7 +442,7 @@ public class ViewPropertyAnimator { /** * This method will cause the View's <code>scaleX</code> property to be animated to the - * specifed value. + * specified value. Animations already running on the property will be canceled. * * @param value The value to be animated to. * @see View#setScaleX(float) @@ -455,7 +455,7 @@ public class ViewPropertyAnimator { /** * This method will cause the View's <code>scaleX</code> property to be animated by the - * specifed value. + * specified value. Animations already running on the property will be canceled. * * @param value The amount to be animated by, as an offset from the current value. * @see View#setScaleX(float) @@ -468,7 +468,7 @@ public class ViewPropertyAnimator { /** * This method will cause the View's <code>scaleY</code> property to be animated to the - * specifed value. + * specified value. Animations already running on the property will be canceled. * * @param value The value to be animated to. * @see View#setScaleY(float) @@ -481,7 +481,7 @@ public class ViewPropertyAnimator { /** * This method will cause the View's <code>scaleY</code> property to be animated by the - * specifed value. + * specified value. Animations already running on the property will be canceled. * * @param value The amount to be animated by, as an offset from the current value. * @see View#setScaleY(float) @@ -494,7 +494,7 @@ public class ViewPropertyAnimator { /** * This method will cause the View's <code>alpha</code> property to be animated to the - * specified value. + * specified value. Animations already running on the property will be canceled. * * @param value The value to be animated to. * @see View#setAlpha(float) @@ -507,7 +507,7 @@ public class ViewPropertyAnimator { /** * This method will cause the View's <code>alpha</code> property to be animated by the - * specified value. + * specified value. Animations already running on the property will be canceled. * * @param value The amount to be animated by, as an offset from the current value. * @see View#setAlpha(float) @@ -548,7 +548,7 @@ public class ViewPropertyAnimator { /** * Utility function, called by the various x(), y(), etc. methods. This stores the - * constnat name for the property along with the from/delta values that will be used to + * constant name for the property along with the from/delta values that will be used to * calculate and set the property during the animation. This structure is added to the * pending animations, awaiting the eventual start() of the underlying animator. A * Runnable is posted to start the animation, and any pending such Runnable is canceled @@ -578,14 +578,14 @@ public class ViewPropertyAnimator { } /** - * Utility function, called by animatePropert() and animatePropertyBy(), which handles the + * Utility function, called by animateProperty() and animatePropertyBy(), which handles the * details of adding a pending animation and posting the request to start the animation. * * @param constantName The specifier for the property being animated - * @param fromValue The starting value of the property + * @param startValue The starting value of the property * @param byValue The amount by which the property will change */ - private void animatePropertyBy(int constantName, float fromValue, float byValue) { + private void animatePropertyBy(int constantName, float startValue, float byValue) { // First, cancel any existing animations on this property if (mAnimatorMap.size() > 0) { Animator animatorToCancel = null; @@ -598,7 +598,7 @@ public class ViewPropertyAnimator { // on a property will cancel a previous animation on that property, so // there can only ever be one such animation running. if (bundle.mPropertyMask == NONE) { - // the animation is not longer changing animthing - cancel it + // the animation is not longer changing anything - cancel it animatorToCancel = runningAnim; break; } @@ -609,7 +609,6 @@ public class ViewPropertyAnimator { } } - float startValue = getValue(constantName); NameValuesHolder nameValuePair = new NameValuesHolder(constantName, startValue, byValue); mPendingAnimations.add(nameValuePair); mView.getHandler().removeCallbacks(mAnimationStarter); diff --git a/core/java/android/widget/ExpandableListView.java b/core/java/android/widget/ExpandableListView.java index 8279ee5e9ccd..f8623686d277 100644 --- a/core/java/android/widget/ExpandableListView.java +++ b/core/java/android/widget/ExpandableListView.java @@ -299,6 +299,9 @@ public class ExpandableListView extends ListView { indicatorRect.right = mIndicatorRight; } + indicatorRect.left += mPaddingLeft; + indicatorRect.right += mPaddingLeft; + lastItemType = pos.position.type; } diff --git a/core/tests/coretests/AndroidManifest.xml b/core/tests/coretests/AndroidManifest.xml index 01734f2f755a..4be6995f46f1 100644 --- a/core/tests/coretests/AndroidManifest.xml +++ b/core/tests/coretests/AndroidManifest.xml @@ -44,6 +44,7 @@ <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> + <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /> <uses-permission android:name="android.permission.BROADCAST_STICKY" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.CLEAR_APP_CACHE" /> diff --git a/core/tests/coretests/src/android/bluetooth/BluetoothStressTest.java b/core/tests/coretests/src/android/bluetooth/BluetoothStressTest.java index 672f252388fd..5dedd4a92b56 100644 --- a/core/tests/coretests/src/android/bluetooth/BluetoothStressTest.java +++ b/core/tests/coretests/src/android/bluetooth/BluetoothStressTest.java @@ -316,4 +316,34 @@ public class BluetoothStressTest extends InstrumentationTestCase { mTestUtils.disablePan(adapter); mTestUtils.disable(adapter); } + + /** + * Stress test for verifying that AudioManager can open and close SCO connections. + * <p> + * In this test, a HSP connection is opened with an external headset and the SCO connection is + * repeatibly opened and closed. + */ + public void testStartStopSco() { + int iterations = BluetoothTestRunner.sStartStopScoIterations; + if (iterations == 0) { + return; + } + + BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); + BluetoothDevice device = adapter.getRemoteDevice(BluetoothTestRunner.sHeadsetAddress); + mTestUtils.enable(adapter); + mTestUtils.pair(adapter, device, BluetoothTestRunner.sPairPasskey, + BluetoothTestRunner.sPairPin); + mTestUtils.connectProfile(adapter, device, BluetoothProfile.HEADSET); + + for (int i = 0; i < iterations; i++) { + mTestUtils.writeOutput("startStopSco iteration " + (i + 1) + " of " + iterations); + mTestUtils.startSco(adapter, device); + mTestUtils.stopSco(adapter, device); + } + + mTestUtils.disconnectProfile(adapter, device, BluetoothProfile.HEADSET); + mTestUtils.unpair(adapter, device); + mTestUtils.disable(adapter); + } } diff --git a/core/tests/coretests/src/android/bluetooth/BluetoothTestRunner.java b/core/tests/coretests/src/android/bluetooth/BluetoothTestRunner.java index cede05a8a174..1febc5cc7beb 100644 --- a/core/tests/coretests/src/android/bluetooth/BluetoothTestRunner.java +++ b/core/tests/coretests/src/android/bluetooth/BluetoothTestRunner.java @@ -39,6 +39,7 @@ import android.util.Log; * [-e connect_headset_iterations <iterations>] \ * [-e connect_input_iterations <iterations>] \ * [-e connect_pan_iterations <iterations>] \ + * [-e start_stop_sco_iterations <iterations>] \ * [-e pair_address <address>] \ * [-e headset_address <address>] \ * [-e a2dp_address <address>] \ @@ -62,6 +63,7 @@ public class BluetoothTestRunner extends InstrumentationTestRunner { public static int sConnectA2dpIterations = 100; public static int sConnectInputIterations = 100; public static int sConnectPanIterations = 100; + public static int sStartStopScoIterations = 100; public static String sPairAddress = ""; public static String sHeadsetAddress = ""; @@ -167,6 +169,14 @@ public class BluetoothTestRunner extends InstrumentationTestRunner { } } + val = arguments.getString("start_stop_sco_iterations"); + if (val != null) { + try { + sStartStopScoIterations = Integer.parseInt(val); + } catch (NumberFormatException e) { + // Invalid argument, fall back to default value + } + } val = arguments.getString("pair_address"); if (val != null) { sPairAddress = val; @@ -214,6 +224,7 @@ public class BluetoothTestRunner extends InstrumentationTestRunner { Log.i(TAG, String.format("connect_headset_iterations=%d", sConnectHeadsetIterations)); Log.i(TAG, String.format("connect_input_iterations=%d", sConnectInputIterations)); Log.i(TAG, String.format("connect_pan_iterations=%d", sConnectPanIterations)); + Log.i(TAG, String.format("start_stop_sco_iterations=%d", sStartStopScoIterations)); Log.i(TAG, String.format("pair_address=%s", sPairAddress)); Log.i(TAG, String.format("a2dp_address=%s", sA2dpAddress)); Log.i(TAG, String.format("headset_address=%s", sHeadsetAddress)); diff --git a/core/tests/coretests/src/android/bluetooth/BluetoothTestUtils.java b/core/tests/coretests/src/android/bluetooth/BluetoothTestUtils.java index 85c5eaa85b9b..1741119cad9b 100644 --- a/core/tests/coretests/src/android/bluetooth/BluetoothTestUtils.java +++ b/core/tests/coretests/src/android/bluetooth/BluetoothTestUtils.java @@ -22,6 +22,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.media.AudioManager; import android.os.Environment; import android.util.Log; @@ -67,6 +68,11 @@ public class BluetoothTestUtils extends Assert { private static final int CONNECT_PROXY_TIMEOUT = 5000; /** + * Timeout to start or stop a SCO channel in ms. + */ + private static final int START_STOP_SCO_TIMEOUT = 10000; + + /** * Time between polls in ms. */ private static final int POLL_TIME = 100; @@ -319,6 +325,32 @@ public class BluetoothTestUtils extends Assert { } } + private class StartStopScoReceiver extends FlagReceiver { + private static final int STATE_CONNECTED_FLAG = 1; + private static final int STATE_DISCONNECTED_FLAG = 1 << 1; + + public StartStopScoReceiver(int expectedFlags) { + super(expectedFlags); + } + + @Override + public void onReceive(Context context, Intent intent) { + if (AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED.equals(intent.getAction())) { + int state = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, + AudioManager.SCO_AUDIO_STATE_ERROR); + assertNotSame(AudioManager.SCO_AUDIO_STATE_ERROR, state); + switch(state) { + case AudioManager.SCO_AUDIO_STATE_CONNECTED: + setFiredFlag(STATE_CONNECTED_FLAG); + break; + case AudioManager.SCO_AUDIO_STATE_DISCONNECTED: + setFiredFlag(STATE_DISCONNECTED_FLAG); + break; + } + } + } + } + private BluetoothProfile.ServiceListener mServiceListener = new BluetoothProfile.ServiceListener() { public void onServiceConnected(int profile, BluetoothProfile proxy) { @@ -1269,6 +1301,103 @@ public class BluetoothTestUtils extends Assert { } /** + * Opens a SCO channel using {@link android.media.AudioManager#startBluetoothSco()} and checks + * to make sure that the channel is opened and that the correct actions were broadcast. + * + * @param adapter The BT adapter. + * @param device The remote device. + */ + public void startSco(BluetoothAdapter adapter, BluetoothDevice device) { + startStopSco(adapter, device, true); + } + + /** + * Closes a SCO channel using {@link android.media.AudioManager#stopBluetoothSco()} and checks + * to make sure that the channel is closed and that the correct actions were broadcast. + * + * @param adapter The BT adapter. + * @param device The remote device. + */ + public void stopSco(BluetoothAdapter adapter, BluetoothDevice device) { + startStopSco(adapter, device, false); + } + /** + * Helper method for {@link #startSco(BluetoothAdapter, BluetoothDevice)} and + * {@link #stopSco(BluetoothAdapter, BluetoothDevice)}. + * + * @param adapter The BT adapter. + * @param device The remote device. + * @param isStart Whether the SCO channel should be opened. + */ + private void startStopSco(BluetoothAdapter adapter, BluetoothDevice device, boolean isStart) { + long start = -1; + int mask; + String methodName; + + if (isStart) { + methodName = "startSco()"; + mask = StartStopScoReceiver.STATE_CONNECTED_FLAG; + } else { + methodName = "stopSco()"; + mask = StartStopScoReceiver.STATE_DISCONNECTED_FLAG; + } + + if (!adapter.isEnabled()) { + fail(String.format("%s bluetooth not enabled: device=%s, start=%b", methodName, device, + isStart)); + } + + if (!adapter.getBondedDevices().contains(device)) { + fail(String.format("%s device not paired: device=%s, start=%b", methodName, device, + isStart)); + } + + AudioManager manager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); + assertNotNull(manager); + + if (!manager.isBluetoothScoAvailableOffCall()) { + fail(String.format("%s device does not support SCO: device=%s, start=%b", methodName, + device, isStart)); + } + + boolean isScoOn = manager.isBluetoothScoOn(); + if (isStart == isScoOn) { + return; + } + + StartStopScoReceiver receiver = getStartStopScoReceiver(mask); + start = System.currentTimeMillis(); + if (isStart) { + manager.startBluetoothSco(); + } else { + manager.stopBluetoothSco(); + } + + long s = System.currentTimeMillis(); + while (System.currentTimeMillis() - s < START_STOP_SCO_TIMEOUT) { + isScoOn = manager.isBluetoothScoOn(); + if ((isStart == isScoOn) && + (receiver.getFiredFlags() & mask) == mask) { + long finish = receiver.getCompletedTime(); + if (start != -1 && finish != -1) { + writeOutput(String.format("%s completed in %d ms", methodName, + (finish - start))); + } else { + writeOutput(String.format("%s completed", methodName)); + } + removeReceiver(receiver); + return; + } + sleep(POLL_TIME); + } + + int firedFlags = receiver.getFiredFlags(); + removeReceiver(receiver); + fail(String.format("%s timeout: start=%b (expected %b), flags=0x%x (expected 0x%x)", + methodName, isScoOn, isStart, firedFlags, mask)); + } + + /** * Writes a string to the logcat and a file if a file has been specified in the constructor. * * @param s The string to be written. @@ -1336,6 +1465,13 @@ public class BluetoothTestUtils extends Assert { return receiver; } + private StartStopScoReceiver getStartStopScoReceiver(int expectedFlags) { + String[] actions = {AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED}; + StartStopScoReceiver receiver = new StartStopScoReceiver(expectedFlags); + addReceiver(receiver, actions); + return receiver; + } + private void removeReceiver(BroadcastReceiver receiver) { mContext.unregisterReceiver(receiver); mReceivers.remove(receiver); diff --git a/include/media/IOMX.h b/include/media/IOMX.h index cb36bbb6476b..16a934262bda 100644 --- a/include/media/IOMX.h +++ b/include/media/IOMX.h @@ -85,6 +85,9 @@ public: virtual status_t enableGraphicBuffers( node_id node, OMX_U32 port_index, OMX_BOOL enable) = 0; + virtual status_t getGraphicBufferUsage( + node_id node, OMX_U32 port_index, OMX_U32* usage) = 0; + virtual status_t useBuffer( node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms, buffer_id *buffer) = 0; diff --git a/include/media/stagefright/HardwareAPI.h b/include/media/stagefright/HardwareAPI.h index 17908b4a821a..d1ecaafea88b 100644 --- a/include/media/stagefright/HardwareAPI.h +++ b/include/media/stagefright/HardwareAPI.h @@ -87,6 +87,18 @@ struct UseAndroidNativeBufferParams { const sp<android_native_buffer_t>& nativeBuffer; }; +// A pointer to this struct is passed to OMX_GetParameter when the extension +// index for the 'OMX.google.android.index.getAndroidNativeBufferUsage' +// extension is given. The usage bits returned from this query will be used to +// allocate the Gralloc buffers that get passed to the useAndroidNativeBuffer +// command. +struct GetAndroidNativeBufferUsageParams { + OMX_U32 nSize; // IN + OMX_VERSIONTYPE nVersion; // IN + OMX_U32 nPortIndex; // IN + OMX_U32 nUsage; // OUT +}; + } // namespace android extern android::OMXPluginBase *createOMXPlugin(); diff --git a/media/libmedia/IOMX.cpp b/media/libmedia/IOMX.cpp index af67175dbb0b..d6a1757ca9fd 100644 --- a/media/libmedia/IOMX.cpp +++ b/media/libmedia/IOMX.cpp @@ -33,6 +33,7 @@ enum { EMPTY_BUFFER, GET_EXTENSION_INDEX, OBSERVER_ON_MSG, + GET_GRAPHIC_BUFFER_USAGE, }; class BpOMX : public BpInterface<IOMX> { @@ -194,6 +195,19 @@ public: return err; } + virtual status_t getGraphicBufferUsage( + node_id node, OMX_U32 port_index, OMX_U32* usage) { + Parcel data, reply; + data.writeInterfaceToken(IOMX::getInterfaceDescriptor()); + data.writeIntPtr((intptr_t)node); + data.writeInt32(port_index); + remote()->transact(GET_GRAPHIC_BUFFER_USAGE, data, &reply); + + status_t err = reply.readInt32(); + *usage = reply.readInt32(); + return err; + } + virtual status_t useBuffer( node_id node, OMX_U32 port_index, const sp<IMemory> ¶ms, buffer_id *buffer) { @@ -508,6 +522,21 @@ status_t BnOMX::onTransact( return NO_ERROR; } + case GET_GRAPHIC_BUFFER_USAGE: + { + CHECK_INTERFACE(IOMX, data, reply); + + node_id node = (void*)data.readIntPtr(); + OMX_U32 port_index = data.readInt32(); + + OMX_U32 usage = 0; + status_t err = getGraphicBufferUsage(node, port_index, &usage); + reply->writeInt32(err); + reply->writeInt32(usage); + + return NO_ERROR; + } + case USE_BUFFER: { CHECK_INTERFACE(IOMX, data, reply); diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp index b0ae3d8661e4..2bbb32048bce 100644 --- a/media/libstagefright/ACodec.cpp +++ b/media/libstagefright/ACodec.cpp @@ -459,16 +459,12 @@ status_t ACodec::allocateOutputBuffersFromNativeWindow() { return err; } - // XXX TODO: Do something so the ANativeWindow knows that we'll need to get - // the same set of buffers. - LOGV("[%s] Allocating %lu buffers from a native window of size %lu on " "output port", mComponentName.c_str(), def.nBufferCountActual, def.nBufferSize); // Dequeue buffers and send them to OMX - OMX_U32 i; - for (i = 0; i < def.nBufferCountActual; i++) { + for (OMX_U32 i = 0; i < def.nBufferCountActual; i++) { android_native_buffer_t *buf; err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf); if (err != 0) { @@ -477,23 +473,26 @@ status_t ACodec::allocateOutputBuffersFromNativeWindow() { } sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false)); + BufferInfo info; + info.mStatus = BufferInfo::OWNED_BY_US; + info.mData = new ABuffer(0); + info.mGraphicBuffer = graphicBuffer; + mBuffers[kPortIndexOutput].push(info); + IOMX::buffer_id bufferId; err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer, &bufferId); if (err != 0) { + LOGE("registering GraphicBuffer %lu with OMX IL component failed: " + "%d", i, err); break; } + mBuffers[kPortIndexOutput].editItemAt(i).mBufferID = bufferId; + LOGV("[%s] Registered graphic buffer with ID %p (pointer = %p)", mComponentName.c_str(), bufferId, graphicBuffer.get()); - - BufferInfo info; - info.mBufferID = bufferId; - info.mStatus = BufferInfo::OWNED_BY_US; - info.mData = new ABuffer(0); - info.mGraphicBuffer = graphicBuffer; - mBuffers[kPortIndexOutput].push(info); } OMX_U32 cancelStart; @@ -503,7 +502,7 @@ status_t ACodec::allocateOutputBuffersFromNativeWindow() { // If an error occurred while dequeuing we need to cancel any buffers // that were dequeued. cancelStart = 0; - cancelEnd = i; + cancelEnd = mBuffers[kPortIndexOutput].size(); } else { // Return the last two buffers to the native window. // XXX TODO: The number of buffers the native window owns should @@ -2286,4 +2285,3 @@ void ACodec::FlushingState::changeStateIfWeOwnAllBuffers() { } } // namespace android - diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp index 5d502e7effbf..00b13104a332 100644 --- a/media/libstagefright/OMXCodec.cpp +++ b/media/libstagefright/OMXCodec.cpp @@ -1769,15 +1769,11 @@ status_t OMXCodec::allocateOutputBuffersFromNativeWindow() { return err; } - // XXX TODO: Do something so the ANativeWindow knows that we'll need to get - // the same set of buffers. - CODEC_LOGI("allocating %lu buffers from a native window of size %lu on " "output port", def.nBufferCountActual, def.nBufferSize); // Dequeue buffers and send them to OMX - OMX_U32 i; - for (i = 0; i < def.nBufferCountActual; i++) { + for (OMX_U32 i = 0; i < def.nBufferCountActual; i++) { android_native_buffer_t* buf; err = mNativeWindow->dequeueBuffer(mNativeWindow.get(), &buf); if (err != 0) { @@ -1786,36 +1782,37 @@ status_t OMXCodec::allocateOutputBuffersFromNativeWindow() { } sp<GraphicBuffer> graphicBuffer(new GraphicBuffer(buf, false)); + BufferInfo info; + info.mData = NULL; + info.mSize = def.nBufferSize; + info.mStatus = OWNED_BY_US; + info.mMem = NULL; + info.mMediaBuffer = new MediaBuffer(graphicBuffer); + info.mMediaBuffer->setObserver(this); + mPortBuffers[kPortIndexOutput].push(info); + IOMX::buffer_id bufferId; err = mOMX->useGraphicBuffer(mNode, kPortIndexOutput, graphicBuffer, &bufferId); if (err != 0) { + CODEC_LOGE("registering GraphicBuffer with OMX IL component " + "failed: %d", err); break; } + mPortBuffers[kPortIndexOutput].editItemAt(i).mBuffer = bufferId; + CODEC_LOGV("registered graphic buffer with ID %p (pointer = %p)", bufferId, graphicBuffer.get()); - - BufferInfo info; - info.mData = NULL; - info.mSize = def.nBufferSize; - info.mBuffer = bufferId; - info.mStatus = OWNED_BY_US; - info.mMem = NULL; - info.mMediaBuffer = new MediaBuffer(graphicBuffer); - info.mMediaBuffer->setObserver(this); - - mPortBuffers[kPortIndexOutput].push(info); } OMX_U32 cancelStart; OMX_U32 cancelEnd; - if (err != 0) { // If an error occurred while dequeuing we need to cancel any buffers // that were dequeued. cancelStart = 0; - cancelEnd = i; + cancelEnd = mPortBuffers[kPortIndexOutput].size(); } else { // Return the last two buffers to the native window. // XXX TODO: The number of buffers the native window owns should probably be diff --git a/media/libstagefright/include/OMX.h b/media/libstagefright/include/OMX.h index 5fed98a8d533..ec3e5fa5313d 100644 --- a/media/libstagefright/include/OMX.h +++ b/media/libstagefright/include/OMX.h @@ -62,6 +62,9 @@ public: virtual status_t enableGraphicBuffers( node_id node, OMX_U32 port_index, OMX_BOOL enable); + virtual status_t getGraphicBufferUsage( + node_id node, OMX_U32 port_index, OMX_U32* usage); + virtual status_t storeMetaDataInBuffers( node_id node, OMX_U32 port_index, OMX_BOOL enable); diff --git a/media/libstagefright/include/OMXNodeInstance.h b/media/libstagefright/include/OMXNodeInstance.h index 86c102ce100f..ca2578fa0d3e 100644 --- a/media/libstagefright/include/OMXNodeInstance.h +++ b/media/libstagefright/include/OMXNodeInstance.h @@ -50,6 +50,9 @@ struct OMXNodeInstance { status_t setConfig(OMX_INDEXTYPE index, const void *params, size_t size); status_t enableGraphicBuffers(OMX_U32 portIndex, OMX_BOOL enable); + + status_t getGraphicBufferUsage(OMX_U32 portIndex, OMX_U32* usage); + status_t storeMetaDataInBuffers(OMX_U32 portIndex, OMX_BOOL enable); status_t useBuffer( diff --git a/media/libstagefright/omx/OMX.cpp b/media/libstagefright/omx/OMX.cpp index 3638f41de766..4b1c3a7ed12f 100644 --- a/media/libstagefright/omx/OMX.cpp +++ b/media/libstagefright/omx/OMX.cpp @@ -297,6 +297,11 @@ status_t OMX::enableGraphicBuffers( return findInstance(node)->enableGraphicBuffers(port_index, enable); } +status_t OMX::getGraphicBufferUsage( + node_id node, OMX_U32 port_index, OMX_U32* usage) { + return findInstance(node)->getGraphicBufferUsage(port_index, usage); +} + status_t OMX::storeMetaDataInBuffers( node_id node, OMX_U32 port_index, OMX_BOOL enable) { return findInstance(node)->storeMetaDataInBuffers(port_index, enable); diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp index c7c14099f992..6cbd599d067e 100644 --- a/media/libstagefright/omx/OMXNodeInstance.cpp +++ b/media/libstagefright/omx/OMXNodeInstance.cpp @@ -302,6 +302,45 @@ status_t OMXNodeInstance::enableGraphicBuffers( return OK; } +status_t OMXNodeInstance::getGraphicBufferUsage( + OMX_U32 portIndex, OMX_U32* usage) { + Mutex::Autolock autoLock(mLock); + + OMX_INDEXTYPE index; + OMX_ERRORTYPE err = OMX_GetExtensionIndex( + mHandle, + const_cast<OMX_STRING>( + "OMX.google.android.index.getAndroidNativeBufferUsage"), + &index); + + if (err != OMX_ErrorNone) { + LOGE("OMX_GetExtensionIndex failed"); + + return StatusFromOMXError(err); + } + + OMX_VERSIONTYPE ver; + ver.s.nVersionMajor = 1; + ver.s.nVersionMinor = 0; + ver.s.nRevision = 0; + ver.s.nStep = 0; + GetAndroidNativeBufferUsageParams params = { + sizeof(GetAndroidNativeBufferUsageParams), ver, portIndex, 0, + }; + + err = OMX_GetParameter(mHandle, index, ¶ms); + + if (err != OMX_ErrorNone) { + LOGE("OMX_GetAndroidNativeBufferUsage failed with error %d (0x%08x)", + err, err); + return UNKNOWN_ERROR; + } + + *usage = params.nUsage; + + return OK; +} + status_t OMXNodeInstance::storeMetaDataInBuffers( OMX_U32 portIndex, OMX_BOOL enable) { diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java index b746c372de67..d342d6698f9e 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java @@ -1601,6 +1601,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { private ActionMode mActionMode; private ActionBarContextView mActionModeView; private PopupWindow mActionModePopup; + private Runnable mShowActionModePopup; public DecorView(Context context, int featureId) { super(context); @@ -1976,6 +1977,12 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { final int height = TypedValue.complexToDimensionPixelSize(heightValue.data, mContext.getResources().getDisplayMetrics()); mActionModePopup.setHeight(height); + mShowActionModePopup = new Runnable() { + public void run() { + mActionModePopup.showAtLocation(PhoneWindow.DecorView.this, + Gravity.TOP | Gravity.FILL_HORIZONTAL, 0, 0); + } + }; } else { ViewStub stub = (ViewStub) findViewById( com.android.internal.R.id.action_mode_bar_stub); @@ -1994,8 +2001,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { mActionModeView.setVisibility(View.VISIBLE); mActionMode = mode; if (mActionModePopup != null) { - mActionModePopup.showAtLocation(this, - Gravity.TOP | Gravity.FILL_HORIZONTAL, 0, 0); + post(mShowActionModePopup); } } else { mActionMode = null; @@ -2183,6 +2189,14 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { } mActionButtonPopup = null; } + + if (mActionModePopup != null) { + removeCallbacks(mShowActionModePopup); + if (mActionModePopup.isShowing()) { + mActionModePopup.dismiss(); + } + mActionModePopup = null; + } } @Override @@ -2246,6 +2260,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback { public void onDestroyActionMode(ActionMode mode) { mWrapped.onDestroyActionMode(mode); if (mActionModePopup != null) { + removeCallbacks(mShowActionModePopup); mActionModePopup.dismiss(); } else if (mActionModeView != null) { mActionModeView.setVisibility(GONE); diff --git a/tools/aapt/NOTICE b/tools/aapt/NOTICE new file mode 100644 index 000000000000..c5b1efa7aac7 --- /dev/null +++ b/tools/aapt/NOTICE @@ -0,0 +1,190 @@ + + Copyright (c) 2005-2008, The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + diff --git a/tools/aidl/NOTICE b/tools/aidl/NOTICE new file mode 100644 index 000000000000..c5b1efa7aac7 --- /dev/null +++ b/tools/aidl/NOTICE @@ -0,0 +1,190 @@ + + Copyright (c) 2005-2008, The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java index 676218e9eb4c..f9d2772cf7ab 100644 --- a/wifi/java/android/net/wifi/WifiStateMachine.java +++ b/wifi/java/android/net/wifi/WifiStateMachine.java @@ -2785,11 +2785,30 @@ public class WifiStateMachine extends HierarchicalStateMachine { class DisconnectedState extends HierarchicalState { private boolean mAlarmEnabled = false; + private long mScanIntervalMs; + + private void setScanAlarm(boolean enabled) { + if (enabled == mAlarmEnabled) return; + if (enabled) { + mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP, + System.currentTimeMillis() + mScanIntervalMs, + mScanIntervalMs, + mScanIntent); + + mAlarmEnabled = true; + } else { + mAlarmManager.cancel(mScanIntent); + mAlarmEnabled = false; + } + } + @Override public void enter() { if (DBG) Log.d(TAG, getName() + "\n"); EventLog.writeEvent(EVENTLOG_WIFI_STATE_CHANGED, getName()); + mScanIntervalMs = Settings.Secure.getLong(mContext.getContentResolver(), + Settings.Secure.WIFI_SCAN_INTERVAL_MS, DEFAULT_SCAN_INTERVAL_MS); /* * We initiate background scanning if it is enabled, otherwise we * initiate an infrequent scan that wakes up the device to ensure @@ -2806,12 +2825,7 @@ public class WifiStateMachine extends HierarchicalStateMachine { WifiNative.enableBackgroundScan(true); } } else { - long scanMs = Settings.Secure.getLong(mContext.getContentResolver(), - Settings.Secure.WIFI_SCAN_INTERVAL_MS, DEFAULT_SCAN_INTERVAL_MS); - - mAlarmManager.setRepeating(AlarmManager.RTC_WAKEUP, - System.currentTimeMillis() + scanMs, scanMs, mScanIntent); - mAlarmEnabled = true; + setScanAlarm(true); } } @Override @@ -2829,7 +2843,13 @@ public class WifiStateMachine extends HierarchicalStateMachine { break; case CMD_ENABLE_BACKGROUND_SCAN: mEnableBackgroundScan = (message.arg1 == 1); - WifiNative.enableBackgroundScan(mEnableBackgroundScan); + if (mEnableBackgroundScan) { + WifiNative.enableBackgroundScan(true); + setScanAlarm(false); + } else { + WifiNative.enableBackgroundScan(false); + setScanAlarm(true); + } break; /* Ignore network disconnect */ case NETWORK_DISCONNECTION_EVENT: @@ -2866,10 +2886,7 @@ public class WifiStateMachine extends HierarchicalStateMachine { if (mEnableBackgroundScan) { WifiNative.enableBackgroundScan(false); } - if (mAlarmEnabled) { - mAlarmManager.cancel(mScanIntent); - mAlarmEnabled = false; - } + setScanAlarm(false); } } |