Merge "enable ALLOW_DEQUEUE_CURRENT_BUFFER for tegra devices" into ics-mr1
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index f9896f7..303f81b 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -2734,8 +2734,9 @@
CharSequence description;
}
- private class ProviderRefCount {
+ private static final class ProviderRefCount {
public int count;
+
ProviderRefCount(int pCount) {
count = pCount;
}
@@ -3988,16 +3989,14 @@
buf.append(": ");
buf.append(cpi.name);
Log.i(TAG, buf.toString());
- IContentProvider cp = installProvider(context, null, cpi, false);
+ IContentProvider cp = installProvider(context, null, cpi,
+ false /*noisy*/, true /*noReleaseNeeded*/);
if (cp != null) {
IActivityManager.ContentProviderHolder cph =
- new IActivityManager.ContentProviderHolder(cpi);
+ new IActivityManager.ContentProviderHolder(cpi);
cph.provider = cp;
+ cph.noReleaseNeeded = true;
results.add(cph);
- // Don't ever unload this provider from the process.
- synchronized(mProviderMap) {
- mProviderRefCountMap.put(cp.asBinder(), new ProviderRefCount(10000));
- }
}
}
@@ -4008,26 +4007,22 @@
}
}
- private IContentProvider getExistingProvider(Context context, String name) {
- synchronized(mProviderMap) {
- final ProviderClientRecord pr = mProviderMap.get(name);
- if (pr != null) {
- return pr.mProvider;
- }
- return null;
- }
- }
-
- private IContentProvider getProvider(Context context, String name) {
- IContentProvider existing = getExistingProvider(context, name);
- if (existing != null) {
- return existing;
+ public final IContentProvider acquireProvider(Context c, String name) {
+ IContentProvider provider = acquireExistingProvider(c, name);
+ if (provider != null) {
+ return provider;
}
+ // There is a possible race here. Another thread may try to acquire
+ // the same provider at the same time. When this happens, we want to ensure
+ // that the first one wins.
+ // Note that we cannot hold the lock while acquiring and installing the
+ // provider since it might take a long time to run and it could also potentially
+ // be re-entrant in the case where the provider is in the same process.
IActivityManager.ContentProviderHolder holder = null;
try {
holder = ActivityManagerNative.getDefault().getContentProvider(
- getApplicationThread(), name);
+ getApplicationThread(), name);
} catch (RemoteException ex) {
}
if (holder == null) {
@@ -4035,136 +4030,137 @@
return null;
}
- IContentProvider prov = installProvider(context, holder.provider,
- holder.info, true);
- //Slog.i(TAG, "noReleaseNeeded=" + holder.noReleaseNeeded);
- if (holder.noReleaseNeeded || holder.provider == null) {
- // We are not going to release the provider if it is an external
- // provider that doesn't care about being released, or if it is
- // a local provider running in this process.
- //Slog.i(TAG, "*** NO RELEASE NEEDED");
- synchronized(mProviderMap) {
- mProviderRefCountMap.put(prov.asBinder(), new ProviderRefCount(10000));
+ // Install provider will increment the reference count for us, and break
+ // any ties in the race.
+ provider = installProvider(c, holder.provider, holder.info,
+ true /*noisy*/, holder.noReleaseNeeded);
+ if (holder.provider != null && provider != holder.provider) {
+ if (localLOGV) {
+ Slog.v(TAG, "acquireProvider: lost the race, releasing extraneous "
+ + "reference to the content provider");
+ }
+ try {
+ ActivityManagerNative.getDefault().removeContentProvider(
+ getApplicationThread(), name);
+ } catch (RemoteException ex) {
}
}
- return prov;
- }
-
- public final IContentProvider acquireProvider(Context c, String name) {
- IContentProvider provider = getProvider(c, name);
- if(provider == null)
- return null;
- IBinder jBinder = provider.asBinder();
- synchronized(mProviderMap) {
- ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
- if(prc == null) {
- mProviderRefCountMap.put(jBinder, new ProviderRefCount(1));
- } else {
- prc.count++;
- } //end else
- } //end synchronized
return provider;
}
public final IContentProvider acquireExistingProvider(Context c, String name) {
- IContentProvider provider = getExistingProvider(c, name);
- if(provider == null)
- return null;
- IBinder jBinder = provider.asBinder();
- synchronized(mProviderMap) {
+ synchronized (mProviderMap) {
+ ProviderClientRecord pr = mProviderMap.get(name);
+ if (pr == null) {
+ return null;
+ }
+
+ IContentProvider provider = pr.mProvider;
+ IBinder jBinder = provider.asBinder();
+
+ // Only increment the ref count if we have one. If we don't then the
+ // provider is not reference counted and never needs to be released.
ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
- if(prc == null) {
- mProviderRefCountMap.put(jBinder, new ProviderRefCount(1));
- } else {
- prc.count++;
- } //end else
- } //end synchronized
- return provider;
+ if (prc != null) {
+ prc.count += 1;
+ if (prc.count == 1) {
+ if (localLOGV) {
+ Slog.v(TAG, "acquireExistingProvider: "
+ + "snatched provider from the jaws of death");
+ }
+ // Because the provider previously had a reference count of zero,
+ // it was scheduled to be removed. Cancel that.
+ mH.removeMessages(H.REMOVE_PROVIDER, provider);
+ }
+ }
+ return provider;
+ }
}
public final boolean releaseProvider(IContentProvider provider) {
if(provider == null) {
return false;
}
+
IBinder jBinder = provider.asBinder();
- synchronized(mProviderMap) {
+ synchronized (mProviderMap) {
ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
- if(prc == null) {
- if(localLOGV) Slog.v(TAG, "releaseProvider::Weird shouldn't be here");
+ if (prc == null) {
+ // The provider has no ref count, no release is needed.
return false;
- } else {
- prc.count--;
- if(prc.count == 0) {
- // Schedule the actual remove asynchronously, since we
- // don't know the context this will be called in.
- // TODO: it would be nice to post a delayed message, so
- // if we come back and need the same provider quickly
- // we will still have it available.
- Message msg = mH.obtainMessage(H.REMOVE_PROVIDER, provider);
- mH.sendMessage(msg);
- } //end if
- } //end else
- } //end synchronized
- return true;
+ }
+
+ if (prc.count == 0) {
+ if (localLOGV) Slog.v(TAG, "releaseProvider: ref count already 0, how?");
+ return false;
+ }
+
+ prc.count -= 1;
+ if (prc.count == 0) {
+ // Schedule the actual remove asynchronously, since we don't know the context
+ // this will be called in.
+ // TODO: it would be nice to post a delayed message, so
+ // if we come back and need the same provider quickly
+ // we will still have it available.
+ Message msg = mH.obtainMessage(H.REMOVE_PROVIDER, provider);
+ mH.sendMessage(msg);
+ }
+ return true;
+ }
}
final void completeRemoveProvider(IContentProvider provider) {
IBinder jBinder = provider.asBinder();
- String name = null;
+ String remoteProviderName = null;
synchronized(mProviderMap) {
ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
- if(prc != null && prc.count == 0) {
- mProviderRefCountMap.remove(jBinder);
- //invoke removeProvider to dereference provider
- name = removeProviderLocked(provider);
+ if (prc == null) {
+ // Either no release is needed (so we shouldn't be here) or the
+ // provider was already released.
+ if (localLOGV) Slog.v(TAG, "completeRemoveProvider: release not needed");
+ return;
+ }
+
+ if (prc.count != 0) {
+ // There was a race! Some other client managed to acquire
+ // the provider before the removal was completed.
+ // Abort the removal. We will do it later.
+ if (localLOGV) Slog.v(TAG, "completeRemoveProvider: lost the race, "
+ + "provider still in use");
+ return;
+ }
+
+ mProviderRefCountMap.remove(jBinder);
+
+ Iterator<ProviderClientRecord> iter = mProviderMap.values().iterator();
+ while (iter.hasNext()) {
+ ProviderClientRecord pr = iter.next();
+ IBinder myBinder = pr.mProvider.asBinder();
+ if (myBinder == jBinder) {
+ iter.remove();
+ if (pr.mLocalProvider == null) {
+ myBinder.unlinkToDeath(pr, 0);
+ if (remoteProviderName == null) {
+ remoteProviderName = pr.mName;
+ }
+ }
+ }
}
}
-
- if (name != null) {
+
+ if (remoteProviderName != null) {
try {
- if(localLOGV) Slog.v(TAG, "removeProvider::Invoking " +
- "ActivityManagerNative.removeContentProvider(" + name);
+ if (localLOGV) {
+ Slog.v(TAG, "removeProvider: Invoking ActivityManagerNative."
+ + "removeContentProvider(" + remoteProviderName + ")");
+ }
ActivityManagerNative.getDefault().removeContentProvider(
- getApplicationThread(), name);
+ getApplicationThread(), remoteProviderName);
} catch (RemoteException e) {
//do nothing content provider object is dead any way
- } //end catch
+ }
}
}
-
- public final String removeProviderLocked(IContentProvider provider) {
- if (provider == null) {
- return null;
- }
- IBinder providerBinder = provider.asBinder();
-
- String name = null;
-
- // remove the provider from mProviderMap
- Iterator<ProviderClientRecord> iter = mProviderMap.values().iterator();
- while (iter.hasNext()) {
- ProviderClientRecord pr = iter.next();
- IBinder myBinder = pr.mProvider.asBinder();
- if (myBinder == providerBinder) {
- //find if its published by this process itself
- if(pr.mLocalProvider != null) {
- if(localLOGV) Slog.i(TAG, "removeProvider::found local provider returning");
- return name;
- }
- if(localLOGV) Slog.v(TAG, "removeProvider::Not local provider Unlinking " +
- "death recipient");
- //content provider is in another process
- myBinder.unlinkToDeath(pr, 0);
- iter.remove();
- //invoke remove only once for the very first name seen
- if(name == null) {
- name = pr.mName;
- }
- } //end if myBinder
- } //end while iter
-
- return name;
- }
final void removeDeadProvider(String name, IContentProvider provider) {
synchronized(mProviderMap) {
@@ -4179,8 +4175,23 @@
}
}
+ /**
+ * Installs the provider.
+ *
+ * Providers that are local to the process or that come from the system server
+ * may be installed permanently which is indicated by setting noReleaseNeeded to true.
+ * Other remote providers are reference counted. The initial reference count
+ * for all reference counted providers is one. Providers that are not reference
+ * counted do not have a reference count (at all).
+ *
+ * This method detects when a provider has already been installed. When this happens,
+ * it increments the reference count of the existing provider (if appropriate)
+ * and returns the existing provider. This can happen due to concurrent
+ * attempts to acquire the same provider.
+ */
private IContentProvider installProvider(Context context,
- IContentProvider provider, ProviderInfo info, boolean noisy) {
+ IContentProvider provider, ProviderInfo info,
+ boolean noisy, boolean noReleaseNeeded) {
ContentProvider localProvider = null;
if (provider == null) {
if (noisy) {
@@ -4238,24 +4249,69 @@
}
synchronized (mProviderMap) {
- // Cache the pointer for the remote provider.
+ // There is a possibility that this thread raced with another thread to
+ // add the provider. If we find another thread got there first then we
+ // just get out of the way and return the original provider.
+ IBinder jBinder = provider.asBinder();
String names[] = PATTERN_SEMICOLON.split(info.authority);
- for (int i=0; i<names.length; i++) {
- ProviderClientRecord pr = new ProviderClientRecord(names[i], provider,
- localProvider);
- try {
- provider.asBinder().linkToDeath(pr, 0);
+ for (int i = 0; i < names.length; i++) {
+ ProviderClientRecord pr = mProviderMap.get(names[i]);
+ if (pr != null) {
+ if (localLOGV) {
+ Slog.v(TAG, "installProvider: lost the race, "
+ + "using existing named provider");
+ }
+ provider = pr.mProvider;
+ } else {
+ pr = new ProviderClientRecord(names[i], provider, localProvider);
+ if (localProvider == null) {
+ try {
+ jBinder.linkToDeath(pr, 0);
+ } catch (RemoteException e) {
+ // Provider already dead. Bail out of here without making
+ // any changes to the provider map or other data structures.
+ return null;
+ }
+ }
mProviderMap.put(names[i], pr);
- } catch (RemoteException e) {
- return null;
}
}
+
if (localProvider != null) {
- mLocalProviders.put(provider.asBinder(),
- new ProviderClientRecord(null, provider, localProvider));
+ ProviderClientRecord pr = mLocalProviders.get(jBinder);
+ if (pr != null) {
+ if (localLOGV) {
+ Slog.v(TAG, "installProvider: lost the race, "
+ + "using existing local provider");
+ }
+ provider = pr.mProvider;
+ } else {
+ pr = new ProviderClientRecord(null, provider, localProvider);
+ mLocalProviders.put(jBinder, pr);
+ }
+ }
+
+ if (!noReleaseNeeded) {
+ ProviderRefCount prc = mProviderRefCountMap.get(jBinder);
+ if (prc != null) {
+ if (localLOGV) {
+ Slog.v(TAG, "installProvider: lost the race, incrementing ref count");
+ }
+ prc.count += 1;
+ if (prc.count == 1) {
+ if (localLOGV) {
+ Slog.v(TAG, "installProvider: "
+ + "snatched provider from the jaws of death");
+ }
+ // Because the provider previously had a reference count of zero,
+ // it was scheduled to be removed. Cancel that.
+ mH.removeMessages(H.REMOVE_PROVIDER, provider);
+ }
+ } else {
+ mProviderRefCountMap.put(jBinder, new ProviderRefCount(1));
+ }
}
}
-
return provider;
}
diff --git a/core/java/android/hardware/Camera.java b/core/java/android/hardware/Camera.java
index 3becec0..c2a757f 100644
--- a/core/java/android/hardware/Camera.java
+++ b/core/java/android/hardware/Camera.java
@@ -1111,9 +1111,21 @@
* Parameters#getMaxNumDetectedFaces()} returns a number larger than 0.
* If the face detection has started, apps should not call this again.
*
- * When the face detection is running, {@link Parameters#setWhiteBalance(String)},
+ * <p>When the face detection is running, {@link Parameters#setWhiteBalance(String)},
* {@link Parameters#setFocusAreas(List)}, and {@link Parameters#setMeteringAreas(List)}
- * have no effect.
+ * have no effect. The camera uses the detected faces to do auto-white balance,
+ * auto exposure, and autofocus.
+ *
+ * <p>If the apps call {@link #autoFocus(AutoFocusCallback)}, the camera
+ * will stop sending face callbacks. The last face callback indicates the
+ * areas used to do autofocus. After focus completes, face detection will
+ * resume sending face callbacks. If the apps call {@link
+ * #cancelAutoFocus()}, the face callbacks will also resume.</p>
+ *
+ * <p>After calling {@link #takePicture(Camera.ShutterCallback, Camera.PictureCallback,
+ * Camera.PictureCallback)} or {@link #stopPreview()}, and then resuming
+ * preview with {@link #startPreview()}, the apps should call this method
+ * again to resume face detection.</p>
*
* @throws IllegalArgumentException if the face detection is unsupported.
* @throws RuntimeException if the method fails or the face detection is
@@ -1163,14 +1175,31 @@
* camera field of view, and (1000, 1000) represents the bottom-right of
* the field of view. For example, suppose the size of the viewfinder UI
* is 800x480. The rect passed from the driver is (-1000, -1000, 0, 0).
- * The corresponding viewfinder rect should be (0, 0, 400, 240). The
- * width and height of the rect will not be 0 or negative. The
- * coordinates can be smaller than -1000 or bigger than 1000. But at
- * least one vertex will be within (-1000, -1000) and (1000, 1000).
+ * The corresponding viewfinder rect should be (0, 0, 400, 240). It is
+ * guaranteed left < right and top < bottom. The coordinates can be
+ * smaller than -1000 or bigger than 1000. But at least one vertex will
+ * be within (-1000, -1000) and (1000, 1000).
*
* <p>The direction is relative to the sensor orientation, that is, what
* the sensor sees. The direction is not affected by the rotation or
- * mirroring of {@link #setDisplayOrientation(int)}.</p>
+ * mirroring of {@link #setDisplayOrientation(int)}. The face bounding
+ * rectangle does not provide any information about face orientation.</p>
+ *
+ * <p>Here is the matrix to convert driver coordinates to View coordinates
+ * in pixels.</p>
+ * <pre>
+ * Matrix matrix = new Matrix();
+ * CameraInfo info = CameraHolder.instance().getCameraInfo()[cameraId];
+ * // Need mirror for front camera.
+ * boolean mirror = (info.facing == CameraInfo.CAMERA_FACING_FRONT);
+ * matrix.setScale(mirror ? -1 : 1, 1);
+ * // This is the value for android.hardware.Camera.setDisplayOrientation.
+ * matrix.postRotate(displayOrientation);
+ * // Camera driver coordinates range from (-1000, -1000) to (1000, 1000).
+ * // UI coordinates range from (0, 0) to (width, height).
+ * matrix.postScale(view.getWidth() / 2000f, view.getHeight() / 2000f);
+ * matrix.postTranslate(view.getWidth() / 2f, view.getHeight() / 2f);
+ * </pre>
*
* @see #startFaceDetection()
*/
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 821b6df..83acef8 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -187,6 +187,16 @@
public static final String DEFERRED_SNIPPETING_QUERY = "deferred_snippeting_query";
/**
+ * A boolean parameter for {@link CommonDataKinds.Phone#CONTENT_URI},
+ * {@link CommonDataKinds.Email#CONTENT_URI}, and
+ * {@link CommonDataKinds.StructuredPostal#CONTENT_URI}.
+ * This enables a content provider to remove duplicate entries in results.
+ *
+ * @hide
+ */
+ public static final String REMOVE_DUPLICATE_ENTRIES = "remove_duplicate_entries";
+
+ /**
* <p>
* API for obtaining a pre-authorized version of a URI that normally requires special
* permission (beyond READ_CONTACTS) to read. The caller obtaining the pre-authorized URI
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 7249497..ec2f55b 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -3097,10 +3097,7 @@
// Special-case layer scrolling so that we do not trigger normal scroll
// updating.
if (mTouchMode == TOUCH_DRAG_LAYER_MODE) {
- nativeScrollLayer(mScrollingLayer, scrollX, scrollY);
- mScrollingLayerRect.left = scrollX;
- mScrollingLayerRect.top = scrollY;
- invalidate();
+ scrollLayerTo(scrollX, scrollY);
return;
}
mInOverScrollMode = false;
@@ -3603,9 +3600,7 @@
mScrollY = y;
} else {
// Update the layer position instead of WebView.
- nativeScrollLayer(mScrollingLayer, x, y);
- mScrollingLayerRect.left = x;
- mScrollingLayerRect.top = y;
+ scrollLayerTo(x, y);
}
abortAnimation();
nativeSetIsScrolling(false);
@@ -3624,6 +3619,17 @@
}
}
+ private void scrollLayerTo(int x, int y) {
+ if (x == mScrollingLayerRect.left && y == mScrollingLayerRect.top) {
+ return;
+ }
+ nativeScrollLayer(mScrollingLayer, x, y);
+ mScrollingLayerRect.left = x;
+ mScrollingLayerRect.top = y;
+ onScrollChanged(mScrollX, mScrollY, mScrollX, mScrollY);
+ invalidate();
+ }
+
private static int computeDuration(int dx, int dy) {
int distance = Math.max(Math.abs(dx), Math.abs(dy));
int duration = distance * 1000 / STD_SPEED;
@@ -8309,12 +8315,8 @@
if (mScrollingLayer == 0) {
pinScrollBy(mAutoScrollX, mAutoScrollY, true, 0);
} else {
- mScrollingLayerRect.left += mAutoScrollX;
- mScrollingLayerRect.top += mAutoScrollY;
- nativeScrollLayer(mScrollingLayer,
- mScrollingLayerRect.left,
- mScrollingLayerRect.top);
- invalidate();
+ scrollLayerTo(mScrollingLayerRect.left + mAutoScrollX,
+ mScrollingLayerRect.top + mAutoScrollY);
}
sendEmptyMessageDelayed(
SCROLL_SELECT_TEXT, SELECT_SCROLL_INTERVAL);
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index b106cc5..f422f60 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -131,7 +131,6 @@
import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
-import android.view.inputmethod.InputMethodSubtype;
import android.view.textservice.SpellCheckerSubtype;
import android.view.textservice.TextServicesManager;
import android.widget.AdapterView.OnItemClickListener;
@@ -5342,7 +5341,6 @@
switch (keyCode) {
case KeyEvent.KEYCODE_ENTER:
- mEnterKeyIsDown = true;
if (event.hasNoModifiers()) {
// When mInputContentType is set, we know that we are
// running in a "modern" cupcake environment, so don't need
@@ -5374,7 +5372,6 @@
break;
case KeyEvent.KEYCODE_DPAD_CENTER:
- mDPadCenterIsDown = true;
if (event.hasNoModifiers()) {
if (shouldAdvanceFocusOnEnter()) {
return 0;
@@ -5488,7 +5485,6 @@
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_CENTER:
- mDPadCenterIsDown = false;
if (event.hasNoModifiers()) {
/*
* If there is a click listener, just call through to
@@ -5513,7 +5509,6 @@
return super.onKeyUp(keyCode, event);
case KeyEvent.KEYCODE_ENTER:
- mEnterKeyIsDown = false;
if (event.hasNoModifiers()) {
if (mInputContentType != null
&& mInputContentType.onEditorActionListener != null
@@ -8972,17 +8967,9 @@
}
private long getLastTouchOffsets() {
- int minOffset, maxOffset;
-
- if (mContextMenuTriggeredByKey) {
- minOffset = getSelectionStart();
- maxOffset = getSelectionEnd();
- } else {
- SelectionModifierCursorController selectionController = getSelectionController();
- minOffset = selectionController.getMinTouchOffset();
- maxOffset = selectionController.getMaxTouchOffset();
- }
-
+ SelectionModifierCursorController selectionController = getSelectionController();
+ final int minOffset = selectionController.getMinTouchOffset();
+ final int maxOffset = selectionController.getMaxTouchOffset();
return packRangeInLong(minOffset, maxOffset);
}
@@ -9075,12 +9062,6 @@
private static final int ID_COPY = android.R.id.copy;
private static final int ID_PASTE = android.R.id.paste;
- private class MenuHandler implements MenuItem.OnMenuItemClickListener {
- public boolean onMenuItemClick(MenuItem item) {
- return onTextContextMenuItem(item.getItemId());
- }
- }
-
/**
* Called when a context menu option for the text view is selected. Currently
* this will be one of {@link android.R.id#selectAll}, {@link android.R.id#cut},
@@ -11480,12 +11461,6 @@
private boolean mSelectionControllerEnabled;
private boolean mInBatchEditControllers;
- // These are needed to desambiguate a long click. If the long click comes from ones of these, we
- // select from the current cursor position. Otherwise, select from long pressed position.
- private boolean mDPadCenterIsDown = false;
- private boolean mEnterKeyIsDown = false;
- private boolean mContextMenuTriggeredByKey = false;
-
private boolean mSelectAllOnFocus = false;
private int mGravity = Gravity.TOP | Gravity.START;
diff --git a/core/res/res/layout/screen_action_bar.xml b/core/res/res/layout/screen_action_bar.xml
index 2392618..b0f1bc5 100644
--- a/core/res/res/layout/screen_action_bar.xml
+++ b/core/res/res/layout/screen_action_bar.xml
@@ -19,6 +19,8 @@
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
android:orientation="vertical"
android:fitsSystemWindows="true">
<com.android.internal.widget.ActionBarContainer android:id="@+id/action_bar_container"
diff --git a/core/res/res/layout/screen_action_bar_overlay.xml b/core/res/res/layout/screen_action_bar_overlay.xml
index 19b861c..2a8c7c3 100644
--- a/core/res/res/layout/screen_action_bar_overlay.xml
+++ b/core/res/res/layout/screen_action_bar_overlay.xml
@@ -19,38 +19,45 @@
the Action Bar enabled overlaying application content.
-->
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
android:fitsSystemWindows="true">
<FrameLayout android:id="@android:id/content"
android:layout_width="match_parent"
android:layout_height="match_parent" />
- <com.android.internal.widget.ActionBarContainer android:id="@+id/action_bar_container"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- style="?android:attr/actionBarStyle"
- android:gravity="top">
- <com.android.internal.widget.ActionBarView
- android:id="@+id/action_bar"
+ <LinearLayout android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="top">
+ <com.android.internal.widget.ActionBarContainer android:id="@+id/action_bar_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- style="?android:attr/actionBarStyle" />
- <com.android.internal.widget.ActionBarContextView
- android:id="@+id/action_context_bar"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:visibility="gone"
- style="?android:attr/actionModeStyle" />
- </com.android.internal.widget.ActionBarContainer>
- <ImageView android:src="?android:attr/windowContentOverlay"
- android:scaleType="fitXY"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_below="@id/action_bar_container" />
+ android:layout_alignParentTop="true"
+ style="?android:attr/actionBarStyle"
+ android:gravity="top">
+ <com.android.internal.widget.ActionBarView
+ android:id="@+id/action_bar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ style="?android:attr/actionBarStyle" />
+ <com.android.internal.widget.ActionBarContextView
+ android:id="@+id/action_context_bar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:visibility="gone"
+ style="?android:attr/actionModeStyle" />
+ </com.android.internal.widget.ActionBarContainer>
+ <ImageView android:src="?android:attr/windowContentOverlay"
+ android:scaleType="fitXY"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_below="@id/action_bar_container" />
+ </LinearLayout>
<com.android.internal.widget.ActionBarContainer android:id="@+id/split_action_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_alignParentBottom="true"
+ android:layout_gravity="bottom"
style="?android:attr/actionBarSplitStyle"
android:visibility="gone"
android:gravity="center"/>
-</RelativeLayout>
+</FrameLayout>
diff --git a/core/res/res/layout/screen_simple.xml b/core/res/res/layout/screen_simple.xml
index 87c29f6..c1914e7 100644
--- a/core/res/res/layout/screen_simple.xml
+++ b/core/res/res/layout/screen_simple.xml
@@ -22,6 +22,8 @@
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
android:fitsSystemWindows="true"
android:orientation="vertical">
<ViewStub android:id="@+id/action_mode_bar_stub"
diff --git a/core/res/res/layout/screen_simple_overlay_action_mode.xml b/core/res/res/layout/screen_simple_overlay_action_mode.xml
index eb093e7..c790d10 100644
--- a/core/res/res/layout/screen_simple_overlay_action_mode.xml
+++ b/core/res/res/layout/screen_simple_overlay_action_mode.xml
@@ -21,6 +21,8 @@
-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
android:fitsSystemWindows="true">
<FrameLayout
android:id="@android:id/content"
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 4eb47cd..c488116 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -171,7 +171,7 @@
<string name="permgroupdesc_accounts" msgid="4948732641827091312">"Kry toegang tot beskikbare rekeninge."</string>
<string name="permgrouplab_hardwareControls" msgid="7998214968791599326">"Hardewarekontroles"</string>
<string name="permgroupdesc_hardwareControls" msgid="4357057861225462702">"Direkte toegang tot hardeware op die selfoon."</string>
- <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"foonoproepe"</string>
+ <string name="permgrouplab_phoneCalls" msgid="9067173988325865923">"Foonoproepe"</string>
<string name="permgroupdesc_phoneCalls" msgid="7489701620446183770">"Monitor, neem op, en verwerk foonoproepe."</string>
<string name="permgrouplab_systemTools" msgid="4652191644082714048">"Stelselhulpmiddels"</string>
<string name="permgroupdesc_systemTools" msgid="8162102602190734305">"Laervlak-toegang en -beheer van die stelsel."</string>
@@ -991,8 +991,8 @@
<string name="usb_storage_error_message" product="default" msgid="120810397713773275">"Kon nie jou SD-kaart vir USB-massaberging gebruik nie."</string>
<string name="usb_storage_notification_title" msgid="8175892554757216525">"USB gekoppel"</string>
<string name="usb_storage_notification_message" msgid="7380082404288219341">"Kies om lêers na/van jou rekenaar te kopieer."</string>
- <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"Skakel USB-geheue af"</string>
- <string name="usb_storage_stop_notification_message" msgid="2591813490269841539">"Kies om USB-geheue af te skakel."</string>
+ <string name="usb_storage_stop_notification_title" msgid="2336058396663516017">"Skakel USB-berging af"</string>
+ <string name="usb_storage_stop_notification_message" msgid="2591813490269841539">"Kies om USB-berging af te skakel."</string>
<string name="usb_storage_stop_title" msgid="660129851708775853">"USB-berging in gebruik"</string>
<string name="usb_storage_stop_message" product="nosdcard" msgid="1368842269463745067">"Voordat jy USB-berging afskakel, maak seker dat jy jou Android se USB-berging van jou rekenaar ontheg (\"uitgestoot\") het."</string>
<string name="usb_storage_stop_message" product="default" msgid="3613713396426604104">"Voordat jy die USB-berging afskakel, maak seker dat jy jou Android se SD-kaart uit die rekenaar ontheg (uitgeskiet) het."</string>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 97ad227..27d0be3 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -159,7 +159,7 @@
<string name="permgrouplab_costMoney" msgid="5429808217861460401">"Tjenester, der koster dig penge"</string>
<string name="permgroupdesc_costMoney" msgid="8193824940620517189">"Tillader, at en applikation kan gøre ting, som kan koste penge."</string>
<string name="permgrouplab_messages" msgid="7521249148445456662">"Dine beskeder"</string>
- <string name="permgroupdesc_messages" msgid="7045736972019211994">"Læs og skriv dine sms-, e-mail- og andre beskeder."</string>
+ <string name="permgroupdesc_messages" msgid="7045736972019211994">"Læs og skriv dine sms-, e-mail og andre beskeder."</string>
<string name="permgrouplab_personalInfo" msgid="3519163141070533474">"Dine personlige oplysninger"</string>
<string name="permgroupdesc_personalInfo" product="tablet" msgid="6975389054186265786">"Få direkte adgang til dine kontakter og din kalender, der er gemt på tabletcomputeren."</string>
<string name="permgroupdesc_personalInfo" product="default" msgid="5488050357388806068">"Få direkte adgang til dine kontakter og din kalender, der er gemt på telefonen."</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index a5caabf..aa38493 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -1024,7 +1024,7 @@
<string name="ext_media_checking_notification_message" msgid="8287319882926737053">"Verificando errores"</string>
<string name="ext_media_nofs_notification_title" product="nosdcard" msgid="7788040745686229307">"Almacenamiento USB en blanco"</string>
<string name="ext_media_nofs_notification_title" product="default" msgid="780477838241212997">"Tarjeta SD vacía"</string>
- <string name="ext_media_nofs_notification_message" product="nosdcard" msgid="8623130522556087311">"Almacenamiento USB en blanco o sistema de archivos no compatible."</string>
+ <string name="ext_media_nofs_notification_message" product="nosdcard" msgid="8623130522556087311">"Almacenamiento USB vacío o sistema de archivos no compatible"</string>
<string name="ext_media_nofs_notification_message" product="default" msgid="3817704088027829380">"Tarjeta SD en blanco o el sistema de archivos no es compatible."</string>
<string name="ext_media_unmountable_notification_title" product="nosdcard" msgid="2090046769532713563">"Almacenamiento USB dañado"</string>
<string name="ext_media_unmountable_notification_title" product="default" msgid="6410723906019100189">"Tarjeta SD dañada"</string>
@@ -1032,7 +1032,7 @@
<string name="ext_media_unmountable_notification_message" product="default" msgid="6902531775948238989">"Tarjeta SD dañada. Es posible que debas reformatearla."</string>
<string name="ext_media_badremoval_notification_title" product="nosdcard" msgid="1661683031330951073">"Almacenamiento USB extraído inesperadamente"</string>
<string name="ext_media_badremoval_notification_title" product="default" msgid="6872152882604407837">"Almacenamiento USB extraído de forma imprevista"</string>
- <string name="ext_media_badremoval_notification_message" product="nosdcard" msgid="4329848819865594241">"Desmontar el almacenamiento USB antes de extraerlo para evitar la pérdida de datos."</string>
+ <string name="ext_media_badremoval_notification_message" product="nosdcard" msgid="4329848819865594241">"Desactivar el almacenamiento USB antes de extraerlo para evitar la pérdida de datos."</string>
<string name="ext_media_badremoval_notification_message" product="default" msgid="7260183293747448241">"Desmontar la tarjeta SD antes de extraerla para evitar la pérdida de datos."</string>
<string name="ext_media_safe_unmount_notification_title" product="nosdcard" msgid="3967973893270360230">"Es seguro extraer el almacenamiento USB"</string>
<string name="ext_media_safe_unmount_notification_title" product="default" msgid="6729801130790616200">"Es seguro extraer la tarjeta SD"</string>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index 250415c..fd248e5 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -137,7 +137,7 @@
<string name="turn_off_radio" msgid="8198784949987062346">"כבה אלחוטי"</string>
<string name="screen_lock" msgid="799094655496098153">"נעילת מסך"</string>
<string name="power_off" msgid="4266614107412865048">"כיבוי"</string>
- <string name="shutdown_progress" msgid="2281079257329981203">"מבצע כיבוי..."</string>
+ <string name="shutdown_progress" msgid="2281079257329981203">"מכבה..."</string>
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"הטבלט שלך יכבה."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"הטלפון שלך יכובה."</string>
<string name="shutdown_confirm_question" msgid="6656441286856415014">"האם ברצונך לבצע כיבוי?"</string>
@@ -740,7 +740,7 @@
<string name="permlab_writeHistoryBookmarks" msgid="9009434109836280374">"כתוב את ההיסטוריה והסימניות של הדפדפן"</string>
<string name="permdesc_writeHistoryBookmarks" product="tablet" msgid="7193514090469945307">"מאפשר ליישום לשנות את ההיסטוריה או את הסימניות של הדפדפן המאוחסנות בטבלט. יישומים זדוניים עלולים להשתמש ביכולת זו כדי למחוק או לשנות את הנתונים בדפדפן."</string>
<string name="permdesc_writeHistoryBookmarks" product="default" msgid="945571990357114950">"מאפשר ליישום לשנות את ההיסטוריה או הסימניות של הדפדפן המאוחסנות בטלפון. יישומים זדוניים עלולים להשתמש ביכולת זו כדי למחוק או לשנות את נתוני הדפדפן."</string>
- <string name="permlab_setAlarm" msgid="5924401328803615165">"הגדר התראה בשעון המעורר"</string>
+ <string name="permlab_setAlarm" msgid="5924401328803615165">"הגדר צלצול בשעון המעורר"</string>
<string name="permdesc_setAlarm" msgid="5966966598149875082">"מאפשר ליישום להגדיר התראה ביישום מותקן של שעון מעורר. ייתכן שיישומי שעון מעורר מסוימים לא יישמו תכונה זו."</string>
<string name="permlab_addVoicemail" msgid="5525660026090959044">"הוסף דואר קולי"</string>
<string name="permdesc_addVoicemail" msgid="4828507394878206682">"מאפשר ליישום להוסיף הודעות לתיבת הדואר הנכנס של הדואר הקולי."</string>
@@ -895,8 +895,8 @@
<string name="chooseUsbActivity" msgid="7892597146032121735">"בחר יישום עבור מכשיר ה-USB"</string>
<string name="noApplications" msgid="1691104391758345586">"אין יישומים שיכולים לבצע פעולה זו."</string>
<string name="aerr_title" msgid="1905800560317137752"></string>
- <string name="aerr_application" msgid="932628488013092776">"למרבה הצער, <xliff:g id="APPLICATION">%1$s</xliff:g> הפסיק לפעול."</string>
- <string name="aerr_process" msgid="4507058997035697579">"למרבה הצער, התהליך <xliff:g id="PROCESS">%1$s</xliff:g> הופסק."</string>
+ <string name="aerr_application" msgid="932628488013092776">"לצערנו ה<xliff:g id="APPLICATION">%1$s</xliff:g> הפסיק לפעול."</string>
+ <string name="aerr_process" msgid="4507058997035697579">"לצערנו, התהליך <xliff:g id="PROCESS">%1$s</xliff:g> הופסק."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="8339738283149696827">"<xliff:g id="APPLICATION">%2$s</xliff:g> אינו מגיב."\n\n" האם ברצונך לסגור אותו?"</string>
<string name="anr_activity_process" msgid="7018289416670457797">"פעילות <xliff:g id="ACTIVITY">%1$s</xliff:g> אינה מגיבה."\n\n"האם ברצונך לסגור אותה?"</string>
@@ -940,8 +940,8 @@
<string name="volume_icon_description_incall" msgid="8890073218154543397">"עוצמת קול של שיחות"</string>
<string name="volume_icon_description_media" msgid="4217311719665194215">"עוצמת קול של מדיה"</string>
<string name="volume_icon_description_notification" msgid="7044986546477282274">"עוצמת קול של התראות"</string>
- <string name="ringtone_default" msgid="3789758980357696936">"רינגטון המוגדר כברירת מחדל"</string>
- <string name="ringtone_default_with_actual" msgid="8129563480895990372">"רינגטון המוגדר כברירת מחדל (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
+ <string name="ringtone_default" msgid="3789758980357696936">"רינגטון ברירת מחדל"</string>
+ <string name="ringtone_default_with_actual" msgid="8129563480895990372">"רינגטון ברירת מחדל (<xliff:g id="ACTUAL_RINGTONE">%1$s</xliff:g>)"</string>
<string name="ringtone_silent" msgid="4440324407807468713">"שקט"</string>
<string name="ringtone_picker_title" msgid="3515143939175119094">"רינגטונים"</string>
<string name="ringtone_unknown" msgid="5477919988701784788">"רינגטון לא ידוע"</string>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 6aac520..ee098d5 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -223,7 +223,7 @@
<string name="permlab_forceStopPackages" msgid="1447830113260156236">"다른 애플리케이션 강제 종료"</string>
<string name="permdesc_forceStopPackages" msgid="7263036616161367402">"애플리케이션이 다른 애플리케이션을 강제로 종료할 수 있도록 합니다."</string>
<string name="permlab_forceBack" msgid="1804196839880393631">"강제로 애플리케이션 닫기"</string>
- <string name="permdesc_forceBack" msgid="6534109744159919013">"애플리케이션이 포그라운드에 있는 활동을 강제로 닫고 되돌아갈 수 있도록 합니다. 일반 애플리케이션에는 절대로 필요하지 않습니다."</string>
+ <string name="permdesc_forceBack" msgid="6534109744159919013">"애플리케이션이 포그라운드에 있는 작업을 강제로 닫고 되돌아갈 수 있도록 합니다. 일반 애플리케이션에는 절대로 필요하지 않습니다."</string>
<string name="permlab_dump" msgid="1681799862438954752">"시스템 내부 상태 검색"</string>
<string name="permdesc_dump" msgid="2198776174276275220">"애플리케이션이 시스템의 내부 상태를 검색할 수 있도록 합니다. 단, 악성 애플리케이션이 이 기능을 이용하여 일반적으로 필요하지 않은 다양한 개인정보와 보안정보를 검색할 수 있습니다."</string>
<string name="permlab_retrieve_window_content" msgid="8022588608994589938">"화면 콘텐츠 검색"</string>
@@ -446,7 +446,7 @@
<string name="permdesc_useCredentials" msgid="7416570544619546974">"애플리케이션이 인증 토큰을 요청하도록 합니다."</string>
<string name="permlab_accessNetworkState" msgid="6865575199464405769">"네트워크 상태 보기"</string>
<string name="permdesc_accessNetworkState" msgid="558721128707712766">"애플리케이션이 모든 네트워크의 상태를 볼 수 있도록 합니다."</string>
- <string name="permlab_createNetworkSockets" msgid="9121633680349549585">"인터넷에 최대한 액세스"</string>
+ <string name="permlab_createNetworkSockets" msgid="9121633680349549585">"인터넷 액세스"</string>
<string name="permdesc_createNetworkSockets" msgid="4593339106921772192">"애플리케이션이 네트워크 소켓을 만들 수 있도록 합니다."</string>
<string name="permlab_writeApnSettings" msgid="505660159675751896">"네트워크 설정 및 트래픽 차단/변경"</string>
<string name="permdesc_writeApnSettings" msgid="2369786339323021771">"애플리케이션이 모든 네트워크 트래픽을 가로채고 검사하거나 네트워크 설정을 변경하도록 허용합니다. 예를 들어 프록시나 APN의 포트를 변경할 수 있습니다. 악성 애플리케이션이 사용자 모르게 네트워크 패킷을 모니터링하고 리디렉션하며 수정할 수도 있습니다."</string>
@@ -899,7 +899,7 @@
<string name="aerr_process" msgid="4507058997035697579">"<xliff:g id="PROCESS">%1$s</xliff:g> 프로세스가 중지되었습니다."</string>
<string name="anr_title" msgid="4351948481459135709"></string>
<string name="anr_activity_application" msgid="8339738283149696827">"<xliff:g id="APPLICATION">%2$s</xliff:g>이(가) 응답하지 않습니다."\n\n"닫으시겠습니까?"</string>
- <string name="anr_activity_process" msgid="7018289416670457797">"<xliff:g id="ACTIVITY">%1$s</xliff:g> 활동이 응답하지 않습니다."\n\n"닫으시겠습니까?"</string>
+ <string name="anr_activity_process" msgid="7018289416670457797">"<xliff:g id="ACTIVITY">%1$s</xliff:g>이(가) 응답하지 않습니다."\n\n"닫으시겠습니까?"</string>
<string name="anr_application_process" msgid="7208175830253210526">"<xliff:g id="APPLICATION">%1$s</xliff:g>이(가) 응답하지 않습니다. 닫으시겠습니까?"</string>
<string name="anr_process" msgid="306819947562555821">"<xliff:g id="PROCESS">%1$s</xliff:g> 프로세스가 응답하지 않습니다."\n\n"닫으시겠습니까?"</string>
<string name="force_close" msgid="8346072094521265605">"확인"</string>
@@ -1208,7 +1208,7 @@
<string name="sha256_fingerprint" msgid="4391271286477279263">"SHA-256 지문:"</string>
<string name="sha1_fingerprint" msgid="7930330235269404581">"SHA-1 지문:"</string>
<string name="activity_chooser_view_see_all" msgid="180268188117163072">"전체 보기..."</string>
- <string name="activity_chooser_view_dialog_title_default" msgid="3325054276356556835">"활동 선택"</string>
+ <string name="activity_chooser_view_dialog_title_default" msgid="3325054276356556835">"작업 선택"</string>
<string name="share_action_provider_share_with" msgid="1791316789651185229">"공유 대상..."</string>
<string name="status_bar_device_locked" msgid="3092703448690669768">"기기가 잠겼습니다."</string>
<string name="list_delimeter" msgid="3975117572185494152">", "</string>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index d66c2d4..44f4d10 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -348,7 +348,7 @@
<string name="permlab_accessFineLocation" msgid="8116127007541369477">"точное местоположение (GPS)"</string>
<string name="permdesc_accessFineLocation" product="tablet" msgid="243973693233359681">"Получать доступ к источникам точного местоположения, таким как GPS, когда это возможно. Вредоносные приложения могут использовать это разрешение для определения вашего местоположения и расходовать ресурс батареи."</string>
<string name="permdesc_accessFineLocation" product="default" msgid="7411213317434337331">"Получать доступ к источникам точного местоположения, таким как GPS, если возможно. Вредоносные приложения могут использовать это разрешение для определения вашего местоположения и расходовать ресурс батареи."</string>
- <string name="permlab_accessCoarseLocation" msgid="4642255009181975828">"отслеживать местоположение по сигналам сети"</string>
+ <string name="permlab_accessCoarseLocation" msgid="4642255009181975828">"примерное местоположение по координатам сети"</string>
<string name="permdesc_accessCoarseLocation" product="tablet" msgid="3704633168985466045">"Получать доступ к источникам данных о местоположении, таким как база данных сотовой сети, для определения приблизительного местоположения планшетного ПК, когда это возможно. Вредоносные приложения могут использовать это разрешение для определения вашего приблизительного местоположения."</string>
<string name="permdesc_accessCoarseLocation" product="default" msgid="8235655958070862293">"Получать доступ к источникам данных о местоположении, таким как база данных сотовой сети, для определения приблизительного местоположения телефона, если возможно. Вредоносные приложения могут использовать эту возможность для определения вашего приблизительного местоположения."</string>
<string name="permlab_accessSurfaceFlinger" msgid="2363969641792388947">"получать доступ к SurfaceFlinger"</string>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index e88de76..05da503 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -136,7 +136,7 @@
<string name="turn_on_radio" msgid="3912793092339962371">"Vula okungenantambo"</string>
<string name="turn_off_radio" msgid="8198784949987062346">"Vala okungenantambo"</string>
<string name="screen_lock" msgid="799094655496098153">"Ukuvala isikrini"</string>
- <string name="power_off" msgid="4266614107412865048">"Amandla avaliwe"</string>
+ <string name="power_off" msgid="4266614107412865048">"Vala amandla"</string>
<string name="shutdown_progress" msgid="2281079257329981203">"Ivala shaqa..."</string>
<string name="shutdown_confirm" product="tablet" msgid="3385745179555731470">"Ithebhulethi yakho izocima."</string>
<string name="shutdown_confirm" product="default" msgid="649792175242821353">"Ifoni yakho izocima."</string>
@@ -146,7 +146,7 @@
<string name="global_actions" product="tablet" msgid="408477140088053665">"Okukhethwa konke kwethebhulethi"</string>
<string name="global_actions" product="default" msgid="2406416831541615258">"Okukhethwa kukho kwefoni"</string>
<string name="global_action_lock" msgid="2844945191792119712">"Ukuvala isikrini"</string>
- <string name="global_action_power_off" msgid="4471879440839879722">"Amandla avaliwe"</string>
+ <string name="global_action_power_off" msgid="4471879440839879722">"Vala amandla"</string>
<string name="global_action_toggle_silent_mode" msgid="8219525344246810925">"Imodi ethulile"</string>
<string name="global_action_silent_mode_on_status" msgid="3289841937003758806">"Umsindo UVALIWE"</string>
<string name="global_action_silent_mode_off_status" msgid="1506046579177066419">"Umsindo UVULIWE"</string>
@@ -838,7 +838,7 @@
<item quantity="one" msgid="2178576254385739855">"Kusasa"</item>
<item quantity="other" msgid="2973062968038355991">"ezinsukwini ezing-<xliff:g id="COUNT">%d</xliff:g>"</item>
</plurals>
- <string name="preposition_for_date" msgid="9093949757757445117">"Ngomhla ka <xliff:g id="DATE">%s</xliff:g>"</string>
+ <string name="preposition_for_date" msgid="9093949757757445117">"ngo-<xliff:g id="DATE">%s</xliff:g>"</string>
<string name="preposition_for_time" msgid="5506831244263083793">"e-<xliff:g id="TIME">%s</xliff:g>"</string>
<string name="preposition_for_year" msgid="5040395640711867177">"phakathi- <xliff:g id="YEAR">%s</xliff:g>"</string>
<string name="day" msgid="8144195776058119424">"usuku"</string>
@@ -886,7 +886,7 @@
<string name="no" msgid="5141531044935541497">"Khansela"</string>
<string name="dialog_alert_title" msgid="2049658708609043103">"Ukunaka"</string>
<string name="loading" msgid="1760724998928255250">"Iyalayisha..."</string>
- <string name="capital_on" msgid="1544682755514494298">"Ngomhla ka"</string>
+ <string name="capital_on" msgid="1544682755514494298">"VULIWE"</string>
<string name="capital_off" msgid="6815870386972805832">"VALIWE"</string>
<string name="whichApplication" msgid="4533185947064773386">"Qedela isenzo usebenzisa"</string>
<string name="alwaysUse" msgid="4583018368000610438">"Sebenzisa ngokuzenzakalelayo kulesenzo."</string>
@@ -1146,7 +1146,7 @@
<string name="checkbox_not_checked" msgid="5174639551134444056">"akuhloliwe"</string>
<string name="radiobutton_selected" msgid="8603599808486581511">"Okukhethiwe"</string>
<string name="radiobutton_not_selected" msgid="2908760184307722393">"akukhethiwe"</string>
- <string name="switch_on" msgid="551417728476977311">"Ngomhla ka-"</string>
+ <string name="switch_on" msgid="551417728476977311">"vuliwe"</string>
<string name="switch_off" msgid="7249798614327155088">"valiwe"</string>
<string name="togglebutton_pressed" msgid="4180411746647422233">"kucindezelwe."</string>
<string name="togglebutton_not_pressed" msgid="4495147725636134425">"akucindezelwe."</string>
diff --git a/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java b/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java
index 01a5fd0..a781472 100644
--- a/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java
+++ b/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java
@@ -350,4 +350,4 @@
}
return true;
}
-}
\ No newline at end of file
+}
diff --git a/core/tests/coretests/src/android/net/NetworkStatsHistoryTest.java b/core/tests/coretests/src/android/net/NetworkStatsHistoryTest.java
index e1db073..1df763a 100644
--- a/core/tests/coretests/src/android/net/NetworkStatsHistoryTest.java
+++ b/core/tests/coretests/src/android/net/NetworkStatsHistoryTest.java
@@ -256,6 +256,10 @@
stats.recordData(TEST_START, TEST_START + DAY_IN_MILLIS, 24L, 24L);
assertEquals(24, stats.size());
+ // try removing invalid data; should be no change
+ stats.removeBucketsBefore(0 - DAY_IN_MILLIS);
+ assertEquals(24, stats.size());
+
// try removing far before buckets; should be no change
stats.removeBucketsBefore(TEST_START - YEAR_IN_MILLIS);
assertEquals(24, stats.size());
diff --git a/include/media/MediaProfiles.h b/include/media/MediaProfiles.h
index eab7648..250f267 100644
--- a/include/media/MediaProfiles.h
+++ b/include/media/MediaProfiles.h
@@ -48,15 +48,21 @@
};
/**
- *Set CIF as default maximum import and export resolution of video editor.
- *The maximum import and export resolutions are platform specific,
- *which should be defined in media_profiles.xml.
+ * Set CIF as default maximum import and export resolution of video editor.
+ * The maximum import and export resolutions are platform specific,
+ * which should be defined in media_profiles.xml.
+ * Set default maximum prefetch YUV frames to 6, which means video editor can
+ * queue up to 6 YUV frames in the video encoder source.
+ * This value is used to limit the amount of memory used by video editor
+ * engine when the encoder consumes YUV frames at a lower speed
+ * than video editor engine produces.
*/
enum videoeditor_capability {
VIDEOEDITOR_DEFAULT_MAX_INPUT_FRAME_WIDTH = 352,
VIDEOEDITOR_DEFUALT_MAX_INPUT_FRAME_HEIGHT = 288,
VIDEOEDITOR_DEFAULT_MAX_OUTPUT_FRAME_WIDTH = 352,
VIDEOEDITOR_DEFUALT_MAX_OUTPUT_FRAME_HEIGHT = 288,
+ VIDEOEDITOR_DEFAULT_MAX_PREFETCH_YUV_FRAMES = 6
};
enum video_decoder {
@@ -138,6 +144,8 @@
* videoeditor.input.height.max - max input video frame height
* videoeditor.output.width.max - max output video frame width
* videoeditor.output.height.max - max output video frame height
+ * maxPrefetchYUVFrames - max prefetch YUV frames in video editor engine. This value is used
+ * to limit the memory consumption.
*/
int getVideoEditorCapParamByName(const char *name) const;
@@ -357,11 +365,12 @@
};
struct VideoEditorCap {
VideoEditorCap(int inFrameWidth, int inFrameHeight,
- int outFrameWidth, int outFrameHeight)
+ int outFrameWidth, int outFrameHeight, int frames)
: mMaxInputFrameWidth(inFrameWidth),
mMaxInputFrameHeight(inFrameHeight),
mMaxOutputFrameWidth(outFrameWidth),
- mMaxOutputFrameHeight(outFrameHeight) {}
+ mMaxOutputFrameHeight(outFrameHeight),
+ mMaxPrefetchYUVFrames(frames) {}
~VideoEditorCap() {}
@@ -369,6 +378,7 @@
int mMaxInputFrameHeight;
int mMaxOutputFrameWidth;
int mMaxOutputFrameHeight;
+ int mMaxPrefetchYUVFrames;
};
int getCamcorderProfileIndex(int cameraId, camcorder_quality quality) const;
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index a8daab0..a2b80c2 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -3062,6 +3062,7 @@
if ((mRcClientDeathHandler != null) && (mRcClientDeathHandler.mCb != null)) {
try {
mRcClientDeathHandler.mCb.unlinkToDeath(mRcClientDeathHandler, 0);
+ mRcClientDeathHandler = null;
} catch (java.util.NoSuchElementException e) {
// not much we can do here
Log.e(TAG, "Encountered " + e + " in unlinkToRcClientDeath()");
@@ -3069,6 +3070,12 @@
}
}
}
+
+ @Override
+ protected void finalize() throws Throwable {
+ unlinkToRcClientDeath();// unlink exception handled inside method
+ super.finalize();
+ }
}
/**
@@ -3115,6 +3122,7 @@
if (packageName.equalsIgnoreCase(rcse.mReceiverComponent.getPackageName())) {
// a stack entry is from the package being removed, remove it from the stack
stackIterator.remove();
+ rcse.unlinkToRcClientDeath();
}
}
if (mRCStack.empty()) {
@@ -3195,6 +3203,7 @@
RemoteControlStackEntry rcse = (RemoteControlStackEntry)stackIterator.next();
if(rcse.mMediaIntent.equals(pi)) {
stackIterator.remove();
+ rcse.unlinkToRcClientDeath();
break;
}
}
@@ -3456,7 +3465,7 @@
rcse.mCallingPackageName = callingPackageName;
rcse.mCallingUid = Binder.getCallingUid();
if (rcClient == null) {
- rcse.mRcClientDeathHandler = null;
+ // here rcse.mRcClientDeathHandler is null;
break;
}
@@ -3512,7 +3521,6 @@
rcse.unlinkToRcClientDeath();
// reset the client-related fields
rcse.mRcClient = null;
- rcse.mRcClientDeathHandler = null;
rcse.mCallingPackageName = null;
}
}
diff --git a/media/libmedia/MediaProfiles.cpp b/media/libmedia/MediaProfiles.cpp
index ad55ff8..6096b72 100644
--- a/media/libmedia/MediaProfiles.cpp
+++ b/media/libmedia/MediaProfiles.cpp
@@ -404,11 +404,12 @@
CHECK(!strcmp("maxInputFrameWidth", atts[0]) &&
!strcmp("maxInputFrameHeight", atts[2]) &&
!strcmp("maxOutputFrameWidth", atts[4]) &&
- !strcmp("maxOutputFrameHeight", atts[6]));
+ !strcmp("maxOutputFrameHeight", atts[6]) &&
+ !strcmp("maxPrefetchYUVFrames", atts[8]));
MediaProfiles::VideoEditorCap *pVideoEditorCap =
new MediaProfiles::VideoEditorCap(atoi(atts[1]), atoi(atts[3]),
- atoi(atts[5]), atoi(atts[7]));
+ atoi(atts[5]), atoi(atts[7]), atoi(atts[9]));
logVideoEditorCap(*pVideoEditorCap);
profiles->mVideoEditorCap = pVideoEditorCap;
@@ -850,7 +851,8 @@
VIDEOEDITOR_DEFAULT_MAX_INPUT_FRAME_WIDTH,
VIDEOEDITOR_DEFUALT_MAX_INPUT_FRAME_HEIGHT,
VIDEOEDITOR_DEFAULT_MAX_OUTPUT_FRAME_WIDTH,
- VIDEOEDITOR_DEFUALT_MAX_OUTPUT_FRAME_HEIGHT);
+ VIDEOEDITOR_DEFUALT_MAX_OUTPUT_FRAME_HEIGHT,
+ VIDEOEDITOR_DEFAULT_MAX_PREFETCH_YUV_FRAMES);
}
/*static*/ void
MediaProfiles::createDefaultExportVideoProfiles(MediaProfiles *profiles)
@@ -1019,6 +1021,8 @@
return mVideoEditorCap->mMaxOutputFrameWidth;
if (!strcmp("videoeditor.output.height.max", name))
return mVideoEditorCap->mMaxOutputFrameHeight;
+ if (!strcmp("maxPrefetchYUVFrames", name))
+ return mVideoEditorCap->mMaxPrefetchYUVFrames;
LOGE("The given video editor param name %s is not found", name);
return -1;
diff --git a/nfc-extras/java/com/android/nfc_extras/NfcAdapterExtras.java b/nfc-extras/java/com/android/nfc_extras/NfcAdapterExtras.java
index 62213de..9c87c22 100644
--- a/nfc-extras/java/com/android/nfc_extras/NfcAdapterExtras.java
+++ b/nfc-extras/java/com/android/nfc_extras/NfcAdapterExtras.java
@@ -16,6 +16,8 @@
package com.android.nfc_extras;
+import java.util.HashMap;
+
import android.content.Context;
import android.nfc.INfcAdapterExtras;
import android.nfc.NfcAdapter;
@@ -57,20 +59,22 @@
// protected by NfcAdapterExtras.class, and final after first construction,
// except for attemptDeadServiceRecovery() when NFC crashes - we accept a
// best effort recovery
- private static NfcAdapter sAdapter;
private static INfcAdapterExtras sService;
private static final CardEmulationRoute ROUTE_OFF =
new CardEmulationRoute(CardEmulationRoute.ROUTE_OFF, null);
+ // contents protected by NfcAdapterExtras.class
+ private static final HashMap<NfcAdapter, NfcAdapterExtras> sNfcExtras = new HashMap();
+
private final NfcExecutionEnvironment mEmbeddedEe;
private final CardEmulationRoute mRouteOnWhenScreenOn;
- final Context mContext;
+ private final NfcAdapter mAdapter;
final String mPackageName;
/** get service handles */
- private static void initService() {
- final INfcAdapterExtras service = sAdapter.getNfcAdapterExtrasInterface();
+ private static void initService(NfcAdapter adapter) {
+ final INfcAdapterExtras service = adapter.getNfcAdapterExtrasInterface();
if (service != null) {
// Leave stale rather than receive a null value.
sService = service;
@@ -95,23 +99,20 @@
synchronized (NfcAdapterExtras.class) {
if (sService == null) {
- try {
- sAdapter = adapter;
- initService();
- } finally {
- if (sService == null) {
- sAdapter = null;
- }
- }
+ initService(adapter);
}
+ NfcAdapterExtras extras = sNfcExtras.get(adapter);
+ if (extras == null) {
+ extras = new NfcAdapterExtras(adapter);
+ sNfcExtras.put(adapter, extras);
+ }
+ return extras;
}
-
- return new NfcAdapterExtras(context);
}
- private NfcAdapterExtras(Context context) {
- mContext = context.getApplicationContext();
- mPackageName = context.getPackageName();
+ private NfcAdapterExtras(NfcAdapter adapter) {
+ mAdapter = adapter;
+ mPackageName = adapter.getContext().getPackageName();
mEmbeddedEe = new NfcExecutionEnvironment(this);
mRouteOnWhenScreenOn = new CardEmulationRoute(CardEmulationRoute.ROUTE_ON_WHEN_SCREEN_ON,
mEmbeddedEe);
@@ -160,8 +161,8 @@
*/
void attemptDeadServiceRecovery(Exception e) {
Log.e(TAG, "NFC Adapter Extras dead - attempting to recover");
- sAdapter.attemptDeadServiceRecovery(e);
- initService();
+ mAdapter.attemptDeadServiceRecovery(e);
+ initService(mAdapter);
}
INfcAdapterExtras getService() {
diff --git a/nfc-extras/tests/Android.mk b/nfc-extras/tests/Android.mk
new file mode 100644
index 0000000..3eca76d
--- /dev/null
+++ b/nfc-extras/tests/Android.mk
@@ -0,0 +1,32 @@
+# Copyright 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.
+
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+# We only want this apk build for tests.
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_JAVA_LIBRARIES := \
+ android.test.runner \
+ com.android.nfc_extras
+
+# Include all test java files.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := NfcExtrasTests
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_PACKAGE)
diff --git a/nfc-extras/tests/AndroidManifest.xml b/nfc-extras/tests/AndroidManifest.xml
new file mode 100644
index 0000000..0cc6653
--- /dev/null
+++ b/nfc-extras/tests/AndroidManifest.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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 name must be unique so suffix with "tests" so package loader doesn't ignore us -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.nfc_extras.tests">
+
+ <!-- We add an application tag here just so that we can indicate that
+ this package needs to link against the android.test library,
+ which is needed when building test cases. -->
+ <application>
+ <uses-library android:name="android.test.runner" />
+ <uses-library android:name="com.android.nfc_extras" />
+ </application>
+
+ <uses-permission android:name="android.permission.NFC"/>
+
+ <!--
+ Run all tests with
+ adb shell am instrument -w com.android.nfc_extras.tests/android.test.InstrumentationTestRunner
+ -->
+ <instrumentation android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.android.nfc_extras.tests"
+ android:label="Tests for NFC Extras library"/>
+
+</manifest>
diff --git a/nfc-extras/tests/src/com/android/nfc_extras/BasicNfcEeTest.java b/nfc-extras/tests/src/com/android/nfc_extras/BasicNfcEeTest.java
new file mode 100644
index 0000000..e1025aa
--- /dev/null
+++ b/nfc-extras/tests/src/com/android/nfc_extras/BasicNfcEeTest.java
@@ -0,0 +1,117 @@
+/*
+ * 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.nfc_extras;
+
+import android.content.Context;
+import android.nfc.NfcAdapter;
+import android.test.InstrumentationTestCase;
+import android.util.Log;
+
+import com.android.nfc_extras.NfcAdapterExtras;
+import com.android.nfc_extras.NfcAdapterExtras.CardEmulationRoute;
+import com.android.nfc_extras.NfcExecutionEnvironment;
+
+import java.io.IOException;
+import java.util.Arrays;
+
+public class BasicNfcEeTest extends InstrumentationTestCase {
+ private Context mContext;
+ private NfcAdapterExtras mAdapterExtras;
+ private NfcExecutionEnvironment mEe;
+
+ public static final byte[] SELECT_CARD_MANAGER_COMMAND = new byte[] {
+ (byte)0x00, (byte)0xA4, (byte)0x04, (byte)0x00, // command
+ (byte)0x08, // data length
+ (byte)0xA0, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x03, (byte)0x00, (byte)0x00,
+ (byte)0x00, // card manager AID
+ (byte)0x00 // trailer
+ };
+
+ public static final byte[] SELECT_CARD_MANAGER_RESPONSE = new byte[] {
+ (byte)0x90, (byte)0x00,
+ };
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+ mContext = getInstrumentation().getContext();
+ mAdapterExtras = NfcAdapterExtras.get(NfcAdapter.getDefaultAdapter(mContext));
+ mEe = mAdapterExtras.getEmbeddedExecutionEnvironment();
+ }
+
+ public void testSendCardManagerApdu() throws IOException {
+ mEe.open();
+
+ try {
+ byte[] out = mEe.transceive(SELECT_CARD_MANAGER_COMMAND);
+ assertTrue(out.length >= SELECT_CARD_MANAGER_RESPONSE.length);
+ byte[] trailing = Arrays.copyOfRange(out,
+ out.length - SELECT_CARD_MANAGER_RESPONSE.length,
+ out.length);
+ assertByteArrayEquals(SELECT_CARD_MANAGER_RESPONSE, trailing);
+
+ } finally {
+ mEe.close();
+ }
+
+ }
+
+ public void testSendCardManagerApduMultiple() throws IOException {
+ for (int i=0; i<10; i++) {
+ try {
+ mEe.open();
+
+ try {
+ byte[] out = mEe.transceive(SELECT_CARD_MANAGER_COMMAND);
+ byte[] trailing = Arrays.copyOfRange(out,
+ out.length - SELECT_CARD_MANAGER_RESPONSE.length,
+ out.length);
+
+ } finally {
+ try {Thread.sleep(1000);} catch (InterruptedException e) {}
+ mEe.close();
+ }
+ } catch (IOException e) {}
+ }
+
+ testSendCardManagerApdu();
+
+ }
+
+ public void testEnableEe() {
+ mAdapterExtras.setCardEmulationRoute(
+ new CardEmulationRoute(CardEmulationRoute.ROUTE_ON_WHEN_SCREEN_ON, mEe));
+ CardEmulationRoute newRoute = mAdapterExtras.getCardEmulationRoute();
+ assertEquals(CardEmulationRoute.ROUTE_ON_WHEN_SCREEN_ON, newRoute.route);
+ assertEquals(mEe, newRoute.nfcEe);
+ }
+
+ public void testDisableEe() {
+ mAdapterExtras.setCardEmulationRoute(
+ new CardEmulationRoute(CardEmulationRoute.ROUTE_OFF, null));
+ CardEmulationRoute newRoute = mAdapterExtras.getCardEmulationRoute();
+ assertEquals(CardEmulationRoute.ROUTE_OFF, newRoute.route);
+ assertNull(newRoute.nfcEe);
+ }
+
+ private static void assertByteArrayEquals(byte[] b1, byte[] b2) {
+ assertEquals(b1.length, b2.length);
+ for (int i = 0; i < b1.length; i++) {
+ assertEquals(b1[i], b2[i]);
+ }
+ }
+}
diff --git a/opengl/libs/EGL/egl.cpp b/opengl/libs/EGL/egl.cpp
index 1e43195..6ad06af 100644
--- a/opengl/libs/EGL/egl.cpp
+++ b/opengl/libs/EGL/egl.cpp
@@ -212,16 +212,20 @@
EGLImageKHR egl_get_image_for_current_context(EGLImageKHR image)
{
- ImageRef _i(image);
- if (!_i.get())
- return EGL_NO_IMAGE_KHR;
-
EGLContext context = egl_tls_t::getContext();
if (context == EGL_NO_CONTEXT || image == EGL_NO_IMAGE_KHR)
return EGL_NO_IMAGE_KHR;
egl_context_t const * const c = get_context(context);
- if (c == NULL) // this should never happen
+ if (c == NULL) // this should never happen, by construction
+ return EGL_NO_IMAGE_KHR;
+
+ egl_display_t* display = egl_display_t::get(c->dpy);
+ if (display == NULL) // this should never happen, by construction
+ return EGL_NO_IMAGE_KHR;
+
+ ImageRef _i(display, image);
+ if (!_i.get())
return EGL_NO_IMAGE_KHR;
// here we don't validate the context because if it's been marked for
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index 63f02e4..095f10c 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -451,7 +451,7 @@
egl_display_t const * const dp = validate_display(dpy);
if (!dp) return EGL_FALSE;
- SurfaceRef _s(surface);
+ SurfaceRef _s(dp, surface);
if (!_s.get())
return setError(EGL_BAD_SURFACE, EGL_FALSE);
@@ -472,7 +472,7 @@
egl_display_t const * const dp = validate_display(dpy);
if (!dp) return EGL_FALSE;
- SurfaceRef _s(surface);
+ SurfaceRef _s(dp, surface);
if (!_s.get())
return setError(EGL_BAD_SURFACE, EGL_FALSE);
@@ -541,7 +541,7 @@
if (!dp)
return EGL_FALSE;
- ContextRef _c(ctx);
+ ContextRef _c(dp, ctx);
if (!_c.get())
return setError(EGL_BAD_CONTEXT, EGL_FALSE);
@@ -592,9 +592,9 @@
}
// get a reference to the object passed in
- ContextRef _c(ctx);
- SurfaceRef _d(draw);
- SurfaceRef _r(read);
+ ContextRef _c(dp, ctx);
+ SurfaceRef _d(dp, draw);
+ SurfaceRef _r(dp, read);
// validate the context (if not EGL_NO_CONTEXT)
if ((ctx != EGL_NO_CONTEXT) && !_c.get()) {
@@ -696,7 +696,7 @@
egl_display_t const * const dp = validate_display(dpy);
if (!dp) return EGL_FALSE;
- ContextRef _c(ctx);
+ ContextRef _c(dp, ctx);
if (!_c.get()) return setError(EGL_BAD_CONTEXT, EGL_FALSE);
egl_context_t * const c = get_context(ctx);
@@ -944,7 +944,7 @@
egl_display_t const * const dp = validate_display(dpy);
if (!dp) return EGL_FALSE;
- SurfaceRef _s(draw);
+ SurfaceRef _s(dp, draw);
if (!_s.get())
return setError(EGL_BAD_SURFACE, EGL_FALSE);
@@ -960,7 +960,7 @@
egl_display_t const * const dp = validate_display(dpy);
if (!dp) return EGL_FALSE;
- SurfaceRef _s(surface);
+ SurfaceRef _s(dp, surface);
if (!_s.get())
return setError(EGL_BAD_SURFACE, EGL_FALSE);
@@ -1002,7 +1002,7 @@
egl_display_t const * const dp = validate_display(dpy);
if (!dp) return EGL_FALSE;
- SurfaceRef _s(surface);
+ SurfaceRef _s(dp, surface);
if (!_s.get())
return setError(EGL_BAD_SURFACE, EGL_FALSE);
@@ -1022,7 +1022,7 @@
egl_display_t const * const dp = validate_display(dpy);
if (!dp) return EGL_FALSE;
- SurfaceRef _s(surface);
+ SurfaceRef _s(dp, surface);
if (!_s.get())
return setError(EGL_BAD_SURFACE, EGL_FALSE);
@@ -1042,7 +1042,7 @@
egl_display_t const * const dp = validate_display(dpy);
if (!dp) return EGL_FALSE;
- SurfaceRef _s(surface);
+ SurfaceRef _s(dp, surface);
if (!_s.get())
return setError(EGL_BAD_SURFACE, EGL_FALSE);
@@ -1201,7 +1201,7 @@
egl_display_t const * const dp = validate_display(dpy);
if (!dp) return EGL_FALSE;
- SurfaceRef _s(surface);
+ SurfaceRef _s(dp, surface);
if (!_s.get())
return setError(EGL_BAD_SURFACE, EGL_FALSE);
@@ -1220,7 +1220,7 @@
egl_display_t const * const dp = validate_display(dpy);
if (!dp) return EGL_FALSE;
- SurfaceRef _s(surface);
+ SurfaceRef _s(dp, surface);
if (!_s.get())
return setError(EGL_BAD_SURFACE, EGL_FALSE);
@@ -1241,7 +1241,7 @@
if (!dp) return EGL_NO_IMAGE_KHR;
if (ctx != EGL_NO_CONTEXT) {
- ContextRef _c(ctx);
+ ContextRef _c(dp, ctx);
if (!_c.get())
return setError(EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR);
egl_context_t * const c = get_context(ctx);
@@ -1310,7 +1310,7 @@
egl_display_t const * const dp = validate_display(dpy);
if (!dp) return EGL_FALSE;
- ImageRef _i(img);
+ ImageRef _i(dp, img);
if (!_i.get()) return setError(EGL_BAD_PARAMETER, EGL_FALSE);
egl_image_t* image = get_image(img);
@@ -1349,7 +1349,7 @@
if (!dp) return EGL_NO_SYNC_KHR;
EGLContext ctx = eglGetCurrentContext();
- ContextRef _c(ctx);
+ ContextRef _c(dp, ctx);
if (!_c.get())
return setError(EGL_BAD_CONTEXT, EGL_NO_SYNC_KHR);
@@ -1372,12 +1372,12 @@
egl_display_t const * const dp = validate_display(dpy);
if (!dp) return EGL_FALSE;
- SyncRef _s(sync);
+ SyncRef _s(dp, sync);
if (!_s.get()) return setError(EGL_BAD_PARAMETER, EGL_FALSE);
egl_sync_t* syncObject = get_sync(sync);
EGLContext ctx = syncObject->context;
- ContextRef _c(ctx);
+ ContextRef _c(dp, ctx);
if (!_c.get())
return setError(EGL_BAD_CONTEXT, EGL_FALSE);
@@ -1399,12 +1399,12 @@
egl_display_t const * const dp = validate_display(dpy);
if (!dp) return EGL_FALSE;
- SyncRef _s(sync);
+ SyncRef _s(dp, sync);
if (!_s.get()) return setError(EGL_BAD_PARAMETER, EGL_FALSE);
egl_sync_t* syncObject = get_sync(sync);
EGLContext ctx = syncObject->context;
- ContextRef _c(ctx);
+ ContextRef _c(dp, ctx);
if (!_c.get())
return setError(EGL_BAD_CONTEXT, EGL_FALSE);
@@ -1424,13 +1424,13 @@
egl_display_t const * const dp = validate_display(dpy);
if (!dp) return EGL_FALSE;
- SyncRef _s(sync);
+ SyncRef _s(dp, sync);
if (!_s.get())
return setError(EGL_BAD_PARAMETER, EGL_FALSE);
egl_sync_t* syncObject = get_sync(sync);
EGLContext ctx = syncObject->context;
- ContextRef _c(ctx);
+ ContextRef _c(dp, ctx);
if (!_c.get())
return setError(EGL_BAD_CONTEXT, EGL_FALSE);
@@ -1455,7 +1455,7 @@
egl_display_t const * const dp = validate_display(dpy);
if (!dp) return EGL_FALSE;
- SurfaceRef _s(draw);
+ SurfaceRef _s(dp, draw);
if (!_s.get())
return setError(EGL_BAD_SURFACE, EGL_FALSE);
diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp
index 558ca77..2935832 100644
--- a/opengl/libs/EGL/egl_display.cpp
+++ b/opengl/libs/EGL/egl_display.cpp
@@ -62,11 +62,13 @@
objects.remove(object);
}
-bool egl_display_t::getObject(egl_object_t* object) {
+bool egl_display_t::getObject(egl_object_t* object) const {
Mutex::Autolock _l(lock);
if (objects.indexOf(object) >= 0) {
- object->incRef();
- return true;
+ if (object->getDisplay() == this) {
+ object->incRef();
+ return true;
+ }
}
return false;
}
diff --git a/opengl/libs/EGL/egl_display.h b/opengl/libs/EGL/egl_display.h
index e0a367d..94077be 100644
--- a/opengl/libs/EGL/egl_display.h
+++ b/opengl/libs/EGL/egl_display.h
@@ -81,7 +81,7 @@
// remove object from this display's list
void removeObject(egl_object_t* object);
// add reference to this object. returns true if this is a valid object.
- bool getObject(egl_object_t* object);
+ bool getObject(egl_object_t* object) const;
static egl_display_t* get(EGLDisplay dpy);
@@ -119,9 +119,9 @@
egl_config_t* configs;
private:
- uint32_t refs;
- Mutex lock;
- SortedVector<egl_object_t*> objects;
+ uint32_t refs;
+ mutable Mutex lock;
+ SortedVector<egl_object_t*> objects;
};
// ----------------------------------------------------------------------------
diff --git a/opengl/libs/EGL/egl_object.cpp b/opengl/libs/EGL/egl_object.cpp
index dbf9a01..20cdc7e 100644
--- a/opengl/libs/EGL/egl_object.cpp
+++ b/opengl/libs/EGL/egl_object.cpp
@@ -55,10 +55,10 @@
}
}
-bool egl_object_t::get() {
+bool egl_object_t::get(egl_display_t const* display, egl_object_t* object) {
// used by LocalRef, this does an incRef() atomically with
// checking that the object is valid.
- return display->getObject(this);
+ return display->getObject(object);
}
// ----------------------------------------------------------------------------
diff --git a/opengl/libs/EGL/egl_object.h b/opengl/libs/EGL/egl_object.h
index 46f7139..df1b261 100644
--- a/opengl/libs/EGL/egl_object.h
+++ b/opengl/libs/EGL/egl_object.h
@@ -52,10 +52,11 @@
inline int32_t incRef() { return android_atomic_inc(&count); }
inline int32_t decRef() { return android_atomic_dec(&count); }
+ inline egl_display_t* getDisplay() const { return display; }
private:
void terminate();
- bool get();
+ static bool get(egl_display_t const* display, egl_object_t* object);
public:
template <typename N, typename T>
@@ -66,9 +67,9 @@
public:
~LocalRef();
explicit LocalRef(egl_object_t* rhs);
- explicit LocalRef(T o) : ref(0) {
+ explicit LocalRef(egl_display_t const* display, T o) : ref(0) {
egl_object_t* native = reinterpret_cast<N*>(o);
- if (o && native->get()) {
+ if (o && egl_object_t::get(display, native)) {
ref = native;
}
}
diff --git a/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml b/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml
index 3ee9e77..180f022 100644
--- a/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml
+++ b/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml
@@ -33,39 +33,29 @@
android:clipToPadding="false"
android:clipChildren="false">
- <LinearLayout android:id="@+id/recents_glow"
+ <com.android.systemui.recent.RecentsHorizontalScrollView android:id="@+id/recents_container"
android:layout_width="wrap_content"
android:layout_height="match_parent"
- android:layout_gravity="bottom|right"
+ android:layout_marginRight="@dimen/status_bar_recents_right_glow_margin"
+ android:divider="@null"
+ android:stackFromBottom="true"
+ android:fadingEdge="horizontal"
+ android:scrollbars="none"
+ android:fadingEdgeLength="@dimen/status_bar_recents_fading_edge_length"
+ android:layout_gravity="bottom|left"
android:orientation="horizontal"
android:clipToPadding="false"
- android:clipChildren="false"
- >
- <com.android.systemui.recent.RecentsHorizontalScrollView android:id="@+id/recents_container"
+ android:clipChildren="false">
+
+ <LinearLayout android:id="@+id/recents_linear_layout"
android:layout_width="wrap_content"
android:layout_height="match_parent"
- android:layout_marginRight="@dimen/status_bar_recents_right_glow_margin"
- android:divider="@null"
- android:stackFromBottom="true"
- android:fadingEdge="horizontal"
- android:scrollbars="none"
- android:fadingEdgeLength="@dimen/status_bar_recents_fading_edge_length"
- android:layout_gravity="bottom|left"
android:orientation="horizontal"
android:clipToPadding="false"
android:clipChildren="false">
+ </LinearLayout>
- <LinearLayout android:id="@+id/recents_linear_layout"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:orientation="horizontal"
- android:clipToPadding="false"
- android:clipChildren="false">
- </LinearLayout>
-
- </com.android.systemui.recent.RecentsHorizontalScrollView>
-
- </LinearLayout>
+ </com.android.systemui.recent.RecentsHorizontalScrollView>
</FrameLayout>
diff --git a/packages/SystemUI/res/layout-port/status_bar_recent_panel.xml b/packages/SystemUI/res/layout-port/status_bar_recent_panel.xml
index d040544..e6a077a 100644
--- a/packages/SystemUI/res/layout-port/status_bar_recent_panel.xml
+++ b/packages/SystemUI/res/layout-port/status_bar_recent_panel.xml
@@ -31,39 +31,29 @@
android:layout_height="match_parent"
android:layout_alignParentBottom="true">
- <LinearLayout android:id="@+id/recents_glow"
+ <com.android.systemui.recent.RecentsVerticalScrollView
+ android:id="@+id/recents_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_gravity="bottom"
- android:orientation="horizontal"
- android:clipChildren="false"
- android:layout_marginTop="@*android:dimen/status_bar_height">
+ android:layout_marginRight="0dp"
+ android:divider="@null"
+ android:stackFromBottom="true"
+ android:fadingEdge="vertical"
+ android:scrollbars="none"
+ android:fadingEdgeLength="@*android:dimen/status_bar_height"
+ android:layout_gravity="bottom|left"
+ android:clipToPadding="false"
+ android:clipChildren="false">
- <com.android.systemui.recent.RecentsVerticalScrollView
- android:id="@+id/recents_container"
+ <LinearLayout android:id="@+id/recents_linear_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginRight="0dp"
- android:divider="@null"
- android:stackFromBottom="true"
- android:fadingEdge="vertical"
- android:scrollbars="none"
- android:fadingEdgeLength="@*android:dimen/status_bar_height"
- android:layout_gravity="bottom|left"
+ android:orientation="vertical"
android:clipToPadding="false"
android:clipChildren="false">
+ </LinearLayout>
- <LinearLayout android:id="@+id/recents_linear_layout"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:clipToPadding="false"
- android:clipChildren="false">
- </LinearLayout>
-
- </com.android.systemui.recent.RecentsVerticalScrollView>
-
- </LinearLayout>
+ </com.android.systemui.recent.RecentsVerticalScrollView>
</FrameLayout>
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_no_recent_apps.xml b/packages/SystemUI/res/layout-sw600dp/status_bar_no_recent_apps.xml
new file mode 100644
index 0000000..bc89281
--- /dev/null
+++ b/packages/SystemUI/res/layout-sw600dp/status_bar_no_recent_apps.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* apps/common/assets/default/default/skins/StatusBar.xml
+**
+** Copyright 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.
+*/
+-->
+
+<FrameLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_height="match_parent"
+ android:layout_width="match_parent"
+ >
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="20dp"
+ android:textColor="@android:color/holo_blue_light"
+ android:text="@string/status_bar_no_recent_apps"
+ android:gravity="left"
+ android:layout_gravity="bottom|left"
+ />
+</FrameLayout>
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml b/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml
index 18a31f7..cb26db00 100644
--- a/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml
+++ b/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml
@@ -23,31 +23,6 @@
android:layout_height="wrap_content"
android:layout_width="wrap_content">
- <FrameLayout android:id="@+id/app_thumbnail"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentLeft="true"
- android:layout_alignParentTop="true"
- android:layout_marginLeft="@dimen/status_bar_recents_thumbnail_left_margin"
- android:scaleType="center"
- android:background="@drawable/recents_thumbnail_bg"
- android:foreground="@drawable/recents_thumbnail_fg"
- android:visibility="invisible">
- <ImageView android:id="@+id/app_thumbnail_image"
- android:layout_width="@dimen/status_bar_recents_thumbnail_width"
- android:layout_height="@dimen/status_bar_recents_thumbnail_height"
- />
- <ImageView android:id="@+id/app_icon"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_marginLeft="@dimen/status_bar_recents_app_icon_left_margin"
- android:layout_marginTop="@dimen/status_bar_recents_app_icon_top_margin"
- android:maxWidth="@dimen/status_bar_recents_app_icon_max_width"
- android:maxHeight="@dimen/status_bar_recents_app_icon_max_height"
- android:adjustViewBounds="true"
- />
- </FrameLayout>
-
<TextView android:id="@+id/app_label"
android:layout_width="@dimen/status_bar_recents_app_label_width"
android:layout_height="wrap_content"
@@ -64,6 +39,35 @@
android:textColor="@color/status_bar_recents_app_label_color"
/>
+ <FrameLayout android:id="@+id/app_thumbnail"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_toRightOf="@id/app_label"
+ android:layout_marginLeft="@dimen/status_bar_recents_thumbnail_left_margin"
+ android:scaleType="center"
+ android:background="@drawable/recents_thumbnail_bg"
+ android:foreground="@drawable/recents_thumbnail_fg"
+ android:visibility="invisible">
+ <ImageView android:id="@+id/app_thumbnail_image"
+ android:layout_width="@dimen/status_bar_recents_thumbnail_width"
+ android:layout_height="@dimen/status_bar_recents_thumbnail_height"
+ />
+ </FrameLayout>
+
+
+ <ImageView android:id="@+id/app_icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_toRightOf="@id/app_label"
+ android:layout_marginLeft="@dimen/status_bar_recents_app_icon_left_margin"
+ android:layout_marginTop="@dimen/status_bar_recents_app_icon_top_margin"
+ android:maxWidth="@dimen/status_bar_recents_app_icon_max_width"
+ android:maxHeight="@dimen/status_bar_recents_app_icon_max_height"
+ android:scaleType="centerInside"
+ android:adjustViewBounds="true"
+ />
+
+
<View android:id="@+id/recents_callout_line"
android:layout_width="@dimen/status_bar_recents_app_label_width"
android:layout_height="1dip"
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_recent_panel.xml b/packages/SystemUI/res/layout-sw600dp/status_bar_recent_panel.xml
index 5dd101e..111f9a4 100644
--- a/packages/SystemUI/res/layout-sw600dp/status_bar_recent_panel.xml
+++ b/packages/SystemUI/res/layout-sw600dp/status_bar_recent_panel.xml
@@ -36,40 +36,36 @@
android:clipToPadding="false"
android:clipChildren="false">
- <LinearLayout android:id="@+id/recents_glow"
+ <com.android.systemui.recent.RecentsVerticalScrollView android:id="@+id/recents_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginBottom="-49dip"
- android:layout_gravity="bottom"
- android:background="@drawable/recents_blue_glow"
- android:orientation="horizontal"
+ android:layout_marginRight="@dimen/status_bar_recents_right_glow_margin"
+ android:divider="@null"
+ android:stackFromBottom="true"
+ android:fadingEdge="vertical"
+ android:scrollbars="none"
+ android:fadingEdgeLength="20dip"
+ android:layout_gravity="bottom|left"
android:clipToPadding="false"
- android:clipChildren="false"
- >
- <com.android.systemui.recent.RecentsVerticalScrollView android:id="@+id/recents_container"
+ android:clipChildren="false">
+
+ <LinearLayout android:id="@+id/recents_linear_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginRight="@dimen/status_bar_recents_right_glow_margin"
- android:divider="@null"
- android:stackFromBottom="true"
- android:fadingEdge="vertical"
- android:scrollbars="none"
- android:fadingEdgeLength="20dip"
- android:layout_gravity="bottom|left"
+ android:orientation="vertical"
android:clipToPadding="false"
android:clipChildren="false">
+ </LinearLayout>
- <LinearLayout android:id="@+id/recents_linear_layout"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:orientation="vertical"
- android:clipToPadding="false"
- android:clipChildren="false">
- </LinearLayout>
+ </com.android.systemui.recent.RecentsVerticalScrollView>
- </com.android.systemui.recent.RecentsVerticalScrollView>
-
- </LinearLayout>
+ <include layout="@layout/status_bar_no_recent_apps"
+ android:id="@+id/recents_no_apps"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_marginLeft="58dip"
+ android:layout_marginBottom="36dip"
+ android:visibility="invisible" />
</FrameLayout>
@@ -82,4 +78,5 @@
android:contentDescription="@string/status_bar_accessibility_dismiss_recents"
/>
+
</com.android.systemui.recent.RecentsPanelView>
diff --git a/packages/SystemUI/res/layout/status_bar.xml b/packages/SystemUI/res/layout/status_bar.xml
index af2c93c..b1aaade 100644
--- a/packages/SystemUI/res/layout/status_bar.xml
+++ b/packages/SystemUI/res/layout/status_bar.xml
@@ -31,21 +31,35 @@
<LinearLayout android:id="@+id/icons"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:orientation="horizontal">
-
- <com.android.systemui.statusbar.phone.IconMerger android:id="@+id/notificationIcons"
+ android:paddingLeft="6dip"
+ android:paddingRight="6dip"
+ android:orientation="horizontal"
+ >
+
+ <LinearLayout
android:layout_width="0dip"
- android:layout_weight="1"
android:layout_height="match_parent"
- android:layout_alignParentLeft="true"
- android:paddingLeft="6dip"
- android:gravity="center_vertical"
- android:orientation="horizontal"/>
-
+ android:layout_weight="1"
+ android:orientation="horizontal"
+ >
+ <com.android.systemui.statusbar.StatusBarIconView android:id="@+id/moreIcon"
+ android:layout_width="@dimen/status_bar_icon_size"
+ android:layout_height="match_parent"
+ android:src="@drawable/stat_notify_more"
+ android:visibility="gone"
+ />
+
+ <com.android.systemui.statusbar.phone.IconMerger android:id="@+id/notificationIcons"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_alignParentLeft="true"
+ android:gravity="center_vertical"
+ android:orientation="horizontal"/>
+ </LinearLayout>
+
<LinearLayout android:id="@+id/statusIcons"
android:layout_width="wrap_content"
android:layout_height="match_parent"
- android:layout_alignParentRight="true"
android:gravity="center_vertical"
android:orientation="horizontal"/>
@@ -53,7 +67,7 @@
android:id="@+id/signal_battery_cluster"
android:layout_width="wrap_content"
android:layout_height="match_parent"
- android:layout_marginRight="6dp"
+ android:paddingLeft="2dp"
android:orientation="horizontal"
android:gravity="center"
>
@@ -66,7 +80,7 @@
android:id="@+id/battery"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
- android:paddingLeft="6dip"
+ android:paddingLeft="4dip"
/>
</LinearLayout>
@@ -76,7 +90,7 @@
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:singleLine="true"
- android:paddingRight="6dip"
+ android:paddingLeft="6dip"
android:gravity="center_vertical|left"
/>
</LinearLayout>
diff --git a/packages/SystemUI/res/values-sw600dp/config.xml b/packages/SystemUI/res/values-sw600dp/config.xml
index 3e2ec59..24185a4 100644
--- a/packages/SystemUI/res/values-sw600dp/config.xml
+++ b/packages/SystemUI/res/values-sw600dp/config.xml
@@ -18,8 +18,11 @@
-->
<resources>
-
<!-- Whether we're using the tablet-optimized recents interface (we use this
value at runtime for some things) -->
<bool name="config_recents_interface_for_tablets">true</bool>
+
+ <!-- Whether recents thumbnails should stretch in both x and y to fill their
+ ImageView -->
+ <bool name="config_recents_thumbnail_image_fits_to_xy">true</bool>
</resources>
diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml
index fe9245d..f522285 100644
--- a/packages/SystemUI/res/values-sw600dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp/dimens.xml
@@ -31,15 +31,15 @@
<!-- Recent Applications parameters -->
<!-- How far the thumbnail for a recent app appears from left edge -->
- <dimen name="status_bar_recents_thumbnail_left_margin">121dp</dimen>
+ <dimen name="status_bar_recents_thumbnail_left_margin">28dp</dimen>
<!-- Upper width limit for application icon -->
<dimen name="status_bar_recents_app_icon_max_width">64dp</dimen>
<!-- Upper height limit for application icon -->
<dimen name="status_bar_recents_app_icon_max_height">64dp</dimen>
<!-- Size of application icon -->
- <dimen name="status_bar_recents_thumbnail_width">245dp</dimen>
- <dimen name="status_bar_recents_thumbnail_height">144dp</dimen>
+ <dimen name="status_bar_recents_thumbnail_width">208dp</dimen>
+ <dimen name="status_bar_recents_thumbnail_height">130dp</dimen>
<!-- Width of recents panel -->
<dimen name="status_bar_recents_width">600dp</dimen>
@@ -59,8 +59,8 @@
<dimen name="status_bar_recents_right_glow_margin">100dip</dimen>
<!-- Where to place the app icon over the thumbnail -->
- <dimen name="status_bar_recents_app_icon_left_margin">13dp</dimen>
- <dimen name="status_bar_recents_app_icon_top_margin">13dp</dimen>
+ <dimen name="status_bar_recents_app_icon_left_margin">0dp</dimen>
+ <dimen name="status_bar_recents_app_icon_top_margin">8dp</dimen>
<!-- size at which Notification icons will be drawn in the status bar -->
<dimen name="status_bar_icon_drawing_size">24dip</dimen>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 1fe4ebb..1f22507 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -25,6 +25,10 @@
value at runtime for some things) -->
<bool name="config_recents_interface_for_tablets">false</bool>
+ <!-- Whether recents thumbnails should stretch in both x and y to fill their
+ ImageView -->
+ <bool name="config_recents_thumbnail_image_fits_to_xy">false</bool>
+
<!-- Control whether status bar should distinguish HSPA data icon form UMTS
data icon on devices -->
<bool name="config_hspa_data_distinguishable">false</bool>
diff --git a/packages/SystemUI/src/com/android/systemui/recent/Choreographer.java b/packages/SystemUI/src/com/android/systemui/recent/Choreographer.java
index 886a14d..ad38a11 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/Choreographer.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/Choreographer.java
@@ -120,8 +120,13 @@
createAnimation(appearing);
- mContentView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
- mContentView.buildLayer();
+ // isHardwareAccelerated() checks if we're attached to a window and if that
+ // window is HW accelerated-- we were sometimes not attached to a window
+ // and buildLayer was throwing an IllegalStateException
+ if (mContentView.isHardwareAccelerated()) {
+ mContentView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ mContentView.buildLayer();
+ }
mContentAnim.start();
mVisible = appearing;
diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
index 6b8b65e..8bfd711 100644
--- a/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/recent/RecentsPanelView.java
@@ -16,14 +16,13 @@
package com.android.systemui.recent;
-import java.util.ArrayList;
-
import android.animation.Animator;
import android.animation.LayoutTransition;
import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.content.res.Configuration;
+import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.graphics.Shader.TileMode;
@@ -42,15 +41,15 @@
import android.view.accessibility.AccessibilityEvent;
import android.view.animation.AnimationUtils;
import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.HorizontalScrollView;
import android.widget.ImageView;
+import android.widget.ImageView.ScaleType;
import android.widget.PopupMenu;
import android.widget.RelativeLayout;
import android.widget.ScrollView;
import android.widget.TextView;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.ImageView.ScaleType;
import com.android.systemui.R;
import com.android.systemui.statusbar.StatusBar;
@@ -58,6 +57,8 @@
import com.android.systemui.statusbar.tablet.StatusBarPanel;
import com.android.systemui.statusbar.tablet.TabletStatusBar;
+import java.util.ArrayList;
+
public class RecentsPanelView extends RelativeLayout implements OnItemClickListener, RecentsCallback,
StatusBarPanel, Animator.AnimatorListener, View.OnTouchListener {
static final String TAG = "RecentsPanelView";
@@ -65,7 +66,6 @@
private Context mContext;
private StatusBar mBar;
private View mRecentsScrim;
- private View mRecentsGlowView;
private View mRecentsNoApps;
private ViewGroup mRecentsContainer;
@@ -79,6 +79,7 @@
private boolean mRecentTasksDirty = true;
private TaskDescriptionAdapter mListAdapter;
private int mThumbnailWidth;
+ private boolean mFitThumbnailToXY;
public void setRecentTasksLoader(RecentTasksLoader loader) {
mRecentTasksLoader = loader;
@@ -174,9 +175,8 @@
// use mRecentsContainer's exact bounds to determine horizontal position
final int l = mRecentsContainer.getLeft();
final int r = mRecentsContainer.getRight();
- // use surrounding mRecentsGlowView's position in parent determine vertical bounds
- final int t = mRecentsGlowView.getTop();
- final int b = mRecentsGlowView.getBottom();
+ final int t = mRecentsContainer.getTop();
+ final int b = mRecentsContainer.getBottom();
return x >= l && x < r && y >= t && y < b;
}
@@ -194,7 +194,7 @@
// if there are no apps, either bring up a "No recent apps" message, or just
// quit early
boolean noApps = (mRecentTaskDescriptions.size() == 0);
- if (mRecentsNoApps != null) { // doesn't exist on large devices
+ if (mRecentsNoApps != null) {
mRecentsNoApps.setVisibility(noApps ? View.VISIBLE : View.INVISIBLE);
} else {
if (noApps) {
@@ -325,8 +325,9 @@
}
public void updateValuesFromResources() {
- mThumbnailWidth =
- (int) mContext.getResources().getDimension(R.dimen.status_bar_recents_thumbnail_width);
+ final Resources res = mContext.getResources();
+ mThumbnailWidth = Math.round(res.getDimension(R.dimen.status_bar_recents_thumbnail_width));
+ mFitThumbnailToXY = res.getBoolean(R.bool.config_recents_thumbnail_image_fits_to_xy);
}
@Override
@@ -351,10 +352,9 @@
}
- mRecentsGlowView = findViewById(R.id.recents_glow);
mRecentsScrim = findViewById(R.id.recents_bg_protect);
mRecentsNoApps = findViewById(R.id.recents_no_apps);
- mChoreo = new Choreographer(this, mRecentsScrim, mRecentsGlowView, mRecentsNoApps, this);
+ mChoreo = new Choreographer(this, mRecentsScrim, mRecentsContainer, mRecentsNoApps, this);
mRecentsDismissButton = findViewById(R.id.recents_dismiss_button);
if (mRecentsDismissButton != null) {
mRecentsDismissButton.setOnClickListener(new OnClickListener() {
@@ -409,11 +409,15 @@
if (h.thumbnailViewImageBitmap == null ||
h.thumbnailViewImageBitmap.getWidth() != thumbnail.getWidth() ||
h.thumbnailViewImageBitmap.getHeight() != thumbnail.getHeight()) {
- Matrix scaleMatrix = new Matrix();
- float scale = mThumbnailWidth / (float) thumbnail.getWidth();
- scaleMatrix.setScale(scale, scale);
- h.thumbnailViewImage.setScaleType(ScaleType.MATRIX);
- h.thumbnailViewImage.setImageMatrix(scaleMatrix);
+ if (mFitThumbnailToXY) {
+ h.thumbnailViewImage.setScaleType(ScaleType.FIT_XY);
+ } else {
+ Matrix scaleMatrix = new Matrix();
+ float scale = mThumbnailWidth / (float) thumbnail.getWidth();
+ scaleMatrix.setScale(scale, scale);
+ h.thumbnailViewImage.setScaleType(ScaleType.MATRIX);
+ h.thumbnailViewImage.setImageMatrix(scaleMatrix);
+ }
}
if (show && h.thumbnailView.getVisibility() != View.VISIBLE) {
if (anim) {
@@ -444,7 +448,7 @@
// only fade in the thumbnail if recents is already visible-- we
// show it immediately otherwise
boolean animateShow = mShowing &&
- mRecentsGlowView.getAlpha() > ViewConfiguration.ALPHA_THRESHOLD;
+ mRecentsContainer.getAlpha() > ViewConfiguration.ALPHA_THRESHOLD;
updateThumbnail(h, ad.getThumbnail(), true, animateShow);
}
}
@@ -516,7 +520,6 @@
final int items = mRecentTaskDescriptions.size();
mRecentsContainer.setVisibility(items > 0 ? View.VISIBLE : View.GONE);
- mRecentsGlowView.setVisibility(items > 0 ? View.VISIBLE : View.GONE);
// Set description for accessibility
int numRecentApps = mRecentTaskDescriptions.size();
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index c259c28..ad37603 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -49,8 +49,6 @@
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
-import android.view.animation.AccelerateInterpolator;
-import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
@@ -131,8 +129,8 @@
// Show the intermediate notification
mTickerAddSpace = !mTickerAddSpace;
mNotificationId = nId;
+ mNotificationManager = nManager;
mNotificationBuilder = new Notification.Builder(context)
- .setLargeIcon(croppedIcon)
.setTicker(r.getString(R.string.screenshot_saving_ticker)
+ (mTickerAddSpace ? " " : ""))
.setContentTitle(r.getString(R.string.screenshot_saving_title))
@@ -141,9 +139,12 @@
.setWhen(System.currentTimeMillis());
Notification n = mNotificationBuilder.getNotification();
n.flags |= Notification.FLAG_NO_CLEAR;
-
- mNotificationManager = nManager;
mNotificationManager.notify(nId, n);
+
+ // On the tablet, the large icon makes the notification appear as if it is clickable (and
+ // on small devices, the large icon is not shown) so defer showing the large icon until
+ // we compose the final post-save notification below.
+ mNotificationBuilder.setLargeIcon(croppedIcon);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
index 6997837..8228df5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarIconView.java
@@ -25,6 +25,7 @@
import android.graphics.Paint;
import android.graphics.Rect;
import android.text.TextUtils;
+import android.util.AttributeSet;
import android.util.Slog;
import android.util.Log;
import android.view.ViewDebug;
@@ -75,6 +76,18 @@
setScaleType(ImageView.ScaleType.CENTER);
}
+ public StatusBarIconView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ final Resources res = context.getResources();
+ final int outerBounds = res.getDimensionPixelSize(R.dimen.status_bar_icon_size);
+ final int imageBounds = res.getDimensionPixelSize(R.dimen.status_bar_icon_drawing_size);
+ final float scale = (float)imageBounds / (float)outerBounds;
+ setScaleX(scale);
+ setScaleY(scale);
+ final float alpha = res.getFraction(R.dimen.status_bar_icon_drawing_alpha, 1, 1);
+ setAlpha(alpha);
+ }
+
private static boolean streq(String a, String b) {
if (a == b) {
return true;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/IconMerger.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/IconMerger.java
index 20215bd..0640282 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/IconMerger.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/IconMerger.java
@@ -30,113 +30,59 @@
public class IconMerger extends LinearLayout {
private static final String TAG = "IconMerger";
+ private static final boolean DEBUG = false;
private int mIconSize;
- private StatusBarIconView mMoreView;
- private StatusBarIcon mMoreIcon = new StatusBarIcon(null, R.drawable.stat_notify_more, 0, 0,
- null);
+ private View mMoreView;
public IconMerger(Context context, AttributeSet attrs) {
super(context, attrs);
mIconSize = context.getResources().getDimensionPixelSize(
- com.android.internal.R.dimen.status_bar_icon_size);
+ R.dimen.status_bar_icon_size);
- mMoreView = new StatusBarIconView(context, "more", null);
- mMoreView.set(mMoreIcon);
- super.addView(mMoreView, 0, new LinearLayout.LayoutParams(mIconSize, mIconSize));
+ if (DEBUG) {
+ setBackgroundColor(0x800099FF);
+ }
}
- public void addView(StatusBarIconView v, int index, LinearLayout.LayoutParams p) {
- super.addView(v, index+1, p);
+ public void setOverflowIndicator(View v) {
+ mMoreView = v;
}
- public void addView(StatusBarIconView v, int index) {
- super.addView(v, index+1, new LinearLayout.LayoutParams(mIconSize, mIconSize));
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ // we need to constrain this to an integral multiple of our children
+ int width = getMeasuredWidth();
+ setMeasuredDimension(width - (width % mIconSize), getMeasuredHeight());
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
+ checkOverflow(r - l);
+ }
- final int maxWidth = r - l;
+ private void checkOverflow(int width) {
+ if (mMoreView == null) return;
+
final int N = getChildCount();
- int i;
-
- // get the rightmost one, and see if we even need to do anything
- int fitRight = -1;
- for (i=N-1; i>=0; i--) {
- final View child = getChildAt(i);
- if (child.getVisibility() != GONE) {
- fitRight = child.getRight();
- break;
- }
+ int visibleChildren = 0;
+ for (int i=0; i<N; i++) {
+ if (getChildAt(i).getVisibility() != GONE) visibleChildren++;
}
-
- // find the first visible one that isn't the more icon
- final StatusBarIconView moreView = mMoreView;
- int fitLeft = -1;
- int startIndex = -1;
- for (i=0; i<N; i++) {
- final View child = getChildAt(i);
- if (child == moreView) {
- startIndex = i+1;
- }
- else if (child.getVisibility() != GONE) {
- fitLeft = child.getLeft();
- break;
- }
- }
-
- if (moreView == null || startIndex < 0) {
- return;
- /*
- throw new RuntimeException("Status Bar / IconMerger moreView == " + moreView
- + " startIndex=" + startIndex);
- */
- }
-
- // if it fits without the more icon, then hide the more icon and update fitLeft
- // so everything gets pushed left
- int adjust = 0;
- if (fitRight - fitLeft <= maxWidth) {
- adjust = fitLeft - moreView.getLeft();
- fitLeft -= adjust;
- fitRight -= adjust;
- moreView.layout(0, moreView.getTop(), 0, moreView.getBottom());
- }
- int extra = fitRight - r;
- int shift = -1;
-
- int breakingPoint = fitLeft + extra + adjust;
- int number = 0;
- for (i=startIndex; i<N; i++) {
- final StatusBarIconView child = (StatusBarIconView)getChildAt(i);
- if (child.getVisibility() != GONE) {
- int childLeft = child.getLeft();
- int childRight = child.getRight();
- if (childLeft < breakingPoint) {
- // hide this one
- child.layout(0, child.getTop(), 0, child.getBottom());
- int n = child.getStatusBarIcon().number;
- if (n == 0) {
- number += 1;
- } else if (n > 0) {
- number += n;
- }
- } else {
- // decide how much to shift by
- if (shift < 0) {
- shift = childLeft - fitLeft;
- }
- // shift this left by shift
- child.layout(childLeft-shift, child.getTop(),
- childRight-shift, child.getBottom());
+ final boolean overflowShown = (mMoreView.getVisibility() == View.VISIBLE);
+ // let's assume we have one more slot if the more icon is already showing
+ if (overflowShown) visibleChildren --;
+ final boolean moreRequired = visibleChildren * mIconSize > width;
+ if (moreRequired != overflowShown) {
+ post(new Runnable() {
+ @Override
+ public void run() {
+ mMoreView.setVisibility(moreRequired ? View.VISIBLE : View.GONE);
}
- }
+ });
}
-
- mMoreIcon.number = number;
- mMoreView.set(mMoreIcon);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 51fb262..b0554d0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -149,6 +149,7 @@
// icons
LinearLayout mIcons;
IconMerger mNotificationIcons;
+ View mMoreIcon;
LinearLayout mStatusIcons;
// expanded notifications
@@ -307,6 +308,8 @@
mPixelFormat = PixelFormat.OPAQUE;
mStatusIcons = (LinearLayout)sb.findViewById(R.id.statusIcons);
mNotificationIcons = (IconMerger)sb.findViewById(R.id.notificationIcons);
+ mMoreIcon = sb.findViewById(R.id.moreIcon);
+ mNotificationIcons.setOverflowIndicator(mMoreIcon);
mIcons = (LinearLayout)sb.findViewById(R.id.icons);
mTickerView = sb.findViewById(R.id.ticker);
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index cd63090..39e8c72 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -1248,7 +1248,14 @@
PrintWriter pw = new PrintWriter(sw);
StringWriter catSw = new StringWriter();
PrintWriter catPw = new PrintWriter(catSw);
- dumpApplicationMemoryUsage(null, pw, " ", new String[] { }, true, catPw);
+ String[] emptyArgs = new String[] { };
+ dumpApplicationMemoryUsage(null, pw, " ", emptyArgs, true, catPw);
+ pw.println();
+ dumpProcessesLocked(null, pw, emptyArgs, 0, false);
+ pw.println();
+ dumpServicesLocked(null, pw, emptyArgs, 0, false, false);
+ pw.println();
+ dumpActivitiesLocked(null, pw, emptyArgs, 0, false, false);
String memUsage = sw.toString();
dropBuilder.append('\n');
dropBuilder.append(memUsage);
@@ -1479,6 +1486,7 @@
mConfiguration.setToDefaults();
mConfiguration.locale = Locale.getDefault();
+ mConfigurationSeq = mConfiguration.seq = 1;
mProcessStats.init();
mCompatModePackages = new CompatModePackages(this, systemDir);
@@ -2436,7 +2444,7 @@
r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
if (config != null) {
r.frozenBeforeDestroy = true;
- if (!updateConfigurationLocked(config, r, false)) {
+ if (!updateConfigurationLocked(config, r, false, false)) {
mMainStack.resumeTopActivityLocked(null);
}
}
@@ -3797,7 +3805,7 @@
app.instrumentationClass, profileFile, profileFd, profileAutoStop,
app.instrumentationArguments, app.instrumentationWatcher, testMode,
isRestrictedBackupMode || !normalMode, app.persistent,
- mConfiguration, app.compat, getCommonServicesLocked(),
+ new Configuration(mConfiguration), app.compat, getCommonServicesLocked(),
mCoreSettingsObserver.getCoreSettingsLocked());
updateLruProcessLocked(app, false, true);
app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
@@ -6707,8 +6715,7 @@
mAlwaysFinishActivities = alwaysFinishActivities;
// This happens before any activities are started, so we can
// change mConfiguration in-place.
- mConfiguration.updateFrom(configuration);
- mConfigurationSeq = mConfiguration.seq = 1;
+ updateConfigurationLocked(configuration, null, false, true);
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Initial config: " + mConfiguration);
}
}
@@ -8789,6 +8796,20 @@
TimeUtils.formatDuration(r.createTime, nowReal, pw);
pw.print(" started="); pw.print(r.startRequested);
pw.print(" connections="); pw.println(r.connections.size());
+ if (r.connections.size() > 0) {
+ pw.println(" Connections:");
+ for (ArrayList<ConnectionRecord> clist : r.connections.values()) {
+ for (int i=0; i<clist.size(); i++) {
+ ConnectionRecord conn = clist.get(i);
+ pw.print(" ");
+ pw.print(conn.binding.intent.intent.getIntent().toShortString(
+ false, false, false));
+ pw.print(" -> ");
+ ProcessRecord proc = conn.binding.client;
+ pw.println(proc != null ? proc.toShortString() : "null");
+ }
+ }
+ }
}
if (dumpClient && r.app != null && r.app.thread != null) {
pw.println(" Client:");
@@ -8908,18 +8929,21 @@
continue;
}
pw.print(" * "); pw.print(cls); pw.print(" (");
- pw.print(comp.flattenToShortString()); pw.print(")");
+ pw.print(comp.flattenToShortString()); pw.println(")");
if (dumpAll) {
- pw.println();
r.dump(pw, " ");
} else {
- pw.print(" * "); pw.print(e.getKey().flattenToShortString());
if (r.proc != null) {
- pw.println(":");
pw.print(" "); pw.println(r.proc);
} else {
pw.println();
}
+ if (r.clients.size() > 0) {
+ pw.println(" Clients:");
+ for (ProcessRecord cproc : r.clients) {
+ pw.print(" - "); pw.println(cproc);
+ }
+ }
}
}
needSep = true;
@@ -12934,7 +12958,7 @@
synchronized(this) {
final long origId = Binder.clearCallingIdentity();
- updateConfigurationLocked(values, null, true);
+ updateConfigurationLocked(values, null, true, false);
Binder.restoreCallingIdentity(origId);
}
}
@@ -12957,7 +12981,7 @@
if (values != null) {
Settings.System.clearConfiguration(values);
}
- updateConfigurationLocked(values, null, false);
+ updateConfigurationLocked(values, null, false, false);
Binder.restoreCallingIdentity(origId);
}
}
@@ -12971,7 +12995,7 @@
* @param persistent TODO
*/
public boolean updateConfigurationLocked(Configuration values,
- ActivityRecord starting, boolean persistent) {
+ ActivityRecord starting, boolean persistent, boolean initLocale) {
int changes = 0;
boolean kept = true;
@@ -12986,7 +13010,7 @@
EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
- if (values.locale != null) {
+ if (values.locale != null && !initLocale) {
saveLocaleLocked(values.locale,
!values.locale.equals(mConfiguration.locale),
values.userSetLocale);
@@ -12999,10 +13023,12 @@
newConfig.seq = mConfigurationSeq;
mConfiguration = newConfig;
Slog.i(TAG, "Config changed: " + newConfig);
-
+
+ final Configuration configCopy = new Configuration(mConfiguration);
+
AttributeCache ac = AttributeCache.instance();
if (ac != null) {
- ac.updateConfiguration(mConfiguration);
+ ac.updateConfiguration(configCopy);
}
// Make sure all resources in our process are updated
@@ -13012,11 +13038,11 @@
// boot, where the first config change needs to guarantee
// all resources have that config before following boot
// code is executed.
- mSystemThread.applyConfigurationToResources(newConfig);
+ mSystemThread.applyConfigurationToResources(configCopy);
if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
- msg.obj = new Configuration(mConfiguration);
+ msg.obj = new Configuration(configCopy);
mHandler.sendMessage(msg);
}
@@ -13026,7 +13052,7 @@
if (app.thread != null) {
if (DEBUG_CONFIGURATION) Slog.v(TAG, "Sending to proc "
+ app.processName + " new config " + mConfiguration);
- app.thread.scheduleConfigurationChanged(mConfiguration);
+ app.thread.scheduleConfigurationChanged(configCopy);
}
} catch (Exception e) {
}
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index c892cb1..c7ce3c3 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -528,7 +528,7 @@
Configuration config = mService.mWindowManager.updateOrientationFromAppTokens(
mService.mConfiguration,
r.mayFreezeScreenLocked(app) ? r.appToken : null);
- mService.updateConfigurationLocked(config, r, false);
+ mService.updateConfigurationLocked(config, r, false, false);
}
r.app = app;
@@ -590,7 +590,8 @@
}
}
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
- System.identityHashCode(r), r.info, mService.mConfiguration,
+ System.identityHashCode(r), r.info,
+ new Configuration(mService.mConfiguration),
r.compat, r.icicle, results, newIntents, !andResume,
mService.isNextTransitionForward(), profileFile, profileFd,
profileAutoStop);
@@ -1460,7 +1461,7 @@
if (config != null) {
next.frozenBeforeDestroy = true;
}
- updated = mService.updateConfigurationLocked(config, next, false);
+ updated = mService.updateConfigurationLocked(config, next, false, false);
}
}
if (!updated) {
@@ -2917,7 +2918,7 @@
mConfigWillChange = false;
if (DEBUG_CONFIGURATION) Slog.v(TAG,
"Updating to new configuration after starting activity.");
- mService.updateConfigurationLocked(config, null, false);
+ mService.updateConfigurationLocked(config, null, false, false);
}
Binder.restoreCallingIdentity(origId);
@@ -4190,7 +4191,7 @@
if (DEBUG_SWITCH) Slog.i(TAG, "Switch is restarting resumed " + r);
r.forceNewConfig = false;
r.app.thread.scheduleRelaunchActivity(r.appToken, results, newIntents,
- changes, !andResume, mService.mConfiguration);
+ changes, !andResume, new Configuration(mService.mConfiguration));
// Note: don't need to call pauseIfSleepingLocked() here, because
// the caller will only pass in 'andResume' if this activity is
// currently resumed, which implies we aren't sleeping.
diff --git a/services/java/com/android/server/am/ContentProviderRecord.java b/services/java/com/android/server/am/ContentProviderRecord.java
index 9c55597..6f6266d 100644
--- a/services/java/com/android/server/am/ContentProviderRecord.java
+++ b/services/java/com/android/server/am/ContentProviderRecord.java
@@ -74,6 +74,10 @@
pw.print(" initOrder="); pw.println(info.initOrder);
}
if (clients.size() > 0) {
+ pw.print(prefix); pw.println("Clients:");
+ for (ProcessRecord cproc : clients) {
+ pw.print(prefix); pw.println(" - "); pw.println(cproc);
+ }
pw.print(prefix); pw.print("clients="); pw.println(clients);
}
if (externals != 0) {
diff --git a/services/java/com/android/server/net/NetworkStatsService.java b/services/java/com/android/server/net/NetworkStatsService.java
index 6365525..28cb983 100644
--- a/services/java/com/android/server/net/NetworkStatsService.java
+++ b/services/java/com/android/server/net/NetworkStatsService.java
@@ -1243,7 +1243,8 @@
// trim any history beyond max
if (mTime.hasCache()) {
- final long currentTime = mTime.currentTimeMillis();
+ final long currentTime = Math.min(
+ System.currentTimeMillis(), mTime.currentTimeMillis());
final long maxHistory = mSettings.getNetworkMaxHistory();
for (NetworkStatsHistory history : input.values()) {
history.removeBucketsBefore(currentTime - maxHistory);
@@ -1287,7 +1288,8 @@
// trim any history beyond max
if (mTime.hasCache()) {
- final long currentTime = mTime.currentTimeMillis();
+ final long currentTime = Math.min(
+ System.currentTimeMillis(), mTime.currentTimeMillis());
final long maxUidHistory = mSettings.getUidMaxHistory();
final long maxTagHistory = mSettings.getTagMaxHistory();
for (UidStatsKey key : mUidStats.keySet()) {
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 50321b3..ebb13d5 100644
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -5090,10 +5090,22 @@
// Constrain thumbnail to smaller of screen width or height. Assumes aspect
// of thumbnail is the same as the screen (in landscape) or square.
+ float targetWidthScale = width / (float) fw;
+ float targetHeightScale = height / (float) fh;
if (dw <= dh) {
- scale = width / (float) fw; // portrait
+ scale = targetWidthScale;
+ // If aspect of thumbnail is the same as the screen (in landscape),
+ // select the slightly larger value so we fill the entire bitmap
+ if (targetHeightScale > scale && (int) (targetHeightScale * fw) == width) {
+ scale = targetHeightScale;
+ }
} else {
- scale = height / (float) fh; // landscape
+ scale = targetHeightScale;
+ // If aspect of thumbnail is the same as the screen (in landscape),
+ // select the slightly larger value so we fill the entire bitmap
+ if (targetWidthScale > scale && (int) (targetWidthScale * fh) == height) {
+ scale = targetWidthScale;
+ }
}
// The screen shot will contain the entire screen.
diff --git a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
index 368595f..0618374 100644
--- a/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/NetworkPolicyManagerServiceTest.java
@@ -80,7 +80,6 @@
import org.easymock.Capture;
import org.easymock.EasyMock;
import org.easymock.IAnswer;
-import org.easymock.IExpectationSetters;
import java.io.File;
import java.util.LinkedHashSet;
@@ -537,6 +536,7 @@
.addIfaceValues(TEST_IFACE, 256L, 2L, 256L, 2L);
expect(mStatsService.getSummaryForNetwork(sTemplateWifi, TIME_FEB_15, TIME_MAR_10))
.andReturn(stats).atLeastOnce();
+ expectPolicyDataEnable(TYPE_WIFI, true);
// TODO: consider making strongly ordered mock
expectRemoveInterfaceQuota(TEST_IFACE);
@@ -580,7 +580,7 @@
NetworkState[] state = null;
NetworkStats stats = null;
Future<Void> future;
- Capture<String> tag;
+ Future<String> tagFuture;
final long TIME_FEB_15 = 1171497600000L;
final long TIME_MAR_10 = 1173484800000L;
@@ -598,6 +598,7 @@
expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce();
expect(mStatsService.getSummaryForNetwork(sTemplateWifi, TIME_FEB_15, currentTimeMillis()))
.andReturn(stats).atLeastOnce();
+ expectPolicyDataEnable(TYPE_WIFI, true);
expectClearNotifications();
future = expectMeteredIfacesChanged();
@@ -620,6 +621,7 @@
expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce();
expect(mStatsService.getSummaryForNetwork(sTemplateWifi, TIME_FEB_15, currentTimeMillis()))
.andReturn(stats).atLeastOnce();
+ expectPolicyDataEnable(TYPE_WIFI, true);
expectRemoveInterfaceQuota(TEST_IFACE);
expectSetInterfaceQuota(TEST_IFACE, 2 * MB_IN_BYTES);
@@ -642,14 +644,15 @@
expectCurrentTime();
expect(mStatsService.getSummaryForNetwork(sTemplateWifi, TIME_FEB_15, currentTimeMillis()))
.andReturn(stats).atLeastOnce();
+ expectPolicyDataEnable(TYPE_WIFI, true);
expectForceUpdate();
expectClearNotifications();
- tag = expectEnqueueNotification();
+ tagFuture = expectEnqueueNotification();
replay();
mNetworkObserver.limitReached(null, TEST_IFACE);
- assertNotificationType(TYPE_WARNING, tag.getValue());
+ assertNotificationType(TYPE_WARNING, tagFuture.get());
verifyAndReset();
}
@@ -662,15 +665,15 @@
expectCurrentTime();
expect(mStatsService.getSummaryForNetwork(sTemplateWifi, TIME_FEB_15, currentTimeMillis()))
.andReturn(stats).atLeastOnce();
- expectPolicyDataEnable(TYPE_WIFI, false).atLeastOnce();
+ expectPolicyDataEnable(TYPE_WIFI, false);
expectForceUpdate();
expectClearNotifications();
- tag = expectEnqueueNotification();
+ tagFuture = expectEnqueueNotification();
replay();
mNetworkObserver.limitReached(null, TEST_IFACE);
- assertNotificationType(TYPE_LIMIT, tag.getValue());
+ assertNotificationType(TYPE_LIMIT, tagFuture.get());
verifyAndReset();
}
@@ -682,21 +685,20 @@
expect(mConnManager.getAllNetworkState()).andReturn(state).atLeastOnce();
expect(mStatsService.getSummaryForNetwork(sTemplateWifi, TIME_FEB_15, currentTimeMillis()))
.andReturn(stats).atLeastOnce();
- expectPolicyDataEnable(TYPE_WIFI, true).atLeastOnce();
+ expectPolicyDataEnable(TYPE_WIFI, true);
// snoozed interface still has high quota so background data is
// still restricted.
expectRemoveInterfaceQuota(TEST_IFACE);
expectSetInterfaceQuota(TEST_IFACE, Long.MAX_VALUE);
+ expectMeteredIfacesChanged(TEST_IFACE);
expectClearNotifications();
- tag = expectEnqueueNotification();
- future = expectMeteredIfacesChanged(TEST_IFACE);
+ tagFuture = expectEnqueueNotification();
replay();
mService.snoozePolicy(sTemplateWifi);
- future.get();
- assertNotificationType(TYPE_LIMIT_SNOOZED, tag.getValue());
+ assertNotificationType(TYPE_LIMIT_SNOOZED, tagFuture.get());
verifyAndReset();
}
}
@@ -737,9 +739,9 @@
expectLastCall().anyTimes();
}
- private Capture<String> expectEnqueueNotification() throws Exception {
- final Capture<String> tag = new Capture<String>();
- mNotifManager.enqueueNotificationWithTag(isA(String.class), capture(tag), anyInt(),
+ private Future<String> expectEnqueueNotification() throws Exception {
+ final FutureCapture<String> tag = new FutureCapture<String>();
+ mNotifManager.enqueueNotificationWithTag(isA(String.class), capture(tag.capture), anyInt(),
isA(Notification.class), isA(int[].class));
return tag;
}
@@ -789,22 +791,25 @@
return future;
}
- private <T> IExpectationSetters<T> expectPolicyDataEnable(int type, boolean enabled)
- throws Exception {
+ private Future<Void> expectPolicyDataEnable(int type, boolean enabled) throws Exception {
+ final FutureAnswer future = new FutureAnswer();
mConnManager.setPolicyDataEnable(type, enabled);
- return expectLastCall();
+ expectLastCall().andAnswer(future);
+ return future;
}
- private static class FutureAnswer extends AbstractFuture<Void> implements IAnswer<Void> {
+ private static class TestAbstractFuture<T> extends AbstractFuture<T> {
@Override
- public Void get() throws InterruptedException, ExecutionException {
+ public T get() throws InterruptedException, ExecutionException {
try {
return get(5, TimeUnit.SECONDS);
} catch (TimeoutException e) {
throw new RuntimeException(e);
}
}
+ }
+ private static class FutureAnswer extends TestAbstractFuture<Void> implements IAnswer<Void> {
@Override
public Void answer() {
set(null);
@@ -812,6 +817,16 @@
}
}
+ private static class FutureCapture<T> extends TestAbstractFuture<T> {
+ public Capture<T> capture = new Capture<T>() {
+ @Override
+ public void setValue(T value) {
+ super.setValue(value);
+ set(value);
+ }
+ };
+ }
+
private static class IdleFuture extends AbstractFuture<Void> implements IdleHandler {
@Override
public Void get() throws InterruptedException, ExecutionException {