Merge "This hardware video decoder lies about its required input buffer sizes allocating 2.7 MB of memory instead of the required 176 KB... Added another quirk."
diff --git a/api/current.xml b/api/current.xml
index a753165..2729ff4 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -23748,7 +23748,7 @@
>
<parameter name="parcel" type="android.os.Parcel">
</parameter>
-<parameter name="flagz" type="int">
+<parameter name="flags" type="int">
</parameter>
</method>
<field name="CREATOR"
@@ -26277,6 +26277,83 @@
</parameter>
</method>
</interface>
+<class name="UiModeManager"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="disableCarMode"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getNightMode"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="setNightMode"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="mode" type="int">
+</parameter>
+</method>
+<field name="MODE_AUTO"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="3"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="MODE_NIGHT"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="MODE_NOTNIGHT"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
<class name="WallpaperInfo"
extends="java.lang.Object"
abstract="false"
@@ -34549,6 +34626,17 @@
visibility="public"
>
</field>
+<field name="UI_MODE_SERVICE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""uimode""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="VIBRATOR_SERVICE"
type="java.lang.String"
transient="false"
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index c7c9429..50dcdf9 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -194,6 +194,7 @@
private AccountManager mAccountManager; // protected by mSync
private DropBoxManager mDropBoxManager = null;
private DevicePolicyManager mDevicePolicyManager = null;
+ private UiModeManager mUiModeManager = null;
private final Object mSync = new Object();
@@ -960,6 +961,8 @@
return getDropBoxManager();
} else if (DEVICE_POLICY_SERVICE.equals(name)) {
return getDevicePolicyManager();
+ } else if (UI_MODE_SERVICE.equals(name)) {
+ return getUiModeManager();
}
return null;
@@ -1153,6 +1156,15 @@
return mDevicePolicyManager;
}
+ private UiModeManager getUiModeManager() {
+ synchronized (mSync) {
+ if (mUiModeManager == null) {
+ mUiModeManager = new UiModeManager();
+ }
+ }
+ return mUiModeManager;
+ }
+
@Override
public int checkPermission(String permission, int pid, int uid) {
if (permission == null) {
diff --git a/core/java/android/app/Dialog.java b/core/java/android/app/Dialog.java
index 4598bb5..0ed5eb8 100644
--- a/core/java/android/app/Dialog.java
+++ b/core/java/android/app/Dialog.java
@@ -822,13 +822,15 @@
final SearchManager searchManager = (SearchManager) mContext
.getSystemService(Context.SEARCH_SERVICE);
- // associate search with owner activity if possible (otherwise it will default to
- // global search).
+ // associate search with owner activity
final ComponentName appName = getAssociatedActivity();
- final boolean globalSearch = (appName == null);
- searchManager.startSearch(null, false, appName, null, globalSearch);
- dismiss();
- return true;
+ if (appName != null) {
+ searchManager.startSearch(null, false, appName, null, false);
+ dismiss();
+ return true;
+ } else {
+ return false;
+ }
}
/**
diff --git a/core/java/android/app/SearchManager.java b/core/java/android/app/SearchManager.java
index ce5f1bf..99edfac 100644
--- a/core/java/android/app/SearchManager.java
+++ b/core/java/android/app/SearchManager.java
@@ -1639,6 +1639,7 @@
return;
}
Intent intent = new Intent(INTENT_ACTION_GLOBAL_SEARCH);
+ intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setComponent(globalSearchActivity);
// TODO: Always pass name of calling package as an extra?
if (appSearchData != null) {
diff --git a/core/java/android/app/UiModeManager.java b/core/java/android/app/UiModeManager.java
new file mode 100644
index 0000000..aca8ab4
--- /dev/null
+++ b/core/java/android/app/UiModeManager.java
@@ -0,0 +1,83 @@
+package android.app;
+
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.Log;
+
+/**
+ * This class provides access to the system uimode services. These services
+ * allow applications to control UI modes of the device.
+ * It provides functionality to disable the car mode and it gives access to the
+ * night mode settings.
+ *
+ * <p>You do not instantiate this class directly; instead, retrieve it through
+ * {@link android.content.Context#getSystemService
+ * Context.getSystemService(Context.UI_MODE_SERVICE)}.
+ */
+public class UiModeManager {
+ private static final String TAG = "UiModeManager";
+
+ public static final int MODE_NOTNIGHT = 1;
+ public static final int MODE_NIGHT = 2;
+ public static final int MODE_AUTO = 3;
+
+ private IUiModeManager mService;
+
+ /*package*/ UiModeManager() {
+ mService = IUiModeManager.Stub.asInterface(
+ ServiceManager.getService("uimode"));
+ }
+
+ /**
+ * Disables the car mode.
+ */
+ public void disableCarMode() {
+ if (mService != null) {
+ try {
+ mService.disableCarMode();
+ } catch (RemoteException e) {
+ Log.e(TAG, "disableCarMode: RemoteException", e);
+ }
+ }
+ }
+
+ /**
+ * Sets the night mode. Changes to the night mode are only effective when
+ * the car mode is enabled on a device.
+ *
+ * <p>The mode can be one of:
+ * <ul>
+ * <li><em>{@link #MODE_NOTNIGHT}<em> - sets the device into notnight
+ * mode.</li>
+ * <li><em>{@link #MODE_NIGHT}</em> - sets the device into night mode.
+ * </li>
+ * <li><em>{@link #MODE_AUTO}</em> - automatic night/notnight switching
+ * depending on the location and certain other sensors.</li>
+ */
+ public void setNightMode(int mode) {
+ if (mService != null) {
+ try {
+ mService.setNightMode(mode);
+ } catch (RemoteException e) {
+ Log.e(TAG, "setNightMode: RemoteException", e);
+ }
+ }
+ }
+
+ /**
+ * Returns the currently configured night mode.
+ *
+ * @return {@link #MODE_NOTNIGHT}, {@link #MODE_NIGHT} or {@link #MODE_AUTO}
+ * When an error occurred -1 is returned.
+ */
+ public int getNightMode() {
+ if (mService != null) {
+ try {
+ return mService.getNightMode();
+ } catch (RemoteException e) {
+ Log.e(TAG, "getNightMode: RemoteException", e);
+ }
+ }
+ return -1;
+ }
+}
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 672e5f7..897d702 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -1204,6 +1204,8 @@
* <dt> {@link #INPUT_METHOD_SERVICE} ("input_method")
* <dd> An {@link android.view.inputmethod.InputMethodManager InputMethodManager}
* for management of input methods.
+ * <dt> {@link #UI_MODE_SERVICE} ("uimode")
+ * <dd> An {@link android.app.UiModeManager} for controlling UI modes.
* </dl>
*
* <p>Note: System services obtained via this API may be closely associated with
@@ -1249,6 +1251,8 @@
* @see android.telephony.TelephonyManager
* @see #INPUT_METHOD_SERVICE
* @see android.view.inputmethod.InputMethodManager
+ * @see #UI_MODE_SERVICE
+ * @see android.app.UiModeManager
*/
public abstract Object getSystemService(String name);
@@ -1511,6 +1515,14 @@
public static final String DEVICE_POLICY_SERVICE = "device_policy";
/**
+ * Use with {@link #getSystemService} to retrieve a
+ * {@link android.app.UiModeManager} for controlling UI modes.
+ *
+ * @see #getSystemService
+ */
+ public static final String UI_MODE_SERVICE = "uimode";
+
+ /**
* Determine whether the given permission is allowed for a particular
* process and user ID running in the system.
*
diff --git a/core/java/android/database/sqlite/SQLiteCompiledSql.java b/core/java/android/database/sqlite/SQLiteCompiledSql.java
index eb85822..a7a1d9a 100644
--- a/core/java/android/database/sqlite/SQLiteCompiledSql.java
+++ b/core/java/android/database/sqlite/SQLiteCompiledSql.java
@@ -95,12 +95,16 @@
}
}
- /* package */ synchronized boolean isInUse() {
- return mInUse;
- }
-
- /* package */ synchronized void acquire() {
+ /**
+ * returns true if acquire() succeeds. false otherwise.
+ */
+ /* package */ synchronized boolean acquire() {
+ if (mInUse) {
+ // someone already has acquired it.
+ return false;
+ }
mInUse = true;
+ return true;
}
/* package */ synchronized void release() {
diff --git a/core/java/android/database/sqlite/SQLiteProgram.java b/core/java/android/database/sqlite/SQLiteProgram.java
index 2bb2f5d..a3a8486 100644
--- a/core/java/android/database/sqlite/SQLiteProgram.java
+++ b/core/java/android/database/sqlite/SQLiteProgram.java
@@ -61,16 +61,13 @@
mCompiledSql.acquire();
} else {
// it is already in compiled-sql cache.
- if (mCompiledSql.isInUse()) {
- // but the CompiledSql in cache is in use by some other SQLiteProgram object.
+ // try to acquire the object.
+ if (!mCompiledSql.acquire()) {
+ // the SQLiteCompiledSql in cache is in use by some other SQLiteProgram object.
// we can't have two different SQLiteProgam objects can't share the same
// CompiledSql object. create a new one.
// finalize it when I am done with it in "this" object.
mCompiledSql = new SQLiteCompiledSql(db, sql);
- } else {
- // the CompiledSql in cache is NOT in use by any other SQLiteProgram object.
- // it is safe to give it to this SQLIteProgram Object.
- mCompiledSql.acquire();
}
}
nStatement = mCompiledSql.nStatement;
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index a79bbee..17d5bb7 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -1960,7 +1960,6 @@
if (getHeight() > 0 && getChildCount() > 0) {
// We do not lose focus initiating a touch (since AbsListView is focusable in
// touch mode). Force an initial layout to get rid of the selection.
- mLayoutMode = LAYOUT_NORMAL;
layoutChildren();
}
} else {
@@ -3118,7 +3117,9 @@
void hideSelector() {
if (mSelectedPosition != INVALID_POSITION) {
- mResurrectToPosition = mSelectedPosition;
+ if (mLayoutMode != LAYOUT_SPECIFIC) {
+ mResurrectToPosition = mSelectedPosition;
+ }
if (mNextSelectedPosition >= 0 && mNextSelectedPosition != mSelectedPosition) {
mResurrectToPosition = mNextSelectedPosition;
}
diff --git a/core/java/com/android/internal/app/AlertController.java b/core/java/com/android/internal/app/AlertController.java
index f56b15c..107b145 100644
--- a/core/java/com/android/internal/app/AlertController.java
+++ b/core/java/com/android/internal/app/AlertController.java
@@ -26,6 +26,7 @@
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
+import android.util.AttributeSet;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@@ -48,7 +49,6 @@
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
import android.widget.AdapterView.OnItemClickListener;
-import android.util.AttributeSet;
import com.android.internal.R;
@@ -322,24 +322,24 @@
public Button getButton(int whichButton) {
switch (whichButton) {
case DialogInterface.BUTTON_POSITIVE:
- return mButtonPositiveMessage != null ? mButtonPositive : null;
+ return mButtonPositive;
case DialogInterface.BUTTON_NEGATIVE:
- return mButtonNegativeMessage != null ? mButtonNegative : null;
+ return mButtonNegative;
case DialogInterface.BUTTON_NEUTRAL:
- return mButtonNeutralMessage != null ? mButtonNeutral : null;
+ return mButtonNeutral;
default:
return null;
}
}
+ @SuppressWarnings({"UnusedDeclaration"})
public boolean onKeyDown(int keyCode, KeyEvent event) {
- if (mScrollView != null && mScrollView.executeKeyEvent(event)) return true;
- return false;
+ return mScrollView != null && mScrollView.executeKeyEvent(event);
}
+ @SuppressWarnings({"UnusedDeclaration"})
public boolean onKeyUp(int keyCode, KeyEvent event) {
- if (mScrollView != null && mScrollView.executeKeyEvent(event)) return true;
- return false;
+ return mScrollView != null && mScrollView.executeKeyEvent(event);
}
private void setupView() {
@@ -469,7 +469,6 @@
}
private boolean setupButtons() {
- View defaultButton = null;
int BIT_BUTTON_POSITIVE = 1;
int BIT_BUTTON_NEGATIVE = 2;
int BIT_BUTTON_NEUTRAL = 4;
@@ -482,7 +481,6 @@
} else {
mButtonPositive.setText(mButtonPositiveText);
mButtonPositive.setVisibility(View.VISIBLE);
- defaultButton = mButtonPositive;
whichButtons = whichButtons | BIT_BUTTON_POSITIVE;
}
@@ -495,9 +493,6 @@
mButtonNegative.setText(mButtonNegativeText);
mButtonNegative.setVisibility(View.VISIBLE);
- if (defaultButton == null) {
- defaultButton = mButtonNegative;
- }
whichButtons = whichButtons | BIT_BUTTON_NEGATIVE;
}
@@ -510,9 +505,6 @@
mButtonNeutral.setText(mButtonNeutralText);
mButtonNeutral.setVisibility(View.VISIBLE);
- if (defaultButton == null) {
- defaultButton = mButtonNeutral;
- }
whichButtons = whichButtons | BIT_BUTTON_NEUTRAL;
}
@@ -565,8 +557,6 @@
R.styleable.AlertDialog_bottomBright, R.drawable.popup_bottom_bright);
int bottomMedium = a.getResourceId(
R.styleable.AlertDialog_bottomMedium, R.drawable.popup_bottom_medium);
- int centerMedium = a.getResourceId(
- R.styleable.AlertDialog_centerMedium, R.drawable.popup_center_medium);
/*
* We now set the background of all of the sections of the alert.
@@ -596,7 +586,7 @@
*/
views[pos] = (contentPanel.getVisibility() == View.GONE)
? null : contentPanel;
- light[pos] = mListView == null ? false : true;
+ light[pos] = mListView != null;
pos++;
if (customPanel != null) {
views[pos] = customPanel;
diff --git a/include/binder/Parcel.h b/include/binder/Parcel.h
index ba6c711..66c34b2 100644
--- a/include/binder/Parcel.h
+++ b/include/binder/Parcel.h
@@ -30,6 +30,7 @@
class ProcessState;
class String8;
class TextOutput;
+class Flattenable;
struct flat_binder_object; // defined in support_p/binder_module.h
@@ -81,6 +82,7 @@
status_t writeString16(const char16_t* str, size_t len);
status_t writeStrongBinder(const sp<IBinder>& val);
status_t writeWeakBinder(const wp<IBinder>& val);
+ status_t write(const Flattenable& val);
// Place a native_handle into the parcel (the native_handle's file-
// descriptors are dup'ed, so it is safe to delete the native_handle
@@ -119,7 +121,7 @@
const char16_t* readString16Inplace(size_t* outLen) const;
sp<IBinder> readStrongBinder() const;
wp<IBinder> readWeakBinder() const;
-
+ status_t read(Flattenable& val) const;
// Retrieve native_handle from the parcel. This returns a copy of the
// parcel's native_handle (the caller takes ownership). The caller
diff --git a/include/ui/GraphicBuffer.h b/include/ui/GraphicBuffer.h
index b9c491be..e72b6b3 100644
--- a/include/ui/GraphicBuffer.h
+++ b/include/ui/GraphicBuffer.h
@@ -23,6 +23,7 @@
#include <ui/android_native_buffer.h>
#include <ui/PixelFormat.h>
#include <ui/Rect.h>
+#include <utils/Flattenable.h>
#include <pixelflinger/pixelflinger.h>
struct android_native_buffer_t;
@@ -30,7 +31,6 @@
namespace android {
class GraphicBufferMapper;
-class Parcel;
// ===========================================================================
// GraphicBuffer
@@ -40,7 +40,7 @@
: public EGLNativeBase<
android_native_buffer_t,
GraphicBuffer,
- LightRefBase<GraphicBuffer> >
+ LightRefBase<GraphicBuffer> >, public Flattenable
{
public:
@@ -97,7 +97,6 @@
uint32_t getVerticalStride() const;
protected:
- GraphicBuffer(const Parcel& reply);
virtual ~GraphicBuffer();
enum {
@@ -122,8 +121,16 @@
status_t initSize(uint32_t w, uint32_t h, PixelFormat format,
uint32_t usage);
- static status_t writeToParcel(Parcel* reply,
- android_native_buffer_t const* buffer);
+ void free_handle();
+
+ // Flattenable interface
+ size_t getFlattenedSize() const;
+ size_t getFdCount() const;
+ status_t flatten(void* buffer, size_t size,
+ int fds[], size_t count) const;
+ status_t unflatten(void const* buffer, size_t size,
+ int fds[], size_t count);
+
GraphicBufferMapper& mBufferMapper;
ssize_t mInitCheck;
diff --git a/include/utils/Flattenable.h b/include/utils/Flattenable.h
new file mode 100644
index 0000000..852be3b
--- /dev/null
+++ b/include/utils/Flattenable.h
@@ -0,0 +1,62 @@
+/*
+ * 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.
+ */
+
+#ifndef ANDROID_UTILS_FLATTENABLE_H
+#define ANDROID_UTILS_FLATTENABLE_H
+
+
+#include <stdint.h>
+#include <sys/types.h>
+#include <utils/Errors.h>
+
+namespace android {
+
+class Flattenable
+{
+public:
+ // size in bytes of the flattened object
+ virtual size_t getFlattenedSize() const = 0;
+
+ // number of file descriptors to flatten
+ virtual size_t getFdCount() const = 0;
+
+ // flattens the object into buffer.
+ // size should be at least of getFlattenedSize()
+ // file descriptors are written in the fds[] array but ownership is
+ // not transfered (ie: they must be dupped by the caller of
+ // flatten() if needed).
+ virtual status_t flatten(void* buffer, size_t size,
+ int fds[], size_t count) const = 0;
+
+ // unflattens the object from buffer.
+ // size should be equal to the value of getFlattenedSize() when the
+ // object was flattened.
+ // unflattened file descriptors are found in the fds[] array and
+ // don't need to be dupped(). ie: the caller of unflatten doesn't
+ // keep ownership. If a fd is not retained by unflatten() it must be
+ // explicitly closed.
+ virtual status_t unflatten(void const* buffer, size_t size,
+ int fds[], size_t count) = 0;
+
+protected:
+ virtual ~Flattenable() = 0;
+
+};
+
+}; // namespace android
+
+
+#endif /* ANDROID_UTILS_FLATTENABLE_H */
diff --git a/keystore/java/android/security/SystemKeyStore.java b/keystore/java/android/security/SystemKeyStore.java
index 61a4293..abdb0ae 100644
--- a/keystore/java/android/security/SystemKeyStore.java
+++ b/keystore/java/android/security/SystemKeyStore.java
@@ -17,6 +17,7 @@
package android.security;
import android.os.Environment;
+import android.os.FileUtils;
import android.os.Process;
import java.io.File;
@@ -92,6 +93,8 @@
fos.write(retKey);
fos.flush();
fos.close();
+ FileUtils.setPermissions(keyFile.getName(), (FileUtils.S_IRUSR | FileUtils.S_IWUSR),
+ -1, -1);
} catch (IOException ioe) {
return null;
}
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index e397bce..00d2210 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -28,6 +28,7 @@
#include <utils/String16.h>
#include <utils/TextOutput.h>
#include <utils/misc.h>
+#include <utils/Flattenable.h>
#include <private/binder/binder_module.h>
@@ -675,6 +676,42 @@
return writeObject(obj, true);
}
+status_t Parcel::write(const Flattenable& val)
+{
+ status_t err;
+
+ // size if needed
+ size_t len = val.getFlattenedSize();
+ size_t fd_count = val.getFdCount();
+
+ err = this->writeInt32(len);
+ if (err) return err;
+
+ err = this->writeInt32(fd_count);
+ if (err) return err;
+
+ // payload
+ void* buf = this->writeInplace(PAD_SIZE(len));
+ if (buf == NULL)
+ return BAD_VALUE;
+
+ int* fds = NULL;
+ if (fd_count) {
+ fds = new int[fd_count];
+ }
+
+ err = val.flatten(buf, len, fds, fd_count);
+ for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {
+ err = this->writeDupFileDescriptor( fds[i] );
+ }
+
+ if (fd_count) {
+ delete [] fds;
+ }
+
+ return err;
+}
+
status_t Parcel::writeObject(const flat_binder_object& val, bool nullMetaData)
{
const bool enoughData = (mDataPos+sizeof(val)) <= mDataCapacity;
@@ -713,7 +750,6 @@
goto restart_write;
}
-
void Parcel::remove(size_t start, size_t amt)
{
LOG_ALWAYS_FATAL("Parcel::remove() not yet implemented!");
@@ -940,6 +976,38 @@
return BAD_TYPE;
}
+status_t Parcel::read(Flattenable& val) const
+{
+ // size
+ const size_t len = this->readInt32();
+ const size_t fd_count = this->readInt32();
+
+ // payload
+ void const* buf = this->readInplace(PAD_SIZE(len));
+ if (buf == NULL)
+ return BAD_VALUE;
+
+ int* fds = NULL;
+ if (fd_count) {
+ fds = new int[fd_count];
+ }
+
+ status_t err = NO_ERROR;
+ for (size_t i=0 ; i<fd_count && err==NO_ERROR ; i++) {
+ fds[i] = dup(this->readFileDescriptor());
+ if (fds[i] < 0) err = BAD_VALUE;
+ }
+
+ if (err == NO_ERROR) {
+ err = val.unflatten(buf, len, fds, fd_count);
+ }
+
+ if (fd_count) {
+ delete [] fds;
+ }
+
+ return err;
+}
const flat_binder_object* Parcel::readObject(bool nullMetaData) const
{
const size_t DPOS = mDataPos;
diff --git a/libs/surfaceflinger_client/ISurface.cpp b/libs/surfaceflinger_client/ISurface.cpp
index 9125146..bb86199 100644
--- a/libs/surfaceflinger_client/ISurface.cpp
+++ b/libs/surfaceflinger_client/ISurface.cpp
@@ -78,7 +78,8 @@
data.writeInt32(bufferIdx);
data.writeInt32(usage);
remote()->transact(REQUEST_BUFFER, data, &reply);
- sp<GraphicBuffer> buffer = new GraphicBuffer(reply);
+ sp<GraphicBuffer> buffer = new GraphicBuffer();
+ reply.read(*buffer);
return buffer;
}
@@ -141,7 +142,9 @@
int bufferIdx = data.readInt32();
int usage = data.readInt32();
sp<GraphicBuffer> buffer(requestBuffer(bufferIdx, usage));
- return GraphicBuffer::writeToParcel(reply, buffer.get());
+ if (buffer == NULL)
+ return BAD_VALUE;
+ return reply->write(*buffer);
}
case REGISTER_BUFFERS: {
CHECK_INTERFACE(ISurface, data, reply);
diff --git a/libs/ui/GraphicBuffer.cpp b/libs/ui/GraphicBuffer.cpp
index 6a5c8a9..ba1fd9c 100644
--- a/libs/ui/GraphicBuffer.cpp
+++ b/libs/ui/GraphicBuffer.cpp
@@ -14,12 +14,12 @@
* limitations under the License.
*/
+#define LOG_TAG "GraphicBuffer"
+
#include <stdlib.h>
#include <stdint.h>
#include <sys/types.h>
-#include <binder/Parcel.h>
-
#include <utils/Errors.h>
#include <utils/Log.h>
@@ -77,34 +77,21 @@
handle = inHandle;
}
-GraphicBuffer::GraphicBuffer(const Parcel& data)
- : BASE(), mOwner(ownHandle), mBufferMapper(GraphicBufferMapper::get()),
- mInitCheck(NO_ERROR), mVStride(0), mIndex(-1)
-{
- // we own the handle in this case
- width = data.readInt32();
- if (width < 0) {
- width = height = stride = format = usage = 0;
- handle = 0;
- } else {
- height = data.readInt32();
- stride = data.readInt32();
- format = data.readInt32();
- usage = data.readInt32();
- handle = data.readNativeHandle();
- }
-}
-
GraphicBuffer::~GraphicBuffer()
{
if (handle) {
- if (mOwner == ownHandle) {
- native_handle_close(handle);
- native_handle_delete(const_cast<native_handle*>(handle));
- } else if (mOwner == ownData) {
- GraphicBufferAllocator& allocator(GraphicBufferAllocator::get());
- allocator.free(handle);
- }
+ free_handle();
+ }
+}
+
+void GraphicBuffer::free_handle()
+{
+ if (mOwner == ownHandle) {
+ native_handle_close(handle);
+ native_handle_delete(const_cast<native_handle*>(handle));
+ } else if (mOwner == ownData) {
+ GraphicBufferAllocator& allocator(GraphicBufferAllocator::get());
+ allocator.free(handle);
}
}
@@ -192,29 +179,83 @@
return res;
}
+size_t GraphicBuffer::getFlattenedSize() const {
+ return (8 + (handle ? handle->numInts : 0))*sizeof(int);
+}
-status_t GraphicBuffer::writeToParcel(Parcel* reply,
- android_native_buffer_t const* buffer)
+size_t GraphicBuffer::getFdCount() const {
+ return handle ? handle->numFds : 0;
+}
+
+status_t GraphicBuffer::flatten(void* buffer, size_t size,
+ int fds[], size_t count) const
{
- if (buffer == NULL)
- return BAD_VALUE;
+ size_t sizeNeeded = GraphicBuffer::getFlattenedSize();
+ if (size < sizeNeeded) return NO_MEMORY;
- if (buffer->width < 0 || buffer->height < 0)
- return BAD_VALUE;
+ size_t fdCountNeeded = GraphicBuffer::getFdCount();
+ if (count < fdCountNeeded) return NO_MEMORY;
- status_t err = NO_ERROR;
- if (buffer->handle == NULL) {
- // this buffer doesn't have a handle
- reply->writeInt32(NO_MEMORY);
- } else {
- reply->writeInt32(buffer->width);
- reply->writeInt32(buffer->height);
- reply->writeInt32(buffer->stride);
- reply->writeInt32(buffer->format);
- reply->writeInt32(buffer->usage);
- err = reply->writeNativeHandle(buffer->handle);
+ int* buf = static_cast<int*>(buffer);
+ buf[0] = 'GBFR';
+ buf[1] = width;
+ buf[2] = height;
+ buf[3] = stride;
+ buf[4] = format;
+ buf[5] = usage;
+ buf[6] = 0;
+ buf[7] = 0;
+
+ if (handle) {
+ buf[6] = handle->numFds;
+ buf[7] = handle->numInts;
+ native_handle_t const* const h = handle;
+ memcpy(fds, h->data, h->numFds*sizeof(int));
+ memcpy(&buf[8], h->data + h->numFds, h->numInts*sizeof(int));
}
- return err;
+
+ return NO_ERROR;
+}
+
+status_t GraphicBuffer::unflatten(void const* buffer, size_t size,
+ int fds[], size_t count)
+{
+ if (size < 8*sizeof(int)) return NO_MEMORY;
+
+ int const* buf = static_cast<int const*>(buffer);
+ if (buf[0] != 'GBFR') return BAD_TYPE;
+
+ const size_t numFds = buf[6];
+ const size_t numInts = buf[7];
+
+ const size_t sizeNeeded = (8 + numInts) * sizeof(int);
+ if (size < sizeNeeded) return NO_MEMORY;
+
+ size_t fdCountNeeded = 0;
+ if (count < fdCountNeeded) return NO_MEMORY;
+
+ if (handle) {
+ // free previous handle if any
+ free_handle();
+ }
+
+ if (numFds || numInts) {
+ width = buf[1];
+ height = buf[2];
+ stride = buf[3];
+ format = buf[4];
+ usage = buf[5];
+ native_handle* h = native_handle_create(numFds, numInts);
+ memcpy(h->data, fds, numFds*sizeof(int));
+ memcpy(h->data + numFds, &buf[8], numInts*sizeof(int));
+ handle = h;
+ } else {
+ width = height = stride = format = usage = 0;
+ handle = NULL;
+ }
+
+ mOwner = ownHandle;
+ return NO_ERROR;
}
diff --git a/libs/utils/Android.mk b/libs/utils/Android.mk
index d2cfd3b..d0eedb4 100644
--- a/libs/utils/Android.mk
+++ b/libs/utils/Android.mk
@@ -25,6 +25,7 @@
CallStack.cpp \
Debug.cpp \
FileMap.cpp \
+ Flattenable.cpp \
RefBase.cpp \
ResourceTypes.cpp \
SharedBuffer.cpp \
diff --git a/libs/utils/Flattenable.cpp b/libs/utils/Flattenable.cpp
new file mode 100644
index 0000000..1f2ffaa
--- /dev/null
+++ b/libs/utils/Flattenable.cpp
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <utils/Flattenable.h>
+
+namespace android {
+
+Flattenable::~Flattenable() {
+}
+
+}; // namespace android
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index 2a78806..39ee314 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -202,7 +202,7 @@
String vs = getVolumeState(path);
if (enable && vs.equals(Environment.MEDIA_MOUNTED)) {
mUmsEnabling = enable; // Override for isUsbMassStorageEnabled()
- int rc = doUnmountVolume(path, false);
+ int rc = doUnmountVolume(path, true);
mUmsEnabling = false; // Clear override
if (rc != StorageResultCode.OperationSucceeded) {
Log.e(TAG, String.format("Failed to unmount before enabling UMS (%d)", rc));