Merge "Metrics constants for new screen" into qt-dev
diff --git a/api/test-current.txt b/api/test-current.txt
index 62d8b20..95f4a2e 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -3391,6 +3391,7 @@
package android.view.inputmethod {
public final class InputMethodManager {
+ method public int getDisplayId();
method public boolean isInputMethodPickerShown();
}
diff --git a/core/java/android/database/AbstractCursor.java b/core/java/android/database/AbstractCursor.java
index b44458a..cc5d3b1 100644
--- a/core/java/android/database/AbstractCursor.java
+++ b/core/java/android/database/AbstractCursor.java
@@ -419,26 +419,36 @@
Preconditions.checkNotNull(cr);
Preconditions.checkNotNull(notifyUris);
- setNotificationUris(cr, notifyUris, cr.getUserId());
+ setNotificationUris(cr, notifyUris, cr.getUserId(), true);
}
- /** @hide - set the notification uri but with an observer for a particular user's view */
- public void setNotificationUris(ContentResolver cr, List<Uri> notifyUris, int userHandle) {
+ /**
+ * Set the notification uri but with an observer for a particular user's view. Also allows
+ * disabling the use of a self observer, which is sensible if either
+ * a) the cursor's owner calls {@link #onChange(boolean)} whenever the content changes, or
+ * b) the cursor is known not to have any content observers.
+ * @hide
+ */
+ public void setNotificationUris(ContentResolver cr, List<Uri> notifyUris, int userHandle,
+ boolean registerSelfObserver) {
synchronized (mSelfObserverLock) {
mNotifyUris = notifyUris;
mNotifyUri = mNotifyUris.get(0);
mContentResolver = cr;
if (mSelfObserver != null) {
mContentResolver.unregisterContentObserver(mSelfObserver);
+ mSelfObserverRegistered = false;
}
- mSelfObserver = new SelfContentObserver(this);
- final int size = mNotifyUris.size();
- for (int i = 0; i < size; ++i) {
- final Uri notifyUri = mNotifyUris.get(i);
- mContentResolver.registerContentObserver(
- notifyUri, true, mSelfObserver, userHandle);
+ if (registerSelfObserver) {
+ mSelfObserver = new SelfContentObserver(this);
+ final int size = mNotifyUris.size();
+ for (int i = 0; i < size; ++i) {
+ final Uri notifyUri = mNotifyUris.get(i);
+ mContentResolver.registerContentObserver(
+ notifyUri, true, mSelfObserver, userHandle);
+ }
+ mSelfObserverRegistered = true;
}
- mSelfObserverRegistered = true;
}
}
diff --git a/core/java/android/os/BugreportManager.java b/core/java/android/os/BugreportManager.java
index 83e1980..3cdebac 100644
--- a/core/java/android/os/BugreportManager.java
+++ b/core/java/android/os/BugreportManager.java
@@ -26,12 +26,14 @@
import android.annotation.SystemService;
import android.annotation.TestApi;
import android.content.Context;
+import android.util.Log;
import com.android.internal.util.Preconditions;
import libcore.io.IoUtils;
-import java.io.FileDescriptor;
+import java.io.File;
+import java.io.FileNotFoundException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.concurrent.Executor;
@@ -45,6 +47,9 @@
@TestApi
@SystemService(Context.BUGREPORT_SERVICE)
public final class BugreportManager {
+
+ private static final String TAG = "BugreportManager";
+
private final Context mContext;
private final IDumpstate mBinder;
@@ -149,16 +154,22 @@
Preconditions.checkNotNull(executor);
Preconditions.checkNotNull(callback);
+ if (screenshotFd == null) {
+ // Binder needs a valid File Descriptor to be passed
+ screenshotFd = ParcelFileDescriptor.open(new File("/dev/null"),
+ ParcelFileDescriptor.MODE_READ_ONLY);
+ }
DumpstateListener dsListener = new DumpstateListener(executor, callback);
// Note: mBinder can get callingUid from the binder transaction.
mBinder.startBugreport(-1 /* callingUid */,
mContext.getOpPackageName(),
bugreportFd.getFileDescriptor(),
- (screenshotFd != null
- ? screenshotFd.getFileDescriptor() : new FileDescriptor()),
+ screenshotFd.getFileDescriptor(),
params.getMode(), dsListener);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
+ } catch (FileNotFoundException e) {
+ Log.wtf(TAG, "Not able to find /dev/null file: ", e);
} finally {
// We can close the file descriptors here because binder would have duped them.
IoUtils.closeQuietly(bugreportFd);
diff --git a/core/java/android/view/ImeInsetsSourceConsumer.java b/core/java/android/view/ImeInsetsSourceConsumer.java
index d415387..83abf1a 100644
--- a/core/java/android/view/ImeInsetsSourceConsumer.java
+++ b/core/java/android/view/ImeInsetsSourceConsumer.java
@@ -173,6 +173,6 @@
}
private InputMethodManager getImm() {
- return mController.getViewRoot().mDisplayContext.getSystemService(InputMethodManager.class);
+ return mController.getViewRoot().mContext.getSystemService(InputMethodManager.class);
}
}
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index b813bc3..4463e13 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -283,13 +283,7 @@
@GuardedBy("mWindowCallbacks")
final ArrayList<WindowCallbacks> mWindowCallbacks = new ArrayList<>();
@UnsupportedAppUsage
- final Context mContext;
- /**
- * TODO(b/116349163): Check if we can merge this into {@link #mContext}.
- * @hide
- */
- @NonNull
- public Context mDisplayContext;
+ public final Context mContext;
@UnsupportedAppUsage
final IWindowSession mWindowSession;
@@ -595,7 +589,6 @@
public ViewRootImpl(Context context, Display display) {
mContext = context;
- mDisplayContext = context.createDisplayContext(display);
mWindowSession = WindowManagerGlobal.getWindowSession();
mDisplay = display;
mBasePackageName = context.getBasePackageName();
@@ -1379,7 +1372,7 @@
} else {
mDisplay = preferredDisplay;
}
- mDisplayContext = mContext.createDisplayContext(mDisplay);
+ mContext.updateDisplay(mDisplay.getDisplayId());
}
void pokeDrawLockIfNeeded() {
@@ -2725,7 +2718,7 @@
.mayUseInputMethod(mWindowAttributes.flags);
if (imTarget != mLastWasImTarget) {
mLastWasImTarget = imTarget;
- InputMethodManager imm = mDisplayContext.getSystemService(InputMethodManager.class);
+ InputMethodManager imm = mContext.getSystemService(InputMethodManager.class);
if (imm != null && imTarget) {
imm.onPreWindowFocus(mView, hasWindowFocus);
imm.onPostWindowFocus(mView, mView.findFocus(),
@@ -2859,7 +2852,7 @@
mLastWasImTarget = WindowManager.LayoutParams
.mayUseInputMethod(mWindowAttributes.flags);
- InputMethodManager imm = mDisplayContext.getSystemService(InputMethodManager.class);
+ InputMethodManager imm = mContext.getSystemService(InputMethodManager.class);
if (imm != null && mLastWasImTarget && !isInLocalFocusMode()) {
imm.onPreWindowFocus(mView, hasWindowFocus);
}
@@ -4564,8 +4557,7 @@
enqueueInputEvent(event, null, 0, true);
} break;
case MSG_CHECK_FOCUS: {
- InputMethodManager imm =
- mDisplayContext.getSystemService(InputMethodManager.class);
+ InputMethodManager imm = mContext.getSystemService(InputMethodManager.class);
if (imm != null) {
imm.checkFocus();
}
@@ -5110,7 +5102,7 @@
@Override
protected int onProcess(QueuedInputEvent q) {
if (mLastWasImTarget && !isInLocalFocusMode()) {
- InputMethodManager imm = mDisplayContext.getSystemService(InputMethodManager.class);
+ InputMethodManager imm = mContext.getSystemService(InputMethodManager.class);
if (imm != null) {
final InputEvent event = q.mEvent;
if (DEBUG_IMF) Log.v(mTag, "Sending input event to IME: " + event);
diff --git a/core/java/android/view/inputmethod/CursorAnchorInfo.java b/core/java/android/view/inputmethod/CursorAnchorInfo.java
index ee5b3ec..21ead4c 100644
--- a/core/java/android/view/inputmethod/CursorAnchorInfo.java
+++ b/core/java/android/view/inputmethod/CursorAnchorInfo.java
@@ -17,6 +17,7 @@
package android.view.inputmethod;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.graphics.Matrix;
import android.graphics.RectF;
import android.os.Parcel;
@@ -388,7 +389,7 @@
"required when positional parameters are specified.");
}
}
- return new CursorAnchorInfo(this);
+ return CursorAnchorInfo.create(this);
}
/**
@@ -412,30 +413,90 @@
}
}
- private CursorAnchorInfo(final Builder builder) {
- mSelectionStart = builder.mSelectionStart;
- mSelectionEnd = builder.mSelectionEnd;
- mComposingTextStart = builder.mComposingTextStart;
- mComposingText = builder.mComposingText;
- mInsertionMarkerFlags = builder.mInsertionMarkerFlags;
- mInsertionMarkerHorizontal = builder.mInsertionMarkerHorizontal;
- mInsertionMarkerTop = builder.mInsertionMarkerTop;
- mInsertionMarkerBaseline = builder.mInsertionMarkerBaseline;
- mInsertionMarkerBottom = builder.mInsertionMarkerBottom;
- mCharacterBoundsArray = builder.mCharacterBoundsArrayBuilder != null ?
- builder.mCharacterBoundsArrayBuilder.build() : null;
- mMatrixValues = new float[9];
+ private static CursorAnchorInfo create(Builder builder) {
+ final SparseRectFArray characterBoundsArray =
+ builder.mCharacterBoundsArrayBuilder != null
+ ? builder.mCharacterBoundsArrayBuilder.build()
+ : null;
+ final float[] matrixValues = new float[9];
if (builder.mMatrixInitialized) {
- System.arraycopy(builder.mMatrixValues, 0, mMatrixValues, 0, 9);
+ System.arraycopy(builder.mMatrixValues, 0, matrixValues, 0, 9);
} else {
- Matrix.IDENTITY_MATRIX.getValues(mMatrixValues);
+ Matrix.IDENTITY_MATRIX.getValues(matrixValues);
}
+ return new CursorAnchorInfo(builder.mSelectionStart, builder.mSelectionEnd,
+ builder.mComposingTextStart, builder.mComposingText, builder.mInsertionMarkerFlags,
+ builder.mInsertionMarkerHorizontal, builder.mInsertionMarkerTop,
+ builder.mInsertionMarkerBaseline, builder.mInsertionMarkerBottom,
+ characterBoundsArray, matrixValues);
+ }
+
+ private CursorAnchorInfo(int selectionStart, int selectionEnd, int composingTextStart,
+ @Nullable CharSequence composingText, int insertionMarkerFlags,
+ float insertionMarkerHorizontal, float insertionMarkerTop,
+ float insertionMarkerBaseline, float insertionMarkerBottom,
+ @Nullable SparseRectFArray characterBoundsArray, @NonNull float[] matrixValues) {
+ mSelectionStart = selectionStart;
+ mSelectionEnd = selectionEnd;
+ mComposingTextStart = composingTextStart;
+ mComposingText = composingText;
+ mInsertionMarkerFlags = insertionMarkerFlags;
+ mInsertionMarkerHorizontal = insertionMarkerHorizontal;
+ mInsertionMarkerTop = insertionMarkerTop;
+ mInsertionMarkerBaseline = insertionMarkerBaseline;
+ mInsertionMarkerBottom = insertionMarkerBottom;
+ mCharacterBoundsArray = characterBoundsArray;
+ mMatrixValues = matrixValues;
+
// To keep hash function simple, we only use some complex objects for hash.
- int hash = Objects.hashCode(mComposingText);
- hash *= 31;
- hash += Arrays.hashCode(mMatrixValues);
- mHashCode = hash;
+ int hashCode = Objects.hashCode(mComposingText);
+ hashCode *= 31;
+ hashCode += Arrays.hashCode(matrixValues);
+ mHashCode = hashCode;
+ }
+
+ /**
+ * Creates a new instance of {@link CursorAnchorInfo} by applying {@code parentMatrix} to
+ * the coordinate transformation matrix.
+ *
+ * @param original {@link CursorAnchorInfo} to be cloned from.
+ * @param parentMatrix {@link Matrix} to be applied to {@code original.getMatrix()}
+ * @return A new instance of {@link CursorAnchorInfo} whose {@link CursorAnchorInfo#getMatrix()}
+ * returns {@code parentMatrix * original.getMatrix()}.
+ * @hide
+ */
+ public static CursorAnchorInfo createForAdditionalParentMatrix(CursorAnchorInfo original,
+ @NonNull Matrix parentMatrix) {
+ return new CursorAnchorInfo(original.mSelectionStart, original.mSelectionEnd,
+ original.mComposingTextStart, original.mComposingText,
+ original.mInsertionMarkerFlags, original.mInsertionMarkerHorizontal,
+ original.mInsertionMarkerTop, original.mInsertionMarkerBaseline,
+ original.mInsertionMarkerBottom, original.mCharacterBoundsArray,
+ computeMatrixValues(parentMatrix, original));
+ }
+
+ /**
+ * Returns a float array that represents {@link Matrix} elements for
+ * {@code parentMatrix * info.getMatrix()}.
+ *
+ * @param parentMatrix {@link Matrix} to be multiplied.
+ * @param info {@link CursorAnchorInfo} to provide {@link Matrix} to be multiplied.
+ * @return {@code parentMatrix * info.getMatrix()}.
+ */
+ private static float[] computeMatrixValues(@NonNull Matrix parentMatrix,
+ @NonNull CursorAnchorInfo info) {
+ if (parentMatrix.isIdentity()) {
+ return info.mMatrixValues;
+ }
+
+ final Matrix newMatrix = new Matrix();
+ newMatrix.setValues(info.mMatrixValues);
+ newMatrix.postConcat(parentMatrix);
+
+ final float[] matrixValues = new float[9];
+ newMatrix.getValues(matrixValues);
+ return matrixValues;
}
/**
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index fd73856..c7b1cda 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -510,7 +510,7 @@
return null;
}
final InputMethodManager fallbackImm =
- viewRootImpl.mDisplayContext.getSystemService(InputMethodManager.class);
+ viewRootImpl.mContext.getSystemService(InputMethodManager.class);
if (fallbackImm == null) {
Log.e(TAG, "b/117267690: Failed to get non-null fallback IMM. view=" + view);
return null;
@@ -2887,6 +2887,16 @@
}
}
+ /**
+ * <p>This is used for CTS test only. Do not use this method outside of CTS package.<p/>
+ * @return the ID of this display which this {@link InputMethodManager} resides
+ * @hide
+ */
+ @TestApi
+ public int getDisplayId() {
+ return mDisplayId;
+ }
+
void doDump(FileDescriptor fd, PrintWriter fout, String[] args) {
final Printer p = new PrintWriterPrinter(fout);
p.println("Input method client state for " + this + ":");
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index 2349c31..b605eaf 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -177,7 +177,7 @@
*/
private static final int NO_DIRECT_SHARE_ANIM_IN_MILLIS = 200;
- private static final float DIRECT_SHARE_EXPANSION_RATE = 0.7f;
+ private static final float DIRECT_SHARE_EXPANSION_RATE = 0.78f;
// TODO(b/121287224): Re-evaluate this limit
private static final int SHARE_TARGET_QUERY_PACKAGE_LIMIT = 20;
@@ -2037,21 +2037,29 @@
return;
}
- int lastHeight = 0;
+ int directShareHeight = 0;
rowsToShow = Math.min(4, rowsToShow);
for (int i = 0; i < Math.min(rowsToShow, mAdapterView.getChildCount()); i++) {
- lastHeight = mAdapterView.getChildAt(i).getHeight();
- offset += lastHeight;
+ View child = mAdapterView.getChildAt(i);
+ int height = child.getHeight();
+ offset += height;
+
+ if (child.getTag() != null
+ && (child.getTag() instanceof DirectShareViewHolder)) {
+ directShareHeight = height;
+ }
}
boolean isPortrait = getResources().getConfiguration().orientation
== Configuration.ORIENTATION_PORTRAIT;
- if (lastHeight != 0 && isSendAction(getTargetIntent()) && isPortrait) {
+ if (directShareHeight != 0 && isSendAction(getTargetIntent()) && isPortrait) {
// make sure to leave room for direct share 4->8 expansion
- int expansionArea =
- (int) (mResolverDrawerLayout.getAlwaysShowHeight()
- / DIRECT_SHARE_EXPANSION_RATE);
- offset = Math.min(offset, bottom - top - lastHeight - expansionArea);
+ int requiredExpansionHeight =
+ (int) (directShareHeight / DIRECT_SHARE_EXPANSION_RATE);
+ int minHeight = bottom - top - mResolverDrawerLayout.getAlwaysShowHeight()
+ - requiredExpansionHeight;
+
+ offset = Math.min(offset, minHeight);
}
mResolverDrawerLayout.setCollapsibleHeightReserved(Math.min(offset, bottom - top));
diff --git a/core/java/com/android/internal/content/FileSystemProvider.java b/core/java/com/android/internal/content/FileSystemProvider.java
index 9e8bd64..cc2caca 100644
--- a/core/java/com/android/internal/content/FileSystemProvider.java
+++ b/core/java/com/android/internal/content/FileSystemProvider.java
@@ -60,9 +60,11 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
+import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
+import java.util.concurrent.CopyOnWriteArrayList;
/**
* A helper class for {@link android.provider.DocumentsProvider} to perform file operations on local
@@ -613,28 +615,28 @@
return projection == null ? mDefaultProjection : projection;
}
- private void startObserving(File file, Uri notifyUri) {
+ private void startObserving(File file, Uri notifyUri, DirectoryCursor cursor) {
synchronized (mObservers) {
DirectoryObserver observer = mObservers.get(file);
if (observer == null) {
- observer = new DirectoryObserver(
- file, getContext().getContentResolver(), notifyUri);
+ observer =
+ new DirectoryObserver(file, getContext().getContentResolver(), notifyUri);
observer.startWatching();
mObservers.put(file, observer);
}
- observer.mRefCount++;
+ observer.mCursors.add(cursor);
if (LOG_INOTIFY) Log.d(TAG, "after start: " + observer);
}
}
- private void stopObserving(File file) {
+ private void stopObserving(File file, DirectoryCursor cursor) {
synchronized (mObservers) {
DirectoryObserver observer = mObservers.get(file);
if (observer == null) return;
- observer.mRefCount--;
- if (observer.mRefCount == 0) {
+ observer.mCursors.remove(cursor);
+ if (observer.mCursors.size() == 0) {
mObservers.remove(file);
observer.stopWatching();
}
@@ -650,27 +652,31 @@
private final File mFile;
private final ContentResolver mResolver;
private final Uri mNotifyUri;
+ private final CopyOnWriteArrayList<DirectoryCursor> mCursors;
- private int mRefCount = 0;
-
- public DirectoryObserver(File file, ContentResolver resolver, Uri notifyUri) {
+ DirectoryObserver(File file, ContentResolver resolver, Uri notifyUri) {
super(file.getAbsolutePath(), NOTIFY_EVENTS);
mFile = file;
mResolver = resolver;
mNotifyUri = notifyUri;
+ mCursors = new CopyOnWriteArrayList<>();
}
@Override
public void onEvent(int event, String path) {
if ((event & NOTIFY_EVENTS) != 0) {
if (LOG_INOTIFY) Log.d(TAG, "onEvent() " + event + " at " + path);
+ for (DirectoryCursor cursor : mCursors) {
+ cursor.notifyChanged();
+ }
mResolver.notifyChange(mNotifyUri, null, false);
}
}
@Override
public String toString() {
- return "DirectoryObserver{file=" + mFile.getAbsolutePath() + ", ref=" + mRefCount + "}";
+ String filePath = mFile.getAbsolutePath();
+ return "DirectoryObserver{file=" + filePath + ", ref=" + mCursors.size() + "}";
}
}
@@ -681,16 +687,22 @@
super(columnNames);
final Uri notifyUri = buildNotificationUri(docId);
- setNotificationUri(getContext().getContentResolver(), notifyUri);
+ boolean registerSelfObserver = false; // Our FileObserver sees all relevant changes.
+ setNotificationUris(getContext().getContentResolver(), Arrays.asList(notifyUri),
+ getContext().getContentResolver().getUserId(), registerSelfObserver);
mFile = file;
- startObserving(mFile, notifyUri);
+ startObserving(mFile, notifyUri, this);
+ }
+
+ public void notifyChanged() {
+ onChange(false);
}
@Override
public void close() {
super.close();
- stopObserving(mFile);
+ stopObserving(mFile, this);
}
}
}
diff --git a/core/proto/android/server/windowmanagerservice.proto b/core/proto/android/server/windowmanagerservice.proto
index dbd2191..e6ae226 100644
--- a/core/proto/android/server/windowmanagerservice.proto
+++ b/core/proto/android/server/windowmanagerservice.proto
@@ -159,6 +159,9 @@
optional int32 surface_size = 14 [deprecated=true];
optional string focused_app = 15;
optional AppTransitionProto app_transition = 16;
+ repeated IdentifierProto opening_apps = 17;
+ repeated IdentifierProto closing_apps = 18;
+ repeated IdentifierProto changing_apps = 19;
}
/* represents DisplayFrames */
diff --git a/core/res/res/layout/chooser_grid_preview_text.xml b/core/res/res/layout/chooser_grid_preview_text.xml
index 96a642c..9c725b9 100644
--- a/core/res/res/layout/chooser_grid_preview_text.xml
+++ b/core/res/res/layout/chooser_grid_preview_text.xml
@@ -23,7 +23,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
- android:paddingBottom="@dimen/chooser_view_spacing"
android:background="?android:attr/colorBackgroundFloating">
<RelativeLayout
@@ -91,6 +90,7 @@
android:orientation="horizontal"
android:layout_marginLeft="@dimen/chooser_edge_margin_normal"
android:layout_marginRight="@dimen/chooser_edge_margin_normal"
+ android:layout_marginBottom="@dimen/chooser_view_spacing"
android:minHeight="80dp"
android:background="@drawable/chooser_content_preview_rounded"
android:id="@+id/content_preview_title_layout">
diff --git a/core/tests/coretests/src/android/view/inputmethod/CursorAnchorInfoTest.java b/core/tests/coretests/src/android/view/inputmethod/CursorAnchorInfoTest.java
index ace6611..833530d 100644
--- a/core/tests/coretests/src/android/view/inputmethod/CursorAnchorInfoTest.java
+++ b/core/tests/coretests/src/android/view/inputmethod/CursorAnchorInfoTest.java
@@ -16,19 +16,9 @@
package android.view.inputmethod;
-import static android.view.inputmethod.CursorAnchorInfo.FLAG_HAS_INVISIBLE_REGION;
-import static android.view.inputmethod.CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION;
-import static android.view.inputmethod.CursorAnchorInfo.FLAG_IS_RTL;
-
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNull;
-import static org.junit.Assert.assertTrue;
import android.graphics.Matrix;
-import android.graphics.RectF;
-import android.os.Parcel;
-import android.text.TextUtils;
import android.view.inputmethod.CursorAnchorInfo.Builder;
import androidx.test.filters.SmallTest;
@@ -37,437 +27,38 @@
import org.junit.Test;
import org.junit.runner.RunWith;
-import java.util.Objects;
-
@SmallTest
@RunWith(AndroidJUnit4.class)
public class CursorAnchorInfoTest {
- private static final float EPSILON = 0.0000001f;
-
- private static final RectF[] MANY_BOUNDS = new RectF[] {
- new RectF(101.0f, 201.0f, 301.0f, 401.0f),
- new RectF(102.0f, 202.0f, 302.0f, 402.0f),
- new RectF(103.0f, 203.0f, 303.0f, 403.0f),
- new RectF(104.0f, 204.0f, 304.0f, 404.0f),
- new RectF(105.0f, 205.0f, 305.0f, 405.0f),
- new RectF(106.0f, 206.0f, 306.0f, 406.0f),
- new RectF(107.0f, 207.0f, 307.0f, 407.0f),
- new RectF(108.0f, 208.0f, 308.0f, 408.0f),
- new RectF(109.0f, 209.0f, 309.0f, 409.0f),
- new RectF(110.0f, 210.0f, 310.0f, 410.0f),
- new RectF(111.0f, 211.0f, 311.0f, 411.0f),
- new RectF(112.0f, 212.0f, 312.0f, 412.0f),
- new RectF(113.0f, 213.0f, 313.0f, 413.0f),
- new RectF(114.0f, 214.0f, 314.0f, 414.0f),
- new RectF(115.0f, 215.0f, 315.0f, 415.0f),
- new RectF(116.0f, 216.0f, 316.0f, 416.0f),
- new RectF(117.0f, 217.0f, 317.0f, 417.0f),
- new RectF(118.0f, 218.0f, 318.0f, 418.0f),
- new RectF(119.0f, 219.0f, 319.0f, 419.0f),
- };
- private static final int[] MANY_FLAGS_ARRAY = new int[] {
- FLAG_HAS_INVISIBLE_REGION,
- FLAG_HAS_INVISIBLE_REGION | FLAG_HAS_VISIBLE_REGION,
- FLAG_HAS_VISIBLE_REGION,
- FLAG_HAS_VISIBLE_REGION,
- FLAG_HAS_VISIBLE_REGION,
- FLAG_HAS_VISIBLE_REGION,
- FLAG_HAS_VISIBLE_REGION | FLAG_IS_RTL,
- FLAG_HAS_INVISIBLE_REGION | FLAG_HAS_VISIBLE_REGION | FLAG_IS_RTL,
- FLAG_HAS_INVISIBLE_REGION | FLAG_IS_RTL,
- FLAG_HAS_VISIBLE_REGION | FLAG_IS_RTL,
- FLAG_HAS_VISIBLE_REGION,
- FLAG_HAS_VISIBLE_REGION | FLAG_IS_RTL,
- FLAG_HAS_VISIBLE_REGION,
- FLAG_HAS_VISIBLE_REGION | FLAG_IS_RTL,
- FLAG_HAS_VISIBLE_REGION,
- FLAG_HAS_VISIBLE_REGION | FLAG_IS_RTL,
- FLAG_HAS_VISIBLE_REGION,
- FLAG_HAS_INVISIBLE_REGION,
- FLAG_HAS_INVISIBLE_REGION | FLAG_IS_RTL,
- };
-
@Test
- public void testBuilder() throws Exception {
- final int SELECTION_START = 30;
- final int SELECTION_END = 40;
- final int COMPOSING_TEXT_START = 32;
- final String COMPOSING_TEXT = "test";
- final int INSERTION_MARKER_FLAGS =
- FLAG_HAS_VISIBLE_REGION | FLAG_HAS_INVISIBLE_REGION | FLAG_IS_RTL;
- final float INSERTION_MARKER_HORIZONTAL = 10.5f;
- final float INSERTION_MARKER_TOP = 100.1f;
- final float INSERTION_MARKER_BASELINE = 110.4f;
- final float INSERTION_MARKER_BOTOM = 111.0f;
-
- Matrix TRANSFORM_MATRIX = new Matrix(Matrix.IDENTITY_MATRIX);
- TRANSFORM_MATRIX.setScale(10.0f, 20.0f);
-
+ public void testCreateForAdditionalParentMatrix() {
+ final Matrix originalMatrix = new Matrix();
+ originalMatrix.setTranslate(10.0f, 20.0f);
final Builder builder = new Builder();
- builder.setSelectionRange(SELECTION_START, SELECTION_END)
- .setComposingText(COMPOSING_TEXT_START, COMPOSING_TEXT)
- .setInsertionMarkerLocation(INSERTION_MARKER_HORIZONTAL, INSERTION_MARKER_TOP,
- INSERTION_MARKER_BASELINE, INSERTION_MARKER_BOTOM, INSERTION_MARKER_FLAGS)
- .setMatrix(TRANSFORM_MATRIX);
- for (int i = 0; i < MANY_BOUNDS.length; i++) {
- final RectF bounds = MANY_BOUNDS[i];
- final int flags = MANY_FLAGS_ARRAY[i];
- builder.addCharacterBounds(i, bounds.left, bounds.top, bounds.right, bounds.bottom,
- flags);
- }
+ builder.setMatrix(originalMatrix);
- final CursorAnchorInfo info = builder.build();
- assertEquals(SELECTION_START, info.getSelectionStart());
- assertEquals(SELECTION_END, info.getSelectionEnd());
- assertEquals(COMPOSING_TEXT_START, info.getComposingTextStart());
- assertTrue(TextUtils.equals(COMPOSING_TEXT, info.getComposingText()));
- assertEquals(INSERTION_MARKER_FLAGS, info.getInsertionMarkerFlags());
- assertEquals(INSERTION_MARKER_HORIZONTAL, info.getInsertionMarkerHorizontal(), EPSILON);
- assertEquals(INSERTION_MARKER_TOP, info.getInsertionMarkerTop(), EPSILON);
- assertEquals(INSERTION_MARKER_BASELINE, info.getInsertionMarkerBaseline(), EPSILON);
- assertEquals(INSERTION_MARKER_BOTOM, info.getInsertionMarkerBottom(), EPSILON);
- assertEquals(TRANSFORM_MATRIX, info.getMatrix());
- for (int i = 0; i < MANY_BOUNDS.length; i++) {
- final RectF expectedBounds = MANY_BOUNDS[i];
- assertEquals(expectedBounds, info.getCharacterBounds(i));
- }
- assertNull(info.getCharacterBounds(-1));
- assertNull(info.getCharacterBounds(MANY_BOUNDS.length + 1));
- for (int i = 0; i < MANY_FLAGS_ARRAY.length; i++) {
- final int expectedFlags = MANY_FLAGS_ARRAY[i];
- assertEquals(expectedFlags, info.getCharacterBoundsFlags(i));
- }
- assertEquals(0, info.getCharacterBoundsFlags(-1));
- assertEquals(0, info.getCharacterBoundsFlags(MANY_BOUNDS.length + 1));
+ final CursorAnchorInfo originalInstance = builder.build();
- // Make sure that the builder can reproduce the same object.
- final CursorAnchorInfo info2 = builder.build();
- assertEquals(SELECTION_START, info2.getSelectionStart());
- assertEquals(SELECTION_END, info2.getSelectionEnd());
- assertEquals(COMPOSING_TEXT_START, info2.getComposingTextStart());
- assertTrue(TextUtils.equals(COMPOSING_TEXT, info2.getComposingText()));
- assertEquals(INSERTION_MARKER_FLAGS, info2.getInsertionMarkerFlags());
- assertEquals(INSERTION_MARKER_HORIZONTAL, info2.getInsertionMarkerHorizontal(), EPSILON);
- assertEquals(INSERTION_MARKER_TOP, info2.getInsertionMarkerTop(), EPSILON);
- assertEquals(INSERTION_MARKER_BASELINE, info2.getInsertionMarkerBaseline(), EPSILON);
- assertEquals(INSERTION_MARKER_BOTOM, info2.getInsertionMarkerBottom(), EPSILON);
- assertEquals(TRANSFORM_MATRIX, info2.getMatrix());
- for (int i = 0; i < MANY_BOUNDS.length; i++) {
- final RectF expectedBounds = MANY_BOUNDS[i];
- assertEquals(expectedBounds, info2.getCharacterBounds(i));
- }
- assertNull(info2.getCharacterBounds(-1));
- assertNull(info2.getCharacterBounds(MANY_BOUNDS.length + 1));
- for (int i = 0; i < MANY_FLAGS_ARRAY.length; i++) {
- final int expectedFlags = MANY_FLAGS_ARRAY[i];
- assertEquals(expectedFlags, info2.getCharacterBoundsFlags(i));
- }
- assertEquals(0, info2.getCharacterBoundsFlags(-1));
- assertEquals(0, info2.getCharacterBoundsFlags(MANY_BOUNDS.length + 1));
- assertEquals(info, info2);
- assertEquals(info.hashCode(), info2.hashCode());
+ assertEquals(originalMatrix, originalInstance.getMatrix());
- // Make sure that object can be marshaled via {@link Parsel}.
- final CursorAnchorInfo info3 = cloneViaParcel(info2);
- assertEquals(SELECTION_START, info3.getSelectionStart());
- assertEquals(SELECTION_END, info3.getSelectionEnd());
- assertEquals(COMPOSING_TEXT_START, info3.getComposingTextStart());
- assertTrue(TextUtils.equals(COMPOSING_TEXT, info3.getComposingText()));
- assertEquals(INSERTION_MARKER_FLAGS, info3.getInsertionMarkerFlags());
- assertEquals(INSERTION_MARKER_HORIZONTAL, info3.getInsertionMarkerHorizontal(), EPSILON);
- assertEquals(INSERTION_MARKER_TOP, info3.getInsertionMarkerTop(), EPSILON);
- assertEquals(INSERTION_MARKER_BASELINE, info3.getInsertionMarkerBaseline(), EPSILON);
- assertEquals(INSERTION_MARKER_BOTOM, info3.getInsertionMarkerBottom(), EPSILON);
- assertEquals(TRANSFORM_MATRIX, info3.getMatrix());
- for (int i = 0; i < MANY_BOUNDS.length; i++) {
- final RectF expectedBounds = MANY_BOUNDS[i];
- assertEquals(expectedBounds, info3.getCharacterBounds(i));
- }
- assertNull(info3.getCharacterBounds(-1));
- assertNull(info3.getCharacterBounds(MANY_BOUNDS.length + 1));
- for (int i = 0; i < MANY_FLAGS_ARRAY.length; i++) {
- final int expectedFlags = MANY_FLAGS_ARRAY[i];
- assertEquals(expectedFlags, info3.getCharacterBoundsFlags(i));
- }
- assertEquals(0, info3.getCharacterBoundsFlags(-1));
- assertEquals(0, info3.getCharacterBoundsFlags(MANY_BOUNDS.length + 1));
- assertEquals(info.hashCode(), info3.hashCode());
+ final Matrix additionalParentMatrix = new Matrix();
+ additionalParentMatrix.setTranslate(1.0f, 2.0f);
+
+ final Matrix newMatrix = new Matrix(originalMatrix);
+ newMatrix.postConcat(additionalParentMatrix);
builder.reset();
- final CursorAnchorInfo uninitializedInfo = builder.build();
- assertEquals(-1, uninitializedInfo.getSelectionStart());
- assertEquals(-1, uninitializedInfo.getSelectionEnd());
- assertEquals(-1, uninitializedInfo.getComposingTextStart());
- assertNull(uninitializedInfo.getComposingText());
- assertEquals(0, uninitializedInfo.getInsertionMarkerFlags());
- assertEquals(Float.NaN, uninitializedInfo.getInsertionMarkerHorizontal(), EPSILON);
- assertEquals(Float.NaN, uninitializedInfo.getInsertionMarkerTop(), EPSILON);
- assertEquals(Float.NaN, uninitializedInfo.getInsertionMarkerBaseline(), EPSILON);
- assertEquals(Float.NaN, uninitializedInfo.getInsertionMarkerBottom(), EPSILON);
- assertEquals(Matrix.IDENTITY_MATRIX, uninitializedInfo.getMatrix());
- }
+ builder.setMatrix(newMatrix);
+ // An instance created by the standard Builder class.
+ final CursorAnchorInfo newInstanceByBuilder = builder.build();
- private static void assertNotEquals(final CursorAnchorInfo reference,
- final CursorAnchorInfo actual) {
- assertFalse(Objects.equals(reference, actual));
- }
+ // An instance created by an @hide method.
+ final CursorAnchorInfo newInstanceByMethod =
+ CursorAnchorInfo.createForAdditionalParentMatrix(
+ originalInstance, additionalParentMatrix);
- @Test
- public void testEquality() throws Exception {
- final Matrix MATRIX1 = new Matrix();
- MATRIX1.setTranslate(10.0f, 20.0f);
- final Matrix MATRIX2 = new Matrix();
- MATRIX2.setTranslate(110.0f, 120.0f);
- final Matrix NAN_MATRIX = new Matrix();
- NAN_MATRIX.setValues(new float[]{
- Float.NaN, Float.NaN, Float.NaN,
- Float.NaN, Float.NaN, Float.NaN,
- Float.NaN, Float.NaN, Float.NaN});
- final int SELECTION_START1 = 2;
- final int SELECTION_END1 = 7;
- final String COMPOSING_TEXT1 = "0123456789";
- final int COMPOSING_TEXT_START1 = 0;
- final int INSERTION_MARKER_FLAGS1 = FLAG_HAS_VISIBLE_REGION;
- final float INSERTION_MARKER_HORIZONTAL1 = 10.5f;
- final float INSERTION_MARKER_TOP1 = 100.1f;
- final float INSERTION_MARKER_BASELINE1 = 110.4f;
- final float INSERTION_MARKER_BOTOM1 = 111.0f;
- final int SELECTION_START2 = 4;
- final int SELECTION_END2 = 8;
- final String COMPOSING_TEXT2 = "9876543210";
- final int COMPOSING_TEXT_START2 = 3;
- final int INSERTION_MARKER_FLAGS2 =
- FLAG_HAS_VISIBLE_REGION | FLAG_HAS_INVISIBLE_REGION | FLAG_IS_RTL;
- final float INSERTION_MARKER_HORIZONTAL2 = 14.5f;
- final float INSERTION_MARKER_TOP2 = 200.1f;
- final float INSERTION_MARKER_BASELINE2 = 210.4f;
- final float INSERTION_MARKER_BOTOM2 = 211.0f;
-
- // Default instance should be equal.
- assertEquals(new Builder().build(), new Builder().build());
-
- assertEquals(
- new Builder().setSelectionRange(SELECTION_START1, SELECTION_END1).build(),
- new Builder().setSelectionRange(SELECTION_START1, SELECTION_END1).build());
- assertNotEquals(
- new Builder().setSelectionRange(SELECTION_START1, SELECTION_END1).build(),
- new Builder().setSelectionRange(SELECTION_START1, SELECTION_END2).build());
- assertNotEquals(
- new Builder().setSelectionRange(SELECTION_START1, SELECTION_END1).build(),
- new Builder().setSelectionRange(SELECTION_START2, SELECTION_END1).build());
- assertNotEquals(
- new Builder().setSelectionRange(SELECTION_START1, SELECTION_END1).build(),
- new Builder().setSelectionRange(SELECTION_START2, SELECTION_END2).build());
- assertEquals(
- new Builder().setComposingText(COMPOSING_TEXT_START1, COMPOSING_TEXT1).build(),
- new Builder().setComposingText(COMPOSING_TEXT_START1, COMPOSING_TEXT1).build());
- assertNotEquals(
- new Builder().setComposingText(COMPOSING_TEXT_START1, COMPOSING_TEXT1).build(),
- new Builder().setComposingText(COMPOSING_TEXT_START2, COMPOSING_TEXT1).build());
- assertNotEquals(
- new Builder().setComposingText(COMPOSING_TEXT_START1, COMPOSING_TEXT1).build(),
- new Builder().setComposingText(COMPOSING_TEXT_START1, COMPOSING_TEXT2).build());
- assertNotEquals(
- new Builder().setComposingText(COMPOSING_TEXT_START1, COMPOSING_TEXT1).build(),
- new Builder().setComposingText(COMPOSING_TEXT_START2, COMPOSING_TEXT2).build());
-
- // For insertion marker locations, {@link Float#NaN} is treated as if it was a number.
- assertEquals(
- new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
- Float.NaN, Float.NaN, Float.NaN, Float.NaN,
- INSERTION_MARKER_FLAGS1).build(),
- new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
- Float.NaN, Float.NaN, Float.NaN, Float.NaN,
- INSERTION_MARKER_FLAGS1).build());
-
- // Check Matrix.
- assertEquals(
- new Builder().setMatrix(MATRIX1).build(),
- new Builder().setMatrix(MATRIX1).build());
- assertNotEquals(
- new Builder().setMatrix(MATRIX1).build(),
- new Builder().setMatrix(MATRIX2).build());
- assertNotEquals(
- new Builder().setMatrix(MATRIX1).build(),
- new Builder().setMatrix(NAN_MATRIX).build());
- // Unlike insertion marker locations, {@link Float#NaN} in the matrix is treated as just a
- // NaN as usual (NaN == NaN -> false).
- assertNotEquals(
- new Builder().setMatrix(NAN_MATRIX).build(),
- new Builder().setMatrix(NAN_MATRIX).build());
-
- assertEquals(
- new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
- INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1,
- INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1,
- INSERTION_MARKER_FLAGS1).build(),
- new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
- INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1,
- INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1,
- INSERTION_MARKER_FLAGS1).build());
- assertNotEquals(
- new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
- Float.NaN, INSERTION_MARKER_TOP1,
- INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1,
- INSERTION_MARKER_FLAGS1).build(),
- new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
- INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1,
- INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1,
- INSERTION_MARKER_FLAGS1).build());
- assertNotEquals(
- new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
- INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1,
- INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1,
- INSERTION_MARKER_FLAGS1).build(),
- new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
- INSERTION_MARKER_HORIZONTAL2, INSERTION_MARKER_TOP1,
- INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1,
- INSERTION_MARKER_FLAGS1).build());
- assertNotEquals(
- new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
- INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1,
- INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1,
- INSERTION_MARKER_FLAGS1).build(),
- new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
- INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP2,
- INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1,
- INSERTION_MARKER_FLAGS1).build());
- assertNotEquals(
- new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
- INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1,
- INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1,
- INSERTION_MARKER_FLAGS1).build(),
- new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
- INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1,
- INSERTION_MARKER_BASELINE2, INSERTION_MARKER_BOTOM1,
- INSERTION_MARKER_FLAGS1).build());
- assertNotEquals(
- new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
- INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1,
- INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1,
- INSERTION_MARKER_FLAGS1).build(),
- new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
- INSERTION_MARKER_HORIZONTAL2, INSERTION_MARKER_TOP1,
- INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1,
- INSERTION_MARKER_FLAGS1).build());
- assertNotEquals(
- new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
- INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1,
- INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1,
- INSERTION_MARKER_FLAGS1).build(),
- new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
- INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1,
- INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM2,
- INSERTION_MARKER_FLAGS1).build());
- assertNotEquals(
- new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
- INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1,
- INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1,
- INSERTION_MARKER_FLAGS1).build(),
- new Builder().setMatrix(MATRIX1).setInsertionMarkerLocation(
- INSERTION_MARKER_HORIZONTAL1, INSERTION_MARKER_TOP1,
- INSERTION_MARKER_BASELINE1, INSERTION_MARKER_BOTOM1,
- INSERTION_MARKER_FLAGS2).build());
- }
-
- @Test
- public void testMatrixIsCopied() throws Exception {
- final Matrix MATRIX1 = new Matrix();
- MATRIX1.setTranslate(10.0f, 20.0f);
- final Matrix MATRIX2 = new Matrix();
- MATRIX2.setTranslate(110.0f, 120.0f);
- final Matrix MATRIX3 = new Matrix();
- MATRIX3.setTranslate(210.0f, 220.0f);
- final Matrix matrix = new Matrix();
- final Builder builder = new Builder();
-
- matrix.set(MATRIX1);
- builder.setMatrix(matrix);
- matrix.postRotate(90.0f);
-
- final CursorAnchorInfo firstInstance = builder.build();
- assertEquals(MATRIX1, firstInstance.getMatrix());
- matrix.set(MATRIX2);
- builder.setMatrix(matrix);
- final CursorAnchorInfo secondInstance = builder.build();
- assertEquals(MATRIX1, firstInstance.getMatrix());
- assertEquals(MATRIX2, secondInstance.getMatrix());
-
- matrix.set(MATRIX3);
- assertEquals(MATRIX1, firstInstance.getMatrix());
- assertEquals(MATRIX2, secondInstance.getMatrix());
- }
-
- @Test
- public void testMatrixIsRequired() throws Exception {
- final int SELECTION_START = 30;
- final int SELECTION_END = 40;
- final int COMPOSING_TEXT_START = 32;
- final String COMPOSING_TEXT = "test";
- final int INSERTION_MARKER_FLAGS = FLAG_HAS_VISIBLE_REGION;
- final float INSERTION_MARKER_HORIZONTAL = 10.5f;
- final float INSERTION_MARKER_TOP = 100.1f;
- final float INSERTION_MARKER_BASELINE = 110.4f;
- final float INSERTION_MARKER_BOTOM = 111.0f;
- Matrix TRANSFORM_MATRIX = new Matrix(Matrix.IDENTITY_MATRIX);
- TRANSFORM_MATRIX.setScale(10.0f, 20.0f);
-
- final Builder builder = new Builder();
- // Check twice to make sure if Builder#reset() works as expected.
- for (int repeatCount = 0; repeatCount < 2; ++repeatCount) {
- builder.setSelectionRange(SELECTION_START, SELECTION_END)
- .setComposingText(COMPOSING_TEXT_START, COMPOSING_TEXT);
- try {
- // Should succeed as coordinate transformation matrix is not required if no
- // positional information is specified.
- builder.build();
- } catch (IllegalArgumentException ex) {
- assertTrue(false);
- }
-
- builder.setInsertionMarkerLocation(INSERTION_MARKER_HORIZONTAL, INSERTION_MARKER_TOP,
- INSERTION_MARKER_BASELINE, INSERTION_MARKER_BOTOM, INSERTION_MARKER_FLAGS);
- try {
- // Coordinate transformation matrix is required if no positional information is
- // specified.
- builder.build();
- assertTrue(false);
- } catch (IllegalArgumentException ex) {
- }
-
- builder.setMatrix(TRANSFORM_MATRIX);
- try {
- // Should succeed as coordinate transformation matrix is required.
- builder.build();
- } catch (IllegalArgumentException ex) {
- assertTrue(false);
- }
-
- builder.reset();
- }
- }
-
- @Test
- public void testBuilderAddCharacterBounds() throws Exception {
- // A negative index should be rejected.
- try {
- new Builder().addCharacterBounds(-1, 0.0f, 0.0f, 0.0f, 0.0f, FLAG_HAS_VISIBLE_REGION);
- assertTrue(false);
- } catch (IllegalArgumentException ex) {
- }
- }
-
- private static CursorAnchorInfo cloneViaParcel(final CursorAnchorInfo src) {
- Parcel parcel = null;
- try {
- parcel = Parcel.obtain();
- src.writeToParcel(parcel, 0);
- parcel.setDataPosition(0);
- return new CursorAnchorInfo(parcel);
- } finally {
- if (parcel != null) {
- parcel.recycle();
- }
- }
+ assertEquals(newMatrix, newInstanceByBuilder.getMatrix());
+ assertEquals(newMatrix, newInstanceByMethod.getMatrix());
+ assertEquals(newInstanceByBuilder.hashCode(), newInstanceByMethod.hashCode());
}
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index ff34578..1d351a5 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -50,6 +50,8 @@
// See mConnectAttempted
private static final long MAX_UUID_DELAY_FOR_AUTO_CONNECT = 5000;
+ // Some Hearing Aids (especially the 2nd device) needs more time to do service discovery
+ private static final long MAX_HEARING_AIDS_DELAY_FOR_AUTO_CONNECT = 15000;
private static final long MAX_HOGP_DELAY_FOR_AUTO_CONNECT = 30000;
private final Context mContext;
@@ -223,7 +225,7 @@
// various profiles
// If UUIDs are not available yet, connect will be happen
// upon arrival of the ACTION_UUID intent.
- Log.d(TAG, "No profiles. Maybe we will connect later");
+ Log.d(TAG, "No profiles. Maybe we will connect later for device " + mDevice);
return;
}
@@ -608,10 +610,12 @@
long timeout = MAX_UUID_DELAY_FOR_AUTO_CONNECT;
if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.Hogp)) {
timeout = MAX_HOGP_DELAY_FOR_AUTO_CONNECT;
+ } else if (BluetoothUuid.isUuidPresent(uuids, BluetoothUuid.HearingAid)) {
+ timeout = MAX_HEARING_AIDS_DELAY_FOR_AUTO_CONNECT;
}
if (BluetoothUtils.D) {
- Log.d(TAG, "onUuidChanged: Time since last connect"
+ Log.d(TAG, "onUuidChanged: Time since last connect="
+ (SystemClock.elapsedRealtime() - mConnectAttempted));
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 1194a1d..d521809 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -1316,7 +1316,11 @@
} else if (oldState == StatusBarState.SHADE_LOCKED
&& statusBarState == StatusBarState.KEYGUARD) {
animateKeyguardStatusBarIn(StackStateAnimator.ANIMATION_DURATION_STANDARD);
- mQs.animateHeaderSlidingOut();
+ // Only animate header if the header is visible. If not, it will partially animate out
+ // the top of QS
+ if (!mQsExpanded) {
+ mQs.animateHeaderSlidingOut();
+ }
} else {
mKeyguardStatusBar.setAlpha(1f);
mKeyguardStatusBar.setVisibility(keyguardShowing ? View.VISIBLE : View.INVISIBLE);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index d350c3a..93168db 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -661,7 +661,13 @@
public boolean onBackPressed(boolean hideImmediately) {
if (mBouncer.isShowing()) {
mStatusBar.endAffordanceLaunch();
- reset(hideImmediately);
+ // The second condition is for SIM card locked bouncer
+ if (mBouncer.isScrimmed() && !mBouncer.needsFullscreenBouncer()) {
+ hideBouncer(false);
+ updateStates();
+ } else {
+ reset(hideImmediately);
+ }
return true;
}
return false;
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java
index 34702ec..d52fe81 100644
--- a/services/core/java/com/android/server/LocationManagerService.java
+++ b/services/core/java/com/android/server/LocationManagerService.java
@@ -3664,6 +3664,13 @@
}
}
+ if (!mIgnoreSettingsPackageWhitelist.isEmpty()) {
+ pw.println(" Bypass Whitelisted Packages:");
+ for (String packageName : mIgnoreSettingsPackageWhitelist) {
+ pw.println(" " + packageName);
+ }
+ }
+
if (mLocationFudger != null) {
pw.append(" fudger: ");
mLocationFudger.dump(fd, pw, args);
diff --git a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
index d4c7ec3..da88ec5 100644
--- a/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
+++ b/services/core/java/com/android/server/rollback/RollbackManagerServiceImpl.java
@@ -239,9 +239,20 @@
}, filter, null, getHandler());
}
+ /**
+ * This method posts a blocking call to the handler thread, so it should not be called from
+ * that same thread.
+ * @throws {@link IllegalStateException} if called from {@link #mHandlerThread}
+ */
@Override
public ParceledListSlice getAvailableRollbacks() {
enforceManageRollbacks("getAvailableRollbacks");
+ if (Thread.currentThread().equals(mHandlerThread)) {
+ Log.wtf(TAG, "Calling getAvailableRollbacks from mHandlerThread "
+ + "causes a deadlock");
+ throw new IllegalStateException("Cannot call RollbackManager#getAvailableRollbacks "
+ + "from the handler thread!");
+ }
// Wait for the handler thread to get the list of available rollbacks
// to get the most up-to-date results. This is intended to reduce test
diff --git a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
index 0891ba4..9decb58 100644
--- a/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/wm/ActivityMetricsLogger.java
@@ -965,16 +965,13 @@
* @param info
* */
private void startTraces(WindowingModeTransitionInfo info) {
- if (info == null) {
+ if (!Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER) || info == null
+ || info.launchTraceActive) {
return;
}
- int transitionType = getTransitionType(info);
- if (!info.launchTraceActive && transitionType == TYPE_TRANSITION_WARM_LAUNCH
- || transitionType == TYPE_TRANSITION_COLD_LAUNCH) {
- Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "launching: "
- + info.launchedActivity.packageName, 0);
- info.launchTraceActive = true;
- }
+ Trace.asyncTraceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "launching: "
+ + info.launchedActivity.packageName, 0);
+ info.launchTraceActive = true;
}
private void stopLaunchTrace(WindowingModeTransitionInfo info) {
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index c4aef30..fe99fd2 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -3055,21 +3055,7 @@
ActivityOptions.abort(options);
if (DEBUG_STATES) Slog.d(TAG_STATES,
"resumeTopActivityInNextFocusableStack: " + reason + ", go home");
- if (isActivityTypeHome()) {
- // resumeTopActivityUncheckedLocked has been prevented to run recursively. Post a
- // runnable to resume home since we are currently in the process of resuming top
- // activity in home stack.
- // See {@link #mInResumeTopActivity}.
- mService.mH.post(
- () -> {
- synchronized (mService.mGlobalLock) {
- mRootActivityContainer.resumeHomeActivity(prev, reason, mDisplayId);
- }
- });
- return true;
- } else {
- return mRootActivityContainer.resumeHomeActivity(prev, reason, mDisplayId);
- }
+ return mRootActivityContainer.resumeHomeActivity(prev, reason, mDisplayId);
}
/** Returns the position the input task should be placed in this stack. */
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index 6a5c84a..652f7ee 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -90,6 +90,9 @@
import static com.android.server.wm.DisplayContentProto.SCREEN_ROTATION_ANIMATION;
import static com.android.server.wm.DisplayContentProto.STACKS;
import static com.android.server.wm.DisplayContentProto.WINDOW_CONTAINER;
+import static com.android.server.wm.DisplayContentProto.OPENING_APPS;
+import static com.android.server.wm.DisplayContentProto.CHANGING_APPS;
+import static com.android.server.wm.DisplayContentProto.CLOSING_APPS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_ADD_REMOVE;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_APP_TRANSITIONS;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_BOOT;
@@ -2736,6 +2739,15 @@
if (mFocusedApp != null) {
mFocusedApp.writeNameToProto(proto, FOCUSED_APP);
}
+ for (int i = mOpeningApps.size() - 1; i >= 0; i--) {
+ mOpeningApps.valueAt(i).mActivityRecord.writeIdentifierToProto(proto, OPENING_APPS);
+ }
+ for (int i = mClosingApps.size() - 1; i >= 0; i--) {
+ mClosingApps.valueAt(i).mActivityRecord.writeIdentifierToProto(proto, CLOSING_APPS);
+ }
+ for (int i = mChangingApps.size() - 1; i >= 0; i--) {
+ mChangingApps.valueAt(i).mActivityRecord.writeIdentifierToProto(proto, CHANGING_APPS);
+ }
proto.end(token);
}
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 26430fb..c23cdbb 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -2720,11 +2720,18 @@
private void updateCurrentUserResources() {
final int userId = mService.mAmInternal.getCurrentUserId();
final Context uiContext = getSystemUiContext();
+
+ if (userId == UserHandle.USER_SYSTEM) {
+ // Skip the (expensive) recreation of resources for the system user below and just
+ // use the resources from the system ui context
+ mCurrentUserResources = uiContext.getResources();
+ return;
+ }
+
+ // For non-system users, ensure that the resources are loaded from the current
+ // user's package info (see ContextImpl.createDisplayContext)
final LoadedApk pi = ActivityThread.currentActivityThread().getPackageInfo(
uiContext.getPackageName(), null, 0, userId);
-
- // Create the resources from the current-user package info
- // (see ContextImpl.createDisplayContext)
mCurrentUserResources = ResourcesManager.getInstance().getResources(null,
pi.getResDir(),
null /* splitResDirs */,
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index be227e7..ed41642 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -1906,7 +1906,8 @@
if (this.meteredOverride != METERED_OVERRIDE_NONE) {
sbuf.append(" meteredOverride ").append(meteredOverride).append("\n");
}
- sbuf.append(" macRandomizationSetting ").append(macRandomizationSetting).append("\n");
+ sbuf.append(" macRandomizationSetting: ").append(macRandomizationSetting).append("\n");
+ sbuf.append(" mRandomizedMacAddress: ").append(mRandomizedMacAddress).append("\n");
sbuf.append(" KeyMgmt:");
for (int k = 0; k < this.allowedKeyManagement.size(); k++) {
if (this.allowedKeyManagement.get(k)) {