diff options
| -rw-r--r-- | api/current.txt | 10 | ||||
| -rw-r--r-- | api/system-current.txt | 10 | ||||
| -rw-r--r-- | api/test-current.txt | 10 | ||||
| -rw-r--r-- | core/java/android/provider/CallLog.java | 39 | ||||
| -rw-r--r-- | core/java/android/security/net/config/NetworkSecurityTrustManager.java | 38 | ||||
| -rw-r--r-- | core/java/android/security/net/config/RootTrustManager.java | 62 | ||||
| -rw-r--r-- | core/java/android/view/inputmethod/InputMethodManager.java | 56 | ||||
| -rw-r--r-- | core/java/android/widget/ListView.java | 83 | ||||
| -rw-r--r-- | libs/hwui/FrameBuilder.cpp | 12 | ||||
| -rw-r--r-- | libs/hwui/RecordedOp.h | 8 | ||||
| -rw-r--r-- | libs/hwui/RecordingCanvas.cpp | 8 | ||||
| -rw-r--r-- | libs/hwui/tests/common/TestUtils.cpp | 1 | ||||
| -rw-r--r-- | libs/hwui/tests/unit/FrameBuilderTests.cpp | 51 | ||||
| -rw-r--r-- | libs/hwui/tests/unit/RecordingCanvasTests.cpp | 22 | ||||
| -rw-r--r-- | location/java/android/location/GnssMeasurement.java | 102 | ||||
| -rw-r--r-- | wifi/java/android/net/wifi/WifiScanner.java | 5 |
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; } |