summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.txt10
-rw-r--r--api/system-current.txt10
-rw-r--r--api/test-current.txt10
-rw-r--r--core/java/android/provider/CallLog.java39
-rw-r--r--core/java/android/security/net/config/NetworkSecurityTrustManager.java38
-rw-r--r--core/java/android/security/net/config/RootTrustManager.java62
-rw-r--r--core/java/android/view/inputmethod/InputMethodManager.java56
-rw-r--r--core/java/android/widget/ListView.java83
-rw-r--r--libs/hwui/FrameBuilder.cpp12
-rw-r--r--libs/hwui/RecordedOp.h8
-rw-r--r--libs/hwui/RecordingCanvas.cpp8
-rw-r--r--libs/hwui/tests/common/TestUtils.cpp1
-rw-r--r--libs/hwui/tests/unit/FrameBuilderTests.cpp51
-rw-r--r--libs/hwui/tests/unit/RecordingCanvasTests.cpp22
-rw-r--r--location/java/android/location/GnssMeasurement.java102
-rw-r--r--wifi/java/android/net/wifi/WifiScanner.java5
16 files changed, 412 insertions, 105 deletions
diff --git a/api/current.txt b/api/current.txt
index 9a43a3bbdce9..0857c8bb696e 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -19253,10 +19253,19 @@ package android.location {
field public static final int MULTIPATH_INDICATOR_DETECTED = 1; // 0x1
field public static final int MULTIPATH_INDICATOR_NOT_USED = 2; // 0x2
field public static final int MULTIPATH_INDICATOR_UNKNOWN = 0; // 0x0
+ field public static final int STATE_BDS_D2_BIT_SYNC = 256; // 0x100
+ field public static final int STATE_BDS_D2_SUBFRAME_SYNC = 512; // 0x200
field public static final int STATE_BIT_SYNC = 2; // 0x2
field public static final int STATE_CODE_LOCK = 1; // 0x1
+ field public static final int STATE_GAL_E1BC_CODE_LOCK = 1024; // 0x400
+ field public static final int STATE_GAL_E1B_PAGE_SYNC = 4096; // 0x1000
+ field public static final int STATE_GAL_E1C_2ND_CODE_LOCK = 2048; // 0x800
+ field public static final int STATE_GLO_STRING_SYNC = 64; // 0x40
+ field public static final int STATE_GLO_TOD_DECODED = 128; // 0x80
field public static final int STATE_MSEC_AMBIGUOUS = 16; // 0x10
+ field public static final int STATE_SBAS_SYNC = 8192; // 0x2000
field public static final int STATE_SUBFRAME_SYNC = 4; // 0x4
+ field public static final int STATE_SYMBOL_SYNC = 32; // 0x20
field public static final int STATE_TOW_DECODED = 8; // 0x8
field public static final int STATE_UNKNOWN = 0; // 0x0
}
@@ -30764,6 +30773,7 @@ package android.provider {
field public static final int REJECTED_TYPE = 5; // 0x5
field public static final java.lang.String TRANSCRIPTION = "transcription";
field public static final java.lang.String TYPE = "type";
+ field public static final java.lang.String VIA_NUMBER = "via_number";
field public static final int VOICEMAIL_TYPE = 4; // 0x4
field public static final java.lang.String VOICEMAIL_URI = "voicemail_uri";
}
diff --git a/api/system-current.txt b/api/system-current.txt
index e325450d2687..219abdfabce0 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -20425,10 +20425,19 @@ package android.location {
field public static final int MULTIPATH_INDICATOR_DETECTED = 1; // 0x1
field public static final int MULTIPATH_INDICATOR_NOT_USED = 2; // 0x2
field public static final int MULTIPATH_INDICATOR_UNKNOWN = 0; // 0x0
+ field public static final int STATE_BDS_D2_BIT_SYNC = 256; // 0x100
+ field public static final int STATE_BDS_D2_SUBFRAME_SYNC = 512; // 0x200
field public static final int STATE_BIT_SYNC = 2; // 0x2
field public static final int STATE_CODE_LOCK = 1; // 0x1
+ field public static final int STATE_GAL_E1BC_CODE_LOCK = 1024; // 0x400
+ field public static final int STATE_GAL_E1B_PAGE_SYNC = 4096; // 0x1000
+ field public static final int STATE_GAL_E1C_2ND_CODE_LOCK = 2048; // 0x800
+ field public static final int STATE_GLO_STRING_SYNC = 64; // 0x40
+ field public static final int STATE_GLO_TOD_DECODED = 128; // 0x80
field public static final int STATE_MSEC_AMBIGUOUS = 16; // 0x10
+ field public static final int STATE_SBAS_SYNC = 8192; // 0x2000
field public static final int STATE_SUBFRAME_SYNC = 4; // 0x4
+ field public static final int STATE_SYMBOL_SYNC = 32; // 0x20
field public static final int STATE_TOW_DECODED = 8; // 0x8
field public static final int STATE_UNKNOWN = 0; // 0x0
}
@@ -33078,6 +33087,7 @@ package android.provider {
field public static final int REJECTED_TYPE = 5; // 0x5
field public static final java.lang.String TRANSCRIPTION = "transcription";
field public static final java.lang.String TYPE = "type";
+ field public static final java.lang.String VIA_NUMBER = "via_number";
field public static final int VOICEMAIL_TYPE = 4; // 0x4
field public static final java.lang.String VOICEMAIL_URI = "voicemail_uri";
}
diff --git a/api/test-current.txt b/api/test-current.txt
index 4140b3a8594f..6cf047a2d411 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -19308,10 +19308,19 @@ package android.location {
field public static final int MULTIPATH_INDICATOR_DETECTED = 1; // 0x1
field public static final int MULTIPATH_INDICATOR_NOT_USED = 2; // 0x2
field public static final int MULTIPATH_INDICATOR_UNKNOWN = 0; // 0x0
+ field public static final int STATE_BDS_D2_BIT_SYNC = 256; // 0x100
+ field public static final int STATE_BDS_D2_SUBFRAME_SYNC = 512; // 0x200
field public static final int STATE_BIT_SYNC = 2; // 0x2
field public static final int STATE_CODE_LOCK = 1; // 0x1
+ field public static final int STATE_GAL_E1BC_CODE_LOCK = 1024; // 0x400
+ field public static final int STATE_GAL_E1B_PAGE_SYNC = 4096; // 0x1000
+ field public static final int STATE_GAL_E1C_2ND_CODE_LOCK = 2048; // 0x800
+ field public static final int STATE_GLO_STRING_SYNC = 64; // 0x40
+ field public static final int STATE_GLO_TOD_DECODED = 128; // 0x80
field public static final int STATE_MSEC_AMBIGUOUS = 16; // 0x10
+ field public static final int STATE_SBAS_SYNC = 8192; // 0x2000
field public static final int STATE_SUBFRAME_SYNC = 4; // 0x4
+ field public static final int STATE_SYMBOL_SYNC = 32; // 0x20
field public static final int STATE_TOW_DECODED = 8; // 0x8
field public static final int STATE_UNKNOWN = 0; // 0x0
}
@@ -30833,6 +30842,7 @@ package android.provider {
field public static final int REJECTED_TYPE = 5; // 0x5
field public static final java.lang.String TRANSCRIPTION = "transcription";
field public static final java.lang.String TYPE = "type";
+ field public static final java.lang.String VIA_NUMBER = "via_number";
field public static final int VOICEMAIL_TYPE = 4; // 0x4
field public static final java.lang.String VOICEMAIL_URI = "voicemail_uri";
}
diff --git a/core/java/android/provider/CallLog.java b/core/java/android/provider/CallLog.java
index e2ae133cf6e9..8ac185a93989 100644
--- a/core/java/android/provider/CallLog.java
+++ b/core/java/android/provider/CallLog.java
@@ -440,6 +440,13 @@ public class CallLog {
public static final String POST_DIAL_DIGITS = "post_dial_digits";
/**
+ * For an incoming call, the secondary line number the call was received via.
+ * When a SIM card has multiple phone numbers associated with it, the via number indicates
+ * which of the numbers associated with the SIM was called.
+ */
+ public static final String VIA_NUMBER = "via_number";
+
+ /**
* Indicates that the entry will be copied from primary user to other users.
* <P>Type: INTEGER</P>
*
@@ -485,10 +492,10 @@ public class CallLog {
public static Uri addCall(CallerInfo ci, Context context, String number,
int presentation, int callType, int features, PhoneAccountHandle accountHandle,
long start, int duration, Long dataUsage) {
- return addCall(ci, context, number, /* postDialDigits =*/ "", presentation,
- callType, features, accountHandle,
- start, duration, dataUsage, /* addForAllUsers =*/ false,
- /* userToBeInsertedTo =*/ null, /* is_read =*/ false);
+ return addCall(ci, context, number, /* postDialDigits =*/ "", /* viaNumber =*/ "",
+ presentation, callType, features, accountHandle, start, duration,
+ dataUsage, /* addForAllUsers =*/ false, /* userToBeInsertedTo =*/ null,
+ /* is_read =*/ false);
}
@@ -499,6 +506,8 @@ public class CallLog {
* if the contact is unknown.
* @param context the context used to get the ContentResolver
* @param number the phone number to be added to the calls db
+ * @param viaNumber the secondary number that the incoming call received with. If the
+ * call was received with the SIM assigned number, then this field must be ''.
* @param presentation enum value from PhoneConstants.PRESENTATION_xxx, which
* is set by the network and denotes the number presenting rules for
* "allowed", "payphone", "restricted" or "unknown"
@@ -519,12 +528,12 @@ public class CallLog {
* {@hide}
*/
public static Uri addCall(CallerInfo ci, Context context, String number,
- String postDialDigits, int presentation, int callType, int features,
- PhoneAccountHandle accountHandle, long start, int duration, Long dataUsage,
- boolean addForAllUsers, UserHandle userToBeInsertedTo) {
- return addCall(ci, context, number, postDialDigits, presentation, callType, features,
- accountHandle, start, duration, dataUsage, addForAllUsers, userToBeInsertedTo,
- /* is_read =*/ false);
+ String postDialDigits, String viaNumber, int presentation, int callType,
+ int features, PhoneAccountHandle accountHandle, long start, int duration,
+ Long dataUsage, boolean addForAllUsers, UserHandle userToBeInsertedTo) {
+ return addCall(ci, context, number, postDialDigits, viaNumber, presentation, callType,
+ features, accountHandle, start, duration, dataUsage, addForAllUsers,
+ userToBeInsertedTo, /* is_read =*/ false);
}
/**
@@ -536,6 +545,8 @@ public class CallLog {
* @param number the phone number to be added to the calls db
* @param postDialDigits the post-dial digits that were dialed after the number,
* if it was outgoing. Otherwise it is ''.
+ * @param viaNumber the secondary number that the incoming call received with. If the
+ * call was received with the SIM assigned number, then this field must be ''.
* @param presentation enum value from PhoneConstants.PRESENTATION_xxx, which
* is set by the network and denotes the number presenting rules for
* "allowed", "payphone", "restricted" or "unknown"
@@ -560,9 +571,10 @@ public class CallLog {
* {@hide}
*/
public static Uri addCall(CallerInfo ci, Context context, String number,
- String postDialDigits, int presentation, int callType, int features,
- PhoneAccountHandle accountHandle, long start, int duration, Long dataUsage,
- boolean addForAllUsers, UserHandle userToBeInsertedTo, boolean is_read) {
+ String postDialDigits, String viaNumber, int presentation, int callType,
+ int features, PhoneAccountHandle accountHandle, long start, int duration,
+ Long dataUsage, boolean addForAllUsers, UserHandle userToBeInsertedTo,
+ boolean is_read) {
if (VERBOSE_LOG) {
Log.v(LOG_TAG, String.format("Add call: number=%s, user=%s, for all=%s",
number, userToBeInsertedTo, addForAllUsers));
@@ -618,6 +630,7 @@ public class CallLog {
values.put(NUMBER, number);
values.put(POST_DIAL_DIGITS, postDialDigits);
+ values.put(VIA_NUMBER, viaNumber);
values.put(NUMBER_PRESENTATION, Integer.valueOf(numberPresentation));
values.put(TYPE, Integer.valueOf(callType));
values.put(FEATURES, features);
diff --git a/core/java/android/security/net/config/NetworkSecurityTrustManager.java b/core/java/android/security/net/config/NetworkSecurityTrustManager.java
index f2c718cde1b1..3c292ca54578 100644
--- a/core/java/android/security/net/config/NetworkSecurityTrustManager.java
+++ b/core/java/android/security/net/config/NetworkSecurityTrustManager.java
@@ -20,6 +20,7 @@ import com.android.org.conscrypt.TrustManagerImpl;
import android.util.ArrayMap;
import java.io.IOException;
+import java.net.Socket;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.security.GeneralSecurityException;
@@ -29,14 +30,15 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
-import javax.net.ssl.X509TrustManager;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.X509ExtendedTrustManager;
/**
- * {@link X509TrustManager} that implements the trust anchor and pinning for a
+ * {@link X509ExtendedTrustManager} that implements the trust anchor and pinning for a
* given {@link NetworkSecurityConfig}.
* @hide
*/
-public class NetworkSecurityTrustManager implements X509TrustManager {
+public class NetworkSecurityTrustManager extends X509ExtendedTrustManager {
// TODO: Replace this with a general X509TrustManager and use duck-typing.
private final TrustManagerImpl mDelegate;
private final NetworkSecurityConfig mNetworkSecurityConfig;
@@ -68,9 +70,37 @@ public class NetworkSecurityTrustManager implements X509TrustManager {
}
@Override
+ public void checkClientTrusted(X509Certificate[] certs, String authType, Socket socket)
+ throws CertificateException {
+ mDelegate.checkClientTrusted(certs, authType, socket);
+ }
+
+ @Override
+ public void checkClientTrusted(X509Certificate[] certs, String authType, SSLEngine engine)
+ throws CertificateException {
+ mDelegate.checkClientTrusted(certs, authType, engine);
+ }
+
+ @Override
public void checkServerTrusted(X509Certificate[] certs, String authType)
throws CertificateException {
- checkServerTrusted(certs, authType, null);
+ checkServerTrusted(certs, authType, (String) null);
+ }
+
+ @Override
+ public void checkServerTrusted(X509Certificate[] certs, String authType, Socket socket)
+ throws CertificateException {
+ List<X509Certificate> trustedChain =
+ mDelegate.getTrustedChainForServer(certs, authType, socket);
+ checkPins(trustedChain);
+ }
+
+ @Override
+ public void checkServerTrusted(X509Certificate[] certs, String authType, SSLEngine engine)
+ throws CertificateException {
+ List<X509Certificate> trustedChain =
+ mDelegate.getTrustedChainForServer(certs, authType, engine);
+ checkPins(trustedChain);
}
/**
diff --git a/core/java/android/security/net/config/RootTrustManager.java b/core/java/android/security/net/config/RootTrustManager.java
index b4e58e6e9da6..19f688787abe 100644
--- a/core/java/android/security/net/config/RootTrustManager.java
+++ b/core/java/android/security/net/config/RootTrustManager.java
@@ -16,24 +16,28 @@
package android.security.net.config;
+import java.net.Socket;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.List;
-import javax.net.ssl.X509TrustManager;
+import javax.net.ssl.SSLSocket;
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.X509ExtendedTrustManager;
/**
- * {@link X509TrustManager} based on an {@link ApplicationConfig}.
+ * {@link X509ExtendedTrustManager} based on an {@link ApplicationConfig}.
*
- * <p>This {@code X509TrustManager} delegates to the specific trust manager for the hostname
- * being used for the connection (See {@link ApplicationConfig#getConfigForHostname(String)} and
+ * <p>This trust manager delegates to the specific trust manager for the hostname being used for
+ * the connection (See {@link ApplicationConfig#getConfigForHostname(String)} and
* {@link NetworkSecurityTrustManager}).</p>
*
* Note that if the {@code ApplicationConfig} has per-domain configurations the hostname aware
* {@link #checkServerTrusted(X509Certificate[], String String)} must be used instead of the normal
* non-aware call.
* @hide */
-public class RootTrustManager implements X509TrustManager {
+public class RootTrustManager extends X509ExtendedTrustManager {
private final ApplicationConfig mConfig;
public RootTrustManager(ApplicationConfig config) {
@@ -53,6 +57,54 @@ public class RootTrustManager implements X509TrustManager {
}
@Override
+ public void checkClientTrusted(X509Certificate[] certs, String authType, Socket socket)
+ throws CertificateException {
+ // Use the default configuration for all client authentication. Domain specific configs are
+ // only for use in checking server trust not client trust.
+ NetworkSecurityConfig config = mConfig.getConfigForHostname("");
+ config.getTrustManager().checkClientTrusted(certs, authType, socket);
+ }
+
+ @Override
+ public void checkClientTrusted(X509Certificate[] certs, String authType, SSLEngine engine)
+ throws CertificateException {
+ // Use the default configuration for all client authentication. Domain specific configs are
+ // only for use in checking server trust not client trust.
+ NetworkSecurityConfig config = mConfig.getConfigForHostname("");
+ config.getTrustManager().checkClientTrusted(certs, authType, engine);
+ }
+
+ @Override
+ public void checkServerTrusted(X509Certificate[] certs, String authType, Socket socket)
+ throws CertificateException {
+ if (socket instanceof SSLSocket) {
+ SSLSocket sslSocket = (SSLSocket) socket;
+ SSLSession session = sslSocket.getHandshakeSession();
+ if (session == null) {
+ throw new CertificateException("Not in handshake; no session available");
+ }
+ String host = session.getPeerHost();
+ NetworkSecurityConfig config = mConfig.getConfigForHostname(host);
+ config.getTrustManager().checkServerTrusted(certs, authType, socket);
+ } else {
+ // Not an SSLSocket, use the hostname unaware checkServerTrusted.
+ checkServerTrusted(certs, authType);
+ }
+ }
+
+ @Override
+ public void checkServerTrusted(X509Certificate[] certs, String authType, SSLEngine engine)
+ throws CertificateException {
+ SSLSession session = engine.getHandshakeSession();
+ if (session == null) {
+ throw new CertificateException("Not in handshake; no session available");
+ }
+ String host = session.getPeerHost();
+ NetworkSecurityConfig config = mConfig.getConfigForHostname(host);
+ config.getTrustManager().checkServerTrusted(certs, authType, engine);
+ }
+
+ @Override
public void checkServerTrusted(X509Certificate[] certs, String authType)
throws CertificateException {
if (mConfig.hasPerDomainConfigs()) {
diff --git a/core/java/android/view/inputmethod/InputMethodManager.java b/core/java/android/view/inputmethod/InputMethodManager.java
index 4bb0c3cbb5ee..f5908a50ec64 100644
--- a/core/java/android/view/inputmethod/InputMethodManager.java
+++ b/core/java/android/view/inputmethod/InputMethodManager.java
@@ -493,12 +493,7 @@ public final class InputMethodManager {
// Check focus again in case that "onWindowFocus" is called before
// handling this message.
if (mServedView != null && mServedView.hasWindowFocus()) {
- // Please note that this handler thread could be different
- // from a thread that created mServedView. That could happen
- // the current activity is running in the system process.
- // In that case, we really should not call
- // mServedInputConnectionWrapper.finishComposingText().
- if (checkFocusNoStartInput(mHasBeenInactive, false)) {
+ if (checkFocusNoStartInput(mHasBeenInactive)) {
final int reason = active ?
InputMethodClient.START_INPUT_REASON_ACTIVATED_BY_IMMS :
InputMethodClient.START_INPUT_REASON_DEACTIVATED_BY_IMMS;
@@ -832,7 +827,7 @@ public final class InputMethodManager {
void finishInputLocked() {
mNextServedView = null;
if (mServedView != null) {
- if (DEBUG) Log.v(TAG, "FINISH INPUT: " + mServedView);
+ if (DEBUG) Log.v(TAG, "FINISH INPUT: mServedView=" + dumpViewInfo(mServedView));
if (mCurrentTextBoxAttribute != null) {
try {
mService.finishInput(mClient);
@@ -1141,10 +1136,10 @@ public final class InputMethodManager {
final View view;
synchronized (mH) {
view = mServedView;
-
+
// Make sure we have a window token for the served view.
if (DEBUG) {
- Log.v(TAG, "Starting input: view=" + view +
+ Log.v(TAG, "Starting input: view=" + dumpViewInfo(view) +
" reason=" + InputMethodClient.getStartInputReason(startInputReason));
}
if (view == null) {
@@ -1152,7 +1147,7 @@ public final class InputMethodManager {
return false;
}
}
-
+
// Now we need to get an input connection from the served view.
// This is complicated in a couple ways: we can't be holding our lock
// when calling out to the view, and we need to make sure we call into
@@ -1197,9 +1192,10 @@ public final class InputMethodManager {
// changed.
if (mServedView != view || !mServedConnecting) {
// Something else happened, so abort.
- if (DEBUG) Log.v(TAG,
- "Starting input: finished by someone else (view="
- + mServedView + " conn=" + mServedConnecting + ")");
+ if (DEBUG) Log.v(TAG,
+ "Starting input: finished by someone else. view=" + dumpViewInfo(view)
+ + " mServedView=" + dumpViewInfo(mServedView)
+ + " mServedConnecting=" + mServedConnecting);
return false;
}
@@ -1243,7 +1239,7 @@ public final class InputMethodManager {
mServedInputConnectionWrapper = servedContext;
try {
- if (DEBUG) Log.v(TAG, "START INPUT: " + view + " ic="
+ if (DEBUG) Log.v(TAG, "START INPUT: view=" + dumpViewInfo(view) + " ic="
+ ic + " tba=" + tba + " controlFlags=#"
+ Integer.toHexString(controlFlags));
final InputBindResult res = mService.startInputOrWindowGainedFocus(
@@ -1309,7 +1305,7 @@ public final class InputMethodManager {
}
void focusInLocked(View view) {
- if (DEBUG) Log.v(TAG, "focusIn: " + view);
+ if (DEBUG) Log.v(TAG, "focusIn: " + dumpViewInfo(view));
if (mCurRootView != view.getRootView()) {
// This is a request from a window that isn't in the window with
@@ -1328,9 +1324,8 @@ public final class InputMethodManager {
*/
public void focusOut(View view) {
synchronized (mH) {
- if (DEBUG) Log.v(TAG, "focusOut: " + view
- + " mServedView=" + mServedView
- + " winFocus=" + view.hasWindowFocus());
+ if (DEBUG) Log.v(TAG, "focusOut: view=" + dumpViewInfo(view)
+ + " mServedView=" + dumpViewInfo(mServedView));
if (mServedView != view) {
// The following code would auto-hide the IME if we end up
// with no more views with focus. This can happen, however,
@@ -1351,9 +1346,8 @@ public final class InputMethodManager {
*/
public void onViewDetachedFromWindow(View view) {
synchronized (mH) {
- if (DEBUG) Log.v(TAG, "onViewDetachedFromWindow: " + view
- + " mServedView=" + mServedView
- + " hasWindowFocus=" + view.hasWindowFocus());
+ if (DEBUG) Log.v(TAG, "onViewDetachedFromWindow: view=" + dumpViewInfo(view)
+ + " mServedView=" + dumpViewInfo(mServedView));
if (mServedView == view && view.hasWindowFocus()) {
mNextServedView = null;
scheduleCheckFocusLocked(view);
@@ -1372,12 +1366,12 @@ public final class InputMethodManager {
* @hide
*/
public void checkFocus() {
- if (checkFocusNoStartInput(false, true)) {
+ if (checkFocusNoStartInput(false)) {
startInputInner(InputMethodClient.START_INPUT_REASON_CHECK_FOCUS, null, 0, 0, 0);
}
}
- private boolean checkFocusNoStartInput(boolean forceNewFocus, boolean finishComposingText) {
+ private boolean checkFocusNoStartInput(boolean forceNewFocus) {
// This is called a lot, so short-circuit before locking.
if (mServedView == mNextServedView && !forceNewFocus) {
return false;
@@ -1411,7 +1405,7 @@ public final class InputMethodManager {
mServedConnecting = true;
}
- if (finishComposingText && ic != null) {
+ if (ic != null) {
ic.finishComposingText();
}
@@ -1457,7 +1451,7 @@ public final class InputMethodManager {
controlFlags |= CONTROL_WINDOW_FIRST;
}
- if (checkFocusNoStartInput(forceNewFocus, true)) {
+ if (checkFocusNoStartInput(forceNewFocus)) {
// We need to restart input on the current focus view. This
// should be done in conjunction with telling the system service
// about the window gaining focus, to help make the transition
@@ -2311,4 +2305,16 @@ public final class InputMethodManager {
}
}
}
+
+ private static String dumpViewInfo(@Nullable final View view) {
+ if (view == null) {
+ return "null";
+ }
+ final StringBuilder sb = new StringBuilder();
+ sb.append(view);
+ sb.append(",focus=" + view.hasFocus());
+ sb.append(",windowFocus=" + view.hasWindowFocus());
+ sb.append(",window=" + view.getWindowToken());
+ return sb.toString();
+ }
}
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 5b4a3685bbdc..7658cc894913 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -16,15 +16,14 @@
package android.widget;
-import android.annotation.Nullable;
-import android.os.Bundle;
-import android.os.Trace;
+import com.google.android.collect.Lists;
+
import com.android.internal.R;
import com.android.internal.util.Predicate;
-import com.google.android.collect.Lists;
import android.annotation.IdRes;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.Context;
import android.content.Intent;
import android.content.res.TypedArray;
@@ -33,6 +32,8 @@ import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
+import android.os.Bundle;
+import android.os.Trace;
import android.util.AttributeSet;
import android.util.MathUtils;
import android.util.SparseBooleanArray;
@@ -1106,20 +1107,63 @@ public class ListView extends AbsListView {
}
private class FocusSelector implements Runnable {
+ // the selector is waiting to set selection on the list view
+ private static final int STATE_SET_SELECTION = 1;
+ // the selector set the selection on the list view, waiting for a layoutChildren pass
+ private static final int STATE_WAIT_FOR_LAYOUT = 2;
+ // the selector's selection has been honored and it is waiting to request focus on the
+ // target child.
+ private static final int STATE_REQUEST_FOCUS = 3;
+
+ private int mAction;
private int mPosition;
private int mPositionTop;
-
- public FocusSelector setup(int position, int top) {
+
+ FocusSelector setupForSetSelection(int position, int top) {
mPosition = position;
mPositionTop = top;
+ mAction = STATE_SET_SELECTION;
return this;
}
-
+
public void run() {
- setSelectionFromTop(mPosition, mPositionTop);
+ if (mAction == STATE_SET_SELECTION) {
+ setSelectionFromTop(mPosition, mPositionTop);
+ mAction = STATE_WAIT_FOR_LAYOUT;
+ } else if (mAction == STATE_REQUEST_FOCUS) {
+ final int childIndex = mPosition - mFirstPosition;
+ final View child = getChildAt(childIndex);
+ if (child != null) {
+ child.requestFocus();
+ }
+ mAction = -1;
+ }
+ }
+
+ @Nullable Runnable setupFocusIfValid(int position) {
+ if (mAction != STATE_WAIT_FOR_LAYOUT || position != mPosition) {
+ return null;
+ }
+ mAction = STATE_REQUEST_FOCUS;
+ return this;
+ }
+
+ void onLayoutComplete() {
+ if (mAction == STATE_WAIT_FOR_LAYOUT) {
+ mAction = -1;
+ }
}
}
-
+
+ @Override
+ protected void onDetachedFromWindow() {
+ if (mFocusSelector != null) {
+ removeCallbacks(mFocusSelector);
+ mFocusSelector = null;
+ }
+ super.onDetachedFromWindow();
+ }
+
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
if (getChildCount() > 0) {
@@ -1132,7 +1176,7 @@ public class ListView extends AbsListView {
if (mFocusSelector == null) {
mFocusSelector = new FocusSelector();
}
- post(mFocusSelector.setup(childPosition, top));
+ post(mFocusSelector.setupForSetSelection(childPosition, top));
}
}
super.onSizeChanged(w, h, oldw, oldh);
@@ -1672,7 +1716,21 @@ public class ListView extends AbsListView {
adjustViewsUpOrDown();
break;
case LAYOUT_SPECIFIC:
- sel = fillSpecific(reconcileSelectedPosition(), mSpecificTop);
+ final int selectedPosition = reconcileSelectedPosition();
+ sel = fillSpecific(selectedPosition, mSpecificTop);
+ /**
+ * When ListView is resized, FocusSelector requests an async selection for the
+ * previously focused item to make sure it is still visible. If the item is not
+ * selectable, it won't regain focus so instead we call FocusSelector
+ * to directly request focus on the view after it is visible.
+ */
+ if (sel == null && mFocusSelector != null) {
+ final Runnable focusRunnable = mFocusSelector
+ .setupFocusIfValid(selectedPosition);
+ if (focusRunnable != null) {
+ post(focusRunnable);
+ }
+ }
break;
case LAYOUT_MOVE_SELECTION:
sel = moveSelection(oldSel, newSel, delta, childrenTop, childrenBottom);
@@ -1812,6 +1870,9 @@ public class ListView extends AbsListView {
invokeOnItemScrollListener();
} finally {
+ if (mFocusSelector != null) {
+ mFocusSelector.onLayoutComplete();
+ }
if (!blockLayoutRequests) {
mBlockLayoutRequests = false;
}
diff --git a/libs/hwui/FrameBuilder.cpp b/libs/hwui/FrameBuilder.cpp
index 0ebb8866bdb3..b1314feebf34 100644
--- a/libs/hwui/FrameBuilder.cpp
+++ b/libs/hwui/FrameBuilder.cpp
@@ -699,7 +699,17 @@ void FrameBuilder::deferTextOnPathOp(const TextOnPathOp& op) {
void FrameBuilder::deferTextureLayerOp(const TextureLayerOp& op) {
if (CC_UNLIKELY(!op.layer->isRenderable())) return;
- BakedOpState* bakedState = tryBakeOpState(op);
+
+ const TextureLayerOp* textureLayerOp = &op;
+ // Now safe to access transform (which was potentially unready at record time)
+ if (!op.layer->getTransform().isIdentity()) {
+ // non-identity transform present, so 'inject it' into op by copying + replacing matrix
+ Matrix4 combinedMatrix(op.localMatrix);
+ combinedMatrix.multiply(op.layer->getTransform());
+ textureLayerOp = mAllocator.create<TextureLayerOp>(op, combinedMatrix);
+ }
+ BakedOpState* bakedState = tryBakeOpState(*textureLayerOp);
+
if (!bakedState) return; // quick rejected
currentLayer().deferUnmergeableOp(mAllocator, bakedState, OpBatchType::TextureLayer);
}
diff --git a/libs/hwui/RecordedOp.h b/libs/hwui/RecordedOp.h
index 64c604a5ee44..0271a80d4c17 100644
--- a/libs/hwui/RecordedOp.h
+++ b/libs/hwui/RecordedOp.h
@@ -419,6 +419,14 @@ struct TextureLayerOp : RecordedOp {
TextureLayerOp(BASE_PARAMS_PAINTLESS, Layer* layer)
: SUPER_PAINTLESS(TextureLayerOp)
, layer(layer) {}
+
+ // Copy an existing TextureLayerOp, replacing the underlying matrix
+ TextureLayerOp(const TextureLayerOp& op, const Matrix4& replacementMatrix)
+ : RecordedOp(RecordedOpId::TextureLayerOp, op.unmappedBounds, replacementMatrix,
+ op.localClip, op.paint)
+ , layer(op.layer) {
+
+ }
Layer* layer;
};
diff --git a/libs/hwui/RecordingCanvas.cpp b/libs/hwui/RecordingCanvas.cpp
index f43dadeca034..4f9cd688d4b6 100644
--- a/libs/hwui/RecordingCanvas.cpp
+++ b/libs/hwui/RecordingCanvas.cpp
@@ -576,15 +576,9 @@ void RecordingCanvas::drawLayer(DeferredLayerUpdater* layerHandle) {
// Note that the backing layer has *not* yet been updated, so don't trust
// its width, height, transform, etc...!
- Matrix4 totalTransform(*(mState.currentSnapshot()->transform));
- if (layerHandle->getTransform()) {
- Matrix4 layerTransform(*layerHandle->getTransform());
- totalTransform.multiply(layerTransform);
- }
-
addOp(alloc().create_trivial<TextureLayerOp>(
Rect(layerHandle->getWidth(), layerHandle->getHeight()),
- totalTransform,
+ *(mState.currentSnapshot()->transform),
getRecordedClip(),
layerHandle->backingLayer()));
}
diff --git a/libs/hwui/tests/common/TestUtils.cpp b/libs/hwui/tests/common/TestUtils.cpp
index 059e9ae56a21..c762eed616e4 100644
--- a/libs/hwui/tests/common/TestUtils.cpp
+++ b/libs/hwui/tests/common/TestUtils.cpp
@@ -44,6 +44,7 @@ sp<DeferredLayerUpdater> TestUtils::createTextureLayerUpdater(
renderthread::RenderThread& renderThread, uint32_t width, uint32_t height,
const SkMatrix& transform) {
Layer* layer = LayerRenderer::createTextureLayer(renderThread.renderState());
+ layer->getTransform().load(transform);
sp<DeferredLayerUpdater> layerUpdater = new DeferredLayerUpdater(layer);
layerUpdater->setSize(width, height);
diff --git a/libs/hwui/tests/unit/FrameBuilderTests.cpp b/libs/hwui/tests/unit/FrameBuilderTests.cpp
index dca56d425f3a..e97aaa6ac688 100644
--- a/libs/hwui/tests/unit/FrameBuilderTests.cpp
+++ b/libs/hwui/tests/unit/FrameBuilderTests.cpp
@@ -372,8 +372,8 @@ RENDERTHREAD_TEST(FrameBuilder, textStyle) {
EXPECT_EQ(3, renderer.getIndex()) << "Expect 3 ops";
}
-RENDERTHREAD_TEST(FrameBuilder, textureLayer) {
- class TextureLayerTestRenderer : public TestRendererBase {
+RENDERTHREAD_TEST(FrameBuilder, textureLayer_clipLocalMatrix) {
+ class TextureLayerClipLocalMatrixTestRenderer : public TestRendererBase {
public:
void onTextureLayerOp(const TextureLayerOp& op, const BakedOpState& state) override {
EXPECT_EQ(0, mIndex++);
@@ -398,11 +398,56 @@ RENDERTHREAD_TEST(FrameBuilder, textureLayer) {
});
FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200,
TestUtils::createSyncedNodeList(node), sLightGeometry, Caches::getInstance());
- TextureLayerTestRenderer renderer;
+ TextureLayerClipLocalMatrixTestRenderer renderer;
frameBuilder.replayBakedOps<TestDispatcher>(renderer);
EXPECT_EQ(1, renderer.getIndex());
}
+RENDERTHREAD_TEST(FrameBuilder, textureLayer_combineMatrices) {
+ class TextureLayerCombineMatricesTestRenderer : public TestRendererBase {
+ public:
+ void onTextureLayerOp(const TextureLayerOp& op, const BakedOpState& state) override {
+ EXPECT_EQ(0, mIndex++);
+
+ Matrix4 expected;
+ expected.loadTranslate(35, 45, 0);
+ EXPECT_MATRIX_APPROX_EQ(expected, state.computedState.transform);
+ }
+ };
+
+ auto layerUpdater = TestUtils::createTextureLayerUpdater(renderThread, 100, 100,
+ SkMatrix::MakeTrans(5, 5));
+
+ auto node = TestUtils::createNode(0, 0, 200, 200,
+ [&layerUpdater](RenderProperties& props, RecordingCanvas& canvas) {
+ canvas.save(SaveFlags::MatrixClip);
+ canvas.translate(30, 40);
+ canvas.drawLayer(layerUpdater.get());
+ canvas.restore();
+ });
+
+ FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200,
+ TestUtils::createSyncedNodeList(node), sLightGeometry, Caches::getInstance());
+ TextureLayerCombineMatricesTestRenderer renderer;
+ frameBuilder.replayBakedOps<TestDispatcher>(renderer);
+ EXPECT_EQ(1, renderer.getIndex());
+}
+
+RENDERTHREAD_TEST(FrameBuilder, textureLayer_reject) {
+ auto layerUpdater = TestUtils::createTextureLayerUpdater(renderThread, 100, 100,
+ SkMatrix::MakeTrans(5, 5));
+ layerUpdater->backingLayer()->setRenderTarget(GL_NONE); // Should be rejected
+
+ auto node = TestUtils::createNode(0, 0, 200, 200,
+ [&layerUpdater](RenderProperties& props, RecordingCanvas& canvas) {
+ canvas.drawLayer(layerUpdater.get());
+ });
+ FrameBuilder frameBuilder(sEmptyLayerUpdateQueue, SkRect::MakeWH(200, 200), 200, 200,
+ TestUtils::createSyncedNodeList(node), sLightGeometry, Caches::getInstance());
+ FailRenderer renderer;
+ frameBuilder.replayBakedOps<TestDispatcher>(renderer);
+}
+
RENDERTHREAD_TEST(FrameBuilder, functor_reject) {
class FunctorTestRenderer : public TestRendererBase {
public:
diff --git a/libs/hwui/tests/unit/RecordingCanvasTests.cpp b/libs/hwui/tests/unit/RecordingCanvasTests.cpp
index 33108c75e97d..58376c64d518 100644
--- a/libs/hwui/tests/unit/RecordingCanvasTests.cpp
+++ b/libs/hwui/tests/unit/RecordingCanvasTests.cpp
@@ -16,6 +16,7 @@
#include <gtest/gtest.h>
+#include <DeferredLayerUpdater.h>
#include <RecordedOp.h>
#include <RecordingCanvas.h>
#include <hwui/Paint.h>
@@ -39,6 +40,12 @@ static void playbackOps(const DisplayList& displayList,
}
}
+static void validateSingleOp(std::unique_ptr<DisplayList>& dl,
+ std::function<void(const RecordedOp& op)> opValidator) {
+ ASSERT_EQ(1u, dl->getOps().size()) << "Must be exactly one op";
+ opValidator(*(dl->getOps()[0]));
+}
+
TEST(RecordingCanvas, emptyPlayback) {
auto dl = TestUtils::createDisplayList<RecordingCanvas>(100, 200, [](RecordingCanvas& canvas) {
canvas.save(SaveFlags::MatrixClip);
@@ -284,6 +291,21 @@ TEST(RecordingCanvas, backgroundAndImage) {
ASSERT_EQ(2, count);
}
+RENDERTHREAD_TEST(RecordingCanvas, textureLayer) {
+ auto layerUpdater = TestUtils::createTextureLayerUpdater(renderThread, 100, 100,
+ SkMatrix::MakeTrans(5, 5));
+
+ auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200,
+ [&layerUpdater](RecordingCanvas& canvas) {
+ canvas.drawLayer(layerUpdater.get());
+ });
+
+ validateSingleOp(dl, [] (const RecordedOp& op) {
+ ASSERT_EQ(RecordedOpId::TextureLayerOp, op.opId);
+ ASSERT_TRUE(op.localMatrix.isIdentity()) << "Op must not apply matrix at record time.";
+ });
+}
+
TEST(RecordingCanvas, saveLayer_simple) {
auto dl = TestUtils::createDisplayList<RecordingCanvas>(200, 200, [](RecordingCanvas& canvas) {
canvas.saveLayerAlpha(10, 20, 190, 180, 128, SaveFlags::ClipToLayer);
diff --git a/location/java/android/location/GnssMeasurement.java b/location/java/android/location/GnssMeasurement.java
index 17ce5336187a..d78ccee11e5f 100644
--- a/location/java/android/location/GnssMeasurement.java
+++ b/location/java/android/location/GnssMeasurement.java
@@ -81,41 +81,42 @@ public final class GnssMeasurement implements Parcelable {
*/
public static final int MULTIPATH_INDICATOR_NOT_USED = 2;
- /**
- * The state of GNSS receiver the measurement is invalid or unknown.
- */
+ /** This GNSS measurement's tracking state is invalid or unknown. */
public static final int STATE_UNKNOWN = 0;
-
- /**
- * The state of the GNSS receiver is ranging code lock.
- */
+ /** This GNSS measurement's tracking state has code lock. */
public static final int STATE_CODE_LOCK = (1<<0);
-
- /**
- * The state of the GNSS receiver is in bit sync.
- */
+ /** This GNSS measurement's tracking state has bit sync. */
public static final int STATE_BIT_SYNC = (1<<1);
-
- /**
- *The state of the GNSS receiver is in sub-frame sync.
- */
+ /** This GNSS measurement's tracking state has sub-frame sync. */
public static final int STATE_SUBFRAME_SYNC = (1<<2);
-
- /**
- * The state of the GNSS receiver has TOW decoded.
- */
+ /** This GNSS measurement's tracking state has time-of-week decoded. */
public static final int STATE_TOW_DECODED = (1<<3);
-
- /**
- * The state of the GNSS receiver contains millisecond ambiguity.
- */
+ /** This GNSS measurement's tracking state contains millisecond ambiguity. */
public static final int STATE_MSEC_AMBIGUOUS = (1<<4);
-
- /**
- * All the GNSS receiver state flags.
- */
- private static final int STATE_ALL = STATE_CODE_LOCK | STATE_BIT_SYNC | STATE_SUBFRAME_SYNC
- | STATE_TOW_DECODED | STATE_MSEC_AMBIGUOUS;
+ /** This GNSS measurement's tracking state has symbol sync. */
+ public static final int STATE_SYMBOL_SYNC = (1<<5);
+ /** This Glonass measurement's tracking state has string sync. */
+ public static final int STATE_GLO_STRING_SYNC = (1<<6);
+ /** This Glonass measurement's tracking state has time-of-day decoded. */
+ public static final int STATE_GLO_TOD_DECODED = (1<<7);
+ /** This Beidou measurement's tracking state has D2 bit sync. */
+ public static final int STATE_BDS_D2_BIT_SYNC = (1<<8);
+ /** This Beidou measurement's tracking state has D2 sub-frame sync. */
+ public static final int STATE_BDS_D2_SUBFRAME_SYNC = (1<<9);
+ /** This Galileo measurement's tracking state has E1B/C code lock. */
+ public static final int STATE_GAL_E1BC_CODE_LOCK = (1<<10);
+ /** This Galileo measurement's tracking state has E1C secondary code lock. */
+ public static final int STATE_GAL_E1C_2ND_CODE_LOCK = (1<<11);
+ /** This Galileo measurement's tracking state has E1B page sync. */
+ public static final int STATE_GAL_E1B_PAGE_SYNC = (1<<12);
+ /** This SBAS measurement's tracking state has whole second level sync. */
+ public static final int STATE_SBAS_SYNC = (1<<13);
+
+ /**
+ * All the GNSS receiver state flags, for bit masking purposes (not a sensible state for any
+ * individual measurement.)
+ */
+ private static final int STATE_ALL = 0x3fff; // 2 bits + 4 bits + 4 bits + 4 bits = 14 bits
/**
* The state of the 'Accumulated Delta Range' is invalid or unknown.
@@ -276,29 +277,58 @@ public final class GnssMeasurement implements Parcelable {
if (mState == STATE_UNKNOWN) {
return "Unknown";
}
+
StringBuilder builder = new StringBuilder();
- if ((mState & STATE_CODE_LOCK) == STATE_CODE_LOCK) {
+ if ((mState & STATE_CODE_LOCK) != 0) {
builder.append("CodeLock|");
}
- if ((mState & STATE_BIT_SYNC) == STATE_BIT_SYNC) {
+ if ((mState & STATE_BIT_SYNC) != 0) {
builder.append("BitSync|");
}
- if ((mState & STATE_SUBFRAME_SYNC) == STATE_SUBFRAME_SYNC) {
+ if ((mState & STATE_SUBFRAME_SYNC) != 0) {
builder.append("SubframeSync|");
}
- if ((mState & STATE_TOW_DECODED) == STATE_TOW_DECODED) {
+ if ((mState & STATE_TOW_DECODED) != 0) {
builder.append("TowDecoded|");
}
- if ((mState & STATE_MSEC_AMBIGUOUS) == STATE_MSEC_AMBIGUOUS) {
- builder.append("MsecAmbiguous");
+ if ((mState & STATE_MSEC_AMBIGUOUS) != 0) {
+ builder.append("MsecAmbiguous|");
+ }
+ if ((mState & STATE_SYMBOL_SYNC) != 0) {
+ builder.append("SymbolSync|");
+ }
+ if ((mState & STATE_GLO_STRING_SYNC) != 0) {
+ builder.append("GloStringSync|");
+ }
+ if ((mState & STATE_GLO_TOD_DECODED) != 0) {
+ builder.append("GloTodDecoded|");
}
+ if ((mState & STATE_BDS_D2_BIT_SYNC) != 0) {
+ builder.append("BdsD2BitSync|");
+ }
+ if ((mState & STATE_BDS_D2_SUBFRAME_SYNC) != 0) {
+ builder.append("BdsD2SubframeSync|");
+ }
+ if ((mState & STATE_GAL_E1BC_CODE_LOCK) != 0) {
+ builder.append("GalE1bcCodeLock|");
+ }
+ if ((mState & STATE_GAL_E1C_2ND_CODE_LOCK) != 0) {
+ builder.append("E1c2ndCodeLock|");
+ }
+ if ((mState & STATE_GAL_E1B_PAGE_SYNC) != 0) {
+ builder.append("GalE1bPageSync|");
+ }
+ if ((mState & STATE_SBAS_SYNC) != 0) {
+ builder.append("SbasSync|");
+ }
+
int remainingStates = mState & ~STATE_ALL;
if (remainingStates > 0) {
builder.append("Other(");
builder.append(Integer.toBinaryString(remainingStates));
builder.append(")|");
}
- builder.deleteCharAt(builder.length() - 1);
+ builder.setLength(builder.length() - 1);
return builder.toString();
}
diff --git a/wifi/java/android/net/wifi/WifiScanner.java b/wifi/java/android/net/wifi/WifiScanner.java
index ecf54474f6f8..508bdff19f9c 100644
--- a/wifi/java/android/net/wifi/WifiScanner.java
+++ b/wifi/java/android/net/wifi/WifiScanner.java
@@ -322,6 +322,11 @@ public class WifiScanner {
return mFlags;
}
+ /** {@hide} */
+ public int getBucketsScanned() {
+ return mBucketsScanned;
+ }
+
public ScanResult[] getResults() {
return mResults;
}