diff options
115 files changed, 1146 insertions, 590 deletions
diff --git a/cmds/am/src/com/android/commands/am/Am.java b/cmds/am/src/com/android/commands/am/Am.java index 7c03a2ff2020..140222ee7130 100644 --- a/cmds/am/src/com/android/commands/am/Am.java +++ b/cmds/am/src/com/android/commands/am/Am.java @@ -121,6 +121,10 @@ public class Am { runProfile(); } else if (op.equals("dumpheap")) { runDumpHeap(); + } else if (op.equals("set-debug-app")) { + runSetDebugApp(); + } else if (op.equals("clear-debug-app")) { + runClearDebugApp(); } else if (op.equals("monitor")) { runMonitor(); } else if (op.equals("screen-compat")) { @@ -666,6 +670,31 @@ public class Am { } } + private void runSetDebugApp() throws Exception { + boolean wait = false; + boolean persistent = false; + + String opt; + while ((opt=nextOption()) != null) { + if (opt.equals("-w")) { + wait = true; + } else if (opt.equals("--persistent")) { + persistent = true; + } else { + System.err.println("Error: Unknown option: " + opt); + showUsage(); + return; + } + } + + String pkg = nextArgRequired(); + mAm.setDebugApp(pkg, wait, persistent); + } + + private void runClearDebugApp() throws Exception { + mAm.setDebugApp(null, false, true); + } + class MyActivityController extends IActivityController.Stub { final String mGdbPort; @@ -1199,6 +1228,8 @@ public class Am { " am profile [looper] start <PROCESS> <FILE>\n" + " am profile [looper] stop [<PROCESS>]\n" + " am dumpheap [flags] <PROCESS> <FILE>\n" + + " am set-debug-app [-w] [--persistent] <PACKAGE>\n" + + " am clear-debug-app\n" + " am monitor [--gdb <port>]\n" + " am screen-compat [on|off] <PACKAGE>\n" + " am display-size [reset|MxN]\n" + @@ -1240,6 +1271,12 @@ public class Am { "am dumpheap: dump the heap of a process. Options are:\n" + " -n: dump native heap instead of managed heap\n" + "\n" + + "am set-debug-app: set application <PACKAGE> to debug. Options are:\n" + + " -w: wait for debugger when application starts\n" + + " --persistent: retain this value\n" + + "\n" + + "am clear-debug-app: clear the previously set-debug-app.\n" + + "\n" + "am monitor: start monitoring for crashes or ANRs.\n" + " --gdb: start gdbserv on the given port at crash/ANR\n" + "\n" + diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index f9896f7ab4e5..303f81b4cd50 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -2734,8 +2734,9 @@ public final class ActivityThread { CharSequence description; } - private class ProviderRefCount { + private static final class ProviderRefCount { public int count; + ProviderRefCount(int pCount) { count = pCount; } @@ -3988,16 +3989,14 @@ public final class ActivityThread { 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 @@ public final class ActivityThread { } } - 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,135 +4030,136 @@ public final class ActivityThread { 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) { @@ -4179,8 +4175,23 @@ public final class ActivityThread { } } + /** + * 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 @@ public final class ActivityThread { } 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 3becec0189f9..c2a757f06808 100644 --- a/core/java/android/hardware/Camera.java +++ b/core/java/android/hardware/Camera.java @@ -1111,9 +1111,21 @@ public class Camera { * 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 @@ public class Camera { * 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 821b6df5fd15..83acef83ad1d 100644 --- a/core/java/android/provider/ContactsContract.java +++ b/core/java/android/provider/ContactsContract.java @@ -187,6 +187,16 @@ public final class ContactsContract { 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 7249497120b2..ec2f55bc4819 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -3097,10 +3097,7 @@ public class WebView extends AbsoluteLayout // 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 @@ public class WebView extends AbsoluteLayout 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 @@ public class WebView extends AbsoluteLayout } } + 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 @@ public class WebView extends AbsoluteLayout 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 b106cc520ce0..f422f60cf21a 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -131,7 +131,6 @@ import android.view.inputmethod.ExtractedText; 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener break; case KeyEvent.KEYCODE_DPAD_CENTER: - mDPadCenterIsDown = true; if (event.hasNoModifiers()) { if (shouldAdvanceFocusOnEnter()) { return 0; @@ -5488,7 +5485,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener return super.onKeyUp(keyCode, event); case KeyEvent.KEYCODE_ENTER: - mEnterKeyIsDown = false; if (event.hasNoModifiers()) { if (mInputContentType != null && mInputContentType.onEditorActionListener != null @@ -8972,17 +8967,9 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener } 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener 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 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener 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 2392618c539b..b0f1bc5e680b 100644 --- a/core/res/res/layout/screen_action_bar.xml +++ b/core/res/res/layout/screen_action_bar.xml @@ -19,6 +19,8 @@ This is an optimized layout for a screen with the Action Bar enabled. --> <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 19b861c9d955..2a8c7c381857 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 @@ This is an optimized layout for a screen with 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" - 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" + <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" - 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 87c29f6ebf03..c1914e7964b9 100644 --- a/core/res/res/layout/screen_simple.xml +++ b/core/res/res/layout/screen_simple.xml @@ -22,6 +22,8 @@ enabled. --> <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 eb093e787beb..c790d10c529e 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 @@ enabled. --> <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 4eb47cdf4cfd..c488116dd9e4 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-ar-rEG/donottranslate-cldr.xml b/core/res/res/values-ar-rEG/donottranslate-cldr.xml index 5819afc5227d..57011d7683b2 100644 --- a/core/res/res/values-ar-rEG/donottranslate-cldr.xml +++ b/core/res/res/values-ar-rEG/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s، %3$s %2$s - %6$s، %8$s %7$s، %9$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">EEEE d MMMM</string> + <string name="abbrev_wday_month_day_no_year">EEE d MMMM</string> <string name="abbrev_wday_month_day_year">EEE، d MMMM yyyy</string> </resources> diff --git a/core/res/res/values-ar/donottranslate-cldr.xml b/core/res/res/values-ar/donottranslate-cldr.xml index d662590d911d..0b9da23b765d 100644 --- a/core/res/res/values-ar/donottranslate-cldr.xml +++ b/core/res/res/values-ar/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s، %3$s %2$s - %6$s، %8$s %7$s، %9$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">E d MMMM</string> + <string name="abbrev_wday_month_day_no_year">E d MMMM</string> <string name="abbrev_wday_month_day_year">EEE، d MMMM y</string> </resources> diff --git a/core/res/res/values-bg/donottranslate-cldr.xml b/core/res/res/values-bg/donottranslate-cldr.xml index dc8b3ad2b5ef..972d661af4f7 100644 --- a/core/res/res/values-bg/donottranslate-cldr.xml +++ b/core/res/res/values-bg/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%3$s %2$s %9$s, %1$s - %8$s %7$s y, %6$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">d MMMM, EEEE</string> + <string name="abbrev_wday_month_day_no_year">d MMMM, EEE</string> <string name="abbrev_wday_month_day_year">d MMM yyyy, E</string> </resources> diff --git a/core/res/res/values-ca-rES/donottranslate-cldr.xml b/core/res/res/values-ca-rES/donottranslate-cldr.xml index 52c33d8059f8..113133dc71e4 100644 --- a/core/res/res/values-ca-rES/donottranslate-cldr.xml +++ b/core/res/res/values-ca-rES/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s %3$s de %2$s - %6$s %8$s de %7$s de %9$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">EEEE d MMMM</string> + <string name="abbrev_wday_month_day_no_year">EEE d MMMM</string> <string name="abbrev_wday_month_day_year">EEE d MMM yyyy</string> </resources> diff --git a/core/res/res/values-ca/donottranslate-cldr.xml b/core/res/res/values-ca/donottranslate-cldr.xml index a77aa383d23c..03cf69dcfd56 100644 --- a/core/res/res/values-ca/donottranslate-cldr.xml +++ b/core/res/res/values-ca/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s %3$s de %2$s - %6$s %8$s de %7$s de %9$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">E d MMMM</string> + <string name="abbrev_wday_month_day_no_year">E d MMMM</string> <string name="abbrev_wday_month_day_year">EEE d MMM y</string> </resources> diff --git a/core/res/res/values-cs/donottranslate-cldr.xml b/core/res/res/values-cs/donottranslate-cldr.xml index a0267348c8a0..59b82d33be84 100644 --- a/core/res/res/values-cs/donottranslate-cldr.xml +++ b/core/res/res/values-cs/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s %3$s. %2$s - %6$s %8$s. %7$s %9$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">EEEE, d. MMMM</string> + <string name="abbrev_wday_month_day_no_year">EEE, d. MMMM</string> <string name="abbrev_wday_month_day_year">E d. MMMM yyyy</string> </resources> diff --git a/core/res/res/values-da/donottranslate-cldr.xml b/core/res/res/values-da/donottranslate-cldr.xml index b0783852cb41..1dfc96cff71b 100644 --- a/core/res/res/values-da/donottranslate-cldr.xml +++ b/core/res/res/values-da/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s d. %3$s. %2$s - %6$s d. %8$s. %7$s %9$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">EEEE d. MMMM</string> + <string name="abbrev_wday_month_day_no_year">EEE d. MMMM</string> <string name="abbrev_wday_month_day_year">EEE d. MMM yyyy</string> </resources> diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml index 97ad227d183a..27d0be39fa63 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-de/donottranslate-cldr.xml b/core/res/res/values-de/donottranslate-cldr.xml index 6b4bf5c6fa7c..8b834db65b2e 100644 --- a/core/res/res/values-de/donottranslate-cldr.xml +++ b/core/res/res/values-de/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s. %2$s - %6$s, %8$s. %7$s %9$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">EEEE, d. MMMM</string> + <string name="abbrev_wday_month_day_no_year">EEE, d. MMMM</string> <string name="abbrev_wday_month_day_year">EEE, d. MMM yyyy</string> </resources> diff --git a/core/res/res/values-el/donottranslate-cldr.xml b/core/res/res/values-el/donottranslate-cldr.xml index 75c11b90abf8..1e7caa4154c2 100644 --- a/core/res/res/values-el/donottranslate-cldr.xml +++ b/core/res/res/values-el/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s %2$s - %6$s, %8$s %7$s %9$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">EEEE, d MMMM</string> + <string name="abbrev_wday_month_day_no_year">EEE, d MMMM</string> <string name="abbrev_wday_month_day_year">EEE, d MMM yyyy</string> </resources> diff --git a/core/res/res/values-en-rAU/donottranslate-cldr.xml b/core/res/res/values-en-rAU/donottranslate-cldr.xml index 02c4ece808df..557833ec496f 100644 --- a/core/res/res/values-en-rAU/donottranslate-cldr.xml +++ b/core/res/res/values-en-rAU/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s %2$s - %6$s, %8$s %7$s %9$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">EEEE, d MMMM</string> + <string name="abbrev_wday_month_day_no_year">EEE, d MMMM</string> <string name="abbrev_wday_month_day_year">E, d MMM yyyy</string> </resources> diff --git a/core/res/res/values-en-rCA/donottranslate-cldr.xml b/core/res/res/values-en-rCA/donottranslate-cldr.xml index 446855e8c09b..2aa7cbe58022 100644 --- a/core/res/res/values-en-rCA/donottranslate-cldr.xml +++ b/core/res/res/values-en-rCA/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %2$s %3$s - %6$s, %7$s %8$s, %9$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">EEEE, MMMM d</string> + <string name="abbrev_wday_month_day_no_year">EEE, MMMM d</string> <string name="abbrev_wday_month_day_year">E, MMM d, yyyy</string> </resources> diff --git a/core/res/res/values-en-rGB/donottranslate-cldr.xml b/core/res/res/values-en-rGB/donottranslate-cldr.xml index 0879d0f7b4dd..cce895ed8cd1 100644 --- a/core/res/res/values-en-rGB/donottranslate-cldr.xml +++ b/core/res/res/values-en-rGB/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s %2$s - %6$s, %8$s %7$s %9$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">EEEE, d MMMM</string> + <string name="abbrev_wday_month_day_no_year">EEE, d MMMM</string> <string name="abbrev_wday_month_day_year">E, d MMM yyyy</string> </resources> diff --git a/core/res/res/values-en-rIE/donottranslate-cldr.xml b/core/res/res/values-en-rIE/donottranslate-cldr.xml index b611f7a0a3f1..46b13ec9470b 100644 --- a/core/res/res/values-en-rIE/donottranslate-cldr.xml +++ b/core/res/res/values-en-rIE/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s %3$s %2$s - %6$s %8$s %7$s %9$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">EEEE, d MMMM</string> + <string name="abbrev_wday_month_day_no_year">EEE, d MMMM</string> <string name="abbrev_wday_month_day_year">E d MMM yyyy</string> </resources> diff --git a/core/res/res/values-en-rIN/donottranslate-cldr.xml b/core/res/res/values-en-rIN/donottranslate-cldr.xml index 0a8ae5a3e7cf..177bd7ed0f9b 100644 --- a/core/res/res/values-en-rIN/donottranslate-cldr.xml +++ b/core/res/res/values-en-rIN/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s %3$s %2$s - %6$s %8$s %7$s %9$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">EEEE, d MMMM</string> + <string name="abbrev_wday_month_day_no_year">EEE, d MMMM</string> <string name="abbrev_wday_month_day_year">E d MMM yyyy</string> </resources> diff --git a/core/res/res/values-en-rNZ/donottranslate-cldr.xml b/core/res/res/values-en-rNZ/donottranslate-cldr.xml index 329b2682ae7c..41a00a5cd73d 100644 --- a/core/res/res/values-en-rNZ/donottranslate-cldr.xml +++ b/core/res/res/values-en-rNZ/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s %2$s - %6$s, %8$s %7$s %9$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">EEEE, d MMMM</string> + <string name="abbrev_wday_month_day_no_year">EEE, d MMMM</string> <string name="abbrev_wday_month_day_year">E, d MMM yyyy</string> </resources> diff --git a/core/res/res/values-en-rUS/donottranslate-cldr.xml b/core/res/res/values-en-rUS/donottranslate-cldr.xml index a94fb58dea33..15fcd8be989c 100644 --- a/core/res/res/values-en-rUS/donottranslate-cldr.xml +++ b/core/res/res/values-en-rUS/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %2$s %3$s – %6$s, %7$s %8$s, %9$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">EEEE, MMMM d</string> + <string name="abbrev_wday_month_day_no_year">EEE, MMMM d</string> <string name="abbrev_wday_month_day_year">EEE, MMM d, yyyy</string> </resources> diff --git a/core/res/res/values-en-rZA/donottranslate-cldr.xml b/core/res/res/values-en-rZA/donottranslate-cldr.xml index 753861175d80..7a5bdbd2a812 100644 --- a/core/res/res/values-en-rZA/donottranslate-cldr.xml +++ b/core/res/res/values-en-rZA/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s %3$s %2$s - %6$s %8$s %7$s %9$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">EEEE, d MMMM</string> + <string name="abbrev_wday_month_day_no_year">EEE, d MMMM</string> <string name="abbrev_wday_month_day_year">E dd MMM yyyy</string> </resources> diff --git a/core/res/res/values-es-rUS/donottranslate-cldr.xml b/core/res/res/values-es-rUS/donottranslate-cldr.xml index 1a59c4bc14f6..e2c3254d90a2 100644 --- a/core/res/res/values-es-rUS/donottranslate-cldr.xml +++ b/core/res/res/values-es-rUS/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s %3$s de %2$s al %6$s %8$s de %7$s de %9$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">EEEE d \'de\' MMMM</string> + <string name="abbrev_wday_month_day_no_year">EEE d \'de\' MMMM</string> <string name="abbrev_wday_month_day_year">E d \'de\' MMM \'de\' yyyy</string> </resources> diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml index a5caabfcbd4e..aa3849320c5e 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-es/donottranslate-cldr.xml b/core/res/res/values-es/donottranslate-cldr.xml index 206b56d99d5f..faf171ab3490 100644 --- a/core/res/res/values-es/donottranslate-cldr.xml +++ b/core/res/res/values-es/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s %3$s de %2$s – %6$s %8$s de %7$s de %9$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">EEEE d \'de\' MMMM</string> + <string name="abbrev_wday_month_day_no_year">EEE d \'de\' MMMM</string> <string name="abbrev_wday_month_day_year">EEE d \'de\' MMM \'de\' yyyy</string> </resources> diff --git a/core/res/res/values-fa/donottranslate-cldr.xml b/core/res/res/values-fa/donottranslate-cldr.xml index 83f49423d74b..11473fe98c7e 100644 --- a/core/res/res/values-fa/donottranslate-cldr.xml +++ b/core/res/res/values-fa/donottranslate-cldr.xml @@ -131,5 +131,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s %3$s LLL تا %6$s %8$s %2$s %9$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">E d LLLL</string> + <string name="abbrev_wday_month_day_no_year">E d LLLL</string> <string name="abbrev_wday_month_day_year">E d MMM y</string> </resources> diff --git a/core/res/res/values-fi-rFI/donottranslate-cldr.xml b/core/res/res/values-fi-rFI/donottranslate-cldr.xml index ddcc0ea80261..e9e1a25d227f 100644 --- a/core/res/res/values-fi-rFI/donottranslate-cldr.xml +++ b/core/res/res/values-fi-rFI/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s %3$s. %2$s – %6$s %8$s. %7$s %9$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">EEEE d. MMMM</string> + <string name="abbrev_wday_month_day_no_year">EEE d. MMMM</string> <string name="abbrev_wday_month_day_year">EEE d. MMM yyyy</string> </resources> diff --git a/core/res/res/values-fi/donottranslate-cldr.xml b/core/res/res/values-fi/donottranslate-cldr.xml index 5146a0aa2626..71cccf39b732 100644 --- a/core/res/res/values-fi/donottranslate-cldr.xml +++ b/core/res/res/values-fi/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s %3$s. %2$s – %6$s %8$s. %7$s %9$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">E d. MMMM</string> + <string name="abbrev_wday_month_day_no_year">E d. MMMM</string> <string name="abbrev_wday_month_day_year">EEE d. MMM y</string> </resources> diff --git a/core/res/res/values-fr/donottranslate-cldr.xml b/core/res/res/values-fr/donottranslate-cldr.xml index 86b8d19eec41..840f728aff81 100644 --- a/core/res/res/values-fr/donottranslate-cldr.xml +++ b/core/res/res/values-fr/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">du %1$s %3$s %2$s au %6$s %8$s %7$s %9$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">EEE d MMMM</string> + <string name="abbrev_wday_month_day_no_year">EEE d MMMM</string> <string name="abbrev_wday_month_day_year">EEE d MMM yyyy</string> </resources> diff --git a/core/res/res/values-hi-rIN/donottranslate-cldr.xml b/core/res/res/values-hi-rIN/donottranslate-cldr.xml index 00cb965e5008..6bfd3de2d704 100644 --- a/core/res/res/values-hi-rIN/donottranslate-cldr.xml +++ b/core/res/res/values-hi-rIN/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %9$s-%2$s-%3$s – %6$s, yyyy-%7$s-%8$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">EEEE, d MMMM</string> + <string name="abbrev_wday_month_day_no_year">EEE, d MMMM</string> <string name="abbrev_wday_month_day_year">EEE, d MMM yyyy</string> </resources> diff --git a/core/res/res/values-hr-rHR/donottranslate-cldr.xml b/core/res/res/values-hr-rHR/donottranslate-cldr.xml index dfcded5676fd..a601d938f69c 100644 --- a/core/res/res/values-hr-rHR/donottranslate-cldr.xml +++ b/core/res/res/values-hr-rHR/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s.%2$s. - %6$s, %8$s.%7$s.%9$s.</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">EEEE, d. MMMM</string> + <string name="abbrev_wday_month_day_no_year">EEE, d. MMMM</string> <string name="abbrev_wday_month_day_year">EEE, d.MMM.yyyy.</string> </resources> diff --git a/core/res/res/values-hr/donottranslate-cldr.xml b/core/res/res/values-hr/donottranslate-cldr.xml index 23332aa3441e..9b5186284570 100644 --- a/core/res/res/values-hr/donottranslate-cldr.xml +++ b/core/res/res/values-hr/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s.%2$s. - %6$s, %8$s.%7$s.%9$s.</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">E, d. MMMM</string> + <string name="abbrev_wday_month_day_no_year">E, d. MMMM</string> <string name="abbrev_wday_month_day_year">EEE, d.MMM.y.</string> </resources> diff --git a/core/res/res/values-hu-rHU/donottranslate-cldr.xml b/core/res/res/values-hu-rHU/donottranslate-cldr.xml index 553667b3c3ad..afb767625d93 100644 --- a/core/res/res/values-hu-rHU/donottranslate-cldr.xml +++ b/core/res/res/values-hu-rHU/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%9$s. %2$s %3$s., %1$s - %7$s %8$s., %6$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">EEEE MMMM d</string> + <string name="abbrev_wday_month_day_no_year">EEE MMMM d</string> <string name="abbrev_wday_month_day_year">yyyy. MMM d., E</string> </resources> diff --git a/core/res/res/values-hu/donottranslate-cldr.xml b/core/res/res/values-hu/donottranslate-cldr.xml index 996eefbce4cd..28b65bcf4dd1 100644 --- a/core/res/res/values-hu/donottranslate-cldr.xml +++ b/core/res/res/values-hu/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%9$s. %2$s %3$s., %1$s - %7$s %8$s., %6$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">E MMMM d</string> + <string name="abbrev_wday_month_day_no_year">E MMMM d</string> <string name="abbrev_wday_month_day_year">y. MMM d., E</string> </resources> diff --git a/core/res/res/values-in-rID/donottranslate-cldr.xml b/core/res/res/values-in-rID/donottranslate-cldr.xml index 4d4ebb226652..b79fe00bdcb3 100644 --- a/core/res/res/values-in-rID/donottranslate-cldr.xml +++ b/core/res/res/values-in-rID/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s %2$s - %6$s, %8$s %7$s %9$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">EEEE MMMM d</string> + <string name="abbrev_wday_month_day_no_year">EEE MMMM d</string> <string name="abbrev_wday_month_day_year">E, d MMM yyyy</string> </resources> diff --git a/core/res/res/values-in/donottranslate-cldr.xml b/core/res/res/values-in/donottranslate-cldr.xml index 7a58a198c46f..9a634cc72e64 100644 --- a/core/res/res/values-in/donottranslate-cldr.xml +++ b/core/res/res/values-in/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %9$s-%2$s-%3$s – %6$s, yyyy-%7$s-%8$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">E MMMM d</string> + <string name="abbrev_wday_month_day_no_year">E MMMM d</string> <string name="abbrev_wday_month_day_year">EEE, y MMM d</string> </resources> diff --git a/core/res/res/values-it/donottranslate-cldr.xml b/core/res/res/values-it/donottranslate-cldr.xml index 8af25f2791bd..8cee828f2faf 100644 --- a/core/res/res/values-it/donottranslate-cldr.xml +++ b/core/res/res/values-it/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s %3$s %2$s - %6$s %8$s %7$s %9$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">EEE d MMMM</string> + <string name="abbrev_wday_month_day_no_year">EEE d MMMM</string> <string name="abbrev_wday_month_day_year">EEE d MMM yyyy</string> </resources> diff --git a/core/res/res/values-iw/donottranslate-cldr.xml b/core/res/res/values-iw/donottranslate-cldr.xml index d373a3430b20..02d1e9c2382e 100644 --- a/core/res/res/values-iw/donottranslate-cldr.xml +++ b/core/res/res/values-iw/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s %3$s %2$s - %6$s %8$s %7$s %9$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">E MMMM d</string> + <string name="abbrev_wday_month_day_no_year">E MMMM d</string> <string name="abbrev_wday_month_day_year">EEE, y MMM d</string> </resources> diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml index 250415c0466f..fd248e570c78 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-ja/donottranslate-cldr.xml b/core/res/res/values-ja/donottranslate-cldr.xml index 7447abcd412f..450adc3309c1 100644 --- a/core/res/res/values-ja/donottranslate-cldr.xml +++ b/core/res/res/values-ja/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%9$s年%2$s%3$s日 (%1$s)~%7$s%8$s日 (%6$s)</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">M月d日 (E)</string> + <string name="abbrev_wday_month_day_no_year">M月d日 (E)</string> <string name="abbrev_wday_month_day_year">yyyy年M月d日 (E)</string> </resources> diff --git a/core/res/res/values-ko/donottranslate-cldr.xml b/core/res/res/values-ko/donottranslate-cldr.xml index cdbd65e62971..5382871c1406 100644 --- a/core/res/res/values-ko/donottranslate-cldr.xml +++ b/core/res/res/values-ko/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%9$s년 %2$s %3$s일 %1$s ~ %7$s %8$s일 %6$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">MMMM d일 EEEE</string> + <string name="abbrev_wday_month_day_no_year">MMMM d일 EEE</string> <string name="abbrev_wday_month_day_year">yyyy년 MMM d일 EEE</string> </resources> diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml index 6aac5206809b..ee098d5771f4 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-lt-rLT/donottranslate-cldr.xml b/core/res/res/values-lt-rLT/donottranslate-cldr.xml index 982f993a6765..0c1d0aa1a252 100644 --- a/core/res/res/values-lt-rLT/donottranslate-cldr.xml +++ b/core/res/res/values-lt-rLT/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%9$s m. %2$s %3$s d., %1$s-%7$s %8$s d., %6$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">MMMM d \'d\'., EEEE</string> + <string name="abbrev_wday_month_day_no_year">MMMM d \'d\'., EEE</string> <string name="abbrev_wday_month_day_year">yyyy \'m\'. MMM d \'d\'., E</string> </resources> diff --git a/core/res/res/values-lt/donottranslate-cldr.xml b/core/res/res/values-lt/donottranslate-cldr.xml index 25458bdee026..8a2c0f4862eb 100644 --- a/core/res/res/values-lt/donottranslate-cldr.xml +++ b/core/res/res/values-lt/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%9$s m. %2$s %3$s d.,%1$s - %7$s %8$s d.,%6$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">E MMMM d</string> + <string name="abbrev_wday_month_day_no_year">E MMMM d</string> <string name="abbrev_wday_month_day_year">y \'m\'. MMM d \'d\'.,E</string> </resources> diff --git a/core/res/res/values-lv-rLV/donottranslate-cldr.xml b/core/res/res/values-lv-rLV/donottranslate-cldr.xml index c4000b04344d..9dbc5e052be0 100644 --- a/core/res/res/values-lv-rLV/donottranslate-cldr.xml +++ b/core/res/res/values-lv-rLV/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %9$s. gada %3$s. %2$s-%6$s, y. gada %8$s. %7$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">EEEE, d. MMMM</string> + <string name="abbrev_wday_month_day_no_year">EEE, d. MMMM</string> <string name="abbrev_wday_month_day_year">EEE, yyyy. \'g\'. dd. MMM</string> </resources> diff --git a/core/res/res/values-lv/donottranslate-cldr.xml b/core/res/res/values-lv/donottranslate-cldr.xml index 2de93676d07c..10dcd35752ab 100644 --- a/core/res/res/values-lv/donottranslate-cldr.xml +++ b/core/res/res/values-lv/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %9$s. gada %3$s. %2$s - %6$s, y. gada %8$s. %7$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">E, d. MMMM</string> + <string name="abbrev_wday_month_day_no_year">E, d. MMMM</string> <string name="abbrev_wday_month_day_year">EEE, yyyy. \'g\'. dd. MMM</string> </resources> diff --git a/core/res/res/values-nb/donottranslate-cldr.xml b/core/res/res/values-nb/donottranslate-cldr.xml index 512eb0146ff5..637dd5e78602 100644 --- a/core/res/res/values-nb/donottranslate-cldr.xml +++ b/core/res/res/values-nb/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s %3$s. %2$s–%6$s %8$s. %7$s %9$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">EEEE d. MMMM</string> + <string name="abbrev_wday_month_day_no_year">EEE d. MMMM</string> <string name="abbrev_wday_month_day_year">EEE d. MMM yyyy</string> </resources> diff --git a/core/res/res/values-nl/donottranslate-cldr.xml b/core/res/res/values-nl/donottranslate-cldr.xml index 3db9e6937e5b..ca3813ffd91f 100644 --- a/core/res/res/values-nl/donottranslate-cldr.xml +++ b/core/res/res/values-nl/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s %3$s %2$s - %6$s %8$s %7$s %9$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">EEEE d MMMM</string> + <string name="abbrev_wday_month_day_no_year">EEE d MMMM</string> <string name="abbrev_wday_month_day_year">EEE d MMM yyyy</string> </resources> diff --git a/core/res/res/values-pl/donottranslate-cldr.xml b/core/res/res/values-pl/donottranslate-cldr.xml index baff79815955..2950e60b62f6 100644 --- a/core/res/res/values-pl/donottranslate-cldr.xml +++ b/core/res/res/values-pl/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s %2$s-%6$s, %8$s %7$s %9$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">EEEE, d MMMM</string> + <string name="abbrev_wday_month_day_no_year">EEE, d MMMM</string> <string name="abbrev_wday_month_day_year">EEE, d MMM yyyy</string> </resources> diff --git a/core/res/res/values-pt-rPT/donottranslate-cldr.xml b/core/res/res/values-pt-rPT/donottranslate-cldr.xml index 25dc7b3e660b..54417a4f0749 100644 --- a/core/res/res/values-pt-rPT/donottranslate-cldr.xml +++ b/core/res/res/values-pt-rPT/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s de %2$s - %6$s, %8$s de %7$s de %9$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">EEE, d \'de\' MMMM</string> + <string name="abbrev_wday_month_day_no_year">EEE, d \'de\' MMMM</string> <string name="abbrev_wday_month_day_year">EEE, d \'de\' MMM \'de\' yyyy</string> </resources> diff --git a/core/res/res/values-pt/donottranslate-cldr.xml b/core/res/res/values-pt/donottranslate-cldr.xml index 4431877a17e1..d999c06db1ee 100644 --- a/core/res/res/values-pt/donottranslate-cldr.xml +++ b/core/res/res/values-pt/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s de %2$s - %6$s, %8$s de %7$s de %9$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">EEE, d \'de\' MMMM</string> + <string name="abbrev_wday_month_day_no_year">EEE, d \'de\' MMMM</string> <string name="abbrev_wday_month_day_year">EEE, d \'de\' MMM \'de\' yyyy</string> </resources> diff --git a/core/res/res/values-ro-rRO/donottranslate-cldr.xml b/core/res/res/values-ro-rRO/donottranslate-cldr.xml index 3e425f0f7984..732ae24f88e3 100644 --- a/core/res/res/values-ro-rRO/donottranslate-cldr.xml +++ b/core/res/res/values-ro-rRO/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s %2$s - %6$s, %8$s %7$s %9$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">EEEE, d MMMM</string> + <string name="abbrev_wday_month_day_no_year">EEE, d MMMM</string> <string name="abbrev_wday_month_day_year">EEE, d MMM yyyy</string> </resources> diff --git a/core/res/res/values-ro/donottranslate-cldr.xml b/core/res/res/values-ro/donottranslate-cldr.xml index ef341031d85a..e9a70dc28459 100644 --- a/core/res/res/values-ro/donottranslate-cldr.xml +++ b/core/res/res/values-ro/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s %2$s - %6$s, %8$s %7$s %9$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">E, d MMMM</string> + <string name="abbrev_wday_month_day_no_year">E, d MMMM</string> <string name="abbrev_wday_month_day_year">EEE, d MMM y</string> </resources> diff --git a/core/res/res/values-ru/donottranslate-cldr.xml b/core/res/res/values-ru/donottranslate-cldr.xml index 83994245a128..2fbcd4349e34 100644 --- a/core/res/res/values-ru/donottranslate-cldr.xml +++ b/core/res/res/values-ru/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%3$s %2$s - %8$s %7$s %9$s г.</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">EEEE, d MMMM</string> + <string name="abbrev_wday_month_day_no_year">EEE, d MMMM</string> <string name="abbrev_wday_month_day_year">E, d MMM yyyy</string> </resources> diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml index d66c2d446323..44f4d10e98f6 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-sk-rSK/donottranslate-cldr.xml b/core/res/res/values-sk-rSK/donottranslate-cldr.xml index 32272eab0e69..2843ae3334a3 100644 --- a/core/res/res/values-sk-rSK/donottranslate-cldr.xml +++ b/core/res/res/values-sk-rSK/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s %3$s. %2$s - %6$s %8$s. %7$s %9$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">EEEE d. MMMM</string> + <string name="abbrev_wday_month_day_no_year">EEE d. MMMM</string> <string name="abbrev_wday_month_day_year">EEE d. MMM yyyy</string> </resources> diff --git a/core/res/res/values-sk/donottranslate-cldr.xml b/core/res/res/values-sk/donottranslate-cldr.xml index b2ed9b778abc..dcdaad16a24f 100644 --- a/core/res/res/values-sk/donottranslate-cldr.xml +++ b/core/res/res/values-sk/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s. %2$s - %6$s, %8$s. %7$s %9$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">E, d. MMMM</string> + <string name="abbrev_wday_month_day_no_year">E, d. MMMM</string> <string name="abbrev_wday_month_day_year">EEE, d. MMM y</string> </resources> diff --git a/core/res/res/values-sl-rSI/donottranslate-cldr.xml b/core/res/res/values-sl-rSI/donottranslate-cldr.xml index e4bc557d3006..cbabccd0f353 100644 --- a/core/res/res/values-sl-rSI/donottranslate-cldr.xml +++ b/core/res/res/values-sl-rSI/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s. %2$s–%6$s, %8$s. %7$s %9$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">EEEE MMMM d</string> + <string name="abbrev_wday_month_day_no_year">EEE MMMM d</string> <string name="abbrev_wday_month_day_year">E, d. MMM yyyy</string> </resources> diff --git a/core/res/res/values-sl/donottranslate-cldr.xml b/core/res/res/values-sl/donottranslate-cldr.xml index 372b0d585607..b804b3fd1fbd 100644 --- a/core/res/res/values-sl/donottranslate-cldr.xml +++ b/core/res/res/values-sl/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s., %3$s. %2$s. – %6$s., %8$s. %7$s. %9$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">E MMMM d</string> + <string name="abbrev_wday_month_day_no_year">E MMMM d</string> <string name="abbrev_wday_month_day_year">E., d. MMM. y</string> </resources> diff --git a/core/res/res/values-sr-rRS/donottranslate-cldr.xml b/core/res/res/values-sr-rRS/donottranslate-cldr.xml index 79752ab60566..7168bccfabba 100644 --- a/core/res/res/values-sr-rRS/donottranslate-cldr.xml +++ b/core/res/res/values-sr-rRS/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s. %2$s - %6$s, %8$s. %7$s %9$s.</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">EEEE MMMM d</string> + <string name="abbrev_wday_month_day_no_year">EEE MMMM d</string> <string name="abbrev_wday_month_day_year">EEE, d. MMM yyyy.</string> </resources> diff --git a/core/res/res/values-sr/donottranslate-cldr.xml b/core/res/res/values-sr/donottranslate-cldr.xml index 7c5c6a971061..7426bdcf1e56 100644 --- a/core/res/res/values-sr/donottranslate-cldr.xml +++ b/core/res/res/values-sr/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s. %2$s - %6$s, %8$s. %7$s %9$s.</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">E MMMM d</string> + <string name="abbrev_wday_month_day_no_year">E MMMM d</string> <string name="abbrev_wday_month_day_year">EEE, d. MMM y.</string> </resources> diff --git a/core/res/res/values-sv/donottranslate-cldr.xml b/core/res/res/values-sv/donottranslate-cldr.xml index bf688ce2bc7f..8b7833fba022 100644 --- a/core/res/res/values-sv/donottranslate-cldr.xml +++ b/core/res/res/values-sv/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s %3$s %2$s – %6$s %8$s %7$s %9$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">EEEE d MMMM</string> + <string name="abbrev_wday_month_day_no_year">EEE d MMMM</string> <string name="abbrev_wday_month_day_year">EEE d MMM yyyy</string> </resources> diff --git a/core/res/res/values-th-rTH/donottranslate-cldr.xml b/core/res/res/values-th-rTH/donottranslate-cldr.xml index 85dc3b930500..7049c5291670 100644 --- a/core/res/res/values-th-rTH/donottranslate-cldr.xml +++ b/core/res/res/values-th-rTH/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s %3$s %2$s – %6$s %8$s %7$s %9$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">EEEE d MMMM</string> + <string name="abbrev_wday_month_day_no_year">EEE d MMMM</string> <string name="abbrev_wday_month_day_year">EEE d MMM yyyy</string> </resources> diff --git a/core/res/res/values-th/donottranslate-cldr.xml b/core/res/res/values-th/donottranslate-cldr.xml index 4e6bafe30fc7..f3196d1277da 100644 --- a/core/res/res/values-th/donottranslate-cldr.xml +++ b/core/res/res/values-th/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s %3$s %2$s – %6$s %8$s %7$s %9$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">E d MMMM</string> + <string name="abbrev_wday_month_day_no_year">E d MMMM</string> <string name="abbrev_wday_month_day_year">EEE d MMM y</string> </resources> diff --git a/core/res/res/values-tl/donottranslate-cldr.xml b/core/res/res/values-tl/donottranslate-cldr.xml index e3106c78ba66..6ff92e3d9e9f 100644 --- a/core/res/res/values-tl/donottranslate-cldr.xml +++ b/core/res/res/values-tl/donottranslate-cldr.xml @@ -119,5 +119,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %9$s-%2$s-%3$s – %6$s, yyyy-%7$s-%8$s</string> <string name="short_format_month">%B</string> <string name="full_wday_month_day_no_year">E MMMM d</string> + <string name="abbrev_wday_month_day_no_year">E MMMM d</string> <string name="abbrev_wday_month_day_year">EEE, y MMM d</string> </resources> diff --git a/core/res/res/values-tr/donottranslate-cldr.xml b/core/res/res/values-tr/donottranslate-cldr.xml index 55b6d1f34378..92b0c72753f5 100644 --- a/core/res/res/values-tr/donottranslate-cldr.xml +++ b/core/res/res/values-tr/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%3$s %2$s %1$s - %8$s %7$s %6$s %9$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">dd MMMM EEEE</string> + <string name="abbrev_wday_month_day_no_year">dd MMMM EEE</string> <string name="abbrev_wday_month_day_year">dd MMM yyyy EEE</string> </resources> diff --git a/core/res/res/values-uk-rUA/donottranslate-cldr.xml b/core/res/res/values-uk-rUA/donottranslate-cldr.xml index 332f8456955c..caf46a389bc8 100644 --- a/core/res/res/values-uk-rUA/donottranslate-cldr.xml +++ b/core/res/res/values-uk-rUA/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s %2$s – %6$s, %8$s %7$s %9$s р.</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">EEEE, d MMMM</string> + <string name="abbrev_wday_month_day_no_year">EEE, d MMMM</string> <string name="abbrev_wday_month_day_year">EEE, d MMM yyyy \'р\'.</string> </resources> diff --git a/core/res/res/values-uk/donottranslate-cldr.xml b/core/res/res/values-uk/donottranslate-cldr.xml index 0a49c20ad120..46211ac2ea95 100644 --- a/core/res/res/values-uk/donottranslate-cldr.xml +++ b/core/res/res/values-uk/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %3$s %2$s – %6$s, %8$s %7$s %9$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">E, d MMMM</string> + <string name="abbrev_wday_month_day_no_year">E, d MMMM</string> <string name="abbrev_wday_month_day_year">EEE, d MMM y</string> </resources> diff --git a/core/res/res/values-vi-rVN/donottranslate-cldr.xml b/core/res/res/values-vi-rVN/donottranslate-cldr.xml index b7edeb3682ba..5d049a1b72fd 100644 --- a/core/res/res/values-vi-rVN/donottranslate-cldr.xml +++ b/core/res/res/values-vi-rVN/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, ngày %3$s %2$s - %6$s, ngày %8$s %7$s năm %9$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">EEEE d MMMM</string> + <string name="abbrev_wday_month_day_no_year">EEE d MMMM</string> <string name="abbrev_wday_month_day_year">EEE, d MMM yyyy</string> </resources> diff --git a/core/res/res/values-vi/donottranslate-cldr.xml b/core/res/res/values-vi/donottranslate-cldr.xml index 30e088717c07..9a757cd5d4dc 100644 --- a/core/res/res/values-vi/donottranslate-cldr.xml +++ b/core/res/res/values-vi/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, ngày %3$s %2$s - %6$s, ngày %8$s %7$s năm %9$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">E d MMMM</string> + <string name="abbrev_wday_month_day_no_year">E d MMMM</string> <string name="abbrev_wday_month_day_year">EEE, d MMM y</string> </resources> diff --git a/core/res/res/values-zh-rCN/donottranslate-cldr.xml b/core/res/res/values-zh-rCN/donottranslate-cldr.xml index ec9d8c02a42a..9e6ef1c3fb39 100644 --- a/core/res/res/values-zh-rCN/donottranslate-cldr.xml +++ b/core/res/res/values-zh-rCN/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%9$s 年 %2$s %3$s 日%1$s - %7$s %8$s 日%6$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">M 月 d 日 E</string> + <string name="abbrev_wday_month_day_no_year">M 月 d 日 E</string> <string name="abbrev_wday_month_day_year">yyyy 年 M 月 d 日 EEE</string> </resources> diff --git a/core/res/res/values-zh-rTW/donottranslate-cldr.xml b/core/res/res/values-zh-rTW/donottranslate-cldr.xml index a43f8572850b..907d82e03a45 100644 --- a/core/res/res/values-zh-rTW/donottranslate-cldr.xml +++ b/core/res/res/values-zh-rTW/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%9$s 年 %2$s %3$s 日%1$s至 %7$s %8$s 日%6$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">M 月 d 日E</string> + <string name="abbrev_wday_month_day_no_year">M 月 d 日E</string> <string name="abbrev_wday_month_day_year">yyyy 年 M 月 d 日EEE</string> </resources> diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml index e88de76c6234..05da503e84df 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/res/res/values/donottranslate-cldr.xml b/core/res/res/values/donottranslate-cldr.xml index a94fb58dea33..15fcd8be989c 100644 --- a/core/res/res/values/donottranslate-cldr.xml +++ b/core/res/res/values/donottranslate-cldr.xml @@ -145,5 +145,6 @@ <string name="same_year_wday1_mdy1_wday2_mdy2">%1$s, %2$s %3$s – %6$s, %7$s %8$s, %9$s</string> <string name="short_format_month">%b</string> <string name="full_wday_month_day_no_year">EEEE, MMMM d</string> + <string name="abbrev_wday_month_day_no_year">EEE, MMMM d</string> <string name="abbrev_wday_month_day_year">EEE, MMM d, yyyy</string> </resources> diff --git a/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java b/core/tests/bandwidthtests/src/com/android/bandwidthtest/BandwidthTest.java index 01a5fd0bdff0..a781472a9af7 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 @@ public class BandwidthTest extends InstrumentationTestCase { } 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 e1db073c0713..1df763a48540 100644 --- a/core/tests/coretests/src/android/net/NetworkStatsHistoryTest.java +++ b/core/tests/coretests/src/android/net/NetworkStatsHistoryTest.java @@ -256,6 +256,10 @@ public class NetworkStatsHistoryTest extends AndroidTestCase { 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 eab764807f77..250f26773726 100644 --- a/include/media/MediaProfiles.h +++ b/include/media/MediaProfiles.h @@ -48,15 +48,21 @@ enum camcorder_quality { }; /** - *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 @@ public: * 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 @@ private: }; 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 @@ private: int mMaxInputFrameHeight; int mMaxOutputFrameWidth; int mMaxOutputFrameHeight; + int mMaxPrefetchYUVFrames; }; int getCamcorderProfileIndex(int cameraId, camcorder_quality quality) const; diff --git a/libs/gui/Android.mk b/libs/gui/Android.mk index ed319f5e9381..9767568bed35 100644 --- a/libs/gui/Android.mk +++ b/libs/gui/Android.mk @@ -32,6 +32,10 @@ LOCAL_SHARED_LIBRARIES := \ LOCAL_MODULE:= libgui +ifeq ($(TARGET_BOARD_PLATFORM), tegra) + LOCAL_CFLAGS += -DALLOW_DEQUEUE_CURRENT_BUFFER +endif + include $(BUILD_SHARED_LIBRARY) ifeq (,$(ONE_SHOT_MAKEFILE)) diff --git a/libs/gui/SurfaceTexture.cpp b/libs/gui/SurfaceTexture.cpp index 6f842067caf7..374f3c524019 100644 --- a/libs/gui/SurfaceTexture.cpp +++ b/libs/gui/SurfaceTexture.cpp @@ -36,8 +36,12 @@ #include <utils/Log.h> #include <utils/String8.h> - -#define ALLOW_DEQUEUE_CURRENT_BUFFER false +#ifdef ALLOW_DEQUEUE_CURRENT_BUFFER +#define FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER true +#warning "ALLOW_DEQUEUE_CURRENT_BUFFER enabled" +#else +#define FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER false +#endif // Macros for including the SurfaceTexture name in log messages #define ST_LOGV(x, ...) LOGV("[%s] "x, mName.string(), ##__VA_ARGS__) @@ -323,7 +327,7 @@ status_t SurfaceTexture::dequeueBuffer(int *outBuf, uint32_t w, uint32_t h, LOGW_IF((state == BufferSlot::FREE) && (mCurrentTexture==i), "dequeueBuffer: buffer %d is both FREE and current!", i); - if (ALLOW_DEQUEUE_CURRENT_BUFFER) { + if (FLAG_ALLOW_DEQUEUE_CURRENT_BUFFER) { if (state == BufferSlot::FREE || i == mCurrentTexture) { foundSync = i; if (i != mCurrentTexture) { diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java index a8daab0f116a..a2b80c25c439 100644 --- a/media/java/android/media/AudioService.java +++ b/media/java/android/media/AudioService.java @@ -3062,6 +3062,7 @@ public class AudioService extends IAudioService.Stub { 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 @@ public class AudioService extends IAudioService.Stub { } } } + + @Override + protected void finalize() throws Throwable { + unlinkToRcClientDeath();// unlink exception handled inside method + super.finalize(); + } } /** @@ -3115,6 +3122,7 @@ public class AudioService extends IAudioService.Stub { 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 @@ public class AudioService extends IAudioService.Stub { RemoteControlStackEntry rcse = (RemoteControlStackEntry)stackIterator.next(); if(rcse.mMediaIntent.equals(pi)) { stackIterator.remove(); + rcse.unlinkToRcClientDeath(); break; } } @@ -3456,7 +3465,7 @@ public class AudioService extends IAudioService.Stub { rcse.mCallingPackageName = callingPackageName; rcse.mCallingUid = Binder.getCallingUid(); if (rcClient == null) { - rcse.mRcClientDeathHandler = null; + // here rcse.mRcClientDeathHandler is null; break; } @@ -3512,7 +3521,6 @@ public class AudioService extends IAudioService.Stub { 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 ad55ff86441b..6096b721ea6e 100644 --- a/media/libmedia/MediaProfiles.cpp +++ b/media/libmedia/MediaProfiles.cpp @@ -404,11 +404,12 @@ MediaProfiles::createVideoEditorCap(const char **atts, MediaProfiles *profiles) 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 @@ MediaProfiles::createDefaultVideoEditorCap(MediaProfiles *profiles) 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 @@ int MediaProfiles::getVideoEditorCapParamByName(const char *name) const 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 62213de5dbed..9c87c2244477 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 @@ public final class NfcAdapterExtras { // 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 @@ public final class NfcAdapterExtras { 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 @@ public final class NfcAdapterExtras { */ 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 000000000000..3eca76d40504 --- /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 000000000000..0cc665343116 --- /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 000000000000..e1025aa2e9b8 --- /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/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml b/packages/SystemUI/res/layout-land/status_bar_recent_panel.xml index 3ee9e77e23a4..180f0228b5d3 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 d040544e63f0..e6a077a5e20a 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 000000000000..bc89281190de --- /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 18a31f7dc136..cb26db00a54b 100644 --- a/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml +++ b/packages/SystemUI/res/layout-sw600dp/status_bar_recent_item.xml @@ -23,11 +23,26 @@ android:layout_height="wrap_content" android:layout_width="wrap_content"> - <FrameLayout android:id="@+id/app_thumbnail" - android:layout_width="wrap_content" + <TextView android:id="@+id/app_label" + android:layout_width="@dimen/status_bar_recents_app_label_width" android:layout_height="wrap_content" + android:textSize="@dimen/status_bar_recents_app_label_text_size" + android:fadingEdge="horizontal" + android:fadingEdgeLength="@dimen/status_bar_recents_fading_edge_length" + android:scrollHorizontally="true" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" + android:layout_marginLeft="@dimen/status_bar_recents_app_label_left_margin" + android:layout_marginTop="32dip" + android:singleLine="true" + android:ellipsize="marquee" + 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" @@ -37,33 +52,22 @@ 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" + + <ImageView android:id="@+id/app_icon" + android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textSize="@dimen/status_bar_recents_app_label_text_size" - android:fadingEdge="horizontal" - android:fadingEdgeLength="@dimen/status_bar_recents_fading_edge_length" - android:scrollHorizontally="true" - android:layout_alignParentLeft="true" - android:layout_alignParentTop="true" - android:layout_marginLeft="@dimen/status_bar_recents_app_label_left_margin" - android:layout_marginTop="32dip" - android:singleLine="true" - android:ellipsize="marquee" - android:textColor="@color/status_bar_recents_app_label_color" + 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 5dd101e286a1..111f9a42de1c 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 af2c93c19f5a..b1aaade7c914 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 3e2ec5957812..24185a4f1844 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 fe9245dda1fc..f522285a18a6 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 1fe4ebbb4102..1f225074c411 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 886a14d9e756..ad38a11a2a3c 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 @@ import android.view.View; 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 6b8b65eab428..8bfd7111fb5a 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.ViewGroup; 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.phone.PhoneStatusBar; 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 @@ public class RecentsPanelView extends RelativeLayout implements OnItemClickListe private Context mContext; private StatusBar mBar; private View mRecentsScrim; - private View mRecentsGlowView; private View mRecentsNoApps; private ViewGroup mRecentsContainer; @@ -79,6 +79,7 @@ public class RecentsPanelView extends RelativeLayout implements OnItemClickListe private boolean mRecentTasksDirty = true; private TaskDescriptionAdapter mListAdapter; private int mThumbnailWidth; + private boolean mFitThumbnailToXY; public void setRecentTasksLoader(RecentTasksLoader loader) { mRecentTasksLoader = loader; @@ -174,9 +175,8 @@ public class RecentsPanelView extends RelativeLayout implements OnItemClickListe // 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 @@ public class RecentsPanelView extends RelativeLayout implements OnItemClickListe // 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 class RecentsPanelView extends RelativeLayout implements OnItemClickListe } 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 @@ public class RecentsPanelView extends RelativeLayout implements OnItemClickListe } - 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 @@ public class RecentsPanelView extends RelativeLayout implements OnItemClickListe 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 @@ public class RecentsPanelView extends RelativeLayout implements OnItemClickListe // 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 @@ public class RecentsPanelView extends RelativeLayout implements OnItemClickListe 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 c259c28031e2..ad37603f4a07 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.Surface; 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 @@ class SaveImageInBackgroundTask extends AsyncTask<SaveImageInBackgroundData, Voi // 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 @@ class SaveImageInBackgroundTask extends AsyncTask<SaveImageInBackgroundData, Voi .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 69978378d140..8228df5a1fcd 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.Canvas; 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 @@ public class StatusBarIconView extends AnimatedImageView { 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 20215bd5cbf0..0640282422d9 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 @@ import com.android.systemui.statusbar.StatusBarIconView; 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; - 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; - } - } - - // 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; - } - } + private void checkOverflow(int width) { + if (mMoreView == null) return; - 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()); + final int N = getChildCount(); + int visibleChildren = 0; + for (int i=0; i<N; i++) { + if (getChildAt(i).getVisibility() != GONE) visibleChildren++; } - 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 51fb262bff82..b0554d0278bc 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 @@ public class PhoneStatusBar extends StatusBar { // icons LinearLayout mIcons; IconMerger mNotificationIcons; + View mMoreIcon; LinearLayout mStatusIcons; // expanded notifications @@ -307,6 +308,8 @@ public class PhoneStatusBar extends StatusBar { 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/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java b/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java index a7da96e4d5ea..ee54de1300e3 100644 --- a/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java +++ b/policy/src/com/android/internal/policy/impl/KeyguardStatusViewManager.java @@ -168,7 +168,7 @@ class KeyguardStatusViewManager implements OnClickListener { boolean emergencyButtonEnabledInScreen) { if (DEBUG) Log.v(TAG, "KeyguardStatusViewManager()"); mContainer = view; - mDateFormatString = getContext().getString(R.string.full_wday_month_day_no_year); + mDateFormatString = getContext().getString(R.string.abbrev_wday_month_day_no_year); mLockPatternUtils = lockPatternUtils; mUpdateMonitor = updateMonitor; mCallback = callback; @@ -481,7 +481,14 @@ class KeyguardStatusViewManager implements OnClickListener { break; case SimMissing: + // Shows "No SIM card | Emergency calls only" on devices that are voice-capable. + // This depends on mPlmn containing the text "Emergency calls only" when the radio + // has some connectivity. Otherwise, it should be null or empty and just show + // "No SIM card" carrierText = getContext().getText(R.string.lockscreen_missing_sim_message_short); + if (mLockPatternUtils.isEmergencyCallCapable()) { + carrierText = makeCarierString(carrierText, mPlmn); + } carrierHelpTextId = R.string.lockscreen_missing_sim_instructions_long; break; diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index 921f3313fb0f..b4dd07bffcfe 100755 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -3097,7 +3097,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { sensorRotation = lastRotation; } - int preferredRotation = -1; + final int preferredRotation; if (mHdmiPlugged) { // Ignore sensor when plugged into HDMI. preferredRotation = mHdmiRotation; @@ -3146,28 +3146,39 @@ public class PhoneWindowManager implements WindowManagerPolicy { } else if (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED) { // Apply rotation lock. preferredRotation = mUserRotation; + } else { + // No overriding preference. + // We will do exactly what the application asked us to do. + preferredRotation = -1; } - // TODO: Sometimes, we might want to override the application-requested - // orientation, such as when HDMI is plugged in or when docked. - // We can do that by modifying the appropriate cases above to return - // the preferred orientation directly instead of continuing on down here. - switch (orientation) { case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT: - // Always return portrait if orientation set to portrait. + // Return portrait unless overridden. + if (isAnyPortrait(preferredRotation)) { + return preferredRotation; + } return mPortraitRotation; case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE: - // Always return landscape if orientation set to landscape. + // Return landscape unless overridden. + if (isLandscapeOrSeascape(preferredRotation)) { + return preferredRotation; + } return mLandscapeRotation; case ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT: - // Always return portrait if orientation set to portrait. + // Return reverse portrait unless overridden. + if (isAnyPortrait(preferredRotation)) { + return preferredRotation; + } return mUpsideDownRotation; case ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE: - // Always return seascape if orientation set to reverse landscape. + // Return seascape unless overridden. + if (isLandscapeOrSeascape(preferredRotation)) { + return preferredRotation; + } return mSeascapeRotation; case ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE: diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index cd630905292e..b6f118482bca 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -1248,15 +1248,23 @@ public final class ActivityManagerService extends ActivityManagerNative 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[] { }; + StringBuilder tag = new StringBuilder(128); + dumpProcessesLocked(null, catPw, emptyArgs, 0, false); + catPw.println(); + dumpServicesLocked(null, catPw, emptyArgs, 0, false, false); + catPw.println(); + dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false); + catPw.println(); + tag.append("Low on memory -- "); + dumpApplicationMemoryUsage(null, pw, " ", emptyArgs, true, catPw, tag); String memUsage = sw.toString(); dropBuilder.append('\n'); dropBuilder.append(memUsage); dropBuilder.append(catSw.toString()); logBuilder.append(memUsage); - addErrorToDropBox("watchdog", null, "system_server", null, - null, "Low on memory -- no more background processes", - dropBuilder.toString(), null, null); + addErrorToDropBox("lowmem", null, "system_server", null, + null, tag.toString(), dropBuilder.toString(), null, null); Slog.i(TAG, logBuilder.toString()); synchronized (ActivityManagerService.this) { long now = SystemClock.uptimeMillis(); @@ -1409,7 +1417,8 @@ public final class ActivityManagerService extends ActivityManagerNative return; } - mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null); + mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, + false, null, null); } } @@ -1479,6 +1488,7 @@ public final class ActivityManagerService extends ActivityManagerNative mConfiguration.setToDefaults(); mConfiguration.locale = Locale.getDefault(); + mConfigurationSeq = mConfiguration.seq = 1; mProcessStats.init(); mCompatModePackages = new CompatModePackages(this, systemDir); @@ -2436,7 +2446,7 @@ public final class ActivityManagerService extends ActivityManagerNative 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 +3807,7 @@ public final class ActivityManagerService extends ActivityManagerNative 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 +6717,7 @@ public final class ActivityManagerService extends ActivityManagerNative 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 +8798,20 @@ public final class ActivityManagerService extends ActivityManagerNative 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 +8931,21 @@ public final class ActivityManagerService extends ActivityManagerNative 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; @@ -8937,8 +8963,8 @@ public final class ActivityManagerService extends ActivityManagerNative if (!matcher.match(r, r.name)) { continue; } - pw.print(" "); pw.print(e.getKey()); pw.print(": "); - pw.println(r); + pw.print(" "); pw.print(e.getKey()); pw.println(":"); + pw.print(" "); pw.println(r); } needSep = true; } @@ -9322,16 +9348,20 @@ public final class ActivityManagerService extends ActivityManagerNative final static class MemItem { final String label; + final String shortLabel; final long pss; + final int id; ArrayList<MemItem> subitems; - public MemItem(String _label, long _pss) { + public MemItem(String _label, String _shortLabel, long _pss, int _id) { label = _label; + shortLabel = _shortLabel; pss = _pss; + id = _id; } } - final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items, + static final void dumpMemItems(PrintWriter pw, String prefix, ArrayList<MemItem> items, boolean sort) { if (sort) { Collections.sort(items, new Comparator<MemItem>() { @@ -9349,16 +9379,56 @@ public final class ActivityManagerService extends ActivityManagerNative for (int i=0; i<items.size(); i++) { MemItem mi = items.get(i); - pw.print(prefix); pw.printf("%7d Kb: ", mi.pss); pw.println(mi.label); + pw.print(prefix); pw.printf("%7d kB: ", mi.pss); pw.println(mi.label); if (mi.subitems != null) { dumpMemItems(pw, prefix + " ", mi.subitems, true); } } } + // These are in KB. + static final long[] DUMP_MEM_BUCKETS = new long[] { + 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024, + 120*1024, 160*1024, 200*1024, + 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024, + 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024 + }; + + static final void appendMemBucket(StringBuilder out, long memKB, String label) { + int start = label.lastIndexOf('.'); + if (start >= 0) start++; + else start = 0; + int end = label.length(); + for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) { + if (DUMP_MEM_BUCKETS[i] >= memKB) { + long bucket = DUMP_MEM_BUCKETS[i]/1024; + out.append(bucket); + out.append("MB "); + out.append(label, start, end); + return; + } + } + out.append(memKB/1024); + out.append("MB "); + out.append(label, start, end); + } + + static final int[] DUMP_MEM_OOM_ADJ = new int[] { + ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, + ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, + ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, + ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ + }; + static final String[] DUMP_MEM_OOM_LABEL = new String[] { + "System", "Persistent", "Foreground", + "Visible", "Perceptible", "Heavy Weight", + "Backup", "A Services", "Home", "Previous", + "B Services", "Background" + }; + final void dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, String prefix, String[] args, boolean brief, - PrintWriter categoryPw) { + PrintWriter categoryPw, StringBuilder outTag) { boolean dumpAll = false; boolean oomOnly = false; @@ -9414,20 +9484,9 @@ public final class ActivityManagerService extends ActivityManagerNative long nativePss=0, dalvikPss=0, otherPss=0; long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS]; - final int[] oomAdj = new int[] { - ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ, ProcessList.FOREGROUND_APP_ADJ, - ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ, - ProcessList.BACKUP_APP_ADJ, ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ, - ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.HIDDEN_APP_MAX_ADJ - }; - final String[] oomLabel = new String[] { - "System", "Persistent", "Foreground", - "Visible", "Perceptible", "Heavy Weight", - "Backup", "A Services", "Home", "Previous", - "B Services", "Background" - }; - long oomPss[] = new long[oomLabel.length]; - ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])new ArrayList[oomLabel.length]; + long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length]; + ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[]) + new ArrayList[DUMP_MEM_OOM_LABEL.length]; long totalPss = 0; @@ -9457,7 +9516,7 @@ public final class ActivityManagerService extends ActivityManagerNative long myTotalPss = mi.getTotalPss(); totalPss += myTotalPss; MemItem pssItem = new MemItem(r.processName + " (pid " + r.pid + ")", - myTotalPss); + r.processName, myTotalPss, 0); procMems.add(pssItem); nativePss += mi.nativePss; @@ -9470,7 +9529,8 @@ public final class ActivityManagerService extends ActivityManagerNative } for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) { - if (r.setAdj <= oomAdj[oomIndex] || oomIndex == (oomPss.length-1)) { + if (r.setAdj <= DUMP_MEM_OOM_ADJ[oomIndex] + || oomIndex == (oomPss.length-1)) { oomPss[oomIndex] += myTotalPss; if (oomProcs[oomIndex] == null) { oomProcs[oomIndex] = new ArrayList<MemItem>(); @@ -9486,22 +9546,47 @@ public final class ActivityManagerService extends ActivityManagerNative if (!isCheckinRequest && procs.size() > 1) { ArrayList<MemItem> catMems = new ArrayList<MemItem>(); - catMems.add(new MemItem("Native", nativePss)); - catMems.add(new MemItem("Dalvik", dalvikPss)); - catMems.add(new MemItem("Unknown", otherPss)); + catMems.add(new MemItem("Native", "Native", nativePss, -1)); + catMems.add(new MemItem("Dalvik", "Dalvik", dalvikPss, -2)); + catMems.add(new MemItem("Unknown", "Unknown", otherPss, -3)); for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) { - catMems.add(new MemItem(Debug.MemoryInfo.getOtherLabel(j), miscPss[j])); + String label = Debug.MemoryInfo.getOtherLabel(j); + catMems.add(new MemItem(label, label, miscPss[j], j)); } ArrayList<MemItem> oomMems = new ArrayList<MemItem>(); for (int j=0; j<oomPss.length; j++) { if (oomPss[j] != 0) { - MemItem item = new MemItem(oomLabel[j], oomPss[j]); + String label = DUMP_MEM_OOM_LABEL[j]; + MemItem item = new MemItem(label, label, oomPss[j], + DUMP_MEM_OOM_ADJ[j]); item.subitems = oomProcs[j]; oomMems.add(item); } } + if (outTag != null) { + appendMemBucket(outTag, totalPss, "total"); + for (int i=0; i<oomMems.size(); i++) { + MemItem miCat = oomMems.get(i); + if (miCat.subitems == null || miCat.subitems.size() < 1) { + continue; + } + if (miCat.id < ProcessList.SERVICE_ADJ + || miCat.id == ProcessList.HOME_APP_ADJ + || miCat.id == ProcessList.PREVIOUS_APP_ADJ) { + outTag.append(" / "); + for (int j=0; j<miCat.subitems.size(); j++) { + MemItem mi = miCat.subitems.get(j); + if (j > 0) { + outTag.append(" "); + } + appendMemBucket(outTag, mi.pss, mi.shortLabel); + } + } + } + } + if (!brief && !oomOnly) { pw.println(); pw.println("Total PSS by process:"); @@ -9517,7 +9602,7 @@ public final class ActivityManagerService extends ActivityManagerNative dumpMemItems(out, " ", catMems, true); } pw.println(); - pw.print("Total PSS: "); pw.print(totalPss); pw.println(" Kb"); + pw.print("Total PSS: "); pw.print(totalPss); pw.println(" kB"); } } @@ -12934,7 +13019,7 @@ public final class ActivityManagerService extends ActivityManagerNative synchronized(this) { final long origId = Binder.clearCallingIdentity(); - updateConfigurationLocked(values, null, true); + updateConfigurationLocked(values, null, true, false); Binder.restoreCallingIdentity(origId); } } @@ -12957,7 +13042,7 @@ public final class ActivityManagerService extends ActivityManagerNative if (values != null) { Settings.System.clearConfiguration(values); } - updateConfigurationLocked(values, null, false); + updateConfigurationLocked(values, null, false, false); Binder.restoreCallingIdentity(origId); } } @@ -12971,7 +13056,7 @@ public final class ActivityManagerService extends ActivityManagerNative * @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 +13071,7 @@ public final class ActivityManagerService extends ActivityManagerNative 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 +13084,12 @@ public final class ActivityManagerService extends ActivityManagerNative 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 +13099,11 @@ public final class ActivityManagerService extends ActivityManagerNative // 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 +13113,7 @@ public final class ActivityManagerService extends ActivityManagerNative 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) { } @@ -13965,7 +14052,6 @@ public final class ActivityManagerService extends ActivityManagerNative // application processes based on their current state. int i = mLruProcesses.size(); int curHiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ; - int numBg = 0; while (i > 0) { i--; ProcessRecord app = mLruProcesses.get(i); @@ -13989,12 +14075,7 @@ public final class ActivityManagerService extends ActivityManagerNative app.processName, app.setAdj, "too many background"); app.killedBackground = true; Process.killProcessQuiet(app.pid); - } else { - numBg++; } - } else if (app.curAdj >= ProcessList.HOME_APP_ADJ - && app.curAdj != ProcessList.SERVICE_B_ADJ) { - numBg++; } } } @@ -14009,12 +14090,18 @@ public final class ActivityManagerService extends ActivityManagerNative // memory they want. if (numHidden <= (ProcessList.MAX_HIDDEN_APPS/2)) { final int N = mLruProcesses.size(); - factor = numBg/3; + factor = numHidden/3; + int minFactor = 2; + if (mHomeProcess != null) minFactor++; + if (mPreviousProcess != null) minFactor++; + if (factor < minFactor) factor = minFactor; step = 0; int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE; for (i=0; i<N; i++) { ProcessRecord app = mLruProcesses.get(i); - if (app.curAdj >= ProcessList.HIDDEN_APP_MIN_ADJ && !app.killedBackground) { + if (app.curAdj >= ProcessList.HOME_APP_ADJ + && app.curAdj != ProcessList.SERVICE_B_ADJ + && !app.killedBackground) { if (app.trimMemoryLevel < curLevel && app.thread != null) { try { app.thread.scheduleTrimMemory(curLevel); diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java index c892cb1f2e3a..c7ce3c3eed8d 100644 --- a/services/java/com/android/server/am/ActivityStack.java +++ b/services/java/com/android/server/am/ActivityStack.java @@ -528,7 +528,7 @@ final class ActivityStack { 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 @@ final class ActivityStack { } } 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 @@ final class ActivityStack { 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 @@ final class ActivityStack { 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 @@ final class ActivityStack { 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 9c55597530d2..38355537e1c6 100644 --- a/services/java/com/android/server/am/ContentProviderRecord.java +++ b/services/java/com/android/server/am/ContentProviderRecord.java @@ -73,12 +73,15 @@ class ContentProviderRecord extends ContentProviderHolder { pw.print("multiprocess="); pw.print(info.multiprocess); pw.print(" initOrder="); pw.println(info.initOrder); } - if (clients.size() > 0) { - pw.print(prefix); pw.print("clients="); pw.println(clients); - } if (externals != 0) { pw.print(prefix); pw.print("externals="); pw.println(externals); } + if (clients.size() > 0) { + pw.print(prefix); pw.println("Clients:"); + for (ProcessRecord cproc : clients) { + pw.print(prefix); pw.print(" - "); pw.println(cproc.toShortString()); + } + } } public String toString() { diff --git a/services/java/com/android/server/net/NetworkStatsService.java b/services/java/com/android/server/net/NetworkStatsService.java index 63655258fe5a..28cb983ad18f 100644 --- a/services/java/com/android/server/net/NetworkStatsService.java +++ b/services/java/com/android/server/net/NetworkStatsService.java @@ -1243,7 +1243,8 @@ public class NetworkStatsService extends INetworkStatsService.Stub { // 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 @@ public class NetworkStatsService extends INetworkStatsService.Stub { // 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 50321b3270f6..ebb13d5c8f61 100644 --- a/services/java/com/android/server/wm/WindowManagerService.java +++ b/services/java/com/android/server/wm/WindowManagerService.java @@ -5090,10 +5090,22 @@ public class WindowManagerService extends IWindowManager.Stub // 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 368595f98ae3..061837478a5d 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 com.google.common.util.concurrent.AbstractFuture; 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 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { .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 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { 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 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { 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 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { 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 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { 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 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { 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 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { 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 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { 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 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { 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 @@ public class NetworkPolicyManagerServiceTest extends AndroidTestCase { } } + 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 { |