diff options
15 files changed, 218 insertions, 115 deletions
diff --git a/api/current.txt b/api/current.txt index 0149a64..470aa56 100644 --- a/api/current.txt +++ b/api/current.txt @@ -28959,9 +28959,9 @@ package android.telephony { method public boolean isVoiceCapable(); method public void listen(android.telephony.PhoneStateListener, int); method public java.lang.String sendEnvelopeWithStatus(java.lang.String); - method public boolean setGlobalPreferredNetworkType(); method public boolean setLine1NumberForDisplay(java.lang.String, java.lang.String); method public boolean setOperatorBrandOverride(java.lang.String); + method public boolean setPreferredNetworkTypeToGlobal(); method public boolean setVoiceMailNumber(java.lang.String, java.lang.String); field public static final java.lang.String ACTION_PHONE_STATE_CHANGED = "android.intent.action.PHONE_STATE"; field public static final java.lang.String ACTION_RESPOND_VIA_MESSAGE = "android.intent.action.RESPOND_VIA_MESSAGE"; diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java index c5c6d06..69872ff 100644 --- a/core/java/android/app/admin/DevicePolicyManager.java +++ b/core/java/android/app/admin/DevicePolicyManager.java @@ -469,20 +469,20 @@ public class DevicePolicyManager { = "android.app.action.SET_NEW_PASSWORD"; /** - * Flag used by {@link #addCrossProfileIntentFilter} to allow access - * <em>from</em> a managed profile <em>to</em> its parent. That is, any - * matching activities in the parent profile are included in the - * disambiguation list shown when an app in the managed profile calls - * {@link Activity#startActivity(Intent)}. + * Flag used by {@link #addCrossProfileIntentFilter} to allow activities in + * the parent profile to access intents sent from the managed profile. + * That is, when an app in the managed profile calls + * {@link Activity#startActivity(Intent)}, the intent can be resolved by a + * matching activity in the parent profile. */ public static final int FLAG_PARENT_CAN_ACCESS_MANAGED = 0x0001; /** - * Flag used by {@link #addCrossProfileIntentFilter} to allow access - * <em>from</em> a parent <em>to</em> its managed profile. That is, any - * matching activities in the managed profile are included in the - * disambiguation list shown when an app in the parent profile calls - * {@link Activity#startActivity(Intent)}. + * Flag used by {@link #addCrossProfileIntentFilter} to allow activities in + * the managed profile to access intents sent from the parent profile. + * That is, when an app in the parent profile calls + * {@link Activity#startActivity(Intent)}, the intent can be resolved by a + * matching activity in the managed profile. */ public static final int FLAG_MANAGED_CAN_ACCESS_PARENT = 0x0002; diff --git a/core/java/com/android/internal/util/StateMachine.java b/core/java/com/android/internal/util/StateMachine.java index 7ad3470..916f19d 100644 --- a/core/java/com/android/internal/util/StateMachine.java +++ b/core/java/com/android/internal/util/StateMachine.java @@ -25,6 +25,7 @@ import android.util.Log; import java.io.FileDescriptor; import java.io.PrintWriter; +import java.io.StringWriter; import java.util.ArrayList; import java.util.Calendar; import java.util.Collection; @@ -1940,19 +1941,25 @@ public class StateMachine { * @param args */ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - pw.println(this.toString()); + // Cannot just invoke pw.println(this.toString()) because if the + // resulting string is to long it won't be displayed. + pw.println(getName() + ":"); + pw.println(" total records=" + getLogRecCount()); + for (int i = 0; i < getLogRecSize(); i++) { + pw.println(" rec[" + i + "]: " + getLogRec(i).toString()); + pw.flush(); + } + pw.println("curState=" + getCurrentState().getName()); } @Override public String toString() { - StringBuilder sb = new StringBuilder(); - sb.append(getName() + ":\n"); - sb.append(" total records=" + getLogRecCount() + "\n"); - for (int i = 0; i < getLogRecSize(); i++) { - sb.append(" rec[" + i + "]: " + getLogRec(i).toString() + "\n"); - } - sb.append("curState=" + getCurrentState().getName()); - return sb.toString(); + StringWriter sr = new StringWriter(); + PrintWriter pr = new PrintWriter(sr); + dump(null, pr, null); + pr.flush(); + pr.close(); + return sr.toString(); } /** diff --git a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java index 06e8574..d898555 100644 --- a/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java +++ b/packages/CaptivePortalLogin/src/com/android/captiveportallogin/CaptivePortalLoginActivity.java @@ -55,7 +55,7 @@ import java.lang.reflect.Method; public class CaptivePortalLoginActivity extends Activity { private static final String TAG = "CaptivePortalLogin"; - private static final String DEFAULT_SERVER = "clients3.google.com"; + private static final String DEFAULT_SERVER = "connectivitycheck.android.com"; private static final int SOCKET_TIMEOUT_MS = 10000; // Keep this in sync with NetworkMonitor. diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java index 096aad0..755479f 100644 --- a/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java +++ b/packages/Keyguard/src/com/android/keyguard/KeyguardUpdateMonitor.java @@ -264,12 +264,16 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { // Hack level over 9000: Because the subscription id is not yet valid when we see the // first update in handleSimStateChange, we need to force refresh all all SIM states // so the subscription id for them is consistent. + ArrayList<SubscriptionInfo> changedSubscriptions = new ArrayList<>(); for (int i = 0; i < subscriptionInfos.size(); i++) { SubscriptionInfo info = subscriptionInfos.get(i); - refreshSimState(info.getSubscriptionId(), info.getSimSlotIndex()); + boolean changed = refreshSimState(info.getSubscriptionId(), info.getSimSlotIndex()); + if (changed) { + changedSubscriptions.add(info); + } } - for (int i = 0; i < subscriptionInfos.size(); i++) { - SimData data = mSimDatas.get(mSubscriptionInfo.get(i).getSubscriptionId()); + for (int i = 0; i < changedSubscriptions.size(); i++) { + SimData data = mSimDatas.get(changedSubscriptions.get(i).getSubscriptionId()); for (int j = 0; j < mCallbacks.size(); j++) { KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get(); if (cb != null) { @@ -1199,7 +1203,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { } } - private void refreshSimState(int subId, int slotId) { + /** + * @return true if and only if the state has changed for the specified {@code slotId} + */ + private boolean refreshSimState(int subId, int slotId) { // This is awful. It exists because there are two APIs for getting the SIM status // that don't return the complete set of values and have different types. In Keyguard we @@ -1214,7 +1221,17 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener { Log.w(TAG, "Unknown sim state: " + simState); state = State.UNKNOWN; } - mSimDatas.put(subId, new SimData(state, slotId, subId)); + SimData data = mSimDatas.get(subId); + final boolean changed; + if (data == null) { + data = new SimData(state, slotId, subId); + mSimDatas.put(subId, data); + changed = true; // no data yet; force update + } else { + changed = data.simState != state; + data.simState = state; + } + return changed; } public static boolean isSimPinSecure(IccCardConstants.State state) { diff --git a/packages/SystemUI/src/com/android/systemui/EventLogTags.logtags b/packages/SystemUI/src/com/android/systemui/EventLogTags.logtags index 191cba5..ec3a0cb 100644 --- a/packages/SystemUI/src/com/android/systemui/EventLogTags.logtags +++ b/packages/SystemUI/src/com/android/systemui/EventLogTags.logtags @@ -9,7 +9,14 @@ option java_package com.android.systemui; 36001 sysui_heads_up_status (key|3),(visible|1) 36002 sysui_fullscreen_notification (key|3) 36003 sysui_heads_up_escalation (key|3) -36004 sysui_status_bar_state (state|1) +# sysui_status_bar_state: Logged whenever the status bar / keyguard state changes +## state: 0: SHADE, 1: KEYGUARD, 2: SHADE_LOCKED +## keyguardShowing: 1: Keyguard shown to the user (or keyguardOccluded) +## keyguardOccluded: 1: Keyguard active, but another activity is occluding it +## bouncerShowing: 1: Bouncer currently shown to the user +## secure: 1: The user has set up a secure unlock method (PIN, password, etc.) +## currentlyInsecure: 1: No secure unlock method set up (!secure), or trusted environment (TrustManager) +36004 sysui_status_bar_state (state|1),(keyguardShowing|1),(keyguardOccluded|1),(bouncerShowing|1),(secure|1),(currentlyInsecure|1) # --------------------------- # PhoneStatusBarView.java diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java index 503f588..227fc79 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java @@ -388,7 +388,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL // TODO: Real icon for facelock. int iconRes = mUnlockMethodCache.isFaceUnlockRunning() ? com.android.internal.R.drawable.ic_account_circle - : mUnlockMethodCache.isMethodInsecure() ? R.drawable.ic_lock_open_24dp + : mUnlockMethodCache.isCurrentlyInsecure() ? R.drawable.ic_lock_open_24dp : R.drawable.ic_lock_24dp; if (mLastUnlockIconRes != iconRes) { Drawable icon = mContext.getDrawable(iconRes); @@ -438,7 +438,7 @@ public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickL } @Override - public void onMethodSecureChanged(boolean methodSecure) { + public void onUnlockMethodStateChanged() { updateLockIcon(); updateCameraVisibility(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java index 34400c4..fc4d7fe 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java @@ -201,6 +201,9 @@ public class KeyguardBouncer { return false; } + /** + * WARNING: This method might cause Binder calls. + */ public boolean isSecure() { return mKeyguardView == null || mKeyguardView.getSecurityMode() != SecurityMode.None; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java index 5bff79a..d691264 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java @@ -147,6 +147,7 @@ import com.android.systemui.statusbar.SignalClusterView; import com.android.systemui.statusbar.SpeedBumpView; import com.android.systemui.statusbar.StatusBarIconView; import com.android.systemui.statusbar.StatusBarState; +import com.android.systemui.statusbar.phone.UnlockMethodCache.OnUnlockMethodChangedListener; import com.android.systemui.statusbar.policy.AccessibilityController; import com.android.systemui.statusbar.policy.BatteryController; import com.android.systemui.statusbar.policy.BatteryController.BatteryStateChangeCallback; @@ -183,7 +184,7 @@ import java.util.List; import java.util.Map; public class PhoneStatusBar extends BaseStatusBar implements DemoMode, - DragDownHelper.DragDownCallback, ActivityStarter { + DragDownHelper.DragDownCallback, ActivityStarter, OnUnlockMethodChangedListener { static final String TAG = "PhoneStatusBar"; public static final boolean DEBUG = BaseStatusBar.DEBUG; public static final boolean SPEW = false; @@ -493,6 +494,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, private boolean mLaunchTransitionFadingAway; private ExpandableNotificationRow mDraggedDownRow; + // Fingerprint (as computed by getLoggingFingerprint() of the last logged state. + private int mLastLoggedStateFingerprint; + private static final int VISIBLE_LOCATIONS = ViewState.LOCATION_FIRST_CARD | ViewState.LOCATION_TOP_STACK_PEEKING | ViewState.LOCATION_MAIN_AREA @@ -603,6 +607,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, mHeadsUpObserver); } mUnlockMethodCache = UnlockMethodCache.getInstance(mContext); + mUnlockMethodCache.addListener(this); startKeyguard(); mDozeServiceHost = new DozeServiceHost(); @@ -2159,8 +2164,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, public boolean isFalsingThresholdNeeded() { boolean onKeyguard = getBarState() == StatusBarState.KEYGUARD; - boolean isMethodInsecure = mUnlockMethodCache.isMethodInsecure(); - return onKeyguard && (isMethodInsecure || mDozing || mScreenOnComingFromTouch); + boolean isCurrentlyInsecure = mUnlockMethodCache.isCurrentlyInsecure(); + return onKeyguard && (isCurrentlyInsecure || mDozing || mScreenOnComingFromTouch); } public boolean isDozing() { @@ -2177,6 +2182,18 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } /** + * To be called when there's a state change in StatusBarKeyguardViewManager. + */ + public void onKeyguardViewManagerStatesUpdated() { + logStateToEventlog(); + } + + @Override // UnlockMethodCache.OnUnlockMethodChangedListener + public void onUnlockMethodStateChanged() { + logStateToEventlog(); + } + + /** * All changes to the status bar and notifications funnel through here and are batched. */ private class H extends BaseStatusBar.H { @@ -3348,6 +3365,47 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, } } + // State logging + + private void logStateToEventlog() { + boolean isShowing = mStatusBarKeyguardViewManager.isShowing(); + boolean isOccluded = mStatusBarKeyguardViewManager.isOccluded(); + boolean isBouncerShowing = mStatusBarKeyguardViewManager.isBouncerShowing(); + boolean isSecure = mUnlockMethodCache.isMethodSecure(); + boolean isCurrentlyInsecure = mUnlockMethodCache.isCurrentlyInsecure(); + int stateFingerprint = getLoggingFingerprint(mState, + isShowing, + isOccluded, + isBouncerShowing, + isSecure, + isCurrentlyInsecure); + if (stateFingerprint != mLastLoggedStateFingerprint) { + EventLogTags.writeSysuiStatusBarState(mState, + isShowing ? 1 : 0, + isOccluded ? 1 : 0, + isBouncerShowing ? 1 : 0, + isSecure ? 1 : 0, + isCurrentlyInsecure ? 1 : 0); + mLastLoggedStateFingerprint = stateFingerprint; + } + } + + /** + * Returns a fingerprint of fields logged to eventlog + */ + private static int getLoggingFingerprint(int statusBarState, boolean keyguardShowing, + boolean keyguardOccluded, boolean bouncerShowing, boolean secure, + boolean currentlyInsecure) { + // Reserve 8 bits for statusBarState. We'll never go higher than + // that, right? Riiiight. + return (statusBarState & 0xFF) + | ((keyguardShowing ? 1 : 0) << 8) + | ((keyguardOccluded ? 1 : 0) << 9) + | ((bouncerShowing ? 1 : 0) << 10) + | ((secure ? 1 : 0) << 11) + | ((currentlyInsecure ? 1 : 0) << 12); + } + // // tracing // @@ -3836,19 +3894,15 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, * @param state The {@link StatusBarState} to set. */ public void setBarState(int state) { - if (state != mState) { - EventLogTags.writeSysuiStatusBarState(state); - - // If we're visible and switched to SHADE_LOCKED (the user dragged - // down on the lockscreen), clear notification LED, vibration, - // ringing. - // Other transitions are covered in handleVisibleToUserChanged(). - if (mVisible && state == StatusBarState.SHADE_LOCKED) { - try { - mBarService.clearNotificationEffects(); - } catch (RemoteException e) { - // Ignore. - } + // If we're visible and switched to SHADE_LOCKED (the user dragged + // down on the lockscreen), clear notification LED, vibration, + // ringing. + // Other transitions are covered in handleVisibleToUserChanged(). + if (state != mState && mVisible && state == StatusBarState.SHADE_LOCKED) { + try { + mBarService.clearNotificationEffects(); + } catch (RemoteException e) { + // Ignore. } } mState = state; @@ -3890,7 +3944,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode, public void onTrackingStopped(boolean expand) { if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) { - if (!expand && !mUnlockMethodCache.isMethodInsecure()) { + if (!expand && !mUnlockMethodCache.isCurrentlyInsecure()) { showBouncer(); } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java index d6bd94b..0e8a794 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java @@ -88,7 +88,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener { public void onTrackingStarted() { mExpanding = true; - mDarkenWhileDragging = !mUnlockMethodCache.isMethodInsecure(); + mDarkenWhileDragging = !mUnlockMethodCache.isCurrentlyInsecure(); } public void onExpandingFinished() { 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 3155efb..19305f3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java @@ -299,6 +299,9 @@ public class StatusBarKeyguardViewManager { } } + /** + * WARNING: This method might cause Binder calls. + */ public boolean isSecure() { return mBouncer.isSecure(); } @@ -392,6 +395,8 @@ public class StatusBarKeyguardViewManager { mLastOccluded = occluded; mLastBouncerShowing = bouncerShowing; mLastBouncerDismissible = bouncerDismissible; + + mPhoneStatusBar.onKeyguardViewManagerStatesUpdated(); } public boolean onMenuPressed() { diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java index e5eef9d..5ef345b 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java @@ -36,7 +36,10 @@ public class UnlockMethodCache { private final LockPatternUtils mLockPatternUtils; private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; private final ArrayList<OnUnlockMethodChangedListener> mListeners = new ArrayList<>(); - private boolean mMethodInsecure; + /** Whether the user configured a secure unlock method (PIN, password, etc.) */ + private boolean mSecure; + /** Whether the unlock method is currently insecure (insecure method or trusted environment) */ + private boolean mCurrentlyInsecure; private boolean mTrustManaged; private boolean mFaceUnlockRunning; @@ -44,7 +47,7 @@ public class UnlockMethodCache { mLockPatternUtils = new LockPatternUtils(ctx); mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(ctx); KeyguardUpdateMonitor.getInstance(ctx).registerCallback(mCallback); - updateMethodSecure(true /* updateAlways */); + update(true /* updateAlways */); } public static UnlockMethodCache getInstance(Context context) { @@ -55,10 +58,17 @@ public class UnlockMethodCache { } /** - * @return whether the current security method is secure, i. e. the bouncer will be shown + * @return whether the user configured a secure unlock method like PIN, password, etc. */ - public boolean isMethodInsecure() { - return mMethodInsecure; + public boolean isMethodSecure() { + return mSecure; + } + + /** + * @return whether the lockscreen is currently insecure, i. e. the bouncer won't be shown + */ + public boolean isCurrentlyInsecure() { + return mCurrentlyInsecure; } public void addListener(OnUnlockMethodChangedListener listener) { @@ -69,58 +79,59 @@ public class UnlockMethodCache { mListeners.remove(listener); } - private void updateMethodSecure(boolean updateAlways) { + private void update(boolean updateAlways) { int user = mLockPatternUtils.getCurrentUser(); - boolean methodInsecure = !mLockPatternUtils.isSecure() || - mKeyguardUpdateMonitor.getUserHasTrust(user); + boolean secure = mLockPatternUtils.isSecure(); + boolean currentlyInsecure = !secure || mKeyguardUpdateMonitor.getUserHasTrust(user); boolean trustManaged = mKeyguardUpdateMonitor.getUserTrustIsManaged(user); boolean faceUnlockRunning = mKeyguardUpdateMonitor.isFaceUnlockRunning(user) && trustManaged; - boolean changed = methodInsecure != mMethodInsecure || trustManaged != mTrustManaged - || faceUnlockRunning != mFaceUnlockRunning; + boolean changed = secure != mSecure || currentlyInsecure != mCurrentlyInsecure || + trustManaged != mTrustManaged || faceUnlockRunning != mFaceUnlockRunning; if (changed || updateAlways) { - mMethodInsecure = methodInsecure; + mSecure = secure; + mCurrentlyInsecure = currentlyInsecure; mTrustManaged = trustManaged; mFaceUnlockRunning = faceUnlockRunning; - notifyListeners(mMethodInsecure); + notifyListeners(); } } - private void notifyListeners(boolean secure) { + private void notifyListeners() { for (OnUnlockMethodChangedListener listener : mListeners) { - listener.onMethodSecureChanged(secure); + listener.onUnlockMethodStateChanged(); } } private final KeyguardUpdateMonitorCallback mCallback = new KeyguardUpdateMonitorCallback() { @Override public void onUserSwitchComplete(int userId) { - updateMethodSecure(false /* updateAlways */); + update(false /* updateAlways */); } @Override public void onTrustChanged(int userId) { - updateMethodSecure(false /* updateAlways */); + update(false /* updateAlways */); } @Override public void onTrustManagedChanged(int userId) { - updateMethodSecure(false /* updateAlways */); + update(false /* updateAlways */); } @Override public void onScreenTurnedOn() { - updateMethodSecure(false /* updateAlways */); + update(false /* updateAlways */); } @Override public void onFingerprintRecognized(int userId) { - updateMethodSecure(false /* updateAlways */); + update(false /* updateAlways */); } @Override public void onFaceUnlockStateChanged(boolean running, int userId) { - updateMethodSecure(false /* updateAlways */); + update(false /* updateAlways */); } }; @@ -133,6 +144,6 @@ public class UnlockMethodCache { } public static interface OnUnlockMethodChangedListener { - void onMethodSecureChanged(boolean methodSecure); + void onUnlockMethodStateChanged(); } } diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java index 0f8fd05..61a7073 100644 --- a/services/core/java/com/android/server/ConnectivityService.java +++ b/services/core/java/com/android/server/ConnectivityService.java @@ -2271,6 +2271,46 @@ public class ConnectivityService extends IConnectivityManager.Stub } } + // Is nai unneeded by all NetworkRequests (and should be disconnected)? + // For validated Networks this is simply whether it is satsifying any NetworkRequests. + // For unvalidated Networks this is whether it is satsifying any NetworkRequests or + // were it to become validated, would it have a chance of satisfying any NetworkRequests. + private boolean unneeded(NetworkAgentInfo nai) { + if (!nai.created || nai.isVPN()) return false; + boolean unneeded = true; + if (nai.everValidated) { + for (int i = 0; i < nai.networkRequests.size() && unneeded; i++) { + final NetworkRequest nr = nai.networkRequests.valueAt(i); + try { + if (isRequest(nr)) unneeded = false; + } catch (Exception e) { + loge("Request " + nr + " not found in mNetworkRequests."); + loge(" it came from request list of " + nai.name()); + } + } + } else { + for (NetworkRequestInfo nri : mNetworkRequests.values()) { + // If this Network is already the highest scoring Network for a request, or if + // there is hope for it to become one if it validated, then it is needed. + if (nri.isRequest && nai.satisfies(nri.request) && + (nai.networkRequests.get(nri.request.requestId) != null || + // Note that this catches two important cases: + // 1. Unvalidated cellular will not be reaped when unvalidated WiFi + // is currently satisfying the request. This is desirable when + // cellular ends up validating but WiFi does not. + // 2. Unvalidated WiFi will not be reaped when validated cellular + // is currently satsifying the request. This is desirable when + // WiFi ends up validating and out scoring cellular. + mNetworkForRequestId.get(nri.request.requestId).getCurrentScore() < + nai.getCurrentScoreAsValidated())) { + unneeded = false; + break; + } + } + } + return unneeded; + } + private void handleReleaseNetworkRequest(NetworkRequest request, int callingUid) { NetworkRequestInfo nri = mNetworkRequests.get(request); if (nri != null) { @@ -2292,16 +2332,9 @@ public class ConnectivityService extends IConnectivityManager.Stub ", leaving " + nai.networkRequests.size() + " requests."); } - // check if has any requests remaining and if not, - // disconnect (unless it's a VPN). - boolean keep = nai.isVPN(); - for (int i = 0; i < nai.networkRequests.size() && !keep; i++) { - NetworkRequest r = nai.networkRequests.valueAt(i); - if (isRequest(r)) keep = true; - } - if (!keep) { + if (unneeded(nai)) { if (DBG) log("no live requests for " + nai.name() + "; disconnecting"); - nai.asyncChannel.disconnect(); + teardownUnneededNetwork(nai); } } } @@ -4056,19 +4089,7 @@ public class ConnectivityService extends IConnectivityManager.Stub } // Linger any networks that are no longer needed. for (NetworkAgentInfo nai : affectedNetworks) { - boolean teardown = !nai.isVPN() && nai.everValidated; - for (int i = 0; i < nai.networkRequests.size() && teardown; i++) { - NetworkRequest nr = nai.networkRequests.valueAt(i); - try { - if (isRequest(nr)) { - teardown = false; - } - } catch (Exception e) { - loge("Request " + nr + " not found in mNetworkRequests."); - loge(" it came from request list of " + nai.name()); - } - } - if (teardown) { + if (nai.everValidated && unneeded(nai)) { nai.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_LINGER); notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOSING); } else { @@ -4168,27 +4189,7 @@ public class ConnectivityService extends IConnectivityManager.Stub } if (reapUnvalidatedNetworks == ReapUnvalidatedNetworks.REAP) { for (NetworkAgentInfo nai : mNetworkAgentInfos.values()) { - if (!nai.created || nai.everValidated || nai.isVPN()) continue; - boolean reap = true; - for (NetworkRequestInfo nri : mNetworkRequests.values()) { - // If this Network is already the highest scoring Network for a request, or if - // there is hope for it to become one if it validated, then don't reap it. - if (nri.isRequest && nai.satisfies(nri.request) && - (nai.networkRequests.get(nri.request.requestId) != null || - // Note that this catches two important cases: - // 1. Unvalidated cellular will not be reaped when unvalidated WiFi - // is currently satisfying the request. This is desirable when - // cellular ends up validating but WiFi does not. - // 2. Unvalidated WiFi will not be reaped when validated cellular - // is currently satsifying the request. This is desirable when - // WiFi ends up validating and out scoring cellular. - mNetworkForRequestId.get(nri.request.requestId).getCurrentScore() < - nai.getCurrentScoreAsValidated())) { - reap = false; - break; - } - } - if (reap) { + if (!nai.everValidated && unneeded(nai)) { if (DBG) log("Reaping " + nai.name()); teardownUnneededNetwork(nai); } diff --git a/services/core/java/com/android/server/connectivity/NetworkMonitor.java b/services/core/java/com/android/server/connectivity/NetworkMonitor.java index 9fa362c..af5ed83 100644 --- a/services/core/java/com/android/server/connectivity/NetworkMonitor.java +++ b/services/core/java/com/android/server/connectivity/NetworkMonitor.java @@ -68,7 +68,7 @@ import java.util.Random; public class NetworkMonitor extends StateMachine { private static final boolean DBG = true; private static final String TAG = "NetworkMonitor"; - private static final String DEFAULT_SERVER = "clients3.google.com"; + private static final String DEFAULT_SERVER = "connectivitycheck.android.com"; private static final int SOCKET_TIMEOUT_MS = 10000; public static final String ACTION_NETWORK_CONDITIONS_MEASURED = "android.net.conn.NETWORK_CONDITIONS_MEASURED"; diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java index 34315bf..03cc7d0 100644 --- a/telephony/java/android/telephony/TelephonyManager.java +++ b/telephony/java/android/telephony/TelephonyManager.java @@ -3095,7 +3095,7 @@ public class TelephonyManager { * * @return true on success; false on any failure. */ - public boolean setGlobalPreferredNetworkType() { + public boolean setPreferredNetworkTypeToGlobal() { return setPreferredNetworkType(RILConstants.NETWORK_MODE_LTE_CDMA_EVDO_GSM_WCDMA); } @@ -3138,8 +3138,6 @@ public class TelephonyManager { * call will return true. This access is granted by the owner of the UICC * card and does not depend on the registered carrier. * - * TODO: Add a link to documentation. - * * @return true if the app has carrier privileges. */ public boolean hasCarrierPrivileges() { |