From 506bccef60254fe810233e4a4110c1a28565c6a8 Mon Sep 17 00:00:00 2001
From: Robert Greenwalt
Date: Wed, 21 May 2014 20:04:36 -0700
Subject: [PATCH 01/93] Move dis/enable of mobile data to Telephony
ConnectivityService doesn't do this anymore.
bug:15077247
Change-Id: I3208c91b2c0369b594987f39ca29da7478435513
---
.../java/android/net/ConnectivityManager.java | 38 ++++++-----------
.../android/net/IConnectivityManager.aidl | 3 --
.../android/server/ConnectivityService.java | 41 -------------------
.../android/telephony/TelephonyManager.java | 21 ++++++++++
.../internal/telephony/ITelephony.aidl | 14 +++++++
5 files changed, 47 insertions(+), 70 deletions(-)
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 80a9598ada9c1..2f2aba3286614 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -35,15 +35,17 @@ import android.os.Messenger;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.provider.Settings;
+import android.telephony.TelephonyManager;
import android.util.ArrayMap;
import android.util.Log;
+import com.android.internal.telephony.ITelephony;
+import com.android.internal.util.Protocol;
+
import java.net.InetAddress;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.HashMap;
-import com.android.internal.util.Protocol;
-
/**
* Class that answers queries about the state of network connectivity. It also
* notifies applications when network connectivity changes. Get an instance
@@ -940,34 +942,18 @@ public class ConnectivityManager {
}
/**
- * Gets the value of the setting for enabling Mobile data.
- *
- * @return Whether mobile data is enabled.
- *
- * This method requires the call to hold the permission
- * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
* @hide
+ * @deprecated Talk to TelephonyManager directly
*/
public boolean getMobileDataEnabled() {
- try {
- return mService.getMobileDataEnabled();
- } catch (RemoteException e) {
- return true;
- }
- }
-
- /**
- * Sets the persisted value for enabling/disabling Mobile data.
- *
- * @param enabled Whether the user wants the mobile data connection used
- * or not.
- * @hide
- */
- public void setMobileDataEnabled(boolean enabled) {
- try {
- mService.setMobileDataEnabled(enabled);
- } catch (RemoteException e) {
+ IBinder b = ServiceManager.getService(Context.TELEPHONY_SERVICE);
+ if (b != null) {
+ try {
+ ITelephony it = ITelephony.Stub.asInterface(b);
+ return it.getDataEnabled();
+ } catch (RemoteException e) { }
}
+ return false;
}
/**
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index d97b1e95bdb04..baec36ad48d38 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -74,9 +74,6 @@ interface IConnectivityManager
boolean requestRouteToHostAddress(int networkType, in byte[] hostAddress, String packageName);
- boolean getMobileDataEnabled();
- void setMobileDataEnabled(boolean enabled);
-
/** Policy control over specific {@link NetworkStateTracker}. */
void setPolicyDataEnable(int networkType, boolean enabled);
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 0ad5ce269abaf..37b75d6877e16 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -342,12 +342,6 @@ public class ConnectivityService extends IConnectivityManager.Stub {
*/
private static final int EVENT_INET_CONDITION_HOLD_END = 5;
- /**
- * used internally to set enable/disable cellular data
- * arg1 = ENBALED or DISABLED
- */
- private static final int EVENT_SET_MOBILE_DATA = 7;
-
/**
* used internally to clear a wakelock when transitioning
* from one net to another
@@ -1822,20 +1816,6 @@ public class ConnectivityService extends IConnectivityManager.Stub {
return true;
}
- /**
- * @see ConnectivityManager#getMobileDataEnabled()
- */
- public boolean getMobileDataEnabled() {
- // TODO: This detail should probably be in DataConnectionTracker's
- // which is where we store the value and maybe make this
- // asynchronous.
- enforceAccessPermission();
- boolean retVal = Settings.Global.getInt(mContext.getContentResolver(),
- Settings.Global.MOBILE_DATA, 1) == 1;
- if (VDBG) log("getMobileDataEnabled returning " + retVal);
- return retVal;
- }
-
public void setDataDependency(int networkType, boolean met) {
enforceConnectivityInternalPermission();
@@ -1908,22 +1888,6 @@ public class ConnectivityService extends IConnectivityManager.Stub {
}
};
- /**
- * @see ConnectivityManager#setMobileDataEnabled(boolean)
- */
- public void setMobileDataEnabled(boolean enabled) {
- enforceChangePermission();
- if (DBG) log("setMobileDataEnabled(" + enabled + ")");
-
- mHandler.sendMessage(mHandler.obtainMessage(EVENT_SET_MOBILE_DATA,
- (enabled ? ENABLED : DISABLED), 0));
- }
-
- private void handleSetMobileData(boolean enabled) {
- // TODO - handle this - probably generalize passing in a transport type and send to the
- // factories?
- }
-
@Override
public void setPolicyDataEnable(int networkType, boolean enabled) {
// only someone like NPMS should only be calling us
@@ -3315,11 +3279,6 @@ public class ConnectivityService extends IConnectivityManager.Stub {
handleInetConditionHoldEnd(netType, sequence);
break;
}
- case EVENT_SET_MOBILE_DATA: {
- boolean enabled = (msg.arg1 == ENABLED);
- handleSetMobileData(enabled);
- break;
- }
case EVENT_APPLY_GLOBAL_HTTP_PROXY: {
handleDeprecatedGlobalHttpProxy();
break;
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 5d485c523823e..a89686195aa5e 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -2249,4 +2249,25 @@ public class TelephonyManager {
}
return false;
}
+
+ /** @hide */
+ @PrivateApi
+ public void setDataEnabled(boolean enable) {
+ try {
+ getITelephony().setDataEnabled(enable);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling ITelephony#setDataEnabled", e);
+ }
+ }
+
+ /** @hide */
+ @PrivateApi
+ public boolean getDataEnabled() {
+ try {
+ return getITelephony().getDataEnabled();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling ITelephony#getDataEnabled", e);
+ }
+ return false;
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index baacb74a6497a..6d7f158a81414 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -436,4 +436,18 @@ interface ITelephony {
* @return true on success; false on any failure.
*/
boolean setPreferredNetworkType(int networkType);
+
+ /**
+ * User enable/disable Mobile Data.
+ *
+ * @param enable true to turn on, else false
+ */
+ void setDataEnabled(boolean enable);
+
+ /**
+ * Get the user enabled state of Mobile Data.
+ *
+ * @return true on enabled
+ */
+ boolean getDataEnabled();
}
From 83e07776d4566e2187a38485c1ba548ed52f68a7 Mon Sep 17 00:00:00 2001
From: Santos Cordon
Date: Wed, 21 May 2014 15:22:12 -0700
Subject: [PATCH 02/93] Adding ITelecommService definition for Telecomm.
Until telecomm code moves into a system service, we need a way for
other apps to call into it for call-related functionality.
Initial implementation only has silenceRinger.
This is to be implemented by the telecomm code and used by
TelephonyManager (until we have a TelecommManager).
Change-Id: I9180797451dcb2e9029b20bed47f5d5cb8cddb9f
---
Android.mk | 1 +
.../policy/impl/PhoneWindowManager.java | 148 ++++++++----------
.../internal/telecomm/ITelecommService.aidl | 34 ++++
.../android/telephony/TelephonyManager.java | 11 +-
4 files changed, 106 insertions(+), 88 deletions(-)
create mode 100644 telecomm/java/com/android/internal/telecomm/ITelecommService.aidl
diff --git a/Android.mk b/Android.mk
index de93ca2588e45..70785b192343d 100644
--- a/Android.mk
+++ b/Android.mk
@@ -325,6 +325,7 @@ LOCAL_SRC_FILES += \
telecomm/java/com/android/internal/telecomm/ICallServiceSelectorAdapter.aidl \
telecomm/java/com/android/internal/telecomm/IInCallAdapter.aidl \
telecomm/java/com/android/internal/telecomm/IInCallService.aidl \
+ telecomm/java/com/android/internal/telecomm/ITelecommService.aidl \
telephony/java/com/android/internal/telephony/IPhoneStateListener.aidl \
telephony/java/com/android/internal/telephony/IPhoneSubInfo.aidl \
telephony/java/com/android/internal/telephony/ITelephony.aidl \
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 99771934ca808..2c51abb62e6f9 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -66,6 +66,7 @@ import android.os.Vibrator;
import android.provider.Settings;
import android.service.dreams.DreamService;
import android.service.dreams.IDreamManager;
+import android.telephony.TelephonyManager;
import android.util.DisplayMetrics;
import android.util.EventLog;
import android.util.Log;
@@ -1921,9 +1922,8 @@ public class PhoneWindowManager implements WindowManagerPolicy {
ServiceManager.checkService(DreamService.DREAM_SERVICE));
}
- static ITelephony getTelephonyService() {
- return ITelephony.Stub.asInterface(
- ServiceManager.checkService(Context.TELEPHONY_SERVICE));
+ TelephonyManager getTelephonyService() {
+ return (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
}
static IAudioService getAudioService() {
@@ -2006,14 +2006,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
// If an incoming call is ringing, HOME is totally disabled.
// (The user is already on the InCallScreen at this point,
// and his ONLY options are to answer or reject the call.)
- try {
- ITelephony telephonyService = getTelephonyService();
- if (telephonyService != null && telephonyService.isRinging()) {
- Log.i(TAG, "Ignoring HOME; there's a ringing incoming call.");
- return -1;
- }
- } catch (RemoteException ex) {
- Log.w(TAG, "RemoteException from getPhoneInterface()", ex);
+ TelephonyManager telephonyManager = getTelephonyService();
+ if (telephonyManager != null && telephonyManager.isRinging()) {
+ Log.i(TAG, "Ignoring HOME; there's a ringing incoming call.");
+ return -1;
}
// Delay handling home if a double-tap is possible.
@@ -3957,37 +3953,33 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
}
if (down) {
- ITelephony telephonyService = getTelephonyService();
- if (telephonyService != null) {
- try {
- if (telephonyService.isRinging()) {
- // If an incoming call is ringing, either VOLUME key means
- // "silence ringer". We handle these keys here, rather than
- // in the InCallScreen, to make sure we'll respond to them
- // even if the InCallScreen hasn't come to the foreground yet.
- // Look for the DOWN event here, to agree with the "fallback"
- // behavior in the InCallScreen.
- Log.i(TAG, "interceptKeyBeforeQueueing:"
- + " VOLUME key-down while ringing: Silence ringer!");
+ TelephonyManager telephonyManager = getTelephonyService();
+ if (telephonyManager != null) {
+ if (telephonyManager.isRinging()) {
+ // If an incoming call is ringing, either VOLUME key means
+ // "silence ringer". We handle these keys here, rather than
+ // in the InCallScreen, to make sure we'll respond to them
+ // even if the InCallScreen hasn't come to the foreground yet.
+ // Look for the DOWN event here, to agree with the "fallback"
+ // behavior in the InCallScreen.
+ Log.i(TAG, "interceptKeyBeforeQueueing:"
+ + " VOLUME key-down while ringing: Silence ringer!");
- // Silence the ringer. (It's safe to call this
- // even if the ringer has already been silenced.)
- telephonyService.silenceRinger();
+ // Silence the ringer. (It's safe to call this
+ // even if the ringer has already been silenced.)
+ telephonyManager.silenceRinger();
- // And *don't* pass this key thru to the current activity
- // (which is probably the InCallScreen.)
- result &= ~ACTION_PASS_TO_USER;
- break;
- }
- if (telephonyService.isOffhook()
- && (result & ACTION_PASS_TO_USER) == 0) {
- // If we are in call but we decided not to pass the key to
- // the application, handle the volume change here.
- handleVolumeKey(AudioManager.STREAM_VOICE_CALL, keyCode);
- break;
- }
- } catch (RemoteException ex) {
- Log.w(TAG, "ITelephony threw RemoteException", ex);
+ // And *don't* pass this key thru to the current activity
+ // (which is probably the InCallScreen.)
+ result &= ~ACTION_PASS_TO_USER;
+ break;
+ }
+ if (telephonyManager.isOffhook()
+ && (result & ACTION_PASS_TO_USER) == 0) {
+ // If we are in call but we decided not to pass the key to
+ // the application, handle the volume change here.
+ handleVolumeKey(AudioManager.STREAM_VOICE_CALL, keyCode);
+ break;
}
}
@@ -4004,14 +3996,10 @@ public class PhoneWindowManager implements WindowManagerPolicy {
case KeyEvent.KEYCODE_ENDCALL: {
result &= ~ACTION_PASS_TO_USER;
if (down) {
- ITelephony telephonyService = getTelephonyService();
+ TelephonyManager telephonyManager = getTelephonyService();
boolean hungUp = false;
- if (telephonyService != null) {
- try {
- hungUp = telephonyService.endCall();
- } catch (RemoteException ex) {
- Log.w(TAG, "ITelephony threw RemoteException", ex);
- }
+ if (telephonyManager != null) {
+ hungUp = telephonyManager.endCall();
}
interceptPowerKeyDown(!interactive || hungUp);
} else {
@@ -4047,23 +4035,19 @@ public class PhoneWindowManager implements WindowManagerPolicy {
interceptScreenshotChord();
}
- ITelephony telephonyService = getTelephonyService();
+ TelephonyManager telephonyManager = getTelephonyService();
boolean hungUp = false;
- if (telephonyService != null) {
- try {
- if (telephonyService.isRinging()) {
- // Pressing Power while there's a ringing incoming
- // call should silence the ringer.
- telephonyService.silenceRinger();
- } else if ((mIncallPowerBehavior
- & Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP) != 0
- && telephonyService.isOffhook() && interactive) {
- // Otherwise, if "Power button ends call" is enabled,
- // the Power button will hang up any current active call.
- hungUp = telephonyService.endCall();
- }
- } catch (RemoteException ex) {
- Log.w(TAG, "ITelephony threw RemoteException", ex);
+ if (telephonyManager != null) {
+ if (telephonyManager.isRinging()) {
+ // Pressing Power while there's a ringing incoming
+ // call should silence the ringer.
+ telephonyManager.silenceRinger();
+ } else if ((mIncallPowerBehavior
+ & Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP) != 0
+ && telephonyManager.isOffhook() && interactive) {
+ // Otherwise, if "Power button ends call" is enabled,
+ // the Power button will hang up any current active call.
+ hungUp = telephonyManager.endCall();
}
}
interceptPowerKeyDown(!interactive || hungUp
@@ -4096,16 +4080,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
case KeyEvent.KEYCODE_MEDIA_PAUSE:
case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
if (down) {
- ITelephony telephonyService = getTelephonyService();
- if (telephonyService != null) {
- try {
- if (!telephonyService.isIdle()) {
- // Suppress PLAY/PAUSE toggle when phone is ringing or in-call
- // to avoid music playback.
- break;
- }
- } catch (RemoteException ex) {
- Log.w(TAG, "ITelephony threw RemoteException", ex);
+ TelephonyManager telephonyManager = getTelephonyService();
+ if (telephonyManager != null) {
+ if (!telephonyManager.isIdle()) {
+ // Suppress PLAY/PAUSE toggle when phone is ringing or in-call
+ // to avoid music playback.
+ break;
}
}
}
@@ -4135,20 +4115,16 @@ public class PhoneWindowManager implements WindowManagerPolicy {
case KeyEvent.KEYCODE_CALL: {
if (down) {
- ITelephony telephonyService = getTelephonyService();
- if (telephonyService != null) {
- try {
- if (telephonyService.isRinging()) {
- Log.i(TAG, "interceptKeyBeforeQueueing:"
- + " CALL key-down while ringing: Answer the call!");
- telephonyService.answerRingingCall();
+ TelephonyManager telephonyManager = getTelephonyService();
+ if (telephonyManager != null) {
+ if (telephonyManager.isRinging()) {
+ Log.i(TAG, "interceptKeyBeforeQueueing:"
+ + " CALL key-down while ringing: Answer the call!");
+ telephonyManager.answerRingingCall();
- // And *don't* pass this key thru to the current activity
- // (which is presumably the InCallScreen.)
- result &= ~ACTION_PASS_TO_USER;
- }
- } catch (RemoteException ex) {
- Log.w(TAG, "ITelephony threw RemoteException", ex);
+ // And *don't* pass this key thru to the current activity
+ // (which is presumably the InCallScreen.)
+ result &= ~ACTION_PASS_TO_USER;
}
}
}
diff --git a/telecomm/java/com/android/internal/telecomm/ITelecommService.aidl b/telecomm/java/com/android/internal/telecomm/ITelecommService.aidl
new file mode 100644
index 0000000000000..c439211347232
--- /dev/null
+++ b/telecomm/java/com/android/internal/telecomm/ITelecommService.aidl
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telecomm;
+
+/**
+ * Interface used to interact with Telecomm. Mostly this is used by TelephonyManager for passing
+ * commands that were previously handled by ITelephony.
+ * {@hide}
+ */
+oneway interface ITelecommService {
+
+ /**
+ * Silence the ringer if an incoming call is currently ringing.
+ * (If vibrating, stop the vibrator also.)
+ *
+ * It's safe to call this if the ringer has already been silenced, or
+ * even if there's no incoming call. (If so, this method will do nothing.)
+ */
+ void silenceRinger();
+}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index a89686195aa5e..4aed1fef16aad 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -30,6 +30,7 @@ import android.os.SystemProperties;
import android.telephony.Rlog;
import android.util.Log;
+import com.android.internal.telecomm.ITelecommService;
import com.android.internal.telephony.IPhoneSubInfo;
import com.android.internal.telephony.ITelephony;
import com.android.internal.telephony.ITelephonyRegistry;
@@ -65,6 +66,8 @@ import java.util.regex.Pattern;
public class TelephonyManager {
private static final String TAG = "TelephonyManager";
+ private static final String TELECOMM_SERVICE_NAME = "telecomm";
+
private static ITelephonyRegistry sRegistry;
/**
@@ -1536,6 +1539,10 @@ public class TelephonyManager {
return ITelephony.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_SERVICE));
}
+ private ITelecommService getTelecommService() {
+ return ITelecommService.Stub.asInterface(ServiceManager.getService(TELECOMM_SERVICE_NAME));
+ }
+
//
//
// PhoneStateListener
@@ -2016,9 +2023,9 @@ public class TelephonyManager {
@PrivateApi
public void silenceRinger() {
try {
- getITelephony().silenceRinger();
+ getTelecommService().silenceRinger();
} catch (RemoteException e) {
- Log.e(TAG, "Error calling ITelephony#silenceRinger", e);
+ Log.e(TAG, "Error calling ITelecommService#silenceRinger", e);
}
}
From e2f9cc8d42b8ed537c81cf2ba60a288830ce9b30 Mon Sep 17 00:00:00 2001
From: John Spurlock
Date: Thu, 22 May 2014 12:20:16 -0400
Subject: [PATCH 03/93] Better wifi-enabled signal from network controller.
The old "is wifi enabled" signal was geared toward the cluster
view. Since the clients of the callbacks are now only QS tiles,
make sure to plumb through the actual enabled value all the way
up to the tile.
Bug:15161053
Change-Id: I8b69c599f06d5b36e3f44dc666e1621840ffd927
---
.../SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java | 2 +-
.../systemui/statusbar/policy/NetworkControllerImpl.java | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index ef7fb89147b8f..a1e70b98e7a91 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -83,7 +83,7 @@ public class WifiTile extends QSTile {
boolean wifiConnected = cb.enabled && (cb.wifiSignalIconId > 0) && (cb.enabledDesc != null);
boolean wifiNotConnected = (cb.wifiSignalIconId > 0) && (cb.enabledDesc == null);
- state.enabled = wifiConnected;
+ state.enabled = cb.enabled;
state.connected = wifiConnected;
state.activityIn = cb.enabled && cb.activityIn;
state.activityOut = cb.enabled && cb.activityOut;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index 966c0b04b3975..56402a5d9b8e0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -339,7 +339,7 @@ public class NetworkControllerImpl extends BroadcastReceiver
boolean wifiOut = wifiEnabled && mWifiSsid != null
&& (mWifiActivity == WifiManager.DATA_ACTIVITY_INOUT
|| mWifiActivity == WifiManager.DATA_ACTIVITY_OUT);
- cb.onWifiSignalChanged(wifiEnabled, mQSWifiIconId, wifiIn, wifiOut,
+ cb.onWifiSignalChanged(mWifiEnabled, mQSWifiIconId, wifiIn, wifiOut,
mContentDescriptionWifi, wifiDesc);
boolean mobileIn = mDataConnected && (mDataActivity == TelephonyManager.DATA_ACTIVITY_INOUT
From 9a97d1217868aa439b20eb0d4ae8ca647063850d Mon Sep 17 00:00:00 2001
From: Ihab Awad
Date: Thu, 22 May 2014 09:49:34 -0700
Subject: [PATCH 04/93] Fix invalid format specifier in log message
Bug: 15154713
Change-Id: Ia1f45eb568b31f02a7443def0dc9ef32a21e7f02
---
telecomm/java/android/telecomm/ConnectionService.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/telecomm/java/android/telecomm/ConnectionService.java b/telecomm/java/android/telecomm/ConnectionService.java
index 9ace36fd67cd2..492b08ec93d97 100644
--- a/telecomm/java/android/telecomm/ConnectionService.java
+++ b/telecomm/java/android/telecomm/ConnectionService.java
@@ -40,7 +40,7 @@ public abstract class ConnectionService extends CallService {
@Override
public void onStateChanged(Connection c, int state) {
String id = mIdByConnection.get(c);
- Log.d(this, "Adapter set state %d %s", id, Connection.stateToString(state));
+ Log.d(this, "Adapter set state %s %s", id, Connection.stateToString(state));
switch (state) {
case Connection.State.ACTIVE:
getAdapter().setActive(id);
From 9ae180181b3c7f19beb86a93067831f5b11b9c35 Mon Sep 17 00:00:00 2001
From: Dianne Hackborn
Date: Wed, 21 May 2014 15:01:03 -0700
Subject: [PATCH 05/93] Battery monitoring fixes:
- Improve monitoring of level changes to not be confused
when it goes up while draining or down while charging.
- Put back in connectivity service code to tell battery
stats about the interfaces.
- Turn back on reporting of mobile radio active state
from the RIL.
- Fix bug in marshalling/unmarshalling that would cause
the UI to show bad data.
Change-Id: I733ef52702894cca81a0813eccdfc1023e546fce
---
.../android/internal/os/BatteryStatsImpl.java | 19 ++++++++++++++-----
.../android/server/ConnectivityService.java | 9 +++++----
.../server/NetworkManagementService.java | 5 ++---
3 files changed, 21 insertions(+), 12 deletions(-)
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 8428f66951cfe..24e55e49f6d49 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -328,11 +328,13 @@ public final class BatteryStatsImpl extends BatteryStats {
int mLastDischargeStepLevel;
long mLastDischargeStepTime;
+ int mMinDischargeStepLevel;
int mNumDischargeStepDurations;
final long[] mDischargeStepDurations = new long[MAX_LEVEL_STEPS];
int mLastChargeStepLevel;
long mLastChargeStepTime;
+ int mMaxChargeStepLevel;
int mNumChargeStepDurations;
final long[] mChargeStepDurations = new long[MAX_LEVEL_STEPS];
@@ -887,6 +889,7 @@ public final class BatteryStatsImpl extends BatteryStats {
mLastTime = 0;
mUnpluggedTime = in.readLong();
timeBase.add(this);
+ if (DEBUG) Log.i(TAG, "**** READ TIMER #" + mType + ": mTotalTime=" + mTotalTime);
}
Timer(int type, TimeBase timeBase) {
@@ -917,6 +920,8 @@ public final class BatteryStatsImpl extends BatteryStats {
}
public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
+ if (DEBUG) Log.i(TAG, "**** WRITING TIMER #" + mType + ": mTotalTime="
+ + computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)));
out.writeInt(mCount);
out.writeInt(mLoadedCount);
out.writeInt(mUnpluggedCount);
@@ -5550,6 +5555,7 @@ public final class BatteryStatsImpl extends BatteryStats {
for (int i=0; i level) {
mNumDischargeStepDurations = addLevelSteps(mDischargeStepDurations,
mNumDischargeStepDurations, mLastDischargeStepTime,
mLastDischargeStepLevel - level, elapsedRealtime);
mLastDischargeStepLevel = level;
+ mMinDischargeStepLevel = level;
mLastDischargeStepTime = elapsedRealtime;
}
} else {
- if (mLastChargeStepLevel != level) {
+ if (mLastChargeStepLevel != level && mMaxChargeStepLevel < level) {
mNumChargeStepDurations = addLevelSteps(mChargeStepDurations,
mNumChargeStepDurations, mLastChargeStepTime,
level - mLastChargeStepLevel, elapsedRealtime);
mLastChargeStepLevel = level;
+ mMaxChargeStepLevel = level;
mLastChargeStepTime = elapsedRealtime;
}
}
@@ -7495,6 +7504,8 @@ public final class BatteryStatsImpl extends BatteryStats {
mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i, null, mOnBatteryTimeBase,
in);
}
+ mInteractive = false;
+ mInteractiveTimer = new StopwatchTimer(null, -9, null, mOnBatteryTimeBase, in);
mPhoneOn = false;
mLowPowerModeEnabledTimer = new StopwatchTimer(null, -2, null, mOnBatteryTimeBase, in);
mPhoneOnTimer = new StopwatchTimer(null, -3, null, mOnBatteryTimeBase, in);
@@ -7536,8 +7547,6 @@ public final class BatteryStatsImpl extends BatteryStats {
mAudioOnTimer = new StopwatchTimer(null, -7, null, mOnBatteryTimeBase);
mVideoOn = false;
mVideoOnTimer = new StopwatchTimer(null, -8, null, mOnBatteryTimeBase);
- mInteractive = false;
- mInteractiveTimer = new StopwatchTimer(null, -9, null, mOnBatteryTimeBase, in);
mDischargeUnplugLevel = in.readInt();
mDischargePlugLevel = in.readInt();
mDischargeCurrentLevel = in.readInt();
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 37b75d6877e16..1e21e1cc5134f 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -5709,10 +5709,11 @@ public class ConnectivityService extends IConnectivityManager.Stub {
// updateNetworkSettings();
}
// notify battery stats service about this network
-// try {
- // TODO
- //BatteryStatsService.getService().noteNetworkInterfaceType(iface, netType);
-// } catch (RemoteException e) { }
+ try {
+ BatteryStatsService.getService().noteNetworkInterfaceType(
+ newNetwork.linkProperties.getInterfaceName(),
+ newNetwork.networkInfo.getType());
+ } catch (RemoteException e) { }
notifyNetworkCallbacks(newNetwork, ConnectivityManager.CALLBACK_AVAILABLE);
} else {
if (DBG && newNetwork.networkRequests.size() != 0) {
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index cf917827dfd75..137387e17ef55 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -240,9 +240,8 @@ public class NetworkManagementService extends INetworkManagementService.Stub
mPhoneStateListener = new PhoneStateListener(mDaemonHandler.getLooper()) {
public void onDataConnectionRealTimeInfoChanged(
DataConnectionRealTimeInfo dcRtInfo) {
- // Disabled for now, until we are getting good data.
- //notifyInterfaceClassActivity(ConnectivityManager.TYPE_MOBILE,
- // dcRtInfo.getDcPowerState(), dcRtInfo.getTime(), true);
+ notifyInterfaceClassActivity(ConnectivityManager.TYPE_MOBILE,
+ dcRtInfo.getDcPowerState(), dcRtInfo.getTime(), true);
}
};
From 8094b3255702bd4f0fa97ff6e4357a9bb4cc6541 Mon Sep 17 00:00:00 2001
From: vandwalle
Date: Thu, 22 May 2014 11:53:15 -0700
Subject: [PATCH 06/93] revert change preventing NULL SSID in a
WifiConfiguration
bug: 15114340
Change-Id: Ic66363fc7781a1d65e5b8647843a752c048145a1
---
wifi/java/android/net/wifi/WifiConfiguration.java | 2 --
1 file changed, 2 deletions(-)
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index bafc71ea477b0..1157de7d10dbd 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -509,8 +509,6 @@ public class WifiConfiguration implements Parcelable {
* @hide
*/
public boolean isValid() {
- if (SSID == null)
- return false;
if (allowedKeyManagement == null)
return false;
From a224654cdf9b370aa679e2ba126ae20b1ebb0960 Mon Sep 17 00:00:00 2001
From: Craig Mautner
Date: Mon, 26 May 2014 16:52:58 -0700
Subject: [PATCH 07/93] Only start TaskPersister once.
Because ActivityManagerService.systemReady() is reentrant we could
restore tasks and start the TaskPersister more than one time. This
fix limits operations on TaskPersister to one time only.
Fixes bug 15256579.
Change-Id: I6bf2c26b37acdfd9b15a6f277966966b743d03b6
---
.../com/android/server/am/ActivityManagerService.java | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index c2518f60e8102..af082da26ba68 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -9577,11 +9577,13 @@ public final class ActivityManagerService extends ActivityManagerNative
return;
}
- mRecentTasks = mTaskPersister.restoreTasksLocked();
- if (!mRecentTasks.isEmpty()) {
- mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
+ if (mRecentTasks == null) {
+ mRecentTasks = mTaskPersister.restoreTasksLocked();
+ if (!mRecentTasks.isEmpty()) {
+ mStackSupervisor.createStackForRestoredTaskHistory(mRecentTasks);
+ }
+ mTaskPersister.startPersisting();
}
- mTaskPersister.startPersisting();
// Check to see if there are any update receivers to run.
if (!mDidUpdate) {
From 04cdbe50b7e65d13c1c9399de898eee003656c60 Mon Sep 17 00:00:00 2001
From: John Reck
Date: Wed, 28 May 2014 12:35:30 -0700
Subject: [PATCH 08/93] Disable RT animations
Bug: 15287046
Change-Id: Ib511053726153649ea1bda337d14bc05db4f0bf9
---
core/java/android/view/ViewPropertyAnimator.java | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/core/java/android/view/ViewPropertyAnimator.java b/core/java/android/view/ViewPropertyAnimator.java
index 310486209467c..b92b983a5a46c 100644
--- a/core/java/android/view/ViewPropertyAnimator.java
+++ b/core/java/android/view/ViewPropertyAnimator.java
@@ -253,9 +253,10 @@ public class ViewPropertyAnimator {
ViewPropertyAnimator(View view) {
mView = view;
view.ensureTransformationInfo();
- if (view.getContext().getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.L) {
- mRTBackend = new ViewPropertyAnimatorRT(view);
- }
+ // TODO: Disabled because of b/15287046
+ //if (view.getContext().getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.L) {
+ // mRTBackend = new ViewPropertyAnimatorRT(view);
+ //}
}
/**
From a1dd77f41a8caf7ce5f5637ecc2183ea578e3b00 Mon Sep 17 00:00:00 2001
From: Lorenzo Colitti
Date: Thu, 29 May 2014 14:05:41 +0900
Subject: [PATCH 09/93] Don't break things if a network goes back to CONNECTED.
Currently, if a network goes from CONNECTED to some other "live"
state (e.g., CONNECTING, because it's VERIFYING_POOR_LINK) and
back, ConnectivityService treats it as if a new network had
connected. This causes it to attempt to create the network
(which fails, since a network with that netid already exists), to
trigger verification, and if the verification succeeds, to tear
down the network because the request it's satisfying is already
satisfied by the network itself.
Instead, if creating the network fails, assume it's because the
network had already been created, and bail out.
Also, when validation completes, ignore NetworkRequests that were
being served by the same NetworkAgent as before.
Bug: 15244052
Change-Id: Ifd73558e5be452d9ef88c64cca429d5f302bf354
---
.../android/server/ConnectivityService.java | 22 +++++++++++++++----
1 file changed, 18 insertions(+), 4 deletions(-)
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 1e21e1cc5134f..5527528fd25e9 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -5606,16 +5606,23 @@ public class ConnectivityService extends IConnectivityManager.Stub {
boolean isNewDefault = false;
if (DBG) log("handleConnectionValidated for "+newNetwork.name());
// check if any NetworkRequest wants this NetworkAgent
- // first check if it satisfies the NetworkCapabilities
ArrayList affectedNetworks = new ArrayList();
if (VDBG) log(" new Network has: " + newNetwork.networkCapabilities);
for (NetworkRequestInfo nri : mNetworkRequests.values()) {
+ NetworkAgentInfo currentNetwork = mNetworkForRequestId.get(nri.request.requestId);
+ if (newNetwork == currentNetwork) {
+ if (VDBG) log("Network " + newNetwork.name() + " was already satisfying" +
+ " request " + nri.request.requestId + ". No change.");
+ keep = true;
+ continue;
+ }
+
+ // check if it satisfies the NetworkCapabilities
if (VDBG) log(" checking if request is satisfied: " + nri.request);
if (nri.request.networkCapabilities.satisfiedByNetworkCapabilities(
newNetwork.networkCapabilities)) {
// next check if it's better than any current network we're using for
// this request
- NetworkAgentInfo currentNetwork = mNetworkForRequestId.get(nri.request.requestId);
if (VDBG) {
log("currentScore = " +
(currentNetwork != null ? currentNetwork.currentScore : 0) +
@@ -5744,12 +5751,19 @@ public class ConnectivityService extends IConnectivityManager.Stub {
}
if (state == NetworkInfo.State.CONNECTED) {
- // TODO - check if we want it (optimization)
try {
+ // This is likely caused by the fact that this network already
+ // exists. An example is when a network goes from CONNECTED to
+ // CONNECTING and back (like wifi on DHCP renew).
+ // TODO: keep track of which networks we've created, or ask netd
+ // to tell us whether we've already created this network or not.
mNetd.createNetwork(networkAgent.network.netId);
} catch (Exception e) {
- loge("Error creating Network " + networkAgent.network.netId);
+ loge("Error creating network " + networkAgent.network.netId + ": "
+ + e.getMessage());
+ return;
}
+
updateLinkProperties(networkAgent, null);
notifyNetworkCallbacks(networkAgent, ConnectivityManager.CALLBACK_PRECHECK);
networkAgent.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_CONNECTED);
From e097a8f288f0fcfafc0f9592065edcfe1d137dbd Mon Sep 17 00:00:00 2001
From: Dan Sandler
Date: Thu, 29 May 2014 11:02:41 -0400
Subject: [PATCH 10/93] Use DecorToolbar.getViewGroup() to get the view
properly.
Bug: 15320825
Change-Id: Ib7e162c816fadf2b5c83af1326e7158f6bd69c8e
---
core/java/com/android/internal/app/WindowDecorActionBar.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/core/java/com/android/internal/app/WindowDecorActionBar.java b/core/java/com/android/internal/app/WindowDecorActionBar.java
index a0c75a64624b9..5c7a4e63fd7d6 100644
--- a/core/java/com/android/internal/app/WindowDecorActionBar.java
+++ b/core/java/com/android/internal/app/WindowDecorActionBar.java
@@ -342,7 +342,7 @@ public class WindowDecorActionBar extends ActionBar implements
@Override
public void setCustomView(int resId) {
setCustomView(LayoutInflater.from(getThemedContext()).inflate(resId,
- (ViewGroup) mDecorToolbar, false));
+ mDecorToolbar.getViewGroup(), false));
}
@Override
From 1baed873c2cd87f20e0281f33a0e6d622e709b74 Mon Sep 17 00:00:00 2001
From: Dianne Hackborn
Date: Fri, 23 May 2014 16:51:05 -0700
Subject: [PATCH 11/93] Fix issue #15195464: battery history says wakelock held
when it's not
Simplify full wake lock logging, so wake_lock_in is a completely
separate event from wake_lock and provides the full real raw log
of wake lock events.
Also attempt to address issue #15018750 (Incorrect wakelock reporting)
by no longer being complicated and rolling up previous state in to a
new history slice.
Bug: 15195464
Bug: 15018750
Change-Id: I32154bdfc2f07113be969f9db5503b2f2807a427
From 9e8497f5b5d1b1df0a60ed069f7edf71555f0152 Mon Sep 17 00:00:00 2001
From: Ashish Sharma
Date: Fri, 23 May 2014 18:22:20 -0700
Subject: [PATCH 12/93] Include START event (reboots) in partial history.
Change-Id: Ia1e5fba6c2c7bdb3f09eb5958d7134564d60e8b0
From a742cbed0ca07e2602da0c9337d6cbbb8294659b Mon Sep 17 00:00:00 2001
From: Adam Powell
Date: Thu, 29 May 2014 12:16:09 -0700
Subject: [PATCH 13/93] Fix for setting Toolbar content descriptions
Allow resid 0 as a null content description.
Change-Id: I0663feac229a77d5efffece2bd686de4ee99d840
---
core/java/android/widget/Toolbar.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/core/java/android/widget/Toolbar.java b/core/java/android/widget/Toolbar.java
index 8c67bb770b5af..5033bee91b366 100644
--- a/core/java/android/widget/Toolbar.java
+++ b/core/java/android/widget/Toolbar.java
@@ -592,7 +592,7 @@ public class Toolbar extends ViewGroup {
*/
public void setNavigationContentDescription(int resId) {
ensureNavButtonView();
- mNavButtonView.setContentDescription(getContext().getText(resId));
+ mNavButtonView.setContentDescription(resId != 0 ? getContext().getText(resId) : null);
}
/**
From 47d7c59fdf2f3c343b56bc73af789a78621eaddb Mon Sep 17 00:00:00 2001
From: Craig Mautner
Date: Thu, 29 May 2014 16:50:59 +0000
Subject: [PATCH 14/93] Revert "Modify task navigation to return to recent
tasks." DO NOT MERGE
This reverts commit 1a4e211e03f1f795d935058e27356a0e8bc5df7c.
Change-Id: Ia691b93347c7eb2395933e5a5ba385ea94e08d6f
---
.../android/view/WindowManagerPolicy.java | 6 --
.../policy/impl/PhoneWindowManager.java | 10 --
.../com/android/server/am/ActivityStack.java | 102 ++++++++++--------
.../server/am/ActivityStackSupervisor.java | 41 +++----
.../com/android/server/am/TaskRecord.java | 44 +++-----
.../server/wm/WindowManagerService.java | 4 -
6 files changed, 88 insertions(+), 119 deletions(-)
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 20194eb9f0d5a..6fa54524e0478 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -1148,12 +1148,6 @@ public interface WindowManagerPolicy {
*/
public void setLastInputMethodWindowLw(WindowState ime, WindowState target);
- /**
- * Show the recents task list app.
- * @hide
- */
- public void showRecentApps();
-
/**
* @return The current height of the input method window.
*/
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 3d53725c3782f..decf73fe06ed7 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -483,7 +483,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
private static final int MSG_DISABLE_POINTER_LOCATION = 2;
private static final int MSG_DISPATCH_MEDIA_KEY_WITH_WAKE_LOCK = 3;
private static final int MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK = 4;
- private static final int MSG_DISPATCH_SHOW_RECENTS = 5;
private class PolicyHandler extends Handler {
@Override
@@ -501,9 +500,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
case MSG_DISPATCH_MEDIA_KEY_REPEAT_WITH_WAKE_LOCK:
dispatchMediaKeyRepeatWithWakeLock((KeyEvent)msg.obj);
break;
- case MSG_DISPATCH_SHOW_RECENTS:
- showRecentApps(false);
- break;
}
}
}
@@ -2467,12 +2463,6 @@ public class PhoneWindowManager implements WindowManagerPolicy {
}
}
- @Override
- public void showRecentApps() {
- mHandler.removeMessages(MSG_DISPATCH_SHOW_RECENTS);
- mHandler.sendEmptyMessage(MSG_DISPATCH_SHOW_RECENTS);
- }
-
private void showRecentApps(boolean triggeredFromAltTab) {
mPreloadedRecentApps = false; // preloading no longer needs to be canceled
try {
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 8f60b0377766d..1804d039fa7ac 100755
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -30,10 +30,6 @@ import static com.android.server.am.ActivityManagerService.DEBUG_USER_LEAVING;
import static com.android.server.am.ActivityManagerService.DEBUG_VISBILITY;
import static com.android.server.am.ActivityManagerService.VALIDATE_TOKENS;
-import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
-import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
-import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
-
import static com.android.server.am.ActivityStackSupervisor.DEBUG_ADD_REMOVE;
import static com.android.server.am.ActivityStackSupervisor.DEBUG_APP;
import static com.android.server.am.ActivityStackSupervisor.DEBUG_SAVED_STATE;
@@ -1067,6 +1063,40 @@ final class ActivityStack {
}
}
+ /**
+ * Determine if home should be visible below the passed record.
+ * @param record activity we are querying for.
+ * @return true if home is visible below the passed activity, false otherwise.
+ */
+ boolean isActivityOverHome(ActivityRecord record) {
+ // Start at record and go down, look for either home or a visible fullscreen activity.
+ final TaskRecord recordTask = record.task;
+ for (int taskNdx = mTaskHistory.indexOf(recordTask); taskNdx >= 0; --taskNdx) {
+ TaskRecord task = mTaskHistory.get(taskNdx);
+ final ArrayList activities = task.mActivities;
+ final int startNdx =
+ task == recordTask ? activities.indexOf(record) : activities.size() - 1;
+ for (int activityNdx = startNdx; activityNdx >= 0; --activityNdx) {
+ final ActivityRecord r = activities.get(activityNdx);
+ if (r.isHomeActivity()) {
+ return true;
+ }
+ if (!r.finishing && r.fullscreen) {
+ // Passed activity is over a fullscreen activity.
+ return false;
+ }
+ }
+ if (task.mOnTopOfHome) {
+ // Got to the bottom of a task on top of home without finding a visible fullscreen
+ // activity. Home is visible.
+ return true;
+ }
+ }
+ // Got to the bottom of this stack and still don't know. If this is over the home stack
+ // then record is over home. May not work if we ever get more than two layers.
+ return mStackSupervisor.isFrontStack(this);
+ }
+
private void setVisibile(ActivityRecord r, boolean visible) {
r.visible = visible;
mWindowManager.setAppVisibility(r.appToken, visible);
@@ -1096,8 +1126,7 @@ final class ActivityStack {
for (int i = mStacks.indexOf(this) + 1; i < mStacks.size(); i++) {
final ArrayList tasks = mStacks.get(i).getAllTasks();
for (int taskNdx = 0; taskNdx < tasks.size(); taskNdx++) {
- final TaskRecord task = tasks.get(taskNdx);
- final ArrayList activities = task.mActivities;
+ final ArrayList activities = tasks.get(taskNdx).mActivities;
for (int activityNdx = 0; activityNdx < activities.size(); activityNdx++) {
final ActivityRecord r = activities.get(activityNdx);
@@ -1108,7 +1137,7 @@ final class ActivityStack {
// - Full Screen Activity OR
// - On top of Home and our stack is NOT home
if (!r.finishing && r.visible && (r.fullscreen ||
- (!isHomeStack() && r.frontOfTask && task.isOverHomeStack()))) {
+ (!isHomeStack() && r.frontOfTask && tasks.get(taskNdx).mOnTopOfHome))) {
return false;
}
}
@@ -1236,7 +1265,7 @@ final class ActivityStack {
// At this point, nothing else needs to be shown
if (DEBUG_VISBILITY) Slog.v(TAG, "Fullscreen: at " + r);
behindFullscreen = true;
- } else if (!isHomeStack() && r.frontOfTask && task.isOverHomeStack()) {
+ } else if (!isHomeStack() && r.frontOfTask && task.mOnTopOfHome) {
if (DEBUG_VISBILITY) Slog.v(TAG, "Showing home: at " + r);
behindFullscreen = true;
}
@@ -1390,7 +1419,6 @@ final class ActivityStack {
final boolean userLeaving = mStackSupervisor.mUserLeaving;
mStackSupervisor.mUserLeaving = false;
- final TaskRecord prevTask = prev != null ? prev.task : null;
if (next == null) {
// There are no more activities! Let's just start up the
// Launcher...
@@ -1398,10 +1426,7 @@ final class ActivityStack {
if (DEBUG_STATES) Slog.d(TAG, "resumeTopActivityLocked: No more activities go home");
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
// Only resume home if on home display
- final int returnTaskType = prevTask == null || !prevTask.isOverHomeStack() ?
- HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo();
- return isOnHomeDisplay() &&
- mStackSupervisor.resumeHomeStackTask(returnTaskType, prev);
+ return isOnHomeDisplay() && mStackSupervisor.resumeHomeActivity(prev);
}
next.delayedResume = false;
@@ -1420,24 +1445,22 @@ final class ActivityStack {
}
final TaskRecord nextTask = next.task;
+ final TaskRecord prevTask = prev != null ? prev.task : null;
if (prevTask != null && prevTask.stack == this &&
- prevTask.isOverHomeStack() && prev.finishing && prev.frontOfTask) {
+ prevTask.mOnTopOfHome && prev.finishing && prev.frontOfTask) {
if (DEBUG_STACK) mStackSupervisor.validateTopActivitiesLocked();
if (prevTask == nextTask) {
prevTask.setFrontOfTask();
} else if (prevTask != topTask()) {
- // This task is going away but it was supposed to return to the home stack.
+ // This task is going away but it was supposed to return to the home task.
// Now the task above it has to return to the home task instead.
final int taskNdx = mTaskHistory.indexOf(prevTask) + 1;
- mTaskHistory.get(taskNdx).setTaskToReturnTo(HOME_ACTIVITY_TYPE);
+ mTaskHistory.get(taskNdx).mOnTopOfHome = true;
} else {
if (DEBUG_STATES && isOnHomeDisplay()) Slog.d(TAG,
"resumeTopActivityLocked: Launching home next");
// Only resume home if on home display
- final int returnTaskType = prevTask == null || !prevTask.isOverHomeStack() ?
- HOME_ACTIVITY_TYPE : prevTask.getTaskToReturnTo();
- return isOnHomeDisplay() &&
- mStackSupervisor.resumeHomeStackTask(returnTaskType, prev);
+ return isOnHomeDisplay() && mStackSupervisor.resumeHomeActivity(prev);
}
}
@@ -1808,11 +1831,10 @@ final class ActivityStack {
ActivityStack lastStack = mStackSupervisor.getLastStack();
final boolean fromHome = lastStack.isHomeStack();
if (!isHomeStack() && (fromHome || topTask() != task)) {
- task.setTaskToReturnTo(fromHome ?
- lastStack.topTask().taskType : APPLICATION_ACTIVITY_TYPE);
+ task.mOnTopOfHome = fromHome;
}
} else {
- task.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE);
+ task.mOnTopOfHome = false;
}
mTaskHistory.remove(task);
@@ -2357,8 +2379,8 @@ final class ActivityStack {
ActivityRecord next = topRunningActivityLocked(null);
if (next != r) {
final TaskRecord task = r.task;
- if (r.frontOfTask && task == topTask() && task.isOverHomeStack()) {
- mStackSupervisor.moveHomeStackTaskToTop(task.getTaskToReturnTo());
+ if (r.frontOfTask && task == topTask() && task.mOnTopOfHome) {
+ mStackSupervisor.moveHomeToTop();
}
}
ActivityRecord top = mStackSupervisor.topRunningActivityLocked();
@@ -2842,9 +2864,8 @@ final class ActivityStack {
if (task != null && task.removeActivity(r)) {
if (DEBUG_STACK) Slog.i(TAG,
"removeActivityFromHistoryLocked: last activity removed from " + this);
- if (mStackSupervisor.isFrontStack(this) && task == topTask() &&
- task.isOverHomeStack()) {
- mStackSupervisor.moveHomeStackTaskToTop(task.getTaskToReturnTo());
+ if (mStackSupervisor.isFrontStack(this) && task == topTask() && task.mOnTopOfHome) {
+ mStackSupervisor.moveHomeToTop();
}
removeTask(task);
}
@@ -3159,13 +3180,12 @@ final class ActivityStack {
}
}
- void moveHomeStackTaskToTop(int homeStackTaskType) {
+ void moveHomeTaskToTop() {
final int top = mTaskHistory.size() - 1;
for (int taskNdx = top; taskNdx >= 0; --taskNdx) {
final TaskRecord task = mTaskHistory.get(taskNdx);
- if (task.taskType == homeStackTaskType) {
- if (DEBUG_TASKS || DEBUG_STACK)
- Slog.d(TAG, "moveHomeStackTaskToTop: moving " + task);
+ if (task.isHomeTask()) {
+ if (DEBUG_TASKS || DEBUG_STACK) Slog.d(TAG, "moveHomeTaskToTop: moving " + task);
mTaskHistory.remove(taskNdx);
mTaskHistory.add(top, task);
updateTaskMovement(task, true);
@@ -3277,12 +3297,12 @@ final class ActivityStack {
int numTasks = mTaskHistory.size();
for (int taskNdx = numTasks - 1; taskNdx >= 1; --taskNdx) {
final TaskRecord task = mTaskHistory.get(taskNdx);
- if (task.isOverHomeStack()) {
+ if (task.mOnTopOfHome) {
break;
}
if (taskNdx == 1) {
// Set the last task before tr to go to home.
- task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
+ task.mOnTopOfHome = true;
}
}
@@ -3303,10 +3323,9 @@ final class ActivityStack {
}
final TaskRecord task = mResumedActivity != null ? mResumedActivity.task : null;
- if (task == tr && tr.isOverHomeStack() || numTasks <= 1 && isOnHomeDisplay()) {
- final int taskToReturnTo = tr.getTaskToReturnTo();
- tr.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE);
- return mStackSupervisor.resumeHomeStackTask(taskToReturnTo, null);
+ if (task == tr && tr.mOnTopOfHome || numTasks <= 1 && isOnHomeDisplay()) {
+ tr.mOnTopOfHome = false;
+ return mStackSupervisor.resumeHomeActivity(null);
}
mStackSupervisor.resumeTopActivitiesLocked();
@@ -3747,11 +3766,8 @@ final class ActivityStack {
final int taskNdx = mTaskHistory.indexOf(task);
final int topTaskNdx = mTaskHistory.size() - 1;
- if (task.isOverHomeStack() && taskNdx < topTaskNdx) {
- final TaskRecord nextTask = mTaskHistory.get(taskNdx + 1);
- if (!nextTask.isOverHomeStack()) {
- nextTask.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
- }
+ if (task.mOnTopOfHome && taskNdx < topTaskNdx) {
+ mTaskHistory.get(taskNdx + 1).mOnTopOfHome = true;
}
mTaskHistory.remove(task);
updateTaskMovement(task, true);
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index f52f79620f681..ed260173beae5 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -31,9 +31,6 @@ import static com.android.server.am.ActivityManagerService.DEBUG_TASKS;
import static com.android.server.am.ActivityManagerService.DEBUG_USER_LEAVING;
import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG;
import static com.android.server.am.ActivityManagerService.TAG;
-import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
-import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
-import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
import android.app.Activity;
import android.app.ActivityManager;
@@ -347,27 +344,18 @@ public final class ActivityStackSupervisor implements DisplayListener {
}
}
- void moveHomeStackTaskToTop(int homeStackTaskType) {
- if (homeStackTaskType == RECENTS_ACTIVITY_TYPE) {
- mWindowManager.showRecentApps();
- return;
- }
+ void moveHomeToTop() {
moveHomeStack(true);
- mHomeStack.moveHomeStackTaskToTop(homeStackTaskType);
+ mHomeStack.moveHomeTaskToTop();
}
- boolean resumeHomeStackTask(int homeStackTaskType, ActivityRecord prev) {
- if (homeStackTaskType == RECENTS_ACTIVITY_TYPE) {
- mWindowManager.showRecentApps();
- return false;
- }
- moveHomeStackTaskToTop(homeStackTaskType);
+ boolean resumeHomeActivity(ActivityRecord prev) {
+ moveHomeToTop();
if (prev != null) {
- prev.task.setTaskToReturnTo(APPLICATION_ACTIVITY_TYPE);
+ prev.task.mOnTopOfHome = false;
}
-
ActivityRecord r = mHomeStack.topRunningActivityLocked(null);
- if (r != null && (r.isHomeActivity() || r.isRecentsActivity())) {
+ if (r != null && r.isHomeActivity()) {
mService.setFocusedActivityLocked(r);
return resumeTopActivitiesLocked(mHomeStack, prev, null);
}
@@ -721,7 +709,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
}
void startHomeActivity(Intent intent, ActivityInfo aInfo) {
- moveHomeStackTaskToTop(HOME_ACTIVITY_TYPE);
+ moveHomeToTop();
startActivityLocked(null, intent, null, aInfo, null, null, null, null, 0, 0, 0, null, 0,
null, false, null, null);
}
@@ -1656,7 +1644,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME))
== (FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_TASK_ON_HOME)) {
// Caller wants to appear on home activity.
- intentActivity.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
+ intentActivity.task.mOnTopOfHome = true;
}
options = null;
}
@@ -1841,11 +1829,6 @@ public final class ActivityStackSupervisor implements DisplayListener {
newTaskInfo != null ? newTaskInfo : r.info,
newTaskIntent != null ? newTaskIntent : intent,
voiceSession, voiceInteractor, true), null, true);
- if (sourceRecord == null) {
- // Launched from a service or notification or task that is finishing.
- r.task.setTaskToReturnTo(isFrontStack(mHomeStack) ?
- mHomeStack.topTask().taskType : RECENTS_ACTIVITY_TYPE);
- }
if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r + " in new task " +
r.task);
} else {
@@ -1857,7 +1840,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
== (Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME)) {
// Caller wants to appear on home activity, so before starting
// their own activity we will bring home to the front.
- r.task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
+ r.task.mOnTopOfHome = r.task.stack.isOnHomeDisplay();
}
}
} else if (sourceRecord != null) {
@@ -2208,7 +2191,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
if ((flags & ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
// Caller wants the home activity moved with it. To accomplish this,
// we'll just indicate that this task returns to the home task.
- task.setTaskToReturnTo(HOME_ACTIVITY_TYPE);
+ task.mOnTopOfHome = true;
}
task.stack.moveTaskToFrontLocked(task, null, options);
if (DEBUG_STACK) Slog.d(TAG, "findTaskToMoveToFront: moved to front of stack="
@@ -2319,7 +2302,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
}
mWindowManager.addTask(taskId, stackId, false);
}
- resumeHomeStackTask(HOME_ACTIVITY_TYPE, null);
+ resumeHomeActivity(null);
}
void moveTaskToStack(int taskId, int stackId, boolean toTop) {
@@ -2581,7 +2564,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
}
} else {
// Stack was moved to another display while user was swapped out.
- resumeHomeStackTask(HOME_ACTIVITY_TYPE, null);
+ resumeHomeActivity(null);
}
return homeInFront;
}
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index c07bc1e9a4edb..ce83ae6fb0e7f 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -17,9 +17,6 @@
package com.android.server.am;
import static com.android.server.am.ActivityManagerService.TAG;
-import static com.android.server.am.ActivityRecord.HOME_ACTIVITY_TYPE;
-import static com.android.server.am.ActivityRecord.APPLICATION_ACTIVITY_TYPE;
-import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
import static com.android.server.am.ActivityStackSupervisor.DEBUG_ADD_REMOVE;
import android.app.Activity;
@@ -57,6 +54,7 @@ final class TaskRecord extends ThumbnailHolder {
private static final String ATTR_ASKEDCOMPATMODE = "asked_compat_mode";
private static final String ATTR_USERID = "user_id";
private static final String ATTR_TASKTYPE = "task_type";
+ private static final String ATTR_ONTOPOFHOME = "on_top_of_home";
private static final String ATTR_LASTDESCRIPTION = "last_description";
private static final String ATTR_LASTTIMEMOVED = "last_time_moved";
@@ -106,11 +104,9 @@ final class TaskRecord extends ThumbnailHolder {
/** True if persistable, has changed, and has not yet been persisted */
boolean needsPersisting = false;
-
- /** Indication of what to run next when task exits. Use ActivityRecord types.
- * ActivityRecord.APPLICATION_ACTIVITY_TYPE indicates to resume the task below this one in the
- * task stack. */
- private int mTaskToReturnTo = APPLICATION_ACTIVITY_TYPE;
+ /** Launch the home activity when leaving this task. Will be false for tasks that are not on
+ * Display.DEFAULT_DISPLAY. */
+ boolean mOnTopOfHome = false;
final ActivityManagerService mService;
@@ -127,8 +123,9 @@ final class TaskRecord extends ThumbnailHolder {
TaskRecord(ActivityManagerService service, int _taskId, Intent _intent, Intent _affinityIntent,
String _affinity, ComponentName _realActivity, ComponentName _origActivity,
- boolean _rootWasReset, boolean _askedCompatMode, int _taskType, int _userId,
- String _lastDescription, ArrayList activities, long lastTimeMoved) {
+ boolean _rootWasReset, boolean _askedCompatMode, int _taskType, boolean _onTopOfHome,
+ int _userId, String _lastDescription, ArrayList activities,
+ long lastTimeMoved) {
mService = service;
taskId = _taskId;
intent = _intent;
@@ -141,7 +138,7 @@ final class TaskRecord extends ThumbnailHolder {
rootWasReset = _rootWasReset;
askedCompatMode = _askedCompatMode;
taskType = _taskType;
- mTaskToReturnTo = HOME_ACTIVITY_TYPE;
+ mOnTopOfHome = _onTopOfHome;
userId = _userId;
lastDescription = _lastDescription;
mActivities = activities;
@@ -209,14 +206,6 @@ final class TaskRecord extends ThumbnailHolder {
}
}
- void setTaskToReturnTo(int taskToReturnTo) {
- mTaskToReturnTo = taskToReturnTo;
- }
-
- int getTaskToReturnTo() {
- return mTaskToReturnTo;
- }
-
void disposeThumbnail() {
super.disposeThumbnail();
for (int i=mActivities.size()-1; i>=0; i--) {
@@ -488,15 +477,11 @@ final class TaskRecord extends ThumbnailHolder {
}
boolean isHomeTask() {
- return taskType == HOME_ACTIVITY_TYPE;
+ return taskType == ActivityRecord.HOME_ACTIVITY_TYPE;
}
boolean isApplicationTask() {
- return taskType == APPLICATION_ACTIVITY_TYPE;
- }
-
- boolean isOverHomeStack() {
- return mTaskToReturnTo == HOME_ACTIVITY_TYPE || mTaskToReturnTo == RECENTS_ACTIVITY_TYPE;
+ return taskType == ActivityRecord.APPLICATION_ACTIVITY_TYPE;
}
public TaskAccessInfo getTaskAccessInfoLocked() {
@@ -638,6 +623,7 @@ final class TaskRecord extends ThumbnailHolder {
out.attribute(null, ATTR_ASKEDCOMPATMODE, String.valueOf(askedCompatMode));
out.attribute(null, ATTR_USERID, String.valueOf(userId));
out.attribute(null, ATTR_TASKTYPE, String.valueOf(taskType));
+ out.attribute(null, ATTR_ONTOPOFHOME, String.valueOf(mOnTopOfHome));
out.attribute(null, ATTR_LASTTIMEMOVED, String.valueOf(mLastTimeMoved));
if (lastDescription != null) {
out.attribute(null, ATTR_LASTDESCRIPTION, lastDescription.toString());
@@ -683,6 +669,7 @@ final class TaskRecord extends ThumbnailHolder {
boolean rootHasReset = false;
boolean askedCompatMode = false;
int taskType = ActivityRecord.APPLICATION_ACTIVITY_TYPE;
+ boolean onTopOfHome = true;
int userId = 0;
String lastDescription = null;
long lastTimeOnTop = 0;
@@ -710,6 +697,8 @@ final class TaskRecord extends ThumbnailHolder {
userId = Integer.valueOf(attrValue);
} else if (ATTR_TASKTYPE.equals(attrName)) {
taskType = Integer.valueOf(attrValue);
+ } else if (ATTR_ONTOPOFHOME.equals(attrName)) {
+ onTopOfHome = Boolean.valueOf(attrValue);
} else if (ATTR_LASTDESCRIPTION.equals(attrName)) {
lastDescription = attrValue;
} else if (ATTR_LASTTIMEMOVED.equals(attrName)) {
@@ -747,7 +736,8 @@ final class TaskRecord extends ThumbnailHolder {
final TaskRecord task = new TaskRecord(stackSupervisor.mService, taskId, intent,
affinityIntent, affinity, realActivity, origActivity, rootHasReset,
- askedCompatMode, taskType, userId, lastDescription, activities, lastTimeOnTop);
+ askedCompatMode, taskType, onTopOfHome, userId, lastDescription, activities,
+ lastTimeOnTop);
for (int activityNdx = activities.size() - 1; activityNdx >=0; --activityNdx) {
final ActivityRecord r = activities.get(activityNdx);
@@ -766,7 +756,7 @@ final class TaskRecord extends ThumbnailHolder {
pw.print(" userId="); pw.print(userId);
pw.print(" taskType="); pw.print(taskType);
pw.print(" numFullscreen="); pw.print(numFullscreen);
- pw.print(" mTaskToReturnTo="); pw.println(mTaskToReturnTo);
+ pw.print(" mOnTopOfHome="); pw.println(mOnTopOfHome);
}
if (affinity != null) {
pw.print(prefix); pw.print("affinity="); pw.println(affinity);
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index d40f5622b1997..ba6316a13cb25 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -10283,10 +10283,6 @@ public class WindowManagerService extends IWindowManager.Stub
mPolicy.lockNow(options);
}
- public void showRecentApps() {
- mPolicy.showRecentApps();
- }
-
@Override
public boolean isSafeModeEnabled() {
return mSafeMode;
From d4010219f99ca0ae4574dc25e6fdd5b22f5ba2b5 Mon Sep 17 00:00:00 2001
From: Adam Powell
Date: Fri, 30 May 2014 10:28:14 -0700
Subject: [PATCH 15/93] Fix bad casts in action bars
Not all DecorToolbars are themselves views. Use the interface
passthrough instead.
Bug 15335176
Change-Id: I88f1701822406d4204d344aef855a4a707e4c7ab
---
.../java/com/android/internal/app/WindowDecorActionBar.java | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/core/java/com/android/internal/app/WindowDecorActionBar.java b/core/java/com/android/internal/app/WindowDecorActionBar.java
index 5c7a4e63fd7d6..c0b5b97d18e1a 100644
--- a/core/java/com/android/internal/app/WindowDecorActionBar.java
+++ b/core/java/com/android/internal/app/WindowDecorActionBar.java
@@ -588,7 +588,7 @@ public class WindowDecorActionBar extends ActionBar implements
return;
}
- final FragmentTransaction trans = ((View) mDecorToolbar).isInEditMode() ? null :
+ final FragmentTransaction trans = mDecorToolbar.getViewGroup().isInEditMode() ? null :
mActivity.getFragmentManager().beginTransaction().disallowAddToBackStack();
if (mSelectedTab == tab) {
@@ -847,7 +847,7 @@ public class WindowDecorActionBar extends ActionBar implements
mDecorToolbar.animateToVisibility(toActionMode ? View.GONE : View.VISIBLE);
mContextView.animateToVisibility(toActionMode ? View.VISIBLE : View.GONE);
if (mTabScrollView != null && !mDecorToolbar.hasEmbeddedTabs() &&
- isCollapsed((View) mDecorToolbar)) {
+ isCollapsed(mDecorToolbar.getViewGroup())) {
mTabScrollView.animateToVisibility(toActionMode ? View.GONE : View.VISIBLE);
}
}
@@ -959,7 +959,7 @@ public class WindowDecorActionBar extends ActionBar implements
// Clear out the context mode views after the animation finishes
mContextView.closeMode();
- ((View) mDecorToolbar).sendAccessibilityEvent(
+ mDecorToolbar.getViewGroup().sendAccessibilityEvent(
AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
mOverlayLayout.setHideOnContentScrollEnabled(mHideOnContentScroll);
From 5a77058ffc884dc27e11dfcb58788b7db7ac923d Mon Sep 17 00:00:00 2001
From: Eric Laurent
Date: Mon, 2 Jun 2014 09:16:02 -0700
Subject: [PATCH 16/93] AudioManager: do not mandate a looper
Having a listener for audio port updates is not mandatory.
do not throw an excepion when AudioManager is contructed
from a thread without looper.
Bug: 15368707.
Change-Id: If5ce54bf4efdff8b785098649fa1cd0564861e1e
---
.../android/media/AudioPortEventHandler.java | 118 +++++++++---------
1 file changed, 61 insertions(+), 57 deletions(-)
diff --git a/media/java/android/media/AudioPortEventHandler.java b/media/java/android/media/AudioPortEventHandler.java
index cd9a4de9e1411..782ecd845d4b6 100644
--- a/media/java/android/media/AudioPortEventHandler.java
+++ b/media/java/android/media/AudioPortEventHandler.java
@@ -49,73 +49,77 @@ class AudioPortEventHandler {
// find the looper for our new event handler
Looper looper = Looper.myLooper();
if (looper == null) {
- throw new IllegalArgumentException("Calling thread not associated with a looper");
+ looper = Looper.getMainLooper();
}
- mHandler = new Handler(looper) {
- @Override
- public void handleMessage(Message msg) {
- Log.i(TAG, "handleMessage: "+msg.what);
- ArrayList listeners;
- synchronized (this) {
- if (msg.what == AUDIOPORT_EVENT_NEW_LISTENER) {
- listeners = new ArrayList();
- if (mListeners.contains(msg.obj)) {
- listeners.add((AudioManager.OnAudioPortUpdateListener)msg.obj);
+ if (looper != null) {
+ mHandler = new Handler(looper) {
+ @Override
+ public void handleMessage(Message msg) {
+ Log.i(TAG, "handleMessage: "+msg.what);
+ ArrayList listeners;
+ synchronized (this) {
+ if (msg.what == AUDIOPORT_EVENT_NEW_LISTENER) {
+ listeners = new ArrayList();
+ if (mListeners.contains(msg.obj)) {
+ listeners.add((AudioManager.OnAudioPortUpdateListener)msg.obj);
+ }
+ } else {
+ listeners = mListeners;
}
- } else {
- listeners = mListeners;
}
- }
- if (listeners.isEmpty()) {
- return;
- }
- // reset audio port cache if the event corresponds to a change coming
- // from audio policy service or if mediaserver process died.
- if (msg.what == AUDIOPORT_EVENT_PORT_LIST_UPDATED ||
- msg.what == AUDIOPORT_EVENT_PATCH_LIST_UPDATED ||
- msg.what == AUDIOPORT_EVENT_SERVICE_DIED) {
- mAudioManager.resetAudioPortGeneration();
- }
- ArrayList ports = new ArrayList();
- ArrayList patches = new ArrayList();
- if (msg.what != AUDIOPORT_EVENT_SERVICE_DIED) {
- int status = mAudioManager.updateAudioPortCache(ports, patches);
- if (status != AudioManager.SUCCESS) {
+ if (listeners.isEmpty()) {
return;
}
- }
-
- switch (msg.what) {
- case AUDIOPORT_EVENT_NEW_LISTENER:
- case AUDIOPORT_EVENT_PORT_LIST_UPDATED:
- AudioPort[] portList = ports.toArray(new AudioPort[0]);
- for (int i = 0; i < listeners.size(); i++) {
- listeners.get(i).OnAudioPortListUpdate(portList);
+ // reset audio port cache if the event corresponds to a change coming
+ // from audio policy service or if mediaserver process died.
+ if (msg.what == AUDIOPORT_EVENT_PORT_LIST_UPDATED ||
+ msg.what == AUDIOPORT_EVENT_PATCH_LIST_UPDATED ||
+ msg.what == AUDIOPORT_EVENT_SERVICE_DIED) {
+ mAudioManager.resetAudioPortGeneration();
}
- if (msg.what == AUDIOPORT_EVENT_PORT_LIST_UPDATED) {
+ ArrayList ports = new ArrayList();
+ ArrayList patches = new ArrayList();
+ if (msg.what != AUDIOPORT_EVENT_SERVICE_DIED) {
+ int status = mAudioManager.updateAudioPortCache(ports, patches);
+ if (status != AudioManager.SUCCESS) {
+ return;
+ }
+ }
+
+ switch (msg.what) {
+ case AUDIOPORT_EVENT_NEW_LISTENER:
+ case AUDIOPORT_EVENT_PORT_LIST_UPDATED:
+ AudioPort[] portList = ports.toArray(new AudioPort[0]);
+ for (int i = 0; i < listeners.size(); i++) {
+ listeners.get(i).OnAudioPortListUpdate(portList);
+ }
+ if (msg.what == AUDIOPORT_EVENT_PORT_LIST_UPDATED) {
+ break;
+ }
+ // FALL THROUGH
+
+ case AUDIOPORT_EVENT_PATCH_LIST_UPDATED:
+ AudioPatch[] patchList = patches.toArray(new AudioPatch[0]);
+ for (int i = 0; i < listeners.size(); i++) {
+ listeners.get(i).OnAudioPatchListUpdate(patchList);
+ }
+ break;
+
+ case AUDIOPORT_EVENT_SERVICE_DIED:
+ for (int i = 0; i < listeners.size(); i++) {
+ listeners.get(i).OnServiceDied();
+ }
+ break;
+
+ default:
break;
}
- // FALL THROUGH
-
- case AUDIOPORT_EVENT_PATCH_LIST_UPDATED:
- AudioPatch[] patchList = patches.toArray(new AudioPatch[0]);
- for (int i = 0; i < listeners.size(); i++) {
- listeners.get(i).OnAudioPatchListUpdate(patchList);
- }
- break;
-
- case AUDIOPORT_EVENT_SERVICE_DIED:
- for (int i = 0; i < listeners.size(); i++) {
- listeners.get(i).OnServiceDied();
- }
- break;
-
- default:
- break;
}
- }
- };
+ };
+ } else {
+ mHandler = null;
+ }
native_setup(new WeakReference(this));
}
From 2e264c8f04bbd4046fe99c2c41bf79d6946ba922 Mon Sep 17 00:00:00 2001
From: Alan Viverette
Date: Tue, 3 Jun 2014 10:13:22 -0700
Subject: [PATCH 17/93] Fix NPE when ripples are canceled due to visibility
change
BUG: 15406248
Change-Id: I63ce42fef8e1614372ee4a82e45eb15e8bbe1fe3
---
graphics/java/android/graphics/drawable/RippleDrawable.java | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java
index 9d7a8b6071e2d..543f4fbf72feb 100644
--- a/graphics/java/android/graphics/drawable/RippleDrawable.java
+++ b/graphics/java/android/graphics/drawable/RippleDrawable.java
@@ -441,8 +441,11 @@ public class RippleDrawable extends LayerDrawable {
final int count = mAnimatingRipplesCount;
final Ripple[] ripples = mAnimatingRipples;
for (int i = 0; i < count; i++) {
- ripples[i].cancel();
+ // Calling cancel may remove the ripple from the animating ripple
+ // array, so cache the reference before nulling it out.
+ final Ripple ripple = ripples[i];
ripples[i] = null;
+ ripple.cancel();
}
mAnimatingRipplesCount = 0;
From bcccf53ff2be5bda881a780a3964b4c2efb61fd1 Mon Sep 17 00:00:00 2001
From: Jorim Jaggi
Date: Tue, 3 Jun 2014 22:34:22 +0200
Subject: [PATCH 18/93] Fix invalid Keyguard state with encrypted devices.
Bug: 15389720
Change-Id: I0a18e78043e5c08f40cf3288abc07f75ea6261a0
---
.../systemui/keyguard/KeyguardViewMediator.java | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 4837a539346a2..ffd76a7d5367d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -878,6 +878,7 @@ public class KeyguardViewMediator extends SystemUI {
if (mLockPatternUtils.checkVoldPassword()) {
if (DEBUG) Log.d(TAG, "Not showing lock screen since just decrypted");
// Without this, settings is not enabled until the lock screen first appears
+ mShowing = false;
hideLocked();
return;
}
@@ -1191,9 +1192,17 @@ public class KeyguardViewMediator extends SystemUI {
if (DEBUG) Log.d(TAG, "handleHide");
try {
- // Don't actually hide the Keyguard at the moment, wait for window manager until
- // it tells us it's safe to do so with startKeyguardExitAnimation.
- mWM.keyguardGoingAway();
+ if (mShowing) {
+
+ // Don't actually hide the Keyguard at the moment, wait for window manager until
+ // it tells us it's safe to do so with startKeyguardExitAnimation.
+ mWM.keyguardGoingAway();
+ } else {
+
+ // Don't try to rely on WindowManager - if Keyguard wasn't showing, window
+ // manager won't start the exit animation.
+ handleStartKeyguardExitAnimation(0, 0);
+ }
} catch (RemoteException e) {
Log.e(TAG, "Error while calling WindowManager", e);
}
From 302209445e875fcf53e949a0da584314ec16e4da Mon Sep 17 00:00:00 2001
From: Alan Viverette
Date: Tue, 3 Jun 2014 12:52:25 -0700
Subject: [PATCH 19/93] Fix drawable cache, add quantum assets to preload list
BUG: 15409352
Change-Id: Idb18fd99dc4229aace9082d6e26c88faf81d15bf
---
core/java/android/content/res/Resources.java | 10 +-
core/res/res/values/arrays.xml | 197 +++++++++++++++++++
2 files changed, 201 insertions(+), 6 deletions(-)
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index 373763883ccdd..f2d71b5232b0f 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -2227,9 +2227,7 @@ public class Resources {
}
// First, check whether we have a cached version of this drawable
- // that's valid for the specified theme. This may apply a theme to a
- // cached drawable that has themeable attributes but was not previously
- // themed.
+ // that was inflated against the specified theme.
if (!mPreloading) {
final Drawable cachedDrawable = getCachedDrawable(caches, key, theme);
if (cachedDrawable != null) {
@@ -2255,8 +2253,8 @@ public class Resources {
dr = loadDrawableForCookie(value, id, theme);
}
- // If we were able to obtain a drawable, attempt to place it in the
- // appropriate cache (e.g. no theme, themed, themeable).
+ // If we were able to obtain a drawable, store it in the appropriate
+ // cache (either preload or themed).
if (dr != null) {
dr.setChangingConfigurations(value.changingConfigurations);
cacheDrawable(value, theme, isColorDrawable, caches, key, dr);
@@ -2364,7 +2362,7 @@ public class Resources {
ArrayMap>> caches,
long key, Theme theme) {
synchronized (mAccessLock) {
- final int themeKey = theme != null ? theme.mThemeResId : 0;
+ final String themeKey = theme != null ? theme.mKey : "";
final LongSparseArray> themedCache = caches.get(themeKey);
if (themedCache != null) {
final Drawable themedDrawable = getCachedDrawableLocked(themedCache, key);
diff --git a/core/res/res/values/arrays.xml b/core/res/res/values/arrays.xml
index f01f10e48ccf8..042af41693030 100644
--- a/core/res/res/values/arrays.xml
+++ b/core/res/res/values/arrays.xml
@@ -298,6 +298,191 @@
- @drawable/quickcontact_badge_overlay_light
- @drawable/quickcontact_badge_overlay_normal_light
- @drawable/quickcontact_badge_overlay_pressed_light
+
+
+ - @drawable/ab_share_pack_qntm_alpha
+ - @drawable/ab_solid_shadow_qntm_alpha
+ - @drawable/btn_cab_done_qntm_alpha
+ - @drawable/btn_check_to_off_qntm_000
+ - @drawable/btn_check_to_off_qntm_001
+ - @drawable/btn_check_to_off_qntm_002
+ - @drawable/btn_check_to_off_qntm_003
+ - @drawable/btn_check_to_off_qntm_004
+ - @drawable/btn_check_to_off_qntm_005
+ - @drawable/btn_check_to_off_qntm_006
+ - @drawable/btn_check_to_off_qntm_007
+ - @drawable/btn_check_to_off_qntm_008
+ - @drawable/btn_check_to_off_qntm_009
+ - @drawable/btn_check_to_off_qntm_010
+ - @drawable/btn_check_to_off_qntm_011
+ - @drawable/btn_check_to_off_qntm_012
+ - @drawable/btn_check_to_off_qntm_013
+ - @drawable/btn_check_to_off_qntm_014
+ - @drawable/btn_check_to_off_qntm_015
+ - @drawable/btn_check_to_on_qntm_000
+ - @drawable/btn_check_to_on_qntm_001
+ - @drawable/btn_check_to_on_qntm_002
+ - @drawable/btn_check_to_on_qntm_003
+ - @drawable/btn_check_to_on_qntm_004
+ - @drawable/btn_check_to_on_qntm_005
+ - @drawable/btn_check_to_on_qntm_006
+ - @drawable/btn_check_to_on_qntm_007
+ - @drawable/btn_check_to_on_qntm_008
+ - @drawable/btn_check_to_on_qntm_009
+ - @drawable/btn_check_to_on_qntm_010
+ - @drawable/btn_check_to_on_qntm_011
+ - @drawable/btn_check_to_on_qntm_012
+ - @drawable/btn_check_to_on_qntm_013
+ - @drawable/btn_check_to_on_qntm_014
+ - @drawable/btn_check_to_on_qntm_015
+ - @drawable/btn_qntm_alpha
+ - @drawable/btn_radio_anim_00000_qntm_alpha
+ - @drawable/btn_radio_anim_00001_qntm_alpha
+ - @drawable/btn_radio_anim_00002_qntm_alpha
+ - @drawable/btn_radio_anim_00003_qntm_alpha
+ - @drawable/btn_radio_anim_00004_qntm_alpha
+ - @drawable/btn_radio_anim_00005_qntm_alpha
+ - @drawable/btn_radio_anim_00006_qntm_alpha
+ - @drawable/btn_radio_anim_00007_qntm_alpha
+ - @drawable/btn_radio_anim_00008_qntm_alpha
+ - @drawable/btn_radio_anim_00009_qntm_alpha
+ - @drawable/btn_radio_anim_00010_qntm_alpha
+ - @drawable/btn_radio_anim_00011_qntm_alpha
+ - @drawable/btn_radio_anim_00012_qntm_alpha
+ - @drawable/btn_radio_anim_00013_qntm_alpha
+ - @drawable/btn_radio_anim_00014_qntm_alpha
+ - @drawable/btn_radio_anim_00015_qntm_alpha
+ - @drawable/btn_radio_to_off_qntm_000
+ - @drawable/btn_radio_to_off_qntm_001
+ - @drawable/btn_radio_to_off_qntm_002
+ - @drawable/btn_radio_to_off_qntm_003
+ - @drawable/btn_radio_to_off_qntm_004
+ - @drawable/btn_radio_to_off_qntm_005
+ - @drawable/btn_radio_to_off_qntm_006
+ - @drawable/btn_radio_to_off_qntm_007
+ - @drawable/btn_radio_to_off_qntm_008
+ - @drawable/btn_radio_to_off_qntm_009
+ - @drawable/btn_radio_to_off_qntm_010
+ - @drawable/btn_radio_to_off_qntm_011
+ - @drawable/btn_radio_to_off_qntm_012
+ - @drawable/btn_radio_to_off_qntm_013
+ - @drawable/btn_radio_to_off_qntm_014
+ - @drawable/btn_radio_to_off_qntm_015
+ - @drawable/btn_radio_to_on_qntm_000
+ - @drawable/btn_radio_to_on_qntm_001
+ - @drawable/btn_radio_to_on_qntm_002
+ - @drawable/btn_radio_to_on_qntm_003
+ - @drawable/btn_radio_to_on_qntm_004
+ - @drawable/btn_radio_to_on_qntm_005
+ - @drawable/btn_radio_to_on_qntm_006
+ - @drawable/btn_radio_to_on_qntm_007
+ - @drawable/btn_radio_to_on_qntm_008
+ - @drawable/btn_radio_to_on_qntm_009
+ - @drawable/btn_radio_to_on_qntm_010
+ - @drawable/btn_radio_to_on_qntm_011
+ - @drawable/btn_radio_to_on_qntm_012
+ - @drawable/btn_radio_to_on_qntm_013
+ - @drawable/btn_radio_to_on_qntm_014
+ - @drawable/btn_radio_to_on_qntm_015
+ - @drawable/btn_rating_star_off_qntm_alpha
+ - @drawable/btn_rating_star_on_qntm_alpha
+ - @drawable/btn_star_qntm_alpha
+ - @drawable/btn_switch_to_off_qntm_000
+ - @drawable/btn_switch_to_off_qntm_001
+ - @drawable/btn_switch_to_off_qntm_002
+ - @drawable/btn_switch_to_off_qntm_003
+ - @drawable/btn_switch_to_off_qntm_004
+ - @drawable/btn_switch_to_off_qntm_005
+ - @drawable/btn_switch_to_off_qntm_006
+ - @drawable/btn_switch_to_off_qntm_007
+ - @drawable/btn_switch_to_off_qntm_008
+ - @drawable/btn_switch_to_off_qntm_009
+ - @drawable/btn_switch_to_off_qntm_010
+ - @drawable/btn_switch_to_off_qntm_011
+ - @drawable/btn_switch_to_off_qntm_012
+ - @drawable/btn_switch_to_off_qntm_013
+ - @drawable/btn_switch_to_off_qntm_014
+ - @drawable/btn_switch_to_on_qntm_000
+ - @drawable/btn_switch_to_on_qntm_001
+ - @drawable/btn_switch_to_on_qntm_002
+ - @drawable/btn_switch_to_on_qntm_003
+ - @drawable/btn_switch_to_on_qntm_004
+ - @drawable/btn_switch_to_on_qntm_005
+ - @drawable/btn_switch_to_on_qntm_006
+ - @drawable/btn_switch_to_on_qntm_007
+ - @drawable/btn_switch_to_on_qntm_008
+ - @drawable/btn_switch_to_on_qntm_009
+ - @drawable/btn_switch_to_on_qntm_010
+ - @drawable/btn_switch_to_on_qntm_011
+ - @drawable/btn_switch_to_on_qntm_012
+ - @drawable/btn_switch_to_on_qntm_013
+ - @drawable/btn_switch_to_on_qntm_014
+ - @drawable/btn_toggle_indicator_qntm_alpha
+ - @drawable/btn_toggle_qntm_alpha
+ - @drawable/expander_close_qntm_alpha
+ - @drawable/expander_open_qntm_alpha
+ - @drawable/fastscroll_thumb_qntm_alpha
+ - @drawable/fastscroll_track_qntm_alpha
+ - @drawable/ic_ab_back_qntm_am_alpha
+ - @drawable/ic_cab_done_qntm_alpha
+ - @drawable/ic_clear_qntm_alpha
+ - @drawable/ic_commit_search_api_qntm_alpha
+ - @drawable/ic_dialog_alert_qntm_alpha
+ - @drawable/ic_find_next_qntm_alpha
+ - @drawable/ic_find_previous_qntm_alpha
+ - @drawable/ic_go_search_api_qntm_alpha
+ - @drawable/ic_media_route_disabled_qntm_alpha
+ - @drawable/ic_media_route_off_qntm_alpha
+ - @drawable/ic_media_route_on_0_qntm_alpha
+ - @drawable/ic_media_route_on_1_qntm_alpha
+ - @drawable/ic_media_route_on_2_qntm_alpha
+ - @drawable/ic_media_route_on_qntm_alpha
+ - @drawable/ic_menu_copy_qntm_am_alpha
+ - @drawable/ic_menu_cut_qntm_alpha
+ - @drawable/ic_menu_find_qntm_alpha
+ - @drawable/ic_menu_moreoverflow_qntm_alpha
+ - @drawable/ic_menu_paste_qntm_am_alpha
+ - @drawable/ic_menu_search_qntm_alpha
+ - @drawable/ic_menu_selectall_qntm_alpha
+ - @drawable/ic_menu_share_qntm_alpha
+ - @drawable/ic_search_api_qntm_alpha
+ - @drawable/ic_voice_search_api_qntm_alpha
+ - @drawable/list_divider_qntm_alpha
+ - @drawable/list_section_divider_qntm_alpha
+ - @drawable/popup_background_qntm_mult
+ - @drawable/progress_primary_qntm_alpha
+ - @drawable/progress_qntm_alpha
+ - @drawable/scrollbar_handle_qntm_alpha
+ - @drawable/scrubber_control_from_pressed_qntm_000
+ - @drawable/scrubber_control_from_pressed_qntm_001
+ - @drawable/scrubber_control_from_pressed_qntm_002
+ - @drawable/scrubber_control_from_pressed_qntm_003
+ - @drawable/scrubber_control_from_pressed_qntm_004
+ - @drawable/scrubber_control_from_pressed_qntm_005
+ - @drawable/scrubber_control_off_pressed_qntm_alpha
+ - @drawable/scrubber_control_off_qntm_alpha
+ - @drawable/scrubber_control_on_pressed_qntm_alpha
+ - @drawable/scrubber_control_on_qntm_alpha
+ - @drawable/scrubber_control_to_pressed_qntm_000
+ - @drawable/scrubber_control_to_pressed_qntm_001
+ - @drawable/scrubber_control_to_pressed_qntm_002
+ - @drawable/scrubber_control_to_pressed_qntm_003
+ - @drawable/scrubber_control_to_pressed_qntm_004
+ - @drawable/scrubber_control_to_pressed_qntm_005
+ - @drawable/scrubber_primary_qntm_alpha
+ - @drawable/scrubber_track_qntm_alpha
+ - @drawable/spinner_qntm_am_alpha
+ - @drawable/switch_track_qntm_alpha
+ - @drawable/tab_indicator_normal_qntm_alpha
+ - @drawable/tab_indicator_selected_qntm_alpha
+ - @drawable/text_cursor_qntm_alpha
+ - @drawable/textfield_activated_qntm_alpha
+ - @drawable/textfield_default_qntm_alpha
+ - @drawable/textfield_search_activated_qntm_alpha
+ - @drawable/textfield_search_default_qntm_alpha
+ - @drawable/text_select_handle_left_qntm_alpha
+ - @drawable/text_select_handle_middle_qntm_alpha
+ - @drawable/text_select_handle_right_qntm_alpha
+ - @color/background_cache_hint_selector_quantum_dark
+ - @color/background_cache_hint_selector_quantum_light
+ - @color/btn_default_quantum_dark
+ - @color/btn_default_quantum_light
+ - @color/primary_text_disable_only_quantum_dark
+ - @color/primary_text_disable_only_quantum_light
+ - @color/primary_text_quantum_dark
+ - @color/primary_text_quantum_light
+ - @color/search_url_text_quantum_dark
+ - @color/search_url_text_quantum_light
From 22928efffbbf9b83bfd3b06b583e207ee2091c7c Mon Sep 17 00:00:00 2001
From: Alan Viverette
Date: Tue, 3 Jun 2014 15:48:30 -0700
Subject: [PATCH 20/93] Fix build, fix Drawable loop
Change-Id: I524b7f40c700ebe601fdbe80644a46e90ab2bba0
Conflicts:
graphics/java/android/graphics/drawable/Drawable.java
---
core/res/res/values/arrays.xml | 2 --
graphics/java/android/graphics/drawable/Drawable.java | 2 +-
2 files changed, 1 insertion(+), 3 deletions(-)
diff --git a/core/res/res/values/arrays.xml b/core/res/res/values/arrays.xml
index 042af41693030..1de26c72621bd 100644
--- a/core/res/res/values/arrays.xml
+++ b/core/res/res/values/arrays.xml
@@ -473,8 +473,6 @@
- @drawable/scrubber_track_qntm_alpha
- @drawable/spinner_qntm_am_alpha
- @drawable/switch_track_qntm_alpha
- - @drawable/tab_indicator_normal_qntm_alpha
- - @drawable/tab_indicator_selected_qntm_alpha
- @drawable/text_cursor_qntm_alpha
- @drawable/textfield_activated_qntm_alpha
- @drawable/textfield_default_qntm_alpha
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index cc2a5956b371f..b94d3f15e740f 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -917,7 +917,7 @@ public abstract class Drawable {
InputStream is, String srcName, Theme theme) {
Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, srcName != null ? srcName : "Unknown drawable");
try {
- return createFromResourceStreamThemed(res, value, is, srcName, null, theme);
+ return createFromResourceStream(res, value, is, srcName, null);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
}
From 47baed998871e8592849dd239da28e93c7154733 Mon Sep 17 00:00:00 2001
From: Adam Powell
Date: Mon, 2 Jun 2014 13:30:11 -0700
Subject: [PATCH 21/93] Support list navigation mode for toolbar action bars
Add support for the list(spinner) navigation mode for ToolbarActionBar
and WindowDecorActionBar when a Toolbar is substituting for an
ActionBarView.
Bug 15332084
Change-Id: Ic618686f7767c4a14410ae359435d7c1b244e4fa
---
.../internal/app/NavItemSelectedListener.java | 46 +++++++++++++++++++
.../internal/app/ToolbarActionBar.java | 38 ++++++++-------
.../internal/app/WindowDecorActionBar.java | 23 ----------
.../internal/widget/ToolbarWidgetWrapper.java | 45 +++++++++++++++---
4 files changed, 105 insertions(+), 47 deletions(-)
create mode 100644 core/java/com/android/internal/app/NavItemSelectedListener.java
diff --git a/core/java/com/android/internal/app/NavItemSelectedListener.java b/core/java/com/android/internal/app/NavItemSelectedListener.java
new file mode 100644
index 0000000000000..545f44be716b8
--- /dev/null
+++ b/core/java/com/android/internal/app/NavItemSelectedListener.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package com.android.internal.app;
+
+import android.app.ActionBar;
+import android.view.View;
+import android.widget.AdapterView;
+
+/**
+ * Wrapper to adapt the ActionBar.OnNavigationListener in an AdapterView.OnItemSelectedListener
+ * for use in Spinner widgets. Used by action bar implementations.
+ */
+class NavItemSelectedListener implements AdapterView.OnItemSelectedListener {
+ private final ActionBar.OnNavigationListener mListener;
+
+ public NavItemSelectedListener(ActionBar.OnNavigationListener listener) {
+ mListener = listener;
+ }
+
+ @Override
+ public void onItemSelected(AdapterView> parent, View view, int position, long id) {
+ if (mListener != null) {
+ mListener.onNavigationItemSelected(position, id);
+ }
+ }
+
+ @Override
+ public void onNothingSelected(AdapterView> parent) {
+ // Do nothing
+ }
+}
diff --git a/core/java/com/android/internal/app/ToolbarActionBar.java b/core/java/com/android/internal/app/ToolbarActionBar.java
index 6056bf25f7fd8..5db09f4defd63 100644
--- a/core/java/com/android/internal/app/ToolbarActionBar.java
+++ b/core/java/com/android/internal/app/ToolbarActionBar.java
@@ -173,14 +173,19 @@ public class ToolbarActionBar extends ActionBar {
@Override
public void setListNavigationCallbacks(SpinnerAdapter adapter, OnNavigationListener callback) {
- throw new UnsupportedOperationException(
- "Navigation modes are not supported in toolbar action bars");
+ mDecorToolbar.setDropdownParams(adapter, new NavItemSelectedListener(callback));
}
@Override
public void setSelectedNavigationItem(int position) {
- throw new UnsupportedOperationException(
- "Navigation modes are not supported in toolbar action bars");
+ switch (mDecorToolbar.getNavigationMode()) {
+ case NAVIGATION_MODE_LIST:
+ mDecorToolbar.setDropdownSelectedPosition(position);
+ break;
+ default:
+ throw new IllegalStateException(
+ "setSelectedNavigationIndex not valid for current navigation mode");
+ }
}
@Override
@@ -276,8 +281,7 @@ public class ToolbarActionBar extends ActionBar {
@Override
public void setNavigationMode(@NavigationMode int mode) {
- throw new UnsupportedOperationException(
- "Navigation modes are not supported in toolbar action bars");
+ mDecorToolbar.setNavigationMode(mode);
}
@Override
@@ -288,67 +292,67 @@ public class ToolbarActionBar extends ActionBar {
@Override
public Tab newTab() {
throw new UnsupportedOperationException(
- "Navigation modes are not supported in toolbar action bars");
+ "Tabs are not supported in toolbar action bars");
}
@Override
public void addTab(Tab tab) {
throw new UnsupportedOperationException(
- "Navigation modes are not supported in toolbar action bars");
+ "Tabs are not supported in toolbar action bars");
}
@Override
public void addTab(Tab tab, boolean setSelected) {
throw new UnsupportedOperationException(
- "Navigation modes are not supported in toolbar action bars");
+ "Tabs are not supported in toolbar action bars");
}
@Override
public void addTab(Tab tab, int position) {
throw new UnsupportedOperationException(
- "Navigation modes are not supported in toolbar action bars");
+ "Tabs are not supported in toolbar action bars");
}
@Override
public void addTab(Tab tab, int position, boolean setSelected) {
throw new UnsupportedOperationException(
- "Navigation modes are not supported in toolbar action bars");
+ "Tabs are not supported in toolbar action bars");
}
@Override
public void removeTab(Tab tab) {
throw new UnsupportedOperationException(
- "Navigation modes are not supported in toolbar action bars");
+ "Tabs are not supported in toolbar action bars");
}
@Override
public void removeTabAt(int position) {
throw new UnsupportedOperationException(
- "Navigation modes are not supported in toolbar action bars");
+ "Tabs are not supported in toolbar action bars");
}
@Override
public void removeAllTabs() {
throw new UnsupportedOperationException(
- "Navigation modes are not supported in toolbar action bars");
+ "Tabs are not supported in toolbar action bars");
}
@Override
public void selectTab(Tab tab) {
throw new UnsupportedOperationException(
- "Navigation modes are not supported in toolbar action bars");
+ "Tabs are not supported in toolbar action bars");
}
@Override
public Tab getSelectedTab() {
throw new UnsupportedOperationException(
- "Navigation modes are not supported in toolbar action bars");
+ "Tabs are not supported in toolbar action bars");
}
@Override
public Tab getTabAt(int index) {
throw new UnsupportedOperationException(
- "Navigation modes are not supported in toolbar action bars");
+ "Tabs are not supported in toolbar action bars");
}
@Override
diff --git a/core/java/com/android/internal/app/WindowDecorActionBar.java b/core/java/com/android/internal/app/WindowDecorActionBar.java
index c0b5b97d18e1a..87a80ace347fb 100644
--- a/core/java/com/android/internal/app/WindowDecorActionBar.java
+++ b/core/java/com/android/internal/app/WindowDecorActionBar.java
@@ -18,9 +18,7 @@ package com.android.internal.app;
import android.animation.ValueAnimator;
import android.content.res.TypedArray;
-import android.view.ViewGroup;
import android.view.ViewParent;
-import android.widget.AdapterView;
import android.widget.Toolbar;
import com.android.internal.R;
import com.android.internal.view.ActionBarPolicy;
@@ -30,7 +28,6 @@ import com.android.internal.view.menu.SubMenuBuilder;
import com.android.internal.widget.ActionBarContainer;
import com.android.internal.widget.ActionBarContextView;
import com.android.internal.widget.ActionBarOverlayLayout;
-import com.android.internal.widget.ActionBarView;
import com.android.internal.widget.DecorToolbar;
import com.android.internal.widget.ScrollingTabContainerView;
@@ -59,7 +56,6 @@ import android.view.Window;
import android.view.accessibility.AccessibilityEvent;
import android.view.animation.AnimationUtils;
import android.widget.SpinnerAdapter;
-import com.android.internal.widget.ToolbarWidgetWrapper;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
@@ -1313,23 +1309,4 @@ public class WindowDecorActionBar extends ActionBar implements
}
}
- static class NavItemSelectedListener implements AdapterView.OnItemSelectedListener {
- private final OnNavigationListener mListener;
-
- public NavItemSelectedListener(OnNavigationListener listener) {
- mListener = listener;
- }
-
- @Override
- public void onItemSelected(AdapterView> parent, View view, int position, long id) {
- if (mListener != null) {
- mListener.onNavigationItemSelected(position, id);
- }
- }
-
- @Override
- public void onNothingSelected(AdapterView> parent) {
- // Do nothing
- }
- }
}
diff --git a/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java b/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java
index 3e15c323a2b33..ea39eed7c6e3c 100644
--- a/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java
+++ b/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java
@@ -27,6 +27,7 @@ import android.os.Parcelable;
import android.text.TextUtils;
import android.util.Log;
import android.util.SparseArray;
+import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
@@ -78,6 +79,8 @@ public class ToolbarWidgetWrapper implements DecorToolbar {
private boolean mMenuPrepared;
private ActionMenuPresenter mActionMenuPresenter;
+ private int mNavigationMode = ActionBar.NAVIGATION_MODE_STANDARD;
+
public ToolbarWidgetWrapper(Toolbar toolbar) {
mToolbar = toolbar;
@@ -420,23 +423,51 @@ public class ToolbarWidgetWrapper implements DecorToolbar {
@Override
public int getNavigationMode() {
- return 0;
+ return mNavigationMode;
}
@Override
public void setNavigationMode(int mode) {
- if (mode != ActionBar.NAVIGATION_MODE_STANDARD) {
- throw new IllegalArgumentException(
- "Navigation modes not supported in this configuration");
+ final int oldMode = mNavigationMode;
+ if (mode != oldMode) {
+ switch (oldMode) {
+ case ActionBar.NAVIGATION_MODE_LIST:
+ if (mSpinner != null && mSpinner.getParent() == mToolbar) {
+ mToolbar.removeView(mSpinner);
+ }
+ break;
+ }
+
+ mNavigationMode = mode;
+
+ switch (mode) {
+ case ActionBar.NAVIGATION_MODE_STANDARD:
+ break;
+ case ActionBar.NAVIGATION_MODE_LIST:
+ ensureSpinner();
+ mToolbar.addView(mSpinner, 0);
+ break;
+ case ActionBar.NAVIGATION_MODE_TABS:
+ throw new IllegalStateException("Tabs not supported in this configuration");
+ default:
+ throw new IllegalArgumentException("Invalid navigation mode " + mode);
+ }
+ }
+ }
+
+ private void ensureSpinner() {
+ if (mSpinner == null) {
+ mSpinner = new Spinner(getContext());
+ Toolbar.LayoutParams lp = new Toolbar.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT, Gravity.START | Gravity.CENTER_VERTICAL);
+ mSpinner.setLayoutParams(lp);
}
}
@Override
public void setDropdownParams(SpinnerAdapter adapter,
AdapterView.OnItemSelectedListener listener) {
- if (mSpinner == null) {
- mSpinner = new Spinner(getContext());
- }
+ ensureSpinner();
mSpinner.setAdapter(adapter);
mSpinner.setOnItemSelectedListener(listener);
}
From d45d85f8a1b2cc1ac6ab71a935bf41864b28aeac Mon Sep 17 00:00:00 2001
From: Robert Greenwalt
Date: Tue, 3 Jun 2014 17:22:11 -0700
Subject: [PATCH 22/93] Fix legacy APIs.
Two fixes. First make sure we mark the request as handled by the network handling it.
Second, convert ensureRouteToHostForAddress to use the new legacyNetworkForType.
bug:14993207
Change-Id: I230968938ca0ed91f834b36a2af60caff2eab682
---
.../android/server/ConnectivityService.java | 28 +++++++++++--------
1 file changed, 16 insertions(+), 12 deletions(-)
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index b2b421714058c..abb8cc5e255e6 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -1754,31 +1754,34 @@ public class ConnectivityService extends IConnectivityManager.Stub {
if (DBG) log("requestRouteToHostAddress on invalid network: " + networkType);
return false;
}
- NetworkStateTracker tracker = mNetTrackers[networkType];
- DetailedState netState = DetailedState.DISCONNECTED;
- if (tracker != null) {
- netState = tracker.getNetworkInfo().getDetailedState();
+
+ NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
+ if (nai == null) {
+ if (mLegacyTypeTracker.isTypeSupported(networkType) == false) {
+ if (DBG) log("requestRouteToHostAddress on unsupported network: " + networkType);
+ } else {
+ if (DBG) log("requestRouteToHostAddress on down network: " + networkType);
+ }
+ return false;
}
+ DetailedState netState = nai.networkInfo.getDetailedState();
+
if ((netState != DetailedState.CONNECTED &&
- netState != DetailedState.CAPTIVE_PORTAL_CHECK) ||
- tracker.isTeardownRequested()) {
+ netState != DetailedState.CAPTIVE_PORTAL_CHECK)) {
if (VDBG) {
log("requestRouteToHostAddress on down network "
+ "(" + networkType + ") - dropped"
- + " tracker=" + tracker
- + " netState=" + netState
- + " isTeardownRequested="
- + ((tracker != null) ? tracker.isTeardownRequested() : "tracker:null"));
+ + " netState=" + netState);
}
return false;
}
final int uid = Binder.getCallingUid();
final long token = Binder.clearCallingIdentity();
try {
- LinkProperties lp = tracker.getLinkProperties();
+ LinkProperties lp = nai.linkProperties;
boolean ok = modifyRouteToAddress(lp, addr, ADD, TO_DEFAULT_TABLE, exempt,
- tracker.getNetwork().netId, uid);
+ nai.network.netId, uid);
if (DBG) log("requestRouteToHostAddress ok=" + ok);
return ok;
} finally {
@@ -3316,6 +3319,7 @@ public class ConnectivityService extends IConnectivityManager.Stub {
if (bestNetwork != null) {
if (VDBG) log("using " + bestNetwork.name());
bestNetwork.addRequest(nri.request);
+ mNetworkForRequestId.put(nri.request.requestId, bestNetwork);
int legacyType = nri.request.legacyType;
if (legacyType != TYPE_NONE) {
mLegacyTypeTracker.add(legacyType, bestNetwork);
From 479b6e94ce7910f2dddaff4e0e60a76393bd7a35 Mon Sep 17 00:00:00 2001
From: Adam Powell
Date: Tue, 3 Jun 2014 17:54:34 -0700
Subject: [PATCH 23/93] Implement action bar tab mode for Toolbar-based decor
action bars
Coordinate between the stacked row, etc. Also fix a silly bug in
Toolbar child views with Gravity.BOTTOM.
Bug 15332084
Change-Id: Ie91b7d5255c63d9befcc65d7939c1523e018809f
---
core/java/android/widget/Toolbar.java | 3 ++-
.../internal/app/ToolbarActionBar.java | 3 +++
.../internal/widget/ActionBarView.java | 5 +---
.../android/internal/widget/DecorToolbar.java | 2 +-
.../internal/widget/ToolbarWidgetWrapper.java | 27 +++++++++++++++++--
5 files changed, 32 insertions(+), 8 deletions(-)
diff --git a/core/java/android/widget/Toolbar.java b/core/java/android/widget/Toolbar.java
index 419c582735cea..cbd9a6af425e8 100644
--- a/core/java/android/widget/Toolbar.java
+++ b/core/java/android/widget/Toolbar.java
@@ -1339,7 +1339,8 @@ public class Toolbar extends ViewGroup {
return getPaddingTop();
case Gravity.BOTTOM:
- return getPaddingBottom() - child.getMeasuredHeight() - lp.bottomMargin;
+ return getHeight() - getPaddingBottom() -
+ child.getMeasuredHeight() - lp.bottomMargin;
default:
case Gravity.CENTER_VERTICAL:
diff --git a/core/java/com/android/internal/app/ToolbarActionBar.java b/core/java/com/android/internal/app/ToolbarActionBar.java
index 5db09f4defd63..e8a3f0a76473e 100644
--- a/core/java/com/android/internal/app/ToolbarActionBar.java
+++ b/core/java/com/android/internal/app/ToolbarActionBar.java
@@ -281,6 +281,9 @@ public class ToolbarActionBar extends ActionBar {
@Override
public void setNavigationMode(@NavigationMode int mode) {
+ if (mode == ActionBar.NAVIGATION_MODE_TABS) {
+ throw new IllegalArgumentException("Tabs not supported in this configuration");
+ }
mDecorToolbar.setNavigationMode(mode);
}
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index af827782f6995..aa642fd55c8a2 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -349,10 +349,7 @@ public class ActionBarView extends AbsActionBarView implements DecorToolbar {
return mIncludeTabs;
}
- public void setEmbeddedTabView(View view) {
- setEmbeddedTabView((ScrollingTabContainerView) view);
- }
-
+ @Override
public void setEmbeddedTabView(ScrollingTabContainerView tabs) {
if (mTabScrollView != null) {
removeView(mTabScrollView);
diff --git a/core/java/com/android/internal/widget/DecorToolbar.java b/core/java/com/android/internal/widget/DecorToolbar.java
index ee6988e57d84a..5281045762ff9 100644
--- a/core/java/com/android/internal/widget/DecorToolbar.java
+++ b/core/java/com/android/internal/widget/DecorToolbar.java
@@ -71,7 +71,7 @@ public interface DecorToolbar {
int getDisplayOptions();
void setDisplayOptions(int opts);
- void setEmbeddedTabView(View tabView);
+ void setEmbeddedTabView(ScrollingTabContainerView tabView);
boolean hasEmbeddedTabs();
boolean isTitleTruncated();
void setCollapsible(boolean collapsible);
diff --git a/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java b/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java
index ea39eed7c6e3c..b298d853369e0 100644
--- a/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java
+++ b/core/java/com/android/internal/widget/ToolbarWidgetWrapper.java
@@ -397,8 +397,19 @@ public class ToolbarWidgetWrapper implements DecorToolbar {
}
@Override
- public void setEmbeddedTabView(View tabView) {
+ public void setEmbeddedTabView(ScrollingTabContainerView tabView) {
+ if (mTabView != null && mTabView.getParent() == mToolbar) {
+ mToolbar.removeView(mTabView);
+ }
mTabView = tabView;
+ if (tabView != null && mNavigationMode == ActionBar.NAVIGATION_MODE_TABS) {
+ mToolbar.addView(mTabView, 0);
+ Toolbar.LayoutParams lp = (Toolbar.LayoutParams) mTabView.getLayoutParams();
+ lp.width = ViewGroup.LayoutParams.WRAP_CONTENT;
+ lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+ lp.gravity = Gravity.START | Gravity.BOTTOM;
+ tabView.setAllowCollapse(true);
+ }
}
@Override
@@ -436,6 +447,11 @@ public class ToolbarWidgetWrapper implements DecorToolbar {
mToolbar.removeView(mSpinner);
}
break;
+ case ActionBar.NAVIGATION_MODE_TABS:
+ if (mTabView != null && mTabView.getParent() == mToolbar) {
+ mToolbar.removeView(mTabView);
+ }
+ break;
}
mNavigationMode = mode;
@@ -448,7 +464,14 @@ public class ToolbarWidgetWrapper implements DecorToolbar {
mToolbar.addView(mSpinner, 0);
break;
case ActionBar.NAVIGATION_MODE_TABS:
- throw new IllegalStateException("Tabs not supported in this configuration");
+ if (mTabView != null) {
+ mToolbar.addView(mTabView, 0);
+ Toolbar.LayoutParams lp = (Toolbar.LayoutParams) mTabView.getLayoutParams();
+ lp.width = ViewGroup.LayoutParams.WRAP_CONTENT;
+ lp.height = ViewGroup.LayoutParams.WRAP_CONTENT;
+ lp.gravity = Gravity.START | Gravity.BOTTOM;
+ }
+ break;
default:
throw new IllegalArgumentException("Invalid navigation mode " + mode);
}
From 8be189752d60e507910eed80a51997433d5482d8 Mon Sep 17 00:00:00 2001
From: Lorenzo Colitti
Date: Wed, 4 Jun 2014 12:20:06 +0900
Subject: [PATCH 24/93] Make requests for restricted networks not require
unrestricted access.
Currently, calling startUsingNetworkFeature for a restricted APN
type (e.g., IMS or FOTA) will create a request that requires
NET_CAPABILITY_NOT_RESTRICTED. Because these APNs are restricted,
when we bring them up we conclude that it does not match the
unrestricted requirement, and we tear them down.
1. Clear the NET_CAPABILITY_NOT_RESTRICTED capability when
creating requests in startUsingNetworkFeature.
2. Refactor the code to a common function so this cannot happen
again.
Bug: 15191336
Change-Id: Id1ec79c58ff79b1a83457ffaecc57d50b61ed4e4
---
.../java/android/net/ConnectivityManager.java | 22 +++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index a48a388820857..c4cbdd54d20aa 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -870,6 +870,26 @@ public class ConnectivityManager {
return 1;
}
+ /**
+ * Removes the NET_CAPABILITY_NOT_RESTRICTED capability from the given
+ * NetworkCapabilities object if it lists any capabilities that are
+ * typically provided by retricted networks.
+ * @hide
+ */
+ public static void maybeMarkCapabilitiesRestricted(NetworkCapabilities nc) {
+ for (Integer capability: nc.getNetworkCapabilities()) {
+ switch (capability.intValue()) {
+ case NetworkCapabilities.NET_CAPABILITY_CBS:
+ case NetworkCapabilities.NET_CAPABILITY_DUN:
+ case NetworkCapabilities.NET_CAPABILITY_FOTA:
+ case NetworkCapabilities.NET_CAPABILITY_IA:
+ case NetworkCapabilities.NET_CAPABILITY_IMS:
+ nc.removeNetworkCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
+ break;
+ }
+ }
+ }
+
private NetworkCapabilities networkCapabilitiesForFeature(int networkType, String feature) {
if (networkType == TYPE_MOBILE) {
int cap = -1;
@@ -893,12 +913,14 @@ public class ConnectivityManager {
NetworkCapabilities netCap = new NetworkCapabilities();
netCap.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
netCap.addNetworkCapability(cap);
+ maybeMarkCapabilitiesRestricted(netCap);
return netCap;
} else if (networkType == TYPE_WIFI) {
if ("p2p".equals(feature)) {
NetworkCapabilities netCap = new NetworkCapabilities();
netCap.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
netCap.addNetworkCapability(NetworkCapabilities.NET_CAPABILITY_WIFI_P2P);
+ maybeMarkCapabilitiesRestricted(netCap);
return netCap;
}
}
From c5490e6797dd2610815c9ca9b5ad2de3ae5827c0 Mon Sep 17 00:00:00 2001
From: Lorenzo Colitti
Date: Wed, 4 Jun 2014 19:59:21 +0900
Subject: [PATCH 25/93] Call a network restricted only if all capabilities are
restricted
When guessing whether a network is restricted or not (e.g., when
constructing a NetworkCapabilities object from an APN type, or
when constructing a request using startUsingNetworkFeature),
only assume the network is restricted if all the capabilities it
provides are typically provided by restricted networks (e.g.,
IMS, FOTA, etc.).
Previous code would conclude a network was restricted even if it
supported one "restricted" capability, so for example an APN
that provides both Internet connectivity and FOTA was marked as
restricted. This caused it to become ineligible to provide the
default Internet connection, because that must be unrestricted.
Also expand the list of restricted APN types a bit.
Bug: 15417453
Change-Id: I8c385f2cc83c695449dc8cf943d918321716fe58
---
.../java/android/net/ConnectivityManager.java | 24 +++++++++++++++----
1 file changed, 19 insertions(+), 5 deletions(-)
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index c4cbdd54d20aa..b96f16646c5be 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -872,22 +872,36 @@ public class ConnectivityManager {
/**
* Removes the NET_CAPABILITY_NOT_RESTRICTED capability from the given
- * NetworkCapabilities object if it lists any capabilities that are
- * typically provided by retricted networks.
+ * NetworkCapabilities object if all the capabilities it provides are
+ * typically provided by restricted networks.
+ *
+ * TODO: consider:
+ * - Moving to NetworkCapabilities
+ * - Renaming it to guessRestrictedCapability and make it set the
+ * restricted capability bit in addition to clearing it.
* @hide
*/
public static void maybeMarkCapabilitiesRestricted(NetworkCapabilities nc) {
- for (Integer capability: nc.getNetworkCapabilities()) {
+ for (Integer capability : nc.getNetworkCapabilities()) {
switch (capability.intValue()) {
case NetworkCapabilities.NET_CAPABILITY_CBS:
case NetworkCapabilities.NET_CAPABILITY_DUN:
+ case NetworkCapabilities.NET_CAPABILITY_EIMS:
case NetworkCapabilities.NET_CAPABILITY_FOTA:
case NetworkCapabilities.NET_CAPABILITY_IA:
case NetworkCapabilities.NET_CAPABILITY_IMS:
- nc.removeNetworkCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
- break;
+ case NetworkCapabilities.NET_CAPABILITY_RCS:
+ case NetworkCapabilities.NET_CAPABILITY_XCAP:
+ continue;
+ default:
+ // At least one capability usually provided by unrestricted
+ // networks. Conclude that this network is unrestricted.
+ return;
}
}
+ // All the capabilities are typically provided by restricted networks.
+ // Conclude that this network is restricted.
+ nc.removeNetworkCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
}
private NetworkCapabilities networkCapabilitiesForFeature(int networkType, String feature) {
From 6f1ad89bf2f5e7e4562e7e5a19666ea6b4fc5387 Mon Sep 17 00:00:00 2001
From: Alan Viverette
Date: Tue, 3 Jun 2014 12:52:25 -0700
Subject: [PATCH 26/93] Fix drawable cache, add quantum assets to preload list
BUG: 15409352
Change-Id: Idb18fd99dc4229aace9082d6e26c88faf81d15bf
---
core/java/android/content/res/Resources.java | 10 +-
core/res/res/values/arrays.xml | 197 +++++++++++++++++++
2 files changed, 201 insertions(+), 6 deletions(-)
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index ed3f9aa8cad30..9625578692951 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -2239,9 +2239,7 @@ public class Resources {
}
// First, check whether we have a cached version of this drawable
- // that's valid for the specified theme. This may apply a theme to a
- // cached drawable that has themeable attributes but was not previously
- // themed.
+ // that was inflated against the specified theme.
if (!mPreloading) {
final Drawable cachedDrawable = getCachedDrawable(caches, key, theme);
if (cachedDrawable != null) {
@@ -2267,8 +2265,8 @@ public class Resources {
dr = loadDrawableForCookie(value, id, theme);
}
- // If we were able to obtain a drawable, attempt to place it in the
- // appropriate cache (e.g. no theme, themed, themeable).
+ // If we were able to obtain a drawable, store it in the appropriate
+ // cache (either preload or themed).
if (dr != null) {
dr.setChangingConfigurations(value.changingConfigurations);
cacheDrawable(value, theme, isColorDrawable, caches, key, dr);
@@ -2376,7 +2374,7 @@ public class Resources {
ArrayMap>> caches,
long key, Theme theme) {
synchronized (mAccessLock) {
- final int themeKey = theme != null ? theme.mThemeResId : 0;
+ final String themeKey = theme != null ? theme.mKey : "";
final LongSparseArray> themedCache = caches.get(themeKey);
if (themedCache != null) {
final Drawable themedDrawable = getCachedDrawableLocked(themedCache, key);
diff --git a/core/res/res/values/arrays.xml b/core/res/res/values/arrays.xml
index f01f10e48ccf8..042af41693030 100644
--- a/core/res/res/values/arrays.xml
+++ b/core/res/res/values/arrays.xml
@@ -298,6 +298,191 @@
- @drawable/quickcontact_badge_overlay_light
- @drawable/quickcontact_badge_overlay_normal_light
- @drawable/quickcontact_badge_overlay_pressed_light
+
+
+ - @drawable/ab_share_pack_qntm_alpha
+ - @drawable/ab_solid_shadow_qntm_alpha
+ - @drawable/btn_cab_done_qntm_alpha
+ - @drawable/btn_check_to_off_qntm_000
+ - @drawable/btn_check_to_off_qntm_001
+ - @drawable/btn_check_to_off_qntm_002
+ - @drawable/btn_check_to_off_qntm_003
+ - @drawable/btn_check_to_off_qntm_004
+ - @drawable/btn_check_to_off_qntm_005
+ - @drawable/btn_check_to_off_qntm_006
+ - @drawable/btn_check_to_off_qntm_007
+ - @drawable/btn_check_to_off_qntm_008
+ - @drawable/btn_check_to_off_qntm_009
+ - @drawable/btn_check_to_off_qntm_010
+ - @drawable/btn_check_to_off_qntm_011
+ - @drawable/btn_check_to_off_qntm_012
+ - @drawable/btn_check_to_off_qntm_013
+ - @drawable/btn_check_to_off_qntm_014
+ - @drawable/btn_check_to_off_qntm_015
+ - @drawable/btn_check_to_on_qntm_000
+ - @drawable/btn_check_to_on_qntm_001
+ - @drawable/btn_check_to_on_qntm_002
+ - @drawable/btn_check_to_on_qntm_003
+ - @drawable/btn_check_to_on_qntm_004
+ - @drawable/btn_check_to_on_qntm_005
+ - @drawable/btn_check_to_on_qntm_006
+ - @drawable/btn_check_to_on_qntm_007
+ - @drawable/btn_check_to_on_qntm_008
+ - @drawable/btn_check_to_on_qntm_009
+ - @drawable/btn_check_to_on_qntm_010
+ - @drawable/btn_check_to_on_qntm_011
+ - @drawable/btn_check_to_on_qntm_012
+ - @drawable/btn_check_to_on_qntm_013
+ - @drawable/btn_check_to_on_qntm_014
+ - @drawable/btn_check_to_on_qntm_015
+ - @drawable/btn_qntm_alpha
+ - @drawable/btn_radio_anim_00000_qntm_alpha
+ - @drawable/btn_radio_anim_00001_qntm_alpha
+ - @drawable/btn_radio_anim_00002_qntm_alpha
+ - @drawable/btn_radio_anim_00003_qntm_alpha
+ - @drawable/btn_radio_anim_00004_qntm_alpha
+ - @drawable/btn_radio_anim_00005_qntm_alpha
+ - @drawable/btn_radio_anim_00006_qntm_alpha
+ - @drawable/btn_radio_anim_00007_qntm_alpha
+ - @drawable/btn_radio_anim_00008_qntm_alpha
+ - @drawable/btn_radio_anim_00009_qntm_alpha
+ - @drawable/btn_radio_anim_00010_qntm_alpha
+ - @drawable/btn_radio_anim_00011_qntm_alpha
+ - @drawable/btn_radio_anim_00012_qntm_alpha
+ - @drawable/btn_radio_anim_00013_qntm_alpha
+ - @drawable/btn_radio_anim_00014_qntm_alpha
+ - @drawable/btn_radio_anim_00015_qntm_alpha
+ - @drawable/btn_radio_to_off_qntm_000
+ - @drawable/btn_radio_to_off_qntm_001
+ - @drawable/btn_radio_to_off_qntm_002
+ - @drawable/btn_radio_to_off_qntm_003
+ - @drawable/btn_radio_to_off_qntm_004
+ - @drawable/btn_radio_to_off_qntm_005
+ - @drawable/btn_radio_to_off_qntm_006
+ - @drawable/btn_radio_to_off_qntm_007
+ - @drawable/btn_radio_to_off_qntm_008
+ - @drawable/btn_radio_to_off_qntm_009
+ - @drawable/btn_radio_to_off_qntm_010
+ - @drawable/btn_radio_to_off_qntm_011
+ - @drawable/btn_radio_to_off_qntm_012
+ - @drawable/btn_radio_to_off_qntm_013
+ - @drawable/btn_radio_to_off_qntm_014
+ - @drawable/btn_radio_to_off_qntm_015
+ - @drawable/btn_radio_to_on_qntm_000
+ - @drawable/btn_radio_to_on_qntm_001
+ - @drawable/btn_radio_to_on_qntm_002
+ - @drawable/btn_radio_to_on_qntm_003
+ - @drawable/btn_radio_to_on_qntm_004
+ - @drawable/btn_radio_to_on_qntm_005
+ - @drawable/btn_radio_to_on_qntm_006
+ - @drawable/btn_radio_to_on_qntm_007
+ - @drawable/btn_radio_to_on_qntm_008
+ - @drawable/btn_radio_to_on_qntm_009
+ - @drawable/btn_radio_to_on_qntm_010
+ - @drawable/btn_radio_to_on_qntm_011
+ - @drawable/btn_radio_to_on_qntm_012
+ - @drawable/btn_radio_to_on_qntm_013
+ - @drawable/btn_radio_to_on_qntm_014
+ - @drawable/btn_radio_to_on_qntm_015
+ - @drawable/btn_rating_star_off_qntm_alpha
+ - @drawable/btn_rating_star_on_qntm_alpha
+ - @drawable/btn_star_qntm_alpha
+ - @drawable/btn_switch_to_off_qntm_000
+ - @drawable/btn_switch_to_off_qntm_001
+ - @drawable/btn_switch_to_off_qntm_002
+ - @drawable/btn_switch_to_off_qntm_003
+ - @drawable/btn_switch_to_off_qntm_004
+ - @drawable/btn_switch_to_off_qntm_005
+ - @drawable/btn_switch_to_off_qntm_006
+ - @drawable/btn_switch_to_off_qntm_007
+ - @drawable/btn_switch_to_off_qntm_008
+ - @drawable/btn_switch_to_off_qntm_009
+ - @drawable/btn_switch_to_off_qntm_010
+ - @drawable/btn_switch_to_off_qntm_011
+ - @drawable/btn_switch_to_off_qntm_012
+ - @drawable/btn_switch_to_off_qntm_013
+ - @drawable/btn_switch_to_off_qntm_014
+ - @drawable/btn_switch_to_on_qntm_000
+ - @drawable/btn_switch_to_on_qntm_001
+ - @drawable/btn_switch_to_on_qntm_002
+ - @drawable/btn_switch_to_on_qntm_003
+ - @drawable/btn_switch_to_on_qntm_004
+ - @drawable/btn_switch_to_on_qntm_005
+ - @drawable/btn_switch_to_on_qntm_006
+ - @drawable/btn_switch_to_on_qntm_007
+ - @drawable/btn_switch_to_on_qntm_008
+ - @drawable/btn_switch_to_on_qntm_009
+ - @drawable/btn_switch_to_on_qntm_010
+ - @drawable/btn_switch_to_on_qntm_011
+ - @drawable/btn_switch_to_on_qntm_012
+ - @drawable/btn_switch_to_on_qntm_013
+ - @drawable/btn_switch_to_on_qntm_014
+ - @drawable/btn_toggle_indicator_qntm_alpha
+ - @drawable/btn_toggle_qntm_alpha
+ - @drawable/expander_close_qntm_alpha
+ - @drawable/expander_open_qntm_alpha
+ - @drawable/fastscroll_thumb_qntm_alpha
+ - @drawable/fastscroll_track_qntm_alpha
+ - @drawable/ic_ab_back_qntm_am_alpha
+ - @drawable/ic_cab_done_qntm_alpha
+ - @drawable/ic_clear_qntm_alpha
+ - @drawable/ic_commit_search_api_qntm_alpha
+ - @drawable/ic_dialog_alert_qntm_alpha
+ - @drawable/ic_find_next_qntm_alpha
+ - @drawable/ic_find_previous_qntm_alpha
+ - @drawable/ic_go_search_api_qntm_alpha
+ - @drawable/ic_media_route_disabled_qntm_alpha
+ - @drawable/ic_media_route_off_qntm_alpha
+ - @drawable/ic_media_route_on_0_qntm_alpha
+ - @drawable/ic_media_route_on_1_qntm_alpha
+ - @drawable/ic_media_route_on_2_qntm_alpha
+ - @drawable/ic_media_route_on_qntm_alpha
+ - @drawable/ic_menu_copy_qntm_am_alpha
+ - @drawable/ic_menu_cut_qntm_alpha
+ - @drawable/ic_menu_find_qntm_alpha
+ - @drawable/ic_menu_moreoverflow_qntm_alpha
+ - @drawable/ic_menu_paste_qntm_am_alpha
+ - @drawable/ic_menu_search_qntm_alpha
+ - @drawable/ic_menu_selectall_qntm_alpha
+ - @drawable/ic_menu_share_qntm_alpha
+ - @drawable/ic_search_api_qntm_alpha
+ - @drawable/ic_voice_search_api_qntm_alpha
+ - @drawable/list_divider_qntm_alpha
+ - @drawable/list_section_divider_qntm_alpha
+ - @drawable/popup_background_qntm_mult
+ - @drawable/progress_primary_qntm_alpha
+ - @drawable/progress_qntm_alpha
+ - @drawable/scrollbar_handle_qntm_alpha
+ - @drawable/scrubber_control_from_pressed_qntm_000
+ - @drawable/scrubber_control_from_pressed_qntm_001
+ - @drawable/scrubber_control_from_pressed_qntm_002
+ - @drawable/scrubber_control_from_pressed_qntm_003
+ - @drawable/scrubber_control_from_pressed_qntm_004
+ - @drawable/scrubber_control_from_pressed_qntm_005
+ - @drawable/scrubber_control_off_pressed_qntm_alpha
+ - @drawable/scrubber_control_off_qntm_alpha
+ - @drawable/scrubber_control_on_pressed_qntm_alpha
+ - @drawable/scrubber_control_on_qntm_alpha
+ - @drawable/scrubber_control_to_pressed_qntm_000
+ - @drawable/scrubber_control_to_pressed_qntm_001
+ - @drawable/scrubber_control_to_pressed_qntm_002
+ - @drawable/scrubber_control_to_pressed_qntm_003
+ - @drawable/scrubber_control_to_pressed_qntm_004
+ - @drawable/scrubber_control_to_pressed_qntm_005
+ - @drawable/scrubber_primary_qntm_alpha
+ - @drawable/scrubber_track_qntm_alpha
+ - @drawable/spinner_qntm_am_alpha
+ - @drawable/switch_track_qntm_alpha
+ - @drawable/tab_indicator_normal_qntm_alpha
+ - @drawable/tab_indicator_selected_qntm_alpha
+ - @drawable/text_cursor_qntm_alpha
+ - @drawable/textfield_activated_qntm_alpha
+ - @drawable/textfield_default_qntm_alpha
+ - @drawable/textfield_search_activated_qntm_alpha
+ - @drawable/textfield_search_default_qntm_alpha
+ - @drawable/text_select_handle_left_qntm_alpha
+ - @drawable/text_select_handle_middle_qntm_alpha
+ - @drawable/text_select_handle_right_qntm_alpha
+ - @color/background_cache_hint_selector_quantum_dark
+ - @color/background_cache_hint_selector_quantum_light
+ - @color/btn_default_quantum_dark
+ - @color/btn_default_quantum_light
+ - @color/primary_text_disable_only_quantum_dark
+ - @color/primary_text_disable_only_quantum_light
+ - @color/primary_text_quantum_dark
+ - @color/primary_text_quantum_light
+ - @color/search_url_text_quantum_dark
+ - @color/search_url_text_quantum_light
From 4fd25780e759736b87644f98814818e2346a31be Mon Sep 17 00:00:00 2001
From: Jorim Jaggi
Date: Tue, 3 Jun 2014 22:34:22 +0200
Subject: [PATCH 27/93] Fix invalid Keyguard state with encrypted devices.
Bug: 15389720
Change-Id: I0a18e78043e5c08f40cf3288abc07f75ea6261a0
---
.../systemui/keyguard/KeyguardViewMediator.java | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index 4837a539346a2..ffd76a7d5367d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -878,6 +878,7 @@ public class KeyguardViewMediator extends SystemUI {
if (mLockPatternUtils.checkVoldPassword()) {
if (DEBUG) Log.d(TAG, "Not showing lock screen since just decrypted");
// Without this, settings is not enabled until the lock screen first appears
+ mShowing = false;
hideLocked();
return;
}
@@ -1191,9 +1192,17 @@ public class KeyguardViewMediator extends SystemUI {
if (DEBUG) Log.d(TAG, "handleHide");
try {
- // Don't actually hide the Keyguard at the moment, wait for window manager until
- // it tells us it's safe to do so with startKeyguardExitAnimation.
- mWM.keyguardGoingAway();
+ if (mShowing) {
+
+ // Don't actually hide the Keyguard at the moment, wait for window manager until
+ // it tells us it's safe to do so with startKeyguardExitAnimation.
+ mWM.keyguardGoingAway();
+ } else {
+
+ // Don't try to rely on WindowManager - if Keyguard wasn't showing, window
+ // manager won't start the exit animation.
+ handleStartKeyguardExitAnimation(0, 0);
+ }
} catch (RemoteException e) {
Log.e(TAG, "Error while calling WindowManager", e);
}
From 03823cb9b30c399ad385ccc3f835f2e12d87b6a6 Mon Sep 17 00:00:00 2001
From: Alan Viverette
Date: Tue, 3 Jun 2014 15:48:30 -0700
Subject: [PATCH 28/93] Fix build, fix Drawable loop
Change-Id: I524b7f40c700ebe601fdbe80644a46e90ab2bba0
---
core/res/res/values/arrays.xml | 2 --
graphics/java/android/graphics/drawable/Drawable.java | 2 +-
2 files changed, 1 insertion(+), 3 deletions(-)
diff --git a/core/res/res/values/arrays.xml b/core/res/res/values/arrays.xml
index 042af41693030..1de26c72621bd 100644
--- a/core/res/res/values/arrays.xml
+++ b/core/res/res/values/arrays.xml
@@ -473,8 +473,6 @@
- @drawable/scrubber_track_qntm_alpha
- @drawable/spinner_qntm_am_alpha
- @drawable/switch_track_qntm_alpha
- - @drawable/tab_indicator_normal_qntm_alpha
- - @drawable/tab_indicator_selected_qntm_alpha
- @drawable/text_cursor_qntm_alpha
- @drawable/textfield_activated_qntm_alpha
- @drawable/textfield_default_qntm_alpha
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index f29b9f06bec57..76dd1c896bcdc 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -908,7 +908,7 @@ public abstract class Drawable {
InputStream is, String srcName) {
Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, srcName != null ? srcName : "Unknown drawable");
try {
- return createFromResourceStream(res, value, is, srcName);
+ return createFromResourceStream(res, value, is, srcName, null);
} finally {
Trace.traceEnd(Trace.TRACE_TAG_RESOURCES);
}
From 4c27428ef5f0baed60642f83f4f232e386fc8bc4 Mon Sep 17 00:00:00 2001
From: Raph Levien
Date: Sat, 31 May 2014 00:02:19 -0700
Subject: [PATCH 29/93] Support for scaleX and skewX in Minikin
Passes textScaleX and textSkewX parameters, as well as paint flags from
the paint to Minikin, to support nontrivial scale and stretch of text.
Passing paint flags should minimize kerning artifacts arising from
mismatch of glyph rendering in layout and drawing.
Also, replaces unsafe snprintf to a fixed size buffer with a safe
version, which still avoids an allocation per layout operation.
This is part of the fix for bug 15186705 "Usability of the suggestion
strip in recent OTA's is severely reduced"
Change-Id: I79788383135836f4c21fb84405f36382627bf959
---
core/jni/android/graphics/MinikinSkia.cpp | 21 +++++++++++++++++-
core/jni/android/graphics/MinikinSkia.h | 2 ++
core/jni/android/graphics/MinikinUtils.cpp | 25 ++++++++++++++++++----
core/jni/android/graphics/MinikinUtils.h | 4 ++++
core/jni/android/graphics/TypefaceImpl.cpp | 1 +
5 files changed, 48 insertions(+), 5 deletions(-)
diff --git a/core/jni/android/graphics/MinikinSkia.cpp b/core/jni/android/graphics/MinikinSkia.cpp
index 243fa10df6474..2b96f1b661042 100644
--- a/core/jni/android/graphics/MinikinSkia.cpp
+++ b/core/jni/android/graphics/MinikinSkia.cpp
@@ -46,8 +46,10 @@ bool MinikinFontSkia::GetGlyph(uint32_t codepoint, uint32_t *glyph) const {
static void MinikinFontSkia_SetSkiaPaint(SkTypeface* typeface, SkPaint* skPaint, const MinikinPaint& paint) {
skPaint->setTypeface(typeface);
skPaint->setTextEncoding(SkPaint::kGlyphID_TextEncoding);
- // TODO: set more paint parameters from Minikin
skPaint->setTextSize(paint.size);
+ skPaint->setTextScaleX(paint.scaleX);
+ skPaint->setTextSkewX(paint.skewX);
+ MinikinFontSkia::unpackPaintFlags(skPaint, paint.paintFlags);
}
float MinikinFontSkia::GetHorizontalAdvance(uint32_t glyph_id,
@@ -96,4 +98,21 @@ int32_t MinikinFontSkia::GetUniqueId() const {
return mTypeface->uniqueID();
}
+uint32_t MinikinFontSkia::packPaintFlags(const SkPaint* paint) {
+ uint32_t flags = paint->getFlags();
+ SkPaint::Hinting hinting = paint->getHinting();
+ // select only flags that might affect text layout
+ flags &= (SkPaint::kAntiAlias_Flag | SkPaint::kFakeBoldText_Flag | SkPaint::kLinearText_Flag |
+ SkPaint::kSubpixelText_Flag | SkPaint::kDevKernText_Flag |
+ SkPaint::kEmbeddedBitmapText_Flag | SkPaint::kAutoHinting_Flag |
+ SkPaint::kVerticalText_Flag);
+ flags |= (hinting << 16);
+ return flags;
+}
+
+void MinikinFontSkia::unpackPaintFlags(SkPaint* paint, uint32_t paintFlags) {
+ paint->setFlags(paintFlags & SkPaint::kAllFlags);
+ paint->setHinting(static_cast(paintFlags >> 16));
+}
+
}
diff --git a/core/jni/android/graphics/MinikinSkia.h b/core/jni/android/graphics/MinikinSkia.h
index 1cc2c51b3ae4d..0452c57ed2fdd 100644
--- a/core/jni/android/graphics/MinikinSkia.h
+++ b/core/jni/android/graphics/MinikinSkia.h
@@ -38,6 +38,8 @@ public:
SkTypeface *GetSkTypeface();
+ static uint32_t packPaintFlags(const SkPaint* paint);
+ static void unpackPaintFlags(SkPaint* paint, uint32_t paintFlags);
private:
SkTypeface *mTypeface;
};
diff --git a/core/jni/android/graphics/MinikinUtils.cpp b/core/jni/android/graphics/MinikinUtils.cpp
index a88b747772e55..146bc3d973456 100644
--- a/core/jni/android/graphics/MinikinUtils.cpp
+++ b/core/jni/android/graphics/MinikinUtils.cpp
@@ -14,6 +14,9 @@
* limitations under the License.
*/
+#define LOG_TAG "Minikin"
+#include
+
#include "SkPaint.h"
#include "minikin/Layout.h"
#include "TypefaceImpl.h"
@@ -23,23 +26,37 @@
namespace android {
+// Do an sprintf starting at offset n, abort on overflow
+static int snprintfcat(char* buf, int off, int size, const char* format, ...) {
+ va_list args;
+ va_start(args, format);
+ int n = vsnprintf(buf + off, size - off, format, args);
+ LOG_ALWAYS_FATAL_IF(n >= size - off, "String overflow in setting layout properties");
+ va_end(args);
+ return off + n;
+}
+
void MinikinUtils::SetLayoutProperties(Layout* layout, const SkPaint* paint, int flags,
TypefaceImpl* typeface) {
TypefaceImpl* resolvedFace = TypefaceImpl_resolveDefault(typeface);
layout->setFontCollection(resolvedFace->fFontCollection);
FontStyle style = resolvedFace->fStyle;
char css[256];
- int off = snprintf(css, sizeof(css),
- "font-size: %d; font-weight: %d; font-style: %s; -minikin-bidi: %d;",
+ int off = snprintfcat(css, 0, sizeof(css),
+ "font-size: %d; font-scale-x: %f; font-skew-x: %f; -paint-flags: %d;"
+ " font-weight: %d; font-style: %s; -minikin-bidi: %d;",
(int)paint->getTextSize(),
+ paint->getTextScaleX(),
+ paint->getTextSkewX(),
+ MinikinFontSkia::packPaintFlags(paint),
style.getWeight() * 100,
style.getItalic() ? "italic" : "normal",
flags);
SkString langString = paint->getPaintOptionsAndroid().getLanguage().getTag();
- off += snprintf(css + off, sizeof(css) - off, " lang: %s;", langString.c_str());
+ off = snprintfcat(css, off, sizeof(css), " lang: %s;", langString.c_str());
SkPaintOptionsAndroid::FontVariant var = paint->getPaintOptionsAndroid().getFontVariant();
const char* varstr = var == SkPaintOptionsAndroid::kElegant_Variant ? "elegant" : "compact";
- off += snprintf(css + off, sizeof(css) - off, " -minikin-variant: %s;", varstr);
+ off = snprintfcat(css, off, sizeof(css), " -minikin-variant: %s;", varstr);
layout->setProperties(css);
}
diff --git a/core/jni/android/graphics/MinikinUtils.h b/core/jni/android/graphics/MinikinUtils.h
index 997d6e30b35e1..3996c82a33160 100644
--- a/core/jni/android/graphics/MinikinUtils.h
+++ b/core/jni/android/graphics/MinikinUtils.h
@@ -26,10 +26,14 @@
namespace android {
+class Layout;
+class TypefaceImpl;
+
class MinikinUtils {
public:
static void SetLayoutProperties(Layout* layout, const SkPaint* paint, int flags,
TypefaceImpl* face);
+
static float xOffsetForTextAlign(SkPaint* paint, const Layout& layout);
// f is a functor of type void f(SkTypeface *, size_t start, size_t end);
diff --git a/core/jni/android/graphics/TypefaceImpl.cpp b/core/jni/android/graphics/TypefaceImpl.cpp
index 786d19c494861..27df7cf0e215b 100644
--- a/core/jni/android/graphics/TypefaceImpl.cpp
+++ b/core/jni/android/graphics/TypefaceImpl.cpp
@@ -32,6 +32,7 @@
#include
#include
#include
+#include "SkPaint.h"
#include "MinikinSkia.h"
#endif
From ef735725360b903d4a1778cf012b6a7cc06a5616 Mon Sep 17 00:00:00 2001
From: Raph Levien
Date: Wed, 4 Jun 2014 14:48:02 -0700
Subject: [PATCH 30/93] Support for context in Minikin shaping
This patch uses the Minikin's new doLayout API that supports context,
and has some simple refactoring (pass css as string rather than setting
on the Layout object) to use this api.
Change-Id: I899474f81d377f3106e95ee3eb8d0fcc44c23ac2
---
core/jni/android/graphics/Canvas.cpp | 4 ++--
core/jni/android/graphics/MinikinUtils.cpp | 8 ++++---
core/jni/android/graphics/MinikinUtils.h | 4 ++--
core/jni/android/graphics/Paint.cpp | 28 +++++++++++-----------
core/jni/android_view_GLES20Canvas.cpp | 8 +++----
5 files changed, 27 insertions(+), 25 deletions(-)
diff --git a/core/jni/android/graphics/Canvas.cpp b/core/jni/android/graphics/Canvas.cpp
index bdaf3a03ea245..d1203a790c866 100644
--- a/core/jni/android/graphics/Canvas.cpp
+++ b/core/jni/android/graphics/Canvas.cpp
@@ -818,8 +818,8 @@ public:
#ifdef USE_MINIKIN
Layout layout;
- MinikinUtils::SetLayoutProperties(&layout, paint, flags, typeface);
- layout.doLayout(textArray + start, count);
+ std::string css = MinikinUtils::setLayoutProperties(&layout, paint, flags, typeface);
+ layout.doLayout(textArray, start, count, contextCount, css);
drawGlyphsToSkia(canvas, paint, layout, x, y);
#else
sp value = TextLayoutEngine::getInstance().getValue(paint,
diff --git a/core/jni/android/graphics/MinikinUtils.cpp b/core/jni/android/graphics/MinikinUtils.cpp
index 146bc3d973456..a9360ea1ecbb9 100644
--- a/core/jni/android/graphics/MinikinUtils.cpp
+++ b/core/jni/android/graphics/MinikinUtils.cpp
@@ -16,6 +16,7 @@
#define LOG_TAG "Minikin"
#include
+#include
#include "SkPaint.h"
#include "minikin/Layout.h"
@@ -36,8 +37,8 @@ static int snprintfcat(char* buf, int off, int size, const char* format, ...) {
return off + n;
}
-void MinikinUtils::SetLayoutProperties(Layout* layout, const SkPaint* paint, int flags,
- TypefaceImpl* typeface) {
+std::string MinikinUtils::setLayoutProperties(Layout* layout, const SkPaint* paint, int bidiFlags,
+ TypefaceImpl* typeface) {
TypefaceImpl* resolvedFace = TypefaceImpl_resolveDefault(typeface);
layout->setFontCollection(resolvedFace->fFontCollection);
FontStyle style = resolvedFace->fStyle;
@@ -51,13 +52,14 @@ void MinikinUtils::SetLayoutProperties(Layout* layout, const SkPaint* paint, int
MinikinFontSkia::packPaintFlags(paint),
style.getWeight() * 100,
style.getItalic() ? "italic" : "normal",
- flags);
+ bidiFlags);
SkString langString = paint->getPaintOptionsAndroid().getLanguage().getTag();
off = snprintfcat(css, off, sizeof(css), " lang: %s;", langString.c_str());
SkPaintOptionsAndroid::FontVariant var = paint->getPaintOptionsAndroid().getFontVariant();
const char* varstr = var == SkPaintOptionsAndroid::kElegant_Variant ? "elegant" : "compact";
off = snprintfcat(css, off, sizeof(css), " -minikin-variant: %s;", varstr);
layout->setProperties(css);
+ return std::string(css);
}
float MinikinUtils::xOffsetForTextAlign(SkPaint* paint, const Layout& layout) {
diff --git a/core/jni/android/graphics/MinikinUtils.h b/core/jni/android/graphics/MinikinUtils.h
index 3996c82a33160..ea7eb5d69e7ce 100644
--- a/core/jni/android/graphics/MinikinUtils.h
+++ b/core/jni/android/graphics/MinikinUtils.h
@@ -31,8 +31,8 @@ class TypefaceImpl;
class MinikinUtils {
public:
- static void SetLayoutProperties(Layout* layout, const SkPaint* paint, int flags,
- TypefaceImpl* face);
+ static std::string setLayoutProperties(Layout* layout, const SkPaint* paint, int bidiFlags,
+ TypefaceImpl* typeface);
static float xOffsetForTextAlign(SkPaint* paint, const Layout& layout);
diff --git a/core/jni/android/graphics/Paint.cpp b/core/jni/android/graphics/Paint.cpp
index 4000b077519be..3dc874e77bea6 100644
--- a/core/jni/android/graphics/Paint.cpp
+++ b/core/jni/android/graphics/Paint.cpp
@@ -520,8 +520,8 @@ public:
#ifdef USE_MINIKIN
Layout layout;
TypefaceImpl* typeface = GraphicsJNI::getNativeTypeface(env, jpaint);
- MinikinUtils::SetLayoutProperties(&layout, paint, bidiFlags, typeface);
- layout.doLayout(textArray + index, count);
+ std::string css = MinikinUtils::setLayoutProperties(&layout, paint, bidiFlags, typeface);
+ layout.doLayout(textArray, index, count, textLength, css);
result = layout.getAdvance();
#else
TextLayout::getTextRunAdvances(paint, textArray, index, count, textLength,
@@ -554,8 +554,8 @@ public:
#ifdef USE_MINIKIN
Layout layout;
TypefaceImpl* typeface = GraphicsJNI::getNativeTypeface(env, jpaint);
- MinikinUtils::SetLayoutProperties(&layout, paint, bidiFlags, typeface);
- layout.doLayout(textArray + start, count);
+ std::string css = MinikinUtils::setLayoutProperties(&layout, paint, bidiFlags, typeface);
+ layout.doLayout(textArray, start, count, textLength, css);
width = layout.getAdvance();
#else
TextLayout::getTextRunAdvances(paint, textArray, start, count, textLength,
@@ -582,8 +582,8 @@ public:
#ifdef USE_MINIKIN
Layout layout;
TypefaceImpl* typeface = GraphicsJNI::getNativeTypeface(env, jpaint);
- MinikinUtils::SetLayoutProperties(&layout, paint, bidiFlags, typeface);
- layout.doLayout(textArray, textLength);
+ std::string css = MinikinUtils::setLayoutProperties(&layout, paint, bidiFlags, typeface);
+ layout.doLayout(textArray, 0, textLength, textLength, css);
width = layout.getAdvance();
#else
TextLayout::getTextRunAdvances(paint, textArray, 0, textLength, textLength,
@@ -617,8 +617,8 @@ public:
#ifdef USE_MINIKIN
Layout layout;
- MinikinUtils::SetLayoutProperties(&layout, paint, bidiFlags, typeface);
- layout.doLayout(text, count);
+ std::string css = MinikinUtils::setLayoutProperties(&layout, paint, bidiFlags, typeface);
+ layout.doLayout(text, 0, count, count, css);
layout.getAdvances(widthsArray);
#else
TextLayout::getTextRunAdvances(paint, text, 0, count, count,
@@ -715,8 +715,8 @@ public:
#ifdef USE_MINIKIN
Layout layout;
- MinikinUtils::SetLayoutProperties(&layout, paint, flags, typeface);
- layout.doLayout(text + start, count);
+ std::string css = MinikinUtils::setLayoutProperties(&layout, paint, flags, typeface);
+ layout.doLayout(text, start, count, contextCount, css);
layout.getAdvances(advancesArray);
totalAdvance = layout.getAdvance();
#else
@@ -860,8 +860,8 @@ public:
jint count, jint bidiFlags, jfloat x, jfloat y, SkPath* path) {
#ifdef USE_MINIKIN
Layout layout;
- MinikinUtils::SetLayoutProperties(&layout, paint, bidiFlags, typeface);
- layout.doLayout(text, count);
+ std::string css = MinikinUtils::setLayoutProperties(&layout, paint, bidiFlags, typeface);
+ layout.doLayout(text, 0, count, count, css);
size_t nGlyphs = layout.nGlyphs();
uint16_t* glyphs = new uint16_t[nGlyphs];
SkPoint* pos = new SkPoint[nGlyphs];
@@ -992,8 +992,8 @@ public:
#ifdef USE_MINIKIN
Layout layout;
- MinikinUtils::SetLayoutProperties(&layout, &paint, bidiFlags, typeface);
- layout.doLayout(text, count);
+ std::string css = MinikinUtils::setLayoutProperties(&layout, &paint, bidiFlags, typeface);
+ layout.doLayout(text, 0, count, count, css);
MinikinRect rect;
layout.getBounds(&rect);
r.fLeft = rect.mLeft;
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index 6b35be11586a6..33fd346488e40 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -645,8 +645,8 @@ static void renderText(OpenGLRenderer* renderer, const jchar* text, int count,
jfloat x, jfloat y, int flags, SkPaint* paint, TypefaceImpl* typeface) {
#ifdef USE_MINIKIN
Layout layout;
- MinikinUtils::SetLayoutProperties(&layout, paint, flags, typeface);
- layout.doLayout(text, count);
+ std::string css = MinikinUtils::setLayoutProperties(&layout, paint, flags, typeface);
+ layout.doLayout(text, 0, count, count, css);
x += xOffsetForTextAlign(paint, layout.getAdvance());
renderTextLayout(renderer, &layout, x, y, paint);
#else
@@ -689,8 +689,8 @@ static void renderTextRun(OpenGLRenderer* renderer, const jchar* text,
int flags, SkPaint* paint, TypefaceImpl* typeface) {
#ifdef USE_MINIKIN
Layout layout;
- MinikinUtils::SetLayoutProperties(&layout, paint, flags, typeface);
- layout.doLayout(text + start, count);
+ std::string css = MinikinUtils::setLayoutProperties(&layout, paint, flags, typeface);
+ layout.doLayout(text, start, count, contextCount, css);
x += xOffsetForTextAlign(paint, layout.getAdvance());
renderTextLayout(renderer, &layout, x, y, paint);
#else
From 9a4f9f130a036db107c2bae54b22100499878f25 Mon Sep 17 00:00:00 2001
From: Sreeram Ramachandran
Date: Wed, 11 Jun 2014 15:56:51 -0700
Subject: [PATCH 31/93] Fix wifi connectivity issues.
http://ag/480881 changed RouteInfo.getDestination() to return an IpPrefix
instead of a LinkAddress. This makes the equals() comparison always fail.
So, when ConnectivityService.updateRoutes() is given identical routes, instead
of realizing that there's no diff, it would consider them different, and thus
add and remove the same route. The add would fail, since the route already
existed in netd, but the remove would succeed, leaving the system with no routes
and thus no connectivity.
Bug: 15564210
Change-Id: I2003b0fcb809cc20837dc489c58af37891ca4556
---
core/java/android/net/RouteInfo.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/core/java/android/net/RouteInfo.java b/core/java/android/net/RouteInfo.java
index af27e1ddd17b5..8b42bcd5cb6e4 100644
--- a/core/java/android/net/RouteInfo.java
+++ b/core/java/android/net/RouteInfo.java
@@ -361,7 +361,7 @@ public class RouteInfo implements Parcelable {
RouteInfo target = (RouteInfo) obj;
- return Objects.equals(mDestination, target.getDestination()) &&
+ return Objects.equals(mDestination, target.getDestinationLinkAddress()) &&
Objects.equals(mGateway, target.getGateway()) &&
Objects.equals(mInterface, target.getInterface());
}
From 2c656c32fed96e89e2ba2a4e40ea8f04e7874dd1 Mon Sep 17 00:00:00 2001
From: Svetoslav
Date: Thu, 12 Jun 2014 10:43:20 -0700
Subject: [PATCH 32/93] Fix NPE in PrintActivity.
It is possible that the orientation is chosen before the media size.
The code handling orientation change was wrognly expecting to have
a selected media size all the time resulting in a NPE.
bug:15512333
Change-Id: I9f2786af314641144a24c1d1363c8d2590b0df57
---
.../src/com/android/printspooler/ui/PrintActivity.java | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
index f71cafe584ccc..3e0d7e557de1b 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
@@ -1735,10 +1735,12 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
} else if (spinner == mOrientationSpinner) {
SpinnerItem orientationItem = mOrientationSpinnerAdapter.getItem(position);
PrintAttributes attributes = mPrintJob.getAttributes();
- if (orientationItem.value == ORIENTATION_PORTRAIT) {
- attributes.copyFrom(attributes.asPortrait());
- } else {
- attributes.copyFrom(attributes.asLandscape());
+ if (mMediaSizeSpinner.getSelectedItem() != null) {
+ if (orientationItem.value == ORIENTATION_PORTRAIT) {
+ attributes.copyFrom(attributes.asPortrait());
+ } else {
+ attributes.copyFrom(attributes.asLandscape());
+ }
}
}
From cdc6dff31e6e99137b50a2bbd9f7e1d1d384e1e7 Mon Sep 17 00:00:00 2001
From: John Reck
Date: Tue, 17 Jun 2014 10:46:09 -0700
Subject: [PATCH 33/93] Make sure the root node has a type
Bug: 15686491
Change-Id: I4bd64a6470dd704740e99d21cfdbe84805961401
---
libs/hwui/DamageAccumulator.cpp | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/libs/hwui/DamageAccumulator.cpp b/libs/hwui/DamageAccumulator.cpp
index 1cb87f2c6bd21..61cbf85303ebf 100644
--- a/libs/hwui/DamageAccumulator.cpp
+++ b/libs/hwui/DamageAccumulator.cpp
@@ -33,6 +33,7 @@ NullDamageAccumulator* NullDamageAccumulator::instance() {
}
enum TransformType {
+ TransformInvalid = 0,
TransformRenderNode,
TransformMatrix4,
TransformNone,
@@ -56,6 +57,7 @@ DamageAccumulator::DamageAccumulator() {
memset(mHead, 0, sizeof(DirtyStack));
// Create a root that we will not pop off
mHead->prev = mHead;
+ mHead->type = TransformNone;
}
void DamageAccumulator::pushCommon() {
@@ -100,6 +102,8 @@ void DamageAccumulator::popTransform() {
case TransformNone:
mHead->pendingDirty.join(dirtyFrame->pendingDirty);
break;
+ default:
+ LOG_ALWAYS_FATAL("Tried to pop an invalid type: %d", dirtyFrame->type);
}
}
@@ -186,8 +190,6 @@ void DamageAccumulator::applyRenderNodeTransform(DirtyStack* frame) {
if (projectionReceiver) {
applyTransforms(frame, projectionReceiver);
projectionReceiver->pendingDirty.join(frame->pendingDirty);
- } else {
- ALOGW("Failed to find projection receiver? Dropping on the floor...");
}
frame->pendingDirty.setEmpty();
From 3717f1b998b9147f9cd5e70e05b7eced466f8e8b Mon Sep 17 00:00:00 2001
From: vandwalle
Date: Tue, 17 Jun 2014 19:37:29 -0700
Subject: [PATCH 34/93] initial tuning
Change-Id: Iffe899225899e7805478a507ce270d537dc84abd
---
wifi/java/android/net/wifi/IWifiManager.aidl | 8 +++
.../android/net/wifi/WifiConfiguration.java | 8 ++-
wifi/java/android/net/wifi/WifiInfo.java | 7 +++
wifi/java/android/net/wifi/WifiManager.java | 50 ++++++++++++++++++-
4 files changed, 70 insertions(+), 3 deletions(-)
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 00e1cd8ea6d1a..e83eed7283fc8 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -132,5 +132,13 @@ interface IWifiManager
void enableVerboseLogging(int verbose);
int getVerboseLoggingLevel();
+
+ int getAggressiveHandover();
+
+ void enableAggressiveHandover(int enabled);
+
+ int getAllowScansWithTraffic();
+
+ void setAllowScansWithTraffic(int enabled);
}
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index b64ad601ff19e..777471dc5f578 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -376,7 +376,7 @@ public class WifiConfiguration implements Parcelable {
public static int LOW_RSSI_24 = -75;
/** @hide **/
- public static int BAD_RSSI_24 = -85;
+ public static int BAD_RSSI_24 = -87;
/** @hide **/
public static int GOOD_RSSI_5 = -55;
@@ -394,7 +394,7 @@ public class WifiConfiguration implements Parcelable {
public static int UNWANTED_BLACKLIST_HARD_BUMP = 8;
/** @hide **/
- public static int UNBLACKLIST_THRESHOLD_24_SOFT = -75;
+ public static int UNBLACKLIST_THRESHOLD_24_SOFT = -77;
/** @hide **/
public static int UNBLACKLIST_THRESHOLD_24_HARD = -68;
@@ -415,6 +415,10 @@ public class WifiConfiguration implements Parcelable {
* 5GHz band is prefered over 2.4 if the 5GHz RSSI is higher than this threshold **/
public static int A_BAND_PREFERENCE_RSSI_THRESHOLD = -65;
+ /** @hide
+ * 5GHz band is penalized if the 5GHz RSSI is lower than this threshold **/
+ public static int G_BAND_PREFERENCE_RSSI_THRESHOLD = -75;
+
/**
* @hide
* A summary of the RSSI and Band status for that configuration
diff --git a/wifi/java/android/net/wifi/WifiInfo.java b/wifi/java/android/net/wifi/WifiInfo.java
index 54a7df2a62cc6..e46f9169f886a 100644
--- a/wifi/java/android/net/wifi/WifiInfo.java
+++ b/wifi/java/android/net/wifi/WifiInfo.java
@@ -131,6 +131,11 @@ public class WifiInfo implements Parcelable {
*/
public int badRssiCount;
+ /**
+ * @hide
+ */
+ public int linkStuckCount;
+
/**
* @hide
*/
@@ -237,6 +242,7 @@ public class WifiInfo implements Parcelable {
txRetriesRate = 0;
lowRssiCount = 0;
badRssiCount = 0;
+ linkStuckCount = 0;
score = 0;
}
@@ -267,6 +273,7 @@ public class WifiInfo implements Parcelable {
score = source.score;
badRssiCount = source.badRssiCount;
lowRssiCount = source.lowRssiCount;
+ linkStuckCount = source.linkStuckCount;
}
}
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 141a69eb48ebb..a30fb797ff40f 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -2226,7 +2226,6 @@ public class WifiManager {
}
}
-
/**
* Set wifi verbose log. Called from developer settings.
* @hide
@@ -2251,4 +2250,53 @@ public class WifiManager {
return 0;
}
}
+
+ /**
+ * Set wifi Aggressive Handover. Called from developer settings.
+ * @hide
+ */
+ public void enableAggressiveHandover(int enabled) {
+ try {
+ mService.enableAggressiveHandover(enabled);
+ } catch (RemoteException e) {
+
+ }
+ }
+
+ /**
+ * Get the WiFi Handover aggressiveness.This is used by settings
+ * to decide what to show within the picker.
+ * @hide
+ */
+ public int getAggressiveHandover() {
+ try {
+ return mService.getAggressiveHandover();
+ } catch (RemoteException e) {
+ return 0;
+ }
+ }
+
+ /**
+ * Set setting for allowing Scans when traffic is ongoing.
+ * @hide
+ */
+ public void setAllowScansWithTraffic(int enabled) {
+ try {
+ mService.setAllowScansWithTraffic(enabled);
+ } catch (RemoteException e) {
+
+ }
+ }
+
+ /**
+ * Get setting for allowing Scans when traffic is ongoing.
+ * @hide
+ */
+ public int getAllowScansWithTraffic() {
+ try {
+ return mService.getAllowScansWithTraffic();
+ } catch (RemoteException e) {
+ return 0;
+ }
+ }
}
From 1f60f8776ded5a9fa4bfa820c62721321159eec9 Mon Sep 17 00:00:00 2001
From: Jeff Sharkey
Date: Thu, 19 Jun 2014 15:48:47 -0700
Subject: [PATCH 35/93] Explicitly collect manifest digests.
Previously it was a side effect of collectCertificates().
Bug: 15740334
Change-Id: I2e044fdcc1c86ce730b9570bfbecf873366325e1
---
core/java/android/content/pm/PackageManager.java | 1 +
core/java/android/content/pm/PackageParser.java | 2 ++
.../core/java/com/android/server/pm/PackageManagerService.java | 2 ++
3 files changed, 5 insertions(+)
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 5d55b0a11bd4c..84153848dac13 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -2876,6 +2876,7 @@ public abstract class PackageManager {
PackageParser.Package pkg = parser.parseMonolithicPackage(apkFile, 0);
if ((flags & GET_SIGNATURES) != 0) {
parser.collectCertificates(pkg, 0);
+ parser.collectManifestDigest(pkg);
}
PackageUserState state = new PackageUserState();
return PackageParser.generatePackageInfo(pkg, null, flags, 0, 0, null, state);
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 546f3a52c3663..0b336d011692e 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -744,6 +744,8 @@ public class PackageParser {
* {@code AndroidManifest.xml}, {@code true} is returned.
*/
public void collectManifestDigest(Package pkg) throws PackageParserException {
+ pkg.manifestDigest = null;
+
// TODO: extend to gather digest for split APKs
try {
final StrictJarFile jarFile = new StrictJarFile(pkg.codePath);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 2f40f2ab19e2c..2f52564140e71 100755
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -4182,6 +4182,7 @@ public class PackageManagerService extends IPackageManager.Stub {
try {
pp.collectCertificates(pkg, parseFlags);
+ pp.collectManifestDigest(pkg);
} catch (PackageParserException e) {
mLastScanError = e.error;
return false;
@@ -10225,6 +10226,7 @@ public class PackageManagerService extends IPackageManager.Stub {
try {
pp.collectCertificates(pkg, parseFlags);
+ pp.collectManifestDigest(pkg);
} catch (PackageParserException e) {
res.returnCode = e.error;
return;
From 42c9f5e5f73a4c65270f334d1bf77101211da574 Mon Sep 17 00:00:00 2001
From: John Reck
Date: Fri, 20 Jun 2014 09:59:56 -0700
Subject: [PATCH 36/93] Add negative guard
Bug: 15631600
Change-Id: Idd7740f58876e73694fafb8ef55ebaff511f6dca
---
libs/hwui/Interpolator.cpp | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/libs/hwui/Interpolator.cpp b/libs/hwui/Interpolator.cpp
index 1f84b86bca732..fc0e8a059f225 100644
--- a/libs/hwui/Interpolator.cpp
+++ b/libs/hwui/Interpolator.cpp
@@ -112,6 +112,10 @@ float LUTInterpolator::interpolate(float input) {
int i1 = (int) ipart;
int i2 = MathUtils::min(i1 + 1, mSize - 1);
+ LOG_ALWAYS_FATAL_IF(i1 < 0 || i2 < 0, "negatives in interpolation!"
+ " i1=%d, i2=%d, input=%f, lutpos=%f, size=%zu, values=%p, ipart=%f, weight=%f",
+ i1, i2, input, lutpos, mSize, mValues, ipart, weight);
+
float v1 = mValues[i1];
float v2 = mValues[i2];
From 0ee6d6a3dde27a403df0a8c0145eaecc8bc97097 Mon Sep 17 00:00:00 2001
From: Alexandra Gherghina
Date: Tue, 24 Jun 2014 16:02:39 +0100
Subject: [PATCH 37/93] Skip forwarding launcher intents
If we forward intents when looking up launcher icons, we end up
having an icon for a disambig activity instead of the apps for that user.
Bug: 15769854
Change-Id: Ia57525466dba57b6669b2b5cedf98f202d08f586
---
.../android/content/pm/PackageManager.java | 7 +++
.../server/pm/LauncherAppsService.java | 3 +-
.../server/pm/PackageManagerService.java | 62 ++++++++++---------
3 files changed, 43 insertions(+), 29 deletions(-)
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index d11698c0df7c9..720315d363ec1 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -197,6 +197,12 @@ public abstract class PackageManager {
*/
public static final int MATCH_DEFAULT_ONLY = 0x00010000;
+ /**
+ * Resolution and querying flag: do not resolve intents cross-profile.
+ * @hide
+ */
+ public static final int NO_CROSS_PROFILE = 0x00020000;
+
/**
* Flag for {@link addCrossProfileIntentFilter}: if the cross-profile intent has been set by the
* profile owner.
@@ -2310,6 +2316,7 @@ public abstract class PackageManager {
* @see #MATCH_DEFAULT_ONLY
* @see #GET_INTENT_FILTERS
* @see #GET_RESOLVED_FILTER
+ * @see #NO_CROSS_PROFILE
* @hide
*/
public abstract List queryIntentActivitiesAsUser(Intent intent,
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index 25ebfc0f9c54b..65cb6c99ba348 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -197,7 +197,8 @@ public class LauncherAppsService extends SystemService {
mainIntent.setPackage(packageName);
long ident = Binder.clearCallingIdentity();
try {
- List apps = mPm.queryIntentActivitiesAsUser(mainIntent, 0,
+ List apps = mPm.queryIntentActivitiesAsUser(mainIntent,
+ PackageManager.NO_CROSS_PROFILE, // We only want the apps for this user
user.getIdentifier());
return apps;
} finally {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 7fc7d0dd1e0c7..179b6e9623cd0 100755
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -3425,31 +3425,35 @@ public class PackageManagerService extends IPackageManager.Stub {
// reader
synchronized (mPackages) {
final String pkgName = intent.getPackage();
+ boolean queryCrossProfile = (flags & PackageManager.NO_CROSS_PROFILE) == 0;
if (pkgName == null) {
- //Check if the intent needs to be forwarded to another user for this package
- ArrayList crossProfileResult =
- queryIntentActivitiesCrossProfilePackage(
- intent, resolvedType, flags, userId);
- if (!crossProfileResult.isEmpty()) {
- // Skip the current profile
- return crossProfileResult;
- }
- List result;
- List matchingFilters =
- getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
- // Check for results that need to skip the current profile.
- ResolveInfo resolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent,
- resolvedType, flags, userId);
- if (resolveInfo != null) {
- result = new ArrayList(1);
- result.add(resolveInfo);
- return result;
+ ResolveInfo resolveInfo;
+ if (queryCrossProfile) {
+ // Check if the intent needs to be forwarded to another user for this package
+ ArrayList crossProfileResult =
+ queryIntentActivitiesCrossProfilePackage(
+ intent, resolvedType, flags, userId);
+ if (!crossProfileResult.isEmpty()) {
+ // Skip the current profile
+ return crossProfileResult;
+ }
+ List matchingFilters =
+ getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
+ // Check for results that need to skip the current profile.
+ resolveInfo = querySkipCurrentProfileIntents(matchingFilters, intent,
+ resolvedType, flags, userId);
+ if (resolveInfo != null) {
+ List result = new ArrayList(1);
+ result.add(resolveInfo);
+ return result;
+ }
+ // Check for cross profile results.
+ resolveInfo = queryCrossProfileIntents(
+ matchingFilters, intent, resolvedType, flags, userId);
}
// Check for results in the current profile.
- result = mActivities.queryIntent(intent, resolvedType, flags, userId);
- // Check for cross profile results.
- resolveInfo = queryCrossProfileIntents(
- matchingFilters, intent, resolvedType, flags, userId);
+ List result = mActivities.queryIntent(
+ intent, resolvedType, flags, userId);
if (resolveInfo != null) {
result.add(resolveInfo);
}
@@ -3457,12 +3461,14 @@ public class PackageManagerService extends IPackageManager.Stub {
}
final PackageParser.Package pkg = mPackages.get(pkgName);
if (pkg != null) {
- ArrayList crossProfileResult =
- queryIntentActivitiesCrossProfilePackage(
- intent, resolvedType, flags, userId, pkg, pkgName);
- if (!crossProfileResult.isEmpty()) {
- // Skip the current profile
- return crossProfileResult;
+ if (queryCrossProfile) {
+ ArrayList crossProfileResult =
+ queryIntentActivitiesCrossProfilePackage(
+ intent, resolvedType, flags, userId, pkg, pkgName);
+ if (!crossProfileResult.isEmpty()) {
+ // Skip the current profile
+ return crossProfileResult;
+ }
}
return mActivities.queryIntentForPackage(intent, resolvedType, flags,
pkg.activities, userId);
From a995ddadc63abe4f8c90b7f8a7d938c092b7dd4e Mon Sep 17 00:00:00 2001
From: Alexandra Gherghina
Date: Wed, 25 Jun 2014 14:20:09 +0100
Subject: [PATCH 38/93] Fix uninitialized variable warning
Change-Id: Ib1d4a4e1431388a839f9ef8027b439f57922b025
---
.../core/java/com/android/server/pm/PackageManagerService.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 179b6e9623cd0..cac27bc2db88e 100755
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -3427,7 +3427,7 @@ public class PackageManagerService extends IPackageManager.Stub {
final String pkgName = intent.getPackage();
boolean queryCrossProfile = (flags & PackageManager.NO_CROSS_PROFILE) == 0;
if (pkgName == null) {
- ResolveInfo resolveInfo;
+ ResolveInfo resolveInfo = null;
if (queryCrossProfile) {
// Check if the intent needs to be forwarded to another user for this package
ArrayList crossProfileResult =
From 0fd3a8e51a1b853f18dc10325403e782cabe3d01 Mon Sep 17 00:00:00 2001
From: Jorim Jaggi
Date: Wed, 25 Jun 2014 21:54:48 +0200
Subject: [PATCH 39/93] Attempt to fix infinite recursion.
When collapsing a panel without animating, it might be that an
overscroll animating was still running, and thus expandedHeight != 0
even if we set expandedFraction manually to 0, which sets the state
to STATE_OPEN again and tries to close it in an infinite loop.
Bug: 15721600
Change-Id: I14e0ee43fb4a47286d618cc97581d4e4a98fb2a2
---
.../android/systemui/statusbar/phone/NotificationPanelView.java | 2 ++
.../src/com/android/systemui/statusbar/phone/PanelBar.java | 2 +-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index a6ce5d5a5fa31..c684c9f2e50cf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -302,6 +302,8 @@ public class NotificationPanelView extends PanelView implements
mUnlockIconActive = false;
mPageSwiper.reset();
closeQs();
+ mNotificationStackScroller.setOverScrollAmount(0f, true /* onTop */, false /* animate */,
+ true /* cancelAnimators */);
}
public void closeQs() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
index b94f6f3d2fba5..b4faaaf545c8f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
@@ -188,10 +188,10 @@ public class PanelBar extends FrameLayout {
pv.collapse();
waiting = true;
} else {
+ pv.resetViews();
pv.setExpandedFraction(0); // just in case
pv.setVisibility(View.GONE);
pv.cancelPeek();
- pv.resetViews();
}
}
if (DEBUG) LOG("collapseAllPanels: animate=%s waiting=%s", animate, waiting);
From 23ed882c03b2d0b620c2accbf3e04922b2f1e6c5 Mon Sep 17 00:00:00 2001
From: "smain@google.com"
Date: Thu, 26 Jun 2014 08:31:11 -0700
Subject: [PATCH 40/93] fix build, remove briefdocs
Change-Id: I94a611f4bdc2b9c7f305727aacf2edbe63b4ece7
---
Android.mk | 1 -
1 file changed, 1 deletion(-)
diff --git a/Android.mk b/Android.mk
index efbee5ec034bf..bb65398360080 100644
--- a/Android.mk
+++ b/Android.mk
@@ -832,7 +832,6 @@ LOCAL_DROIDDOC_OPTIONS:= \
$(framework_docs_LOCAL_DROIDDOC_OPTIONS) \
-toroot / \
-hdf android.whichdoc online \
- -briefdocs \
$(sample_groups) \
-hdf android.hasSamples true \
-samplesdir $(samples_dir)
From 09d1a017a066038db64ded251eaeab7cd8e2c36c Mon Sep 17 00:00:00 2001
From: RoboErik
Date: Fri, 27 Jun 2014 11:38:59 -0700
Subject: [PATCH 41/93] clear calling identity when changing volume
bug: 15925039
Change-Id: I8596266109fd65d7c2de5718ccdda937694befba
---
.../android/server/media/MediaSessionRecord.java | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index 6f1eb8f607ac9..a40658018ef3c 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -38,6 +38,7 @@ import android.media.AudioManager;
import android.media.MediaMetadata;
import android.media.Rating;
import android.media.VolumeProvider;
+import android.os.Binder;
import android.os.Bundle;
import android.os.DeadObjectException;
import android.os.Handler;
@@ -1119,12 +1120,22 @@ public class MediaSessionRecord implements IBinder.DeathRecipient {
@Override
public void adjustVolumeBy(int delta, int flags) {
- MediaSessionRecord.this.adjustVolumeBy(delta, flags);
+ final long token = Binder.clearCallingIdentity();
+ try {
+ MediaSessionRecord.this.adjustVolumeBy(delta, flags);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
}
@Override
public void setVolumeTo(int value, int flags) {
- MediaSessionRecord.this.setVolumeTo(value, flags);
+ final long token = Binder.clearCallingIdentity();
+ try {
+ MediaSessionRecord.this.setVolumeTo(value, flags);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
}
@Override
From 0b60ec5c4a722ff87712444436a8b44d22394cd4 Mon Sep 17 00:00:00 2001
From: Jean-Michel Trivi
Date: Mon, 30 Jun 2014 12:10:44 -0700
Subject: [PATCH 42/93] Don't swear when setting remote music volume without a
controller
Root cause still TBD
bug 15986562
Change-Id: I8828989acfb642f44c59ba531df43914ece916a8
---
.../SystemUI/src/com/android/systemui/volume/VolumePanel.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java b/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
index d514c99bb7aac..99cba4d8f83ed 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
@@ -455,7 +455,7 @@ public class VolumePanel extends Handler {
if (sc.controller != null) {
sc.controller.setVolumeTo(index, flags);
} else {
- Log.wtf(mTag, "Adjusting remote volume without a controller!");
+ Log.w(mTag, "Adjusting remote volume without a controller!");
}
} else if (getStreamVolume(sc.streamType) != index) {
if (sc.streamType == STREAM_MASTER) {
From ff2f792732b4cc621d79d057a5daed3298fd53bb Mon Sep 17 00:00:00 2001
From: George Mount
Date: Mon, 30 Jun 2014 10:43:28 -0700
Subject: [PATCH 43/93] Don't throw exception for root scene transitions.
Bug 13745751
Change-Id: I7bb3cbabf4f402b38f5aa57ad0ee3b4320fa83cc
---
policy/src/com/android/internal/policy/impl/PhoneWindow.java | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 5e1aa3b14e172..149f4aaef3d5b 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -395,8 +395,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
}
if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
// TODO Augment the scenes/transitions API to support this.
- throw new UnsupportedOperationException(
- "addContentView does not support content transitions");
+ Log.v(TAG, "addContentView does not support content transitions");
}
mContentParent.addView(view, params);
final Callback cb = getCallback();
From 570aa16e3fdf0d06564ae9effdf0010b1405cdb1 Mon Sep 17 00:00:00 2001
From: Adam Powell
Date: Tue, 1 Jul 2014 15:22:50 -0700
Subject: [PATCH 44/93] Remove ActionBar.LayoutParams MarginLayoutParams
constructor
Adding this for L caused some fun issues with source compatibility.
Apps that previously passed another MarginLayoutParams subclass to
ActionBar.LayoutParams' constructor started statically linking to a
constructor overload that did not exist on older platform changes with
no other source changes. In the interests of avoiding these headaches
for developers, remove it.
Bug 15933193
Change-Id: I01cf8dfa2341b9d9629331639433b59352e7e15a
---
api/current.txt | 1 -
core/java/android/app/ActionBar.java | 12 +++++++++---
core/java/android/view/ViewGroup.java | 14 ++++++++++++++
core/java/android/widget/Toolbar.java | 7 +++++++
4 files changed, 30 insertions(+), 4 deletions(-)
diff --git a/api/current.txt b/api/current.txt
index 27971bb09dd1d..1af8b629679aa 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -3209,7 +3209,6 @@ package android.app {
ctor public ActionBar.LayoutParams(int);
ctor public ActionBar.LayoutParams(android.app.ActionBar.LayoutParams);
ctor public ActionBar.LayoutParams(android.view.ViewGroup.LayoutParams);
- ctor public ActionBar.LayoutParams(android.view.ViewGroup.MarginLayoutParams);
field public int gravity;
}
diff --git a/core/java/android/app/ActionBar.java b/core/java/android/app/ActionBar.java
index 628875f0218e2..5c981802b0dc4 100644
--- a/core/java/android/app/ActionBar.java
+++ b/core/java/android/app/ActionBar.java
@@ -1334,8 +1334,14 @@ public abstract class ActionBar {
super(source);
}
- public LayoutParams(MarginLayoutParams source) {
- super(source);
- }
+ /*
+ * Note for framework developers:
+ *
+ * You might notice that ActionBar.LayoutParams is missing a constructor overload
+ * for MarginLayoutParams. While it may seem like a good idea to add one, at this
+ * point it's dangerous for source compatibility. Upon building against a new
+ * version of the SDK an app can end up statically linking to the new MarginLayoutParams
+ * overload, causing a crash when running on older platform versions with no other changes.
+ */
}
}
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 45ac0739f2abd..67a2067c536cc 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -6471,6 +6471,20 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
mMarginFlags &= ~RTL_COMPATIBILITY_MODE_MASK;
}
+ /**
+ * @hide Used internally.
+ */
+ public final void copyMarginsFrom(MarginLayoutParams source) {
+ this.leftMargin = source.leftMargin;
+ this.topMargin = source.topMargin;
+ this.rightMargin = source.rightMargin;
+ this.bottomMargin = source.bottomMargin;
+ this.startMargin = source.startMargin;
+ this.endMargin = source.endMargin;
+
+ this.mMarginFlags = source.mMarginFlags;
+ }
+
/**
* Sets the margins, in pixels. A call to {@link android.view.View#requestLayout()} needs
* to be done so that the new margins are taken into account. Left and right margins may be
diff --git a/core/java/android/widget/Toolbar.java b/core/java/android/widget/Toolbar.java
index 122df2cdd4977..d140c82b38652 100644
--- a/core/java/android/widget/Toolbar.java
+++ b/core/java/android/widget/Toolbar.java
@@ -1585,6 +1585,10 @@ public class Toolbar extends ViewGroup {
/**
* Layout information for child views of Toolbars.
*
+ * Toolbar.LayoutParams extends ActionBar.LayoutParams for compatibility with existing
+ * ActionBar API. See {@link android.app.Activity#setActionBar(Toolbar) Activity.setActionBar}
+ * for more info on how to use a Toolbar as your Activity's ActionBar.
+ *
* @attr ref android.R.styleable#Toolbar_LayoutParams_layout_gravity
*/
public static class LayoutParams extends ActionBar.LayoutParams {
@@ -1624,6 +1628,9 @@ public class Toolbar extends ViewGroup {
public LayoutParams(MarginLayoutParams source) {
super(source);
+ // ActionBar.LayoutParams doesn't have a MarginLayoutParams constructor.
+ // Fake it here and copy over the relevant data.
+ copyMarginsFrom(source);
}
public LayoutParams(ViewGroup.LayoutParams source) {
From 58590ebfbebe8c6e68c150410791735cca5c8944 Mon Sep 17 00:00:00 2001
From: Adam Powell
Date: Tue, 1 Jul 2014 17:37:48 -0700
Subject: [PATCH 45/93] Fix checking for compatibility between window title
features.
New features that have nothing to do with titles were tripping the,
"is this compatible with custom titles" feature check in
PhoneWindow. Define a better way of checking for this for when we
add new window features in the future.
Bug 13789588
Change-Id: Ie1cacffb113958dac5142a5a39f548df53b47299
---
.../internal/policy/impl/PhoneWindow.java | 25 +++++++++++--------
1 file changed, 14 insertions(+), 11 deletions(-)
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindow.java b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
index 149f4aaef3d5b..abe907660027d 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindow.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindow.java
@@ -122,6 +122,11 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
private final static int DEFAULT_BACKGROUND_FADE_DURATION_MS = 300;
+ private static final int CUSTOM_TITLE_COMPATIBLE_FEATURES = DEFAULT_FEATURES |
+ (1 << FEATURE_CUSTOM_TITLE) |
+ (1 << FEATURE_CONTENT_TRANSITIONS) |
+ (1 << FEATURE_ACTION_MODE_OVERLAY);
+
/**
* Simple callback used by the context menu and its submenus. The options
* menu submenus do not use this (their behavior is more complex).
@@ -275,16 +280,13 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
throw new AndroidRuntimeException("requestFeature() must be called before adding content");
}
final int features = getFeatures();
- if ((features != DEFAULT_FEATURES) && (featureId == FEATURE_CUSTOM_TITLE)) {
-
- /* Another feature is enabled and the user is trying to enable the custom title feature */
- throw new AndroidRuntimeException("You cannot combine custom titles with other title features");
- }
- if (((features & (1 << FEATURE_CUSTOM_TITLE)) != 0) &&
- (featureId != FEATURE_CUSTOM_TITLE) && (featureId != FEATURE_ACTION_MODE_OVERLAY)) {
-
- /* Custom title feature is enabled and the user is trying to enable another feature */
- throw new AndroidRuntimeException("You cannot combine custom titles with other title features");
+ final int newFeatures = features | (1 << featureId);
+ if ((newFeatures & (1 << FEATURE_CUSTOM_TITLE)) != 0 &&
+ (newFeatures & ~CUSTOM_TITLE_COMPATIBLE_FEATURES) != 0) {
+ // Another feature is enabled and the user is trying to enable the custom title feature
+ // or custom title feature is enabled and the user is trying to enable another feature
+ throw new AndroidRuntimeException(
+ "You cannot combine custom titles with other title features");
}
if ((features & (1 << FEATURE_NO_TITLE)) != 0 && featureId == FEATURE_ACTION_BAR) {
return false; // Ignore. No title dominates.
@@ -395,7 +397,8 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
}
if (hasFeature(FEATURE_CONTENT_TRANSITIONS)) {
// TODO Augment the scenes/transitions API to support this.
- Log.v(TAG, "addContentView does not support content transitions");
+ throw new UnsupportedOperationException(
+ "addContentView does not support content transitions");
}
mContentParent.addView(view, params);
final Callback cb = getCallback();
From 7ed277f785747d8fde43ae3408d0274861ce8b76 Mon Sep 17 00:00:00 2001
From: Paul Jensen
Date: Wed, 2 Jul 2014 12:02:59 -0400
Subject: [PATCH 46/93] When adding a NetworkRequest, cancel linger for
satisfying Network.
This fixes a problem where a requested network can later suddenly disappear if
it was lingering when the request arrived and later the linger timeout expired.
bug:15927234
Change-Id: Ib3fae45820ce4421e3bc5b623937a16d5f1efa0f
---
.../core/java/com/android/server/ConnectivityService.java | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 87d28d35a2217..bce2800f45b9b 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -3332,6 +3332,12 @@ public class ConnectivityService extends IConnectivityManager.Stub {
}
if (bestNetwork != null) {
if (VDBG) log("using " + bestNetwork.name());
+ if (nri.isRequest && bestNetwork.networkInfo.isConnected()) {
+ // Cancel any lingering so the linger timeout doesn't teardown this network
+ // even though we have a request for it.
+ bestNetwork.networkLingered.clear();
+ bestNetwork.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_CONNECTED);
+ }
bestNetwork.addRequest(nri.request);
mNetworkForRequestId.put(nri.request.requestId, bestNetwork);
int legacyType = nri.request.legacyType;
From f1f043153f289ad80e524564e38fda12eaf70a64 Mon Sep 17 00:00:00 2001
From: RoboErik
Date: Fri, 27 Jun 2014 18:02:40 -0700
Subject: [PATCH 47/93] Don't send remote volume changes for local playback
bug: 15913248
Change-Id: I701d0a446ef981deae171b9e882c29906593b3c8
---
.../java/com/android/server/media/MediaSessionService.java | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java
index 5738a05c327d9..5a16e4ddb9bdc 100644
--- a/services/core/java/com/android/server/media/MediaSessionService.java
+++ b/services/core/java/com/android/server/media/MediaSessionService.java
@@ -971,7 +971,8 @@ public class MediaSessionService extends SystemService implements Monitor {
}
} else {
session.adjustVolumeBy(delta, flags);
- if (mRvc != null) {
+ if (session.getPlaybackType() == MediaSession.PLAYBACK_TYPE_REMOTE
+ && mRvc != null) {
try {
mRvc.remoteVolumeChanged(session.getControllerBinder(), flags);
} catch (Exception e) {
From 9816bd8cd47c81eeec88b7d060b9b200921973a7 Mon Sep 17 00:00:00 2001
From: John Reck
Date: Mon, 7 Jul 2014 09:50:32 -0700
Subject: [PATCH 48/93] Fix VPA.cancel()
Bug: 15978905
Need to make sure we re-sync the UI properties on animator cancel, also
don't animate for 1 frame after cancel() is called
Change-Id: Ib660c0fb195b9f02bd795d03d43ea67bffebb499
---
libs/hwui/Animator.cpp | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/libs/hwui/Animator.cpp b/libs/hwui/Animator.cpp
index f3ef48b18edb2..d35dce92b600e 100644
--- a/libs/hwui/Animator.cpp
+++ b/libs/hwui/Animator.cpp
@@ -126,6 +126,9 @@ bool BaseRenderNodeAnimator::animate(TreeInfo& info) {
if (mPlayState < RUNNING) {
return false;
}
+ if (mPlayState == FINISHED) {
+ return true;
+ }
// If BaseRenderNodeAnimator is handling the delay (not typical), then
// because the staging properties reflect the final value, we always need
@@ -209,6 +212,10 @@ void RenderPropertyAnimator::onAttached() {
void RenderPropertyAnimator::onStagingPlayStateChanged() {
if (mStagingPlayState == RUNNING) {
(mTarget->mutateStagingProperties().*mPropertyAccess->setter)(finalValue());
+ } else if (mStagingPlayState == FINISHED) {
+ // We're being canceled, so make sure that whatever values the UI thread
+ // is observing for us is pushed over
+ mTarget->setPropertyFieldsDirty(dirtyMask());
}
}
From d15032df3f54e89ea36b033fd4d09b7324f518dd Mon Sep 17 00:00:00 2001
From: John Reck
Date: Tue, 8 Jul 2014 15:37:18 +0000
Subject: [PATCH 49/93] Revert "Fix destroyHardwareResources"
This reverts commit bac48c4d0c6f71f67074a430cd365ea2e15924b8.
Change-Id: Iba8b729d5e91ca31976fc2bdf9c1dd5fdb19de9a
---
core/java/android/view/ThreadedRenderer.java | 2 --
core/java/android/view/View.java | 4 +++-
libs/hwui/RenderNode.cpp | 9 ++-------
3 files changed, 5 insertions(+), 10 deletions(-)
diff --git a/core/java/android/view/ThreadedRenderer.java b/core/java/android/view/ThreadedRenderer.java
index fa4564ee7f08e..57d1bebe23a6b 100644
--- a/core/java/android/view/ThreadedRenderer.java
+++ b/core/java/android/view/ThreadedRenderer.java
@@ -127,8 +127,6 @@ public class ThreadedRenderer extends HardwareRenderer {
@Override
void destroyHardwareResources(View view) {
destroyResources(view);
- // mRootNode belongs to us and not a view, so we need to destroy it
- mRootNode.destroyDisplayListData();
nDestroyHardwareResources(mNativeProxy);
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 706fb1c55ede5..f1a0913dcdc0b 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -13625,7 +13625,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @hide
*/
protected void destroyHardwareResources() {
- resetDisplayList();
+ // Intentionally empty. RenderNode's lifecycle is now fully managed
+ // by the hardware renderer.
+ // However some subclasses (eg, WebView, TextureView) still need this signal
}
/**
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index 3cf625fc08eb9..89105ea19fbdf 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -211,8 +211,7 @@ void RenderNode::prepareTreeImpl(TreeInfo& info) {
// This will also release the hardware layer if we have one as
// isRenderable() will return false, thus causing pushLayerUpdate
// to recycle the hardware layer
- LOG_ALWAYS_FATAL_IF(mStagingDisplayListData || (mDisplayListData && !mNeedsDisplayListDataSync),
- "View.destroyHardwareResources wasn't called!");
+ setStagingDisplayList(NULL);
break;
}
@@ -261,11 +260,7 @@ void RenderNode::pushStagingDisplayListChanges(TreeInfo& info) {
mNeedsDisplayListDataSync = false;
// Do a push pass on the old tree to handle freeing DisplayListData
// that are no longer used
- TreeInfo::TraversalMode mode = TreeInfo::MODE_MAYBE_DETACHING;
- if (CC_UNLIKELY(info.mode == TreeInfo::MODE_DESTROY_RESOURCES)) {
- mode = TreeInfo::MODE_DESTROY_RESOURCES;
- }
- TreeInfo oldTreeInfo(mode, info);
+ TreeInfo oldTreeInfo(TreeInfo::MODE_MAYBE_DETACHING, info);
prepareSubTree(oldTreeInfo, mDisplayListData);
delete mDisplayListData;
mDisplayListData = mStagingDisplayListData;
From 43b800e1707e941a155bc8b03298e19f564f52b0 Mon Sep 17 00:00:00 2001
From: Jeff Sharkey
Date: Tue, 8 Jul 2014 08:59:49 -0700
Subject: [PATCH 50/93] Gracefully handle apps without native libraries.
Bug: 16148014
Change-Id: Ida23545046387b567744ee520baa4713e8403f30
---
core/java/com/android/internal/content/NativeLibraryHelper.java | 1 +
1 file changed, 1 insertion(+)
diff --git a/core/java/com/android/internal/content/NativeLibraryHelper.java b/core/java/com/android/internal/content/NativeLibraryHelper.java
index b4352f854c9e3..c39f1676b377a 100644
--- a/core/java/com/android/internal/content/NativeLibraryHelper.java
+++ b/core/java/com/android/internal/content/NativeLibraryHelper.java
@@ -189,6 +189,7 @@ public class NativeLibraryHelper {
// Convenience method to call removeNativeBinariesFromDirLI(File)
public static boolean removeNativeBinariesLI(String nativeLibraryPath) {
+ if (nativeLibraryPath == null) return false;
return removeNativeBinariesFromDirLI(new File(nativeLibraryPath));
}
From ffa0c9f1c2eb3b27642b732bfe2e3b15a6ddc531 Mon Sep 17 00:00:00 2001
From: Christopher Tate
Date: Tue, 8 Jul 2014 11:08:50 -0700
Subject: [PATCH 51/93] Fix NPE in platform restore
Bug 16061451
Change-Id: I79d7913455886828a493a0c4ea850d259bfeeeab
---
.../com/android/server/backup/BackupManagerService.java | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index b31a3d6d2c7ab..5bfde4dbaadbb 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -6537,10 +6537,10 @@ if (MORE_DEBUG) Slog.v(TAG, " + got " + nRead + "; now wanting " + (size - soF
}
// Pull the Package Manager metadata from the restore set first
- PackageInfo omPackage = new PackageInfo();
- omPackage.packageName = PACKAGE_MANAGER_SENTINEL;
+ mCurrentPackage = new PackageInfo();
+ mCurrentPackage.packageName = PACKAGE_MANAGER_SENTINEL;
mPmAgent = new PackageManagerBackupAgent(mPackageManager, null);
- initiateOneRestore(omPackage, 0,
+ initiateOneRestore(mCurrentPackage, 0,
IBackupAgent.Stub.asInterface(mPmAgent.onBind()));
// The PM agent called operationComplete() already, because our invocation
// of it is process-local and therefore synchronous. That means that a
From 495103c14c9aee738663b999a892dff9e7de8182 Mon Sep 17 00:00:00 2001
From: John Reck
Date: Tue, 8 Jul 2014 13:59:49 -0700
Subject: [PATCH 52/93] Fix layers lifecycle issues
Bug: 16118540
Fix an issue where we could have a reference to a Layer after
the GL context was destroyed
Change-Id: I7bfd909d735ca6b942ebe188fc10099422eb6d95
---
core/java/android/view/View.java | 8 ++-
libs/hwui/RenderNode.cpp | 80 ++++++++++++++++--------
libs/hwui/RenderNode.h | 14 +++++
libs/hwui/TreeInfo.h | 9 ---
libs/hwui/renderthread/CanvasContext.cpp | 3 +-
5 files changed, 74 insertions(+), 40 deletions(-)
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index f1a0913dcdc0b..1e5f448beaa87 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -13625,9 +13625,11 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @hide
*/
protected void destroyHardwareResources() {
- // Intentionally empty. RenderNode's lifecycle is now fully managed
- // by the hardware renderer.
- // However some subclasses (eg, WebView, TextureView) still need this signal
+ // Although the Layer will be destroyed by RenderNode, we want to release
+ // the staging display list, which is also a signal to RenderNode that it's
+ // safe to free its copy of the display list as it knows that we will
+ // push an updated DisplayList if we try to draw again
+ resetDisplayList();
}
/**
diff --git a/libs/hwui/RenderNode.cpp b/libs/hwui/RenderNode.cpp
index 89105ea19fbdf..fe03806903a58 100644
--- a/libs/hwui/RenderNode.cpp
+++ b/libs/hwui/RenderNode.cpp
@@ -63,11 +63,12 @@ RenderNode::RenderNode()
, mDisplayListData(0)
, mStagingDisplayListData(0)
, mAnimatorManager(*this)
- , mLayer(0) {
+ , mLayer(0)
+ , mParentCount(0) {
}
RenderNode::~RenderNode() {
- delete mDisplayListData;
+ deleteDisplayListData();
delete mStagingDisplayListData;
LayerRenderer::destroyLayerDeferred(mLayer);
}
@@ -196,27 +197,12 @@ void RenderNode::pushLayerUpdate(TreeInfo& info) {
void RenderNode::prepareTreeImpl(TreeInfo& info) {
info.damageAccumulator->pushTransform(this);
- switch (info.mode) {
- case TreeInfo::MODE_FULL:
+ if (info.mode == TreeInfo::MODE_FULL) {
pushStagingPropertiesChanges(info);
- mAnimatorManager.animate(info);
- break;
- case TreeInfo::MODE_MAYBE_DETACHING:
- pushStagingPropertiesChanges(info);
- break;
- case TreeInfo::MODE_RT_ONLY:
- mAnimatorManager.animate(info);
- break;
- case TreeInfo::MODE_DESTROY_RESOURCES:
- // This will also release the hardware layer if we have one as
- // isRenderable() will return false, thus causing pushLayerUpdate
- // to recycle the hardware layer
- setStagingDisplayList(NULL);
- break;
}
-
+ mAnimatorManager.animate(info);
prepareLayer(info);
- if (info.mode == TreeInfo::MODE_FULL || info.mode == TreeInfo::MODE_DESTROY_RESOURCES) {
+ if (info.mode == TreeInfo::MODE_FULL) {
pushStagingDisplayListChanges(info);
}
prepareSubTree(info, mDisplayListData);
@@ -258,17 +244,30 @@ void RenderNode::applyLayerPropertiesToLayer(TreeInfo& info) {
void RenderNode::pushStagingDisplayListChanges(TreeInfo& info) {
if (mNeedsDisplayListDataSync) {
mNeedsDisplayListDataSync = false;
- // Do a push pass on the old tree to handle freeing DisplayListData
- // that are no longer used
- TreeInfo oldTreeInfo(TreeInfo::MODE_MAYBE_DETACHING, info);
- prepareSubTree(oldTreeInfo, mDisplayListData);
- delete mDisplayListData;
+ // Make sure we inc first so that we don't fluctuate between 0 and 1,
+ // which would thrash the layer cache
+ if (mStagingDisplayListData) {
+ for (size_t i = 0; i < mStagingDisplayListData->children().size(); i++) {
+ mStagingDisplayListData->children()[i]->mRenderNode->incParentRefCount();
+ }
+ }
+ deleteDisplayListData();
mDisplayListData = mStagingDisplayListData;
- mStagingDisplayListData = 0;
+ mStagingDisplayListData = NULL;
damageSelf(info);
}
}
+void RenderNode::deleteDisplayListData() {
+ if (mDisplayListData) {
+ for (size_t i = 0; i < mDisplayListData->children().size(); i++) {
+ mDisplayListData->children()[i]->mRenderNode->decParentRefCount();
+ }
+ }
+ delete mDisplayListData;
+ mDisplayListData = NULL;
+}
+
void RenderNode::prepareSubTree(TreeInfo& info, DisplayListData* subtree) {
if (subtree) {
TextureCache& cache = Caches::getInstance().textureCache;
@@ -291,6 +290,35 @@ void RenderNode::prepareSubTree(TreeInfo& info, DisplayListData* subtree) {
}
}
+void RenderNode::destroyHardwareResources() {
+ if (mLayer) {
+ LayerRenderer::destroyLayer(mLayer);
+ mLayer = NULL;
+ }
+ if (mDisplayListData) {
+ for (size_t i = 0; i < mDisplayListData->children().size(); i++) {
+ mDisplayListData->children()[i]->mRenderNode->destroyHardwareResources();
+ }
+ if (mNeedsDisplayListDataSync) {
+ // Next prepare tree we are going to push a new display list, so we can
+ // drop our current one now
+ deleteDisplayListData();
+ }
+ }
+}
+
+void RenderNode::decParentRefCount() {
+ LOG_ALWAYS_FATAL_IF(!mParentCount, "already 0!");
+ mParentCount--;
+ if (!mParentCount) {
+ // If a child of ours is being attached to our parent then this will incorrectly
+ // destroy its hardware resources. However, this situation is highly unlikely
+ // and the failure is "just" that the layer is re-created, so this should
+ // be safe enough
+ destroyHardwareResources();
+ }
+}
+
/*
* For property operations, we pass a savecount of 0, since the operations aren't part of the
* displaylist, and thus don't have to compensate for the record-time/playback-time discrepancy in
diff --git a/libs/hwui/RenderNode.h b/libs/hwui/RenderNode.h
index 7d42b59054adb..54fa143f9aa8d 100644
--- a/libs/hwui/RenderNode.h
+++ b/libs/hwui/RenderNode.h
@@ -168,6 +168,7 @@ public:
}
ANDROID_API virtual void prepareTree(TreeInfo& info);
+ void destroyHardwareResources();
// UI thread only!
ANDROID_API void addAnimator(const sp& animator);
@@ -248,6 +249,10 @@ private:
void applyLayerPropertiesToLayer(TreeInfo& info);
void prepareLayer(TreeInfo& info);
void pushLayerUpdate(TreeInfo& info);
+ void deleteDisplayListData();
+
+ void incParentRefCount() { mParentCount++; }
+ void decParentRefCount();
String8 mName;
@@ -256,6 +261,7 @@ private:
RenderProperties mStagingProperties;
bool mNeedsDisplayListDataSync;
+ // WARNING: Do not delete this directly, you must go through deleteDisplayListData()!
DisplayListData* mDisplayListData;
DisplayListData* mStagingDisplayListData;
@@ -272,6 +278,14 @@ private:
// for projection surfaces, contains a list of all children items
Vector mProjectedNodes;
+
+ // How many references our parent(s) have to us. Typically this should alternate
+ // between 2 and 1 (when a staging push happens we inc first then dec)
+ // When this hits 0 we are no longer in the tree, so any hardware resources
+ // (specifically Layers) should be released.
+ // This is *NOT* thread-safe, and should therefore only be tracking
+ // mDisplayListData, not mStagingDisplayListData.
+ uint32_t mParentCount;
}; // class RenderNode
} /* namespace uirenderer */
diff --git a/libs/hwui/TreeInfo.h b/libs/hwui/TreeInfo.h
index 9746ac53906e4..de09755803b6b 100644
--- a/libs/hwui/TreeInfo.h
+++ b/libs/hwui/TreeInfo.h
@@ -58,15 +58,6 @@ public:
// animators, but potentially things like SurfaceTexture updates
// could be handled by this as well if there are no listeners
MODE_RT_ONLY,
- // The subtree is being detached. Maybe. If the RenderNode is present
- // in both the old and new display list's children then it will get a
- // MODE_MAYBE_DETACHING followed shortly by a MODE_FULL.
- // Push any pending display list changes in case it is detached,
- // but don't evaluate animators and such as if it isn't detached as a
- // MODE_FULL will follow shortly.
- MODE_MAYBE_DETACHING,
- // Destroy all hardware resources, including DisplayListData, in the tree.
- MODE_DESTROY_RESOURCES,
};
explicit TreeInfo(TraversalMode mode, RenderState& renderState)
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index f5d4f8bc954ce..57279b778d92b 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -250,8 +250,7 @@ void CanvasContext::destroyHardwareResources() {
stopDrawing();
if (mEglManager.hasEglContext()) {
requireGlContext();
- TreeInfo info(TreeInfo::MODE_DESTROY_RESOURCES, mRenderThread.renderState());
- mRootRenderNode->prepareTree(info);
+ mRootRenderNode->destroyHardwareResources();
Caches::getInstance().flush(Caches::kFlushMode_Layers);
}
}
From 9c3ac3d3bafe9ada1127a6864031460af14219ed Mon Sep 17 00:00:00 2001
From: Jeff Sharkey
Date: Tue, 8 Jul 2014 14:57:34 -0700
Subject: [PATCH 53/93] Derive library path for upgraded system apps.
Bug: 16156270
Change-Id: I368433063ff33d15129c8076ddc6f1e2a0963e54
---
.../internal/content/NativeLibraryHelper.java | 10 +++++-
.../server/pm/PackageManagerService.java | 32 ++++++++++++++++---
2 files changed, 36 insertions(+), 6 deletions(-)
diff --git a/core/java/com/android/internal/content/NativeLibraryHelper.java b/core/java/com/android/internal/content/NativeLibraryHelper.java
index c39f1676b377a..d66a7bbf8f3e3 100644
--- a/core/java/com/android/internal/content/NativeLibraryHelper.java
+++ b/core/java/com/android/internal/content/NativeLibraryHelper.java
@@ -22,6 +22,7 @@ import static android.content.pm.PackageManager.NO_NATIVE_LIBRARIES;
import android.content.pm.PackageManager;
import android.content.pm.PackageParser;
+import android.content.pm.PackageParser.Package;
import android.content.pm.PackageParser.PackageLite;
import android.content.pm.PackageParser.PackageParserException;
import android.util.Slog;
@@ -65,8 +66,15 @@ public class NativeLibraryHelper {
}
}
+ public static Handle create(Package pkg) throws IOException {
+ return create(pkg.getAllCodePaths());
+ }
+
public static Handle create(PackageLite lite) throws IOException {
- final List codePaths = lite.getAllCodePaths();
+ return create(lite.getAllCodePaths());
+ }
+
+ private static Handle create(List codePaths) throws IOException {
final int size = codePaths.size();
final long[] apkHandles = new long[size];
for (int i = 0; i < size; i++) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 016d612e9dd06..b65cf722c2f0a 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -6148,7 +6148,8 @@ public class PackageManagerService extends IPackageManager.Stub {
final boolean bundledApk = isSystemApp(pkg) && !isUpdatedSystemApp(pkg);
final File codeFile = new File(pkg.applicationInfo.getCodePath());
final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
- final String nativeLibraryPath;
+
+ String nativeLibraryPath = null;
if (bundledApk) {
// If "/system/lib64/apkname" exists, assume that is the per-package
// native library directory to use; otherwise use "/system/lib/apkname".
@@ -6158,9 +6159,29 @@ public class PackageManagerService extends IPackageManager.Stub {
File libDir = (packLib64.exists()) ? lib64 : new File(apkRoot, LIB_DIR_NAME);
nativeLibraryPath = (new File(libDir, apkName)).getAbsolutePath();
} else {
- // We're installing an upgrade; use directory found during scan
- // TODO: consider deriving this based on instructionSet
- nativeLibraryPath = pkg.applicationInfo.nativeLibraryDir;
+ // Upgraded system app; derive its library path by inspecting.
+ // TODO: pipe through abiOverride
+ String[] abiList = Build.SUPPORTED_ABIS;
+ NativeLibraryHelper.Handle handle = null;
+ try {
+ handle = NativeLibraryHelper.Handle.create(codeFile);
+ if (Build.SUPPORTED_64_BIT_ABIS.length > 0 &&
+ NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
+ abiList = Build.SUPPORTED_32_BIT_ABIS;
+ }
+
+ final int abiIndex = NativeLibraryHelper.findSupportedAbi(handle, abiList);
+ if (abiIndex >= 0) {
+ final File baseLibFile = new File(codeFile, LIB_DIR_NAME);
+ final String abi = Build.SUPPORTED_ABIS[abiIndex];
+ final String instructionSet = VMRuntime.getInstructionSet(abi);
+ nativeLibraryPath = new File(baseLibFile, instructionSet).getAbsolutePath();
+ }
+ } catch (IOException e) {
+ Slog.e(TAG, "Failed to detect native libraries", e);
+ } finally {
+ IoUtils.closeQuietly(handle);
+ }
}
pkg.applicationInfo.nativeLibraryDir = nativeLibraryPath;
// pkgSetting might be null during rescan following uninstall of updates
@@ -9086,7 +9107,8 @@ public class PackageManagerService extends IPackageManager.Stub {
// Example topology:
// /data/app/com.example/base.apk
// /data/app/com.example/split_foo.apk
- // /data/app/com.example/native/arm/libfoo.so
+ // /data/app/com.example/lib/arm/libfoo.so
+ // /data/app/com.example/lib/arm64/libfoo.so
// /data/app/com.example/dalvik/arm/base.apk@classes.dex
/** New install */
From f6f703f110328d3f10496f0b6756336742790235 Mon Sep 17 00:00:00 2001
From: John Spurlock
Date: Wed, 9 Jul 2014 14:26:00 -0400
Subject: [PATCH 54/93] Defer opening a stats session until first use.
Bug:16174801
Change-Id: Ia70f9a01bd348809db4ab2992e5e1265778cfcfa
---
.../policy/MobileDataController.java | 19 +++++++++++++------
1 file changed, 13 insertions(+), 6 deletions(-)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileDataController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileDataController.java
index ac9d807ad9ced..f2dfe05899e74 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileDataController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileDataController.java
@@ -63,13 +63,19 @@ public class MobileDataController {
mStatsService = INetworkStatsService.Stub.asInterface(
ServiceManager.getService(Context.NETWORK_STATS_SERVICE));
mPolicyManager = NetworkPolicyManager.from(mContext);
+ }
- try {
- mSession = mStatsService.openSession();
- } catch (RemoteException e) {
- Log.w(TAG, "Failed to open stats session");
- mSession = null;
+ private INetworkStatsSession getSession() {
+ if (mSession == null) {
+ try {
+ mSession = mStatsService.openSession();
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed to open stats session", e);
+ } catch (RuntimeException e) {
+ Log.w(TAG, "Failed to open stats session", e);
+ }
}
+ return mSession;
}
public void setCallback(Callback callback) {
@@ -86,7 +92,8 @@ public class MobileDataController {
if (subscriberId == null) {
return warn("no subscriber id");
}
- if (mSession == null) {
+ final INetworkStatsSession session = getSession();
+ if (session == null) {
return warn("no stats session");
}
final NetworkTemplate template = NetworkTemplate.buildTemplateMobileAll(subscriberId);
From cce69855c29c07861da18a58059e1a317884e14f Mon Sep 17 00:00:00 2001
From: Jeff Sharkey
Date: Wed, 9 Jul 2014 13:10:55 -0700
Subject: [PATCH 55/93] Upgraded system apps could be mono or cluster.
Derive old-style paths for monolithic installations, otherwise
assume cluster installation.
Bug: 16163776
Change-Id: I03f1a12f9c07f6177a5c09be2bfe967416c07652
---
.../java/com/android/server/pm/PackageManagerService.java | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 27c008c500eab..0e1fd05dda138 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -6151,8 +6151,11 @@ public class PackageManagerService extends IPackageManager.Stub {
File packLib64 = new File(lib64, apkName);
File libDir = (packLib64.exists()) ? lib64 : new File(apkRoot, LIB_DIR_NAME);
nativeLibraryPath = (new File(libDir, apkName)).getAbsolutePath();
+ } else if (isApkFile(codeFile)) {
+ // Monolithic install
+ nativeLibraryPath = (new File(mAppLibInstallDir, apkName)).getAbsolutePath();
} else {
- // Upgraded system app; derive its library path by inspecting.
+ // Cluster install
// TODO: pipe through abiOverride
String[] abiList = Build.SUPPORTED_ABIS;
NativeLibraryHelper.Handle handle = null;
From 183cce95a9331c216438bf13d720a314e079df01 Mon Sep 17 00:00:00 2001
From: John Spurlock
Date: Thu, 10 Jul 2014 09:39:04 -0400
Subject: [PATCH 56/93] Volume: allow dialog to play sound over keyguard.
Now that we are allowing the volume dialog above the keyguard,
the old suppression rule does not apply.
Bug:16186697
Change-Id: I071f1a2856850218e267d1fbaf547db44b644382
---
media/java/android/media/AudioService.java | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index f262390ae3e85..7316e14fc6a2e 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -850,11 +850,10 @@ public class AudioService extends IAudioService.Stub {
streamType = getActiveStreamType(suggestedStreamType);
}
- // Play sounds on STREAM_RING only and if lock screen is not on.
+ // Play sounds on STREAM_RING and STREAM_REMOTE_MUSIC only.
if ((streamType != STREAM_REMOTE_MUSIC) &&
(flags & AudioManager.FLAG_PLAY_SOUND) != 0 &&
- ((mStreamVolumeAlias[streamType] != AudioSystem.STREAM_RING)
- || (mKeyguardManager != null && mKeyguardManager.isKeyguardLocked()))) {
+ (mStreamVolumeAlias[streamType] != AudioSystem.STREAM_RING)) {
flags &= ~AudioManager.FLAG_PLAY_SOUND;
}
From 9eaa4e1f1342fc7ce952e4e021a055c47d78381b Mon Sep 17 00:00:00 2001
From: Santos Cordon
Date: Thu, 10 Jul 2014 10:35:07 -0700
Subject: [PATCH 57/93] Dynamically obtain telecomm service from
PhoneManager.java
Bug: 16206418
Change-Id: Ie8845f4baf8956d03fcaf26cb899f5fb056df6cc
---
core/java/android/app/ContextImpl.java | 4 +-
phone/java/android/phone/PhoneManager.java | 54 ++++++++++++++--------
2 files changed, 35 insertions(+), 23 deletions(-)
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index cacb2dfad83a2..bbfb05e12eccd 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -565,9 +565,7 @@ class ContextImpl extends Context {
registerService(PHONE_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
- IBinder b = ServiceManager.getService(TELECOMM_SERVICE);
- return new PhoneManager(ctx.getOuterContext(),
- ITelecommService.Stub.asInterface(b));
+ return new PhoneManager(ctx.getOuterContext());
}});
registerService(UI_MODE_SERVICE, new ServiceFetcher() {
diff --git a/phone/java/android/phone/PhoneManager.java b/phone/java/android/phone/PhoneManager.java
index 360565e0634cf..d5f20532dae3a 100644
--- a/phone/java/android/phone/PhoneManager.java
+++ b/phone/java/android/phone/PhoneManager.java
@@ -30,20 +30,17 @@ public final class PhoneManager {
private static final String TAG = PhoneManager.class.getSimpleName();
private final Context mContext;
- private final ITelecommService mService;
/**
* @hide
*/
- public PhoneManager(Context context, ITelecommService service) {
+ public PhoneManager(Context context) {
Context appContext = context.getApplicationContext();
if (appContext != null) {
mContext = appContext;
} else {
mContext = context;
}
-
- mService = service;
}
/**
@@ -56,10 +53,13 @@ public final class PhoneManager {
* @return True if the digits were processed as an MMI code, false otherwise.
*/
public boolean handlePinMmi(String dialString) {
- try {
- return mService.handlePinMmi(dialString);
- } catch (RemoteException e) {
- Log.e(TAG, "Error calling ITelecommService#handlePinMmi", e);
+ ITelecommService service = getTelecommService();
+ if (service != null) {
+ try {
+ return service.handlePinMmi(dialString);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling ITelecommService()#handlePinMmi", e);
+ }
}
return false;
}
@@ -71,10 +71,13 @@ public final class PhoneManager {
*
*/
public void cancelMissedCallsNotification() {
- try {
- mService.cancelMissedCallsNotification();
- } catch (RemoteException e) {
- Log.e(TAG, "Error calling ITelecommService#cancelMissedCallNotification", e);
+ ITelecommService service = getTelecommService();
+ if (service != null) {
+ try {
+ service.cancelMissedCallsNotification();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling ITelecommService()#cancelMissedCallNotification", e);
+ }
}
}
@@ -89,10 +92,13 @@ public final class PhoneManager {
* @param showDialpad Brings up the in-call dialpad as part of showing the in-call screen.
*/
public void showCallScreen(boolean showDialpad) {
- try {
- mService.showCallScreen(showDialpad);
- } catch (RemoteException e) {
- Log.e(TAG, "Error calling ITelecommService#showCallScreen", e);
+ ITelecommService service = getTelecommService();
+ if (service != null) {
+ try {
+ service.showCallScreen(showDialpad);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling ITelecommService()#showCallScreen", e);
+ }
}
}
@@ -103,11 +109,19 @@ public final class PhoneManager {
*
*/
public boolean isInAPhoneCall() {
- try {
- return mService.isInAPhoneCall();
- } catch (RemoteException e) {
- Log.e(TAG, "Error caling ITelecommService#isInAPhoneCall", e);
+ ITelecommService service = getTelecommService();
+ if (service != null) {
+ try {
+ return service.isInAPhoneCall();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error caling ITelecommService()#isInAPhoneCall", e);
+ }
}
return false;
}
+
+ private ITelecommService getTelecommService() {
+ return ITelecommService.Stub.asInterface(
+ ServiceManager.getService(Context.TELECOMM_SERVICE));
+ }
}
From fbfb3ac14a5794efd8cdb9fe88f8738e654d7b53 Mon Sep 17 00:00:00 2001
From: Wink Saville
Date: Thu, 10 Jul 2014 13:01:52 -0700
Subject: [PATCH 58/93] Ignore hasService in updateTelephonySignalStrength
A possible reason for empty triangle is there is no service, I'm
temporarily ignoring hasService in updateTelphonySignalStrength and
adding more debug.
Add logSSC to see history of Service State Changes.
Bug: 16148026
Change-Id: Ia463997eac7b062653b3cef00570d3fffc115ad3
---
.../policy/NetworkControllerImpl.java | 41 ++++++-----
.../com/android/server/TelephonyRegistry.java | 73 +++++++++++++++++--
2 files changed, 92 insertions(+), 22 deletions(-)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index 799b41fd6360f..2b089022b0ae4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -34,6 +34,7 @@ import android.os.Message;
import android.os.Messenger;
import android.provider.Settings;
import android.telephony.PhoneStateListener;
+import android.telephony.Rlog;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.TelephonyManager;
@@ -474,8 +475,8 @@ public class NetworkControllerImpl extends BroadcastReceiver
PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
@Override
public void onSignalStrengthsChanged(SignalStrength signalStrength) {
- if (DEBUG) {
- Log.d(TAG, "onSignalStrengthsChanged signalStrength=" + signalStrength +
+ if (true/*DEBUG*/) {
+ Rlog.d(TAG, "onSignalStrengthsChanged signalStrength=" + signalStrength +
((signalStrength == null) ? "" : (" level=" + signalStrength.getLevel())));
}
mSignalStrength = signalStrength;
@@ -485,8 +486,8 @@ public class NetworkControllerImpl extends BroadcastReceiver
@Override
public void onServiceStateChanged(ServiceState state) {
- if (DEBUG) {
- Log.d(TAG, "onServiceStateChanged voiceState=" + state.getVoiceRegState()
+ if (true/*DEBUG*/) {
+ Rlog.d(TAG, "onServiceStateChanged voiceState=" + state.getVoiceRegState()
+ " dataState=" + state.getDataRegState());
}
mServiceState = state;
@@ -498,8 +499,8 @@ public class NetworkControllerImpl extends BroadcastReceiver
@Override
public void onCallStateChanged(int state, String incomingNumber) {
- if (DEBUG) {
- Log.d(TAG, "onCallStateChanged state=" + state);
+ if (true/*DEBUG*/) {
+ Rlog.d(TAG, "onCallStateChanged state=" + state);
}
// In cdma, if a voice call is made, RSSI should switch to 1x.
if (isCdma()) {
@@ -510,8 +511,8 @@ public class NetworkControllerImpl extends BroadcastReceiver
@Override
public void onDataConnectionStateChanged(int state, int networkType) {
- if (DEBUG) {
- Log.d(TAG, "onDataConnectionStateChanged: state=" + state
+ if (true/*DEBUG*/) {
+ Rlog.d(TAG, "onDataConnectionStateChanged: state=" + state
+ " type=" + networkType);
}
mDataState = state;
@@ -523,8 +524,8 @@ public class NetworkControllerImpl extends BroadcastReceiver
@Override
public void onDataActivity(int direction) {
- if (DEBUG) {
- Log.d(TAG, "onDataActivity: direction=" + direction);
+ if (true/*DEBUG*/) {
+ Rlog.d(TAG, "onDataActivity: direction=" + direction);
}
mDataActivity = direction;
updateDataIcon();
@@ -555,6 +556,7 @@ public class NetworkControllerImpl extends BroadcastReceiver
} else {
mSimState = IccCardConstants.State.UNKNOWN;
}
+ Rlog.d(TAG, "updateSimState: mSimState=" + mSimState);
}
private boolean isCdma() {
@@ -562,6 +564,7 @@ public class NetworkControllerImpl extends BroadcastReceiver
}
private boolean hasService() {
+ boolean retVal;
if (mServiceState != null) {
// Consider the device to be in service if either voice or data service is available.
// Some SIM cards are marketed as data-only and do not support voice service, and on
@@ -569,16 +572,18 @@ public class NetworkControllerImpl extends BroadcastReceiver
// service" or "emergency calls only" text that indicates that voice is not available.
switch(mServiceState.getVoiceRegState()) {
case ServiceState.STATE_POWER_OFF:
- return false;
+ retVal = false;
case ServiceState.STATE_OUT_OF_SERVICE:
case ServiceState.STATE_EMERGENCY_ONLY:
- return mServiceState.getDataRegState() == ServiceState.STATE_IN_SERVICE;
+ retVal = mServiceState.getDataRegState() == ServiceState.STATE_IN_SERVICE;
default:
- return true;
+ retVal = true;
}
} else {
- return false;
+ retVal = false;
}
+ Rlog.d(TAG, "hasService: mServiceState=" + mServiceState + " retVal=" + retVal);
+ return retVal;
}
private void updateAirplaneMode() {
@@ -591,14 +596,15 @@ public class NetworkControllerImpl extends BroadcastReceiver
}
private final void updateTelephonySignalStrength() {
- if (!hasService()) {
+ Rlog.d(TAG, "updateTelephonySignalStrength: hasService=" + hasService() + " ss=" + mSignalStrength);
+ if (false/*!hasService()*/) {
if (CHATTY) Log.d(TAG, "updateTelephonySignalStrength: !hasService()");
mPhoneSignalIconId = R.drawable.stat_sys_signal_null;
mQSPhoneSignalIconId = R.drawable.ic_qs_signal_no_signal;
mDataSignalIconId = R.drawable.stat_sys_signal_null;
} else {
if (mSignalStrength == null) {
- if (CHATTY) Log.d(TAG, "updateTelephonySignalStrength: mSignalStrength == null");
+ if (true/*CHATTY*/) Rlog.d(TAG, "updateTelephonySignalStrength: mSignalStrength == null");
mPhoneSignalIconId = R.drawable.stat_sys_signal_null;
mQSPhoneSignalIconId = R.drawable.ic_qs_signal_no_signal;
mDataSignalIconId = R.drawable.stat_sys_signal_null;
@@ -609,7 +615,7 @@ public class NetworkControllerImpl extends BroadcastReceiver
int[] iconList;
if (isCdma() && mAlwaysShowCdmaRssi) {
mLastSignalLevel = iconLevel = mSignalStrength.getCdmaLevel();
- if(DEBUG) Log.d(TAG, "mAlwaysShowCdmaRssi=" + mAlwaysShowCdmaRssi
+ if(true/*DEBUG*/) Rlog.d(TAG, "updateTelephonySignalStrength: mAlwaysShowCdmaRssi=" + mAlwaysShowCdmaRssi
+ " set to cdmaLevel=" + mSignalStrength.getCdmaLevel()
+ " instead of level=" + mSignalStrength.getLevel());
} else {
@@ -636,6 +642,7 @@ public class NetworkControllerImpl extends BroadcastReceiver
mContentDescriptionPhoneSignal = mContext.getString(
AccessibilityContentDescriptions.PHONE_SIGNAL_STRENGTH[iconLevel]);
mDataSignalIconId = TelephonyIcons.DATA_SIGNAL_STRENGTH[mInetCondition][iconLevel];
+ Rlog.d(TAG, "updateTelephonySignalStrength: iconLevel=" + iconLevel);
}
}
}
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 88598c9cc5330..a19eb151a6c34 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -47,8 +47,10 @@ import android.telephony.PreciseCallState;
import android.telephony.PreciseDataConnectionState;
import android.telephony.PreciseDisconnectCause;
import android.text.TextUtils;
+import android.text.format.Time;
import java.util.ArrayList;
+import java.util.Calendar;
import java.util.List;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -354,10 +356,12 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
}
int phoneId = SubscriptionManager.getPhoneId(subId);
r.events = events;
- if (true/*DBG*/) log("listen: set events record=" + r);
+ if (true/*DBG*/) log("listen: set events record=" + r + " subId=" + subId + " phoneId=" + phoneId);
+ toStringLogSSC("listen");
if (notifyNow && validatePhoneId(phoneId)) {
if ((events & PhoneStateListener.LISTEN_SERVICE_STATE) != 0) {
try {
+ log("listen: call onSSC state=" + mServiceState[phoneId]);
r.callback.onServiceStateChanged(
new ServiceState(mServiceState[phoneId]));
} catch (RemoteException ex) {
@@ -550,14 +554,17 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
subId = mDefaultSubId;
log("notifyServiceStateUsingSubId: using mDefaultSubId=" + mDefaultSubId);
}
- if (true/*VDBG*/) {
- log("notifyServiceStateUsingSubId: subId=" + subId
- + " state=" + state);
- }
synchronized (mRecords) {
int phoneId = SubscriptionManager.getPhoneId(subId);
+ if (true/*VDBG*/) {
+ log("notifyServiceStateUsingSubId: subId=" + subId + " phoneId=" + phoneId
+ + " state=" + state);
+ }
if (validatePhoneId(phoneId)) {
mServiceState[phoneId] = state;
+ logServiceStateChanged("notifyServiceStateUsingSubId", subId, phoneId, state);
+ toStringLogSSC("notifyServiceStateUsingSubId");
+
for (Record r : mRecords) {
log("notifyServiceStateUsingSubId: r.events=0x" + Integer.toHexString(r.events) + " r.subId=" + r.subId + " subId=" + subId + " state=" + state);
// FIXME: use DEFAULT_SUB_ID instead??
@@ -591,6 +598,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
if (true/*VDBG*/) {
log("notifySignalStrengthUsingSubId: subId=" + subId
+ " signalStrength=" + signalStrength);
+ toStringLogSSC("notifySignalStrengthUsingSubId");
}
synchronized (mRecords) {
int phoneId = SubscriptionManager.getPhoneId(subId);
@@ -1295,4 +1303,59 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
private static void log(String s) {
Rlog.d(TAG, s);
}
+
+ private static class LogSSC {
+ private Time mTime;
+ private String mS;
+ private long mSubId;
+ private int mPhoneId;
+ private ServiceState mState;
+
+ public void set(Time t, String s, long subId, int phoneId, ServiceState state) {
+ mTime = t; mS = s; mSubId = subId; mPhoneId = phoneId; mState = state;
+ }
+
+ @Override
+ public String toString() {
+ return mS + " " + mTime.toString() + " " + mSubId + " " + mPhoneId + " " + mState;
+ }
+ }
+
+ private LogSSC logSSC [] = new LogSSC[10];
+ private int next = 0;
+
+ private void logServiceStateChanged(String s, long subId, int phoneId, ServiceState state) {
+ if (logSSC == null || logSSC.length == 0) {
+ return;
+ }
+ if (logSSC[next] == null) {
+ logSSC[next] = new LogSSC();
+ }
+ Time t = new Time();
+ t.setToNow();
+ logSSC[next].set(t, s, subId, phoneId, state);
+ if (++next >= logSSC.length) {
+ next = 0;
+ }
+ }
+
+ private void toStringLogSSC(String prompt) {
+ if (logSSC == null || logSSC.length == 0 || (next == 0 && logSSC[next] == null)) {
+ log(prompt + ": logSSC is empty");
+ } else {
+ // There is at least one element
+ log(prompt + ": logSSC.length=" + logSSC.length + " next=" + next);
+ int i = next;
+ if (logSSC[i] == null) {
+ // logSSC is not full so back to the beginning
+ i = 0;
+ }
+ do {
+ log(logSSC[i].toString());
+ if (++i >= logSSC.length) {
+ i = 0;
+ }
+ } while (i != next);
+ }
+ }
}
From 18b8cd6c3bc8678b5ed70cf8d8f95c15872abf9f Mon Sep 17 00:00:00 2001
From: Svetoslav
Date: Thu, 10 Jul 2014 17:36:27 -0700
Subject: [PATCH 59/93] Fix print document with zero pages backwards
compatibility.
Historically, we were allowing an app that prints to specify that
the printed document has zero pages. While this does not make any
sense we should keep the behavior as people may have apps that do
that. This change fixes this issue and now we treat zero the same
way as undefined page count and ask the app to write all pages to
check the written PDF for the page count.
bug:16199127
Change-Id: I4e7de66b669e9f783db0252244a6c1e5b24ffe28
---
core/java/android/print/PrintDocumentInfo.java | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/core/java/android/print/PrintDocumentInfo.java b/core/java/android/print/PrintDocumentInfo.java
index 928be6cae90ad..e4e753e6043a5 100644
--- a/core/java/android/print/PrintDocumentInfo.java
+++ b/core/java/android/print/PrintDocumentInfo.java
@@ -308,7 +308,7 @@ public final class PrintDocumentInfo implements Parcelable {
public Builder setPageCount(int pageCount) {
if (pageCount < 0 && pageCount != PAGE_COUNT_UNKNOWN) {
throw new IllegalArgumentException("pageCount"
- + " must be greater than or euqal to zero or"
+ + " must be greater than or equal to zero or"
+ " DocumentInfo#PAGE_COUNT_UNKNOWN");
}
mPrototype.mPageCount = pageCount;
@@ -338,6 +338,12 @@ public final class PrintDocumentInfo implements Parcelable {
* @return The new instance.
*/
public PrintDocumentInfo build() {
+ // Zero pages is the same as unknown as in this case
+ // we will have to ask for all pages and look a the
+ // wiritten PDF file for the page count.
+ if (mPrototype.mPageCount == 0) {
+ mPrototype.mPageCount = PAGE_COUNT_UNKNOWN;
+ }
return new PrintDocumentInfo(mPrototype);
}
}
From 298cb0e374bbddbc53f7d386671979c7441a233d Mon Sep 17 00:00:00 2001
From: Paul Lawrence
Date: Tue, 6 Jan 2015 13:11:23 -0800
Subject: [PATCH 60/93] Fix crash caused by toHex returning exception
toHex was changed to throw an exception in
I4986a8e806d9066129f696ab9f2e80655424e723, but its caller was not adjusted
accordingly, causing a crash whenever an unencrypted device was booted.
Bug: 18886749
Change-Id: If0505f617001cf5e0d99cf14c8b09e6a6a377167
---
services/core/java/com/android/server/MountService.java | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/services/core/java/com/android/server/MountService.java b/services/core/java/com/android/server/MountService.java
index 7d6ebaf5bac8d..9eb70d8fdfeec 100644
--- a/services/core/java/com/android/server/MountService.java
+++ b/services/core/java/com/android/server/MountService.java
@@ -2419,9 +2419,16 @@ class MountService extends IMountService.Stub
final NativeDaemonEvent event;
try {
event = mConnector.execute("cryptfs", "getpw");
+ if ("-1".equals(event.getMessage())) {
+ // -1 equals no password
+ return null;
+ }
return fromHex(event.getMessage());
} catch (NativeDaemonConnectorException e) {
throw e.rethrowAsParcelableException();
+ } catch (IllegalArgumentException e) {
+ Slog.e(TAG, "Invalid response to getPassword");
+ return null;
}
}
From 4607e177a8f979f2e714460926ac125b2c728447 Mon Sep 17 00:00:00 2001
From: Svetoslav
Date: Thu, 12 Feb 2015 11:30:36 -0800
Subject: [PATCH 61/93] Fix a reversed condition in the next alarm validator
bug:19361375
Change-Id: Ib5ac90503842aafd994423632fd1f463e49088a0
---
core/java/android/provider/Settings.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 7b3ecebec0ba7..c836a331ba202 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -2098,7 +2098,7 @@ public final class Settings {
@Override
public boolean validate(String value) {
// TODO: No idea what the correct format is.
- return value == null || value.length() > MAX_LENGTH;
+ return value == null || value.length() < MAX_LENGTH;
}
};
From d216c7639fa6bd8accfa0b52ab22a65ddbaf7d1c Mon Sep 17 00:00:00 2001
From: Svetoslav
Date: Thu, 12 Feb 2015 14:11:42 -0800
Subject: [PATCH 62/93] Handle a missed case in query the settings provider
bug:19361521
Change-Id: Ibf4731b5d665563bb87ef93a4cf63e4c4d2e46a4
---
.../providers/settings/SettingsProvider.java | 36 +++++++++++--------
.../providers/settings/SettingsState.java | 3 +-
.../settings/BaseSettingsProviderTest.java | 21 ++++++++---
.../settings/SettingsProviderTest.java | 24 ++++++++++++-
4 files changed, 62 insertions(+), 22 deletions(-)
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index ff2c004e06114..5aac06d93542e 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -1228,6 +1228,7 @@ public class SettingsProvider extends ContentProvider {
&& whereArgs.length == 1) {
name = whereArgs[0];
table = computeTableForSetting(uri, name);
+ return;
} else if (where != null
&& (WHERE_PATTERN_NO_PARAM_NO_BRACKETS.matcher(where).matches()
|| WHERE_PATTERN_NO_PARAM_IN_BRACKETS.matcher(where).matches())) {
@@ -1237,30 +1238,35 @@ public class SettingsProvider extends ContentProvider {
where.lastIndexOf("\""));
name = where.substring(startIndex, endIndex);
table = computeTableForSetting(uri, name);
+ return;
} else if (supportAll && where == null && whereArgs == null) {
name = null;
table = computeTableForSetting(uri, null);
- } else if (uri.getPathSegments().size() == 2
- && where == null && whereArgs == null) {
- name = uri.getPathSegments().get(1);
- table = computeTableForSetting(uri, name);
- } else {
- EventLogTags.writeUnsupportedSettingsQuery(
- uri.toSafeString(), where, Arrays.toString(whereArgs));
- throw new IllegalArgumentException("Only null where and args"
- + " or name=? where and a single arg or name='SOME_SETTING' "
- + "are supported uri: " + uri + " where: " + where + " args: "
- + Arrays.toString(whereArgs));
+ return;
}
} break;
- default: {
- throw new IllegalArgumentException("Invalid URI: " + uri);
- }
+ case 2: {
+ if (where == null && whereArgs == null) {
+ name = uri.getPathSegments().get(1);
+ table = computeTableForSetting(uri, name);
+ return;
+ }
+ } break;
}
+
+ EventLogTags.writeUnsupportedSettingsQuery(
+ uri.toSafeString(), where, Arrays.toString(whereArgs));
+ String message = String.format( "Supported SQL:\n"
+ + " uri content://some_table/some_property with null where and where args\n"
+ + " uri content://some_table with query name=? and single name as arg\n"
+ + " uri content://some_table with query name=some_name and null args\n"
+ + " but got - uri:%1s, where:%2s whereArgs:%3s", uri, where,
+ Arrays.toString(whereArgs));
+ throw new IllegalArgumentException(message);
}
- public static String computeTableForSetting(Uri uri, String name) {
+ private static String computeTableForSetting(Uri uri, String name) {
String table = getValidTableOrThrow(uri);
if (name != null) {
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
index e63d22053f32e..833638cfcda2d 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
@@ -275,7 +275,8 @@ final class SettingsState {
if (newSize > mMaxBytesPerAppPackage) {
throw new IllegalStateException("You are adding too many system settings. "
- + "You should stop using system settings for app specific data.");
+ + "You should stop using system settings for app specific data"
+ + " package: " + packageName);
}
if (DEBUG) {
diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/BaseSettingsProviderTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/BaseSettingsProviderTest.java
index f713c333401d9..8473db495c57e 100644
--- a/packages/SettingsProvider/test/src/com/android/providers/settings/BaseSettingsProviderTest.java
+++ b/packages/SettingsProvider/test/src/com/android/providers/settings/BaseSettingsProviderTest.java
@@ -136,16 +136,27 @@ abstract class BaseSettingsProviderTest extends AndroidTestCase {
}
protected String queryStringViaProviderApi(int type, String name) {
- return queryStringViaProviderApi(type, name, false);
+ return queryStringViaProviderApi(type, name, false, false);
}
- protected String queryStringViaProviderApi(int type, String name, boolean queryStringInQuotes) {
- Uri uri = getBaseUriForType(type);
+ protected String queryStringViaProviderApi(int type, String name, boolean queryStringInQuotes,
+ boolean appendNameToUri) {
+ final Uri uri;
+ final String queryString;
+ final String[] queryArgs;
- String queryString = queryStringInQuotes ? "(name=?)" : "name=?";
+ if (appendNameToUri) {
+ uri = Uri.withAppendedPath(getBaseUriForType(type), name);
+ queryString = null;
+ queryArgs = null;
+ } else {
+ uri = getBaseUriForType(type);
+ queryString = queryStringInQuotes ? "(name=?)" : "name=?";
+ queryArgs = new String[]{name};
+ }
Cursor cursor = getContext().getContentResolver().query(uri, NAME_VALUE_COLUMNS,
- queryString, new String[]{name}, null);
+ queryString, queryArgs, null);
if (cursor == null) {
return null;
diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderTest.java
index cbfcbf5c9cd66..b89fb10c0f90c 100644
--- a/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderTest.java
+++ b/packages/SettingsProvider/test/src/com/android/providers/settings/SettingsProviderTest.java
@@ -184,6 +184,28 @@ public class SettingsProviderTest extends BaseSettingsProviderTest {
doTestQueryStringInBracketsViaProviderApiForType(SETTING_TYPE_SYSTEM);
}
+ public void testQueryStringWithAppendedNameToUriViaProviderApi() throws Exception {
+ // Make sure we have a clean slate.
+ deleteStringViaProviderApi(SETTING_TYPE_SYSTEM, FAKE_SETTING_NAME);
+
+ try {
+ // Insert the setting.
+ final Uri uri = insertStringViaProviderApi(SETTING_TYPE_SYSTEM, FAKE_SETTING_NAME,
+ FAKE_SETTING_VALUE, false);
+ Uri expectUri = Uri.withAppendedPath(getBaseUriForType(SETTING_TYPE_SYSTEM),
+ FAKE_SETTING_NAME);
+ assertEquals("Did not get expected Uri.", expectUri, uri);
+
+ // Make sure the first setting is there.
+ String firstValue = queryStringViaProviderApi(SETTING_TYPE_SYSTEM, FAKE_SETTING_NAME,
+ false, true);
+ assertEquals("Setting must be present", FAKE_SETTING_VALUE, firstValue);
+ } finally {
+ // Clean up.
+ deleteStringViaProviderApi(SETTING_TYPE_SYSTEM, FAKE_SETTING_NAME);
+ }
+ }
+
private void doTestQueryStringInBracketsViaProviderApiForType(int type) {
// Make sure we have a clean slate.
deleteStringViaProviderApi(type, FAKE_SETTING_NAME);
@@ -196,7 +218,7 @@ public class SettingsProviderTest extends BaseSettingsProviderTest {
assertEquals("Did not get expected Uri.", expectUri, uri);
// Make sure the first setting is there.
- String firstValue = queryStringViaProviderApi(type, FAKE_SETTING_NAME, true);
+ String firstValue = queryStringViaProviderApi(type, FAKE_SETTING_NAME, true, false);
assertEquals("Setting must be present", FAKE_SETTING_VALUE, firstValue);
} finally {
// Clean up.
From c3401f208963338e05e12b9636b5d1b8d1db5daf Mon Sep 17 00:00:00 2001
From: Chris Craik
Date: Wed, 18 Feb 2015 09:24:33 -0800
Subject: [PATCH 63/93] Fix layer shader to store layer pointer
bug:19419672
Change-Id: I4277348ceab41fbf45a107a8b21f64e2b4af23e0
---
libs/hwui/SkiaShader.cpp | 2 +-
tests/HwAccelerationTest/res/layout/projection_clipping.xml | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp
index 81531e83ef777..2fcf7f3914708 100644
--- a/libs/hwui/SkiaShader.cpp
+++ b/libs/hwui/SkiaShader.cpp
@@ -685,7 +685,7 @@ bool tryStoreLayer(Caches& caches, const SkShader& shader, const Matrix4& modelV
}
description->hasBitmap = true;
-
+ outData->layer = layer;
outData->bitmapSampler = (*textureUnit)++;
const float width = layer->getWidth();
diff --git a/tests/HwAccelerationTest/res/layout/projection_clipping.xml b/tests/HwAccelerationTest/res/layout/projection_clipping.xml
index 7177fc8f5102c..1f2b93946f487 100644
--- a/tests/HwAccelerationTest/res/layout/projection_clipping.xml
+++ b/tests/HwAccelerationTest/res/layout/projection_clipping.xml
@@ -14,13 +14,13 @@
android:id="@+id/clickable1"
android:layout_width="100dp"
android:layout_height="100dp"
- android:background="?android:attr/selectableItemBackground"/>
+ android:background="?android:attr/selectableItemBackgroundBorderless"/>
+ android:background="?android:attr/selectableItemBackgroundBorderless"/>
-
\ No newline at end of file
+
From 7c1d28c93976f120df96226865669821a345a331 Mon Sep 17 00:00:00 2001
From: Wale Ogunwale
Date: Mon, 23 Feb 2015 09:24:42 -0800
Subject: [PATCH 64/93] Don't delete home stack when last task is removed.
Bug: 19470291
Change-Id: I4a6c24edb6cc83a0f155836ce4e1394807da1563
---
.../core/java/com/android/server/am/ActivityStack.java | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 7afe23aafdb8c..83a7b68b32e51 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -4162,14 +4162,17 @@ final class ActivityStack {
if (mTaskHistory.isEmpty()) {
if (DEBUG_STACK) Slog.i(TAG, "removeTask: moving to back stack=" + this);
+ final boolean notHomeStack = !isHomeStack();
if (isOnHomeDisplay()) {
- mStackSupervisor.moveHomeStack(!isHomeStack(), reason + " leftTaskHistoryEmpty");
+ mStackSupervisor.moveHomeStack(notHomeStack, reason + " leftTaskHistoryEmpty");
}
if (mStacks != null) {
mStacks.remove(this);
mStacks.add(0, this);
}
- mActivityContainer.onTaskListEmptyLocked();
+ if (notHomeStack) {
+ mActivityContainer.onTaskListEmptyLocked();
+ }
}
task.stack = null;
From 2ba5a0f3e446762512e2f9d657eefb01e113b001 Mon Sep 17 00:00:00 2001
From: Wale Ogunwale
Date: Wed, 25 Feb 2015 07:28:55 -0800
Subject: [PATCH 65/93] Revert "Have AMS.setFocusedActivityLocked() move the
focus stack to the front"
This reverts commit af0e44885992b0675d7881c391caeff88414695f.
Unblock the release while I figure-out how the change broke things...
Bug: 19505341
Bug: 19507107
---
.../server/am/ActivityManagerService.java | 4 +-
.../com/android/server/am/ActivityStack.java | 18 ++---
.../server/am/ActivityStackSupervisor.java | 67 ++++++++++---------
3 files changed, 42 insertions(+), 47 deletions(-)
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 008d71879398d..966dc884543bf 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -2398,7 +2398,8 @@ public final class ActivityManagerService extends ActivityManagerNative
} else {
finishRunningVoiceLocked();
}
- if (r != null && mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity")) {
+ mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity");
+ if (r != null) {
mWindowManager.setFocusedApp(r.appToken, true);
}
applyUpdateLockStateLocked(r);
@@ -2422,7 +2423,6 @@ public final class ActivityManagerService extends ActivityManagerNative
ActivityRecord r = stack.topRunningActivityLocked(null);
if (r != null) {
setFocusedActivityLocked(r, "setFocusedStack");
- mStackSupervisor.resumeTopActivitiesLocked(stack, null, null);
}
}
}
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index c073df6c522b3..c3343f5f92c68 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -496,19 +496,11 @@ final class ActivityStack {
final void moveToFront(String reason) {
if (isAttached()) {
- final boolean homeStack = isHomeStack()
- || (mActivityContainer.mParentActivity != null
- && mActivityContainer.mParentActivity.isHomeActivity());
-
- if (!homeStack) {
- // Need to move this stack to the front before calling
- // {@link ActivityStackSupervisor#moveHomeStack} below.
- mStacks.remove(this);
- mStacks.add(this);
- }
if (isOnHomeDisplay()) {
- mStackSupervisor.moveHomeStack(homeStack, reason);
+ mStackSupervisor.moveHomeStack(isHomeStack(), reason);
}
+ mStacks.remove(this);
+ mStacks.add(this);
final TaskRecord task = topTask();
if (task != null) {
mWindowManager.moveTaskToTop(task.taskId);
@@ -2588,6 +2580,7 @@ final class ActivityStack {
if (top == null) {
return false;
}
+ stack.moveToFront(myReason);
mService.setFocusedActivityLocked(top, myReason);
return true;
}
@@ -3663,7 +3656,8 @@ final class ActivityStack {
}
}
- if (DEBUG_TRANSITION) Slog.v(TAG, "Prepare to back transition: task=" + taskId);
+ if (DEBUG_TRANSITION) Slog.v(TAG,
+ "Prepare to back transition: task=" + taskId);
boolean prevIsHome = false;
if (tr.isOverHomeStack()) {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index f6ef29530481d..907381e04c839 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -1541,27 +1541,25 @@ public final class ActivityStackSupervisor implements DisplayListener {
return err;
}
- ActivityStack computeStackFocus(ActivityRecord r, boolean newTask) {
+ ActivityStack adjustStackFocus(ActivityRecord r, boolean newTask) {
final TaskRecord task = r.task;
// On leanback only devices we should keep all activities in the same stack.
if (!mLeanbackOnlyDevice &&
(r.isApplicationActivity() || (task != null && task.isApplicationTask()))) {
-
- ActivityStack stack;
-
if (task != null) {
- stack = task.stack;
- if (stack.isOnHomeDisplay()) {
- if (mFocusedStack != stack) {
- if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "computeStackFocus: Setting " +
+ final ActivityStack taskStack = task.stack;
+ if (taskStack.isOnHomeDisplay()) {
+ if (mFocusedStack != taskStack) {
+ if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: Setting " +
"focused stack to r=" + r + " task=" + task);
+ mFocusedStack = taskStack;
} else {
if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
- "computeStackFocus: Focused stack already=" + mFocusedStack);
+ "adjustStackFocus: Focused stack already=" + mFocusedStack);
}
}
- return stack;
+ return taskStack;
}
final ActivityContainer container = r.mInitialActivityContainer;
@@ -1574,41 +1572,43 @@ public final class ActivityStackSupervisor implements DisplayListener {
if (mFocusedStack != mHomeStack && (!newTask ||
mFocusedStack.mActivityContainer.isEligibleForNewTasks())) {
if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
- "computeStackFocus: Have a focused stack=" + mFocusedStack);
+ "adjustStackFocus: Have a focused stack=" + mFocusedStack);
return mFocusedStack;
}
final ArrayList homeDisplayStacks = mHomeStack.mStacks;
for (int stackNdx = homeDisplayStacks.size() - 1; stackNdx >= 0; --stackNdx) {
- stack = homeDisplayStacks.get(stackNdx);
+ final ActivityStack stack = homeDisplayStacks.get(stackNdx);
if (!stack.isHomeStack()) {
if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG,
- "computeStackFocus: Setting focused stack=" + stack);
- return stack;
+ "adjustStackFocus: Setting focused stack=" + stack);
+ mFocusedStack = stack;
+ return mFocusedStack;
}
}
// Need to create an app stack for this user.
- stack = createStackOnDisplay(getNextStackId(), Display.DEFAULT_DISPLAY);
- if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "computeStackFocus: New stack r=" + r +
- " stackId=" + stack.mStackId);
- return stack;
+ mFocusedStack = createStackOnDisplay(getNextStackId(), Display.DEFAULT_DISPLAY);
+ if (DEBUG_FOCUS || DEBUG_STACK) Slog.d(TAG, "adjustStackFocus: New stack r=" + r +
+ " stackId=" + mFocusedStack.mStackId);
+ return mFocusedStack;
}
return mHomeStack;
}
- boolean setFocusedStack(ActivityRecord r, String reason) {
- if (r == null) {
- // Not sure what you are trying to do, but it is not going to work...
- return false;
+ void setFocusedStack(ActivityRecord r, String reason) {
+ if (r != null) {
+ final TaskRecord task = r.task;
+ boolean isHomeActivity = !r.isApplicationActivity();
+ if (!isHomeActivity && task != null) {
+ isHomeActivity = !task.isApplicationTask();
+ }
+ if (!isHomeActivity && task != null) {
+ final ActivityRecord parent = task.stack.mActivityContainer.mParentActivity;
+ isHomeActivity = parent != null && parent.isHomeActivity();
+ }
+ moveHomeStack(isHomeActivity, reason);
}
- final TaskRecord task = r.task;
- if (task == null || task.stack == null) {
- Slog.w(TAG, "Can't set focus stack for r=" + r + " task=" + task);
- return false;
- }
- task.stack.moveToFront(reason);
- return true;
}
final int startActivityUncheckedLocked(final ActivityRecord r, ActivityRecord sourceRecord,
@@ -2082,9 +2082,10 @@ public final class ActivityStackSupervisor implements DisplayListener {
return ActivityManager.START_RETURN_LOCK_TASK_MODE_VIOLATION;
}
newTask = true;
- targetStack = computeStackFocus(r, newTask);
- targetStack.moveToFront("startingNewTask");
-
+ targetStack = adjustStackFocus(r, newTask);
+ if (!launchTaskBehind) {
+ targetStack.moveToFront("startingNewTask");
+ }
if (reuseTask == null) {
r.setTask(targetStack.createTaskRecord(getNextTaskId(),
newTaskInfo != null ? newTaskInfo : r.info,
@@ -2205,7 +2206,7 @@ public final class ActivityStackSupervisor implements DisplayListener {
// This not being started from an existing activity, and not part
// of a new task... just put it in the top task, though these days
// this case should never happen.
- targetStack = computeStackFocus(r, newTask);
+ targetStack = adjustStackFocus(r, newTask);
targetStack.moveToFront("addingToTopTask");
ActivityRecord prev = targetStack.topActivity();
r.setTask(prev != null ? prev.task : targetStack.createTaskRecord(getNextTaskId(),
From dfb3e5bbd3ac34e34ff56f3ea58b74745d77d14d Mon Sep 17 00:00:00 2001
From: Alan Viverette
Date: Wed, 25 Feb 2015 11:12:55 -0800
Subject: [PATCH 66/93] Create blank state in no-arg RotateDrawable constructor
Also removes unnecessary constructor in InsetState so that it matches
the other DrawableWrapper classes.
Bug: 19489698
Change-Id: Ib2e510c6ae90858774970d928e541a9b08cb714a
---
.../java/android/graphics/drawable/InsetDrawable.java | 8 ++------
.../java/android/graphics/drawable/RotateDrawable.java | 2 +-
2 files changed, 3 insertions(+), 7 deletions(-)
diff --git a/graphics/java/android/graphics/drawable/InsetDrawable.java b/graphics/java/android/graphics/drawable/InsetDrawable.java
index b0cd386ab2c4d..97f7105c4a024 100644
--- a/graphics/java/android/graphics/drawable/InsetDrawable.java
+++ b/graphics/java/android/graphics/drawable/InsetDrawable.java
@@ -58,7 +58,7 @@ public class InsetDrawable extends DrawableWrapper {
* No-arg constructor used by drawable inflation.
*/
InsetDrawable() {
- this(new InsetState(), null);
+ this(new InsetState(null), null);
}
/**
@@ -82,7 +82,7 @@ public class InsetDrawable extends DrawableWrapper {
*/
public InsetDrawable(Drawable drawable, int insetLeft, int insetTop,int insetRight,
int insetBottom) {
- this(new InsetState(), null);
+ this(new InsetState(null), null);
mState.mInsetLeft = insetLeft;
mState.mInsetTop = insetTop;
@@ -267,10 +267,6 @@ public class InsetDrawable extends DrawableWrapper {
int mInsetRight = 0;
int mInsetBottom = 0;
- InsetState() {
- this(null);
- }
-
InsetState(InsetState orig) {
super(orig);
diff --git a/graphics/java/android/graphics/drawable/RotateDrawable.java b/graphics/java/android/graphics/drawable/RotateDrawable.java
index 595061cd31362..aeef65932b1fc 100644
--- a/graphics/java/android/graphics/drawable/RotateDrawable.java
+++ b/graphics/java/android/graphics/drawable/RotateDrawable.java
@@ -61,7 +61,7 @@ public class RotateDrawable extends DrawableWrapper {
* Create a new rotating drawable with an empty state.
*/
public RotateDrawable() {
- this(null, null);
+ this(new RotateState(null), null);
}
@Override
From 7b8016c1287593f0c34c455ed825f3499cf8c910 Mon Sep 17 00:00:00 2001
From: Amit Mahajan
Date: Thu, 26 Feb 2015 10:48:02 -0800
Subject: [PATCH 67/93] Adding logging to debug SignalStrength callback missing
issue.
This is a temporary change. Needs to be reverted.
Bug: 19323020
Change-Id: Ifdc2b14f4da6cd5a28e85c3bce35ddf0e975b6f4
---
.../com/android/server/TelephonyRegistry.java | 38 +++++++++----------
1 file changed, 18 insertions(+), 20 deletions(-)
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 8d7a182d5669c..376ef2a14d20e 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -736,50 +736,47 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
}
public void notifySignalStrengthForSubscriber(int subId, SignalStrength signalStrength) {
+ log("notifySignalStrengthForSubscriber: subId=" + subId
+ + " signalStrength=" + signalStrength);
if (!checkNotifyPermission("notifySignalStrength()")) {
+ log("notifySignalStrengthForSubscriber: permission check failure");
return;
}
- if (VDBG) {
- log("notifySignalStrengthForSubscriber: subId=" + subId
- + " signalStrength=" + signalStrength);
- toStringLogSSC("notifySignalStrengthForSubscriber");
- }
+ toStringLogSSC("notifySignalStrengthForSubscriber");
synchronized (mRecords) {
int phoneId = SubscriptionManager.getPhoneId(subId);
if (validatePhoneId(phoneId)) {
- if (VDBG) log("notifySignalStrengthForSubscriber: valid phoneId=" + phoneId);
+ log("notifySignalStrengthForSubscriber: valid phoneId=" + phoneId);
mSignalStrength[phoneId] = signalStrength;
for (Record r : mRecords) {
- if (VDBG) {
- log("notifySignalStrengthForSubscriber: r=" + r + " subId=" + subId
- + " phoneId=" + phoneId + " ss=" + signalStrength);
- }
+ log("notifySignalStrengthForSubscriber: r=" + r + " subId=" + subId
+ + " phoneId=" + phoneId + " ss=" + signalStrength);
if (r.matchPhoneStateListenerEvent(
PhoneStateListener.LISTEN_SIGNAL_STRENGTHS) &&
idMatch(r.subId, subId, phoneId)) {
try {
- if (DBG) {
- log("notifySignalStrengthForSubscriber: callback.onSsS r=" + r
- + " subId=" + subId + " phoneId=" + phoneId
- + " ss=" + signalStrength);
- }
+ log("notifySignalStrengthForSubscriber: callback.onSsS r=" + r
+ + " subId=" + subId + " phoneId=" + phoneId
+ + " ss=" + signalStrength);
r.callback.onSignalStrengthsChanged(new SignalStrength(signalStrength));
} catch (RemoteException ex) {
+ log("notifySignalStrengthForSubscriber: Exception while calling callback!!");
mRemoveList.add(r.binder);
}
+ } else {
+ log("notifySignalStrengthForSubscriber: no match for LISTEN_SIGNAL_STRENGTHS");
}
if (r.matchPhoneStateListenerEvent(PhoneStateListener.LISTEN_SIGNAL_STRENGTH) &&
idMatch(r.subId, subId, phoneId)){
try {
int gsmSignalStrength = signalStrength.getGsmSignalStrength();
int ss = (gsmSignalStrength == 99 ? -1 : gsmSignalStrength);
- if (DBG) {
- log("notifySignalStrengthForSubscriber: callback.onSS r=" + r
- + " subId=" + subId + " phoneId=" + phoneId
- + " gsmSS=" + gsmSignalStrength + " ss=" + ss);
- }
+ log("notifySignalStrengthForSubscriber: callback.onSS r=" + r
+ + " subId=" + subId + " phoneId=" + phoneId
+ + " gsmSS=" + gsmSignalStrength + " ss=" + ss);
r.callback.onSignalStrengthChanged(ss);
} catch (RemoteException ex) {
+ log("notifySignalStrengthForSubscriber: Exception in deprecated LISTEN_SIGNAL_STRENGTH");
mRemoveList.add(r.binder);
}
}
@@ -787,6 +784,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
} else {
log("notifySignalStrengthForSubscriber: invalid phoneId=" + phoneId);
}
+ log("notifySignalStrengthForSubscriber: done with all records");
handleRemoveListLocked();
}
broadcastSignalStrengthChanged(signalStrength, subId);
From 55cb478765e86752b7401178bef2562cb3d6aa7a Mon Sep 17 00:00:00 2001
From: James Cook
Date: Thu, 26 Feb 2015 10:53:41 -0800
Subject: [PATCH 68/93] Revert "Improvements to TextView Ctrl-Z undo support"
This reverts commit 7713d18847c7fe81fb5f34e888aaf8167862f5fd.
It causes crashes on text input after device orientation change.
Bug: 19332904
Bug: 19450037
BUG: 19505388
---
core/java/android/widget/Editor.java | 324 +++++++++------------------
1 file changed, 107 insertions(+), 217 deletions(-)
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 1ba11da1f6f8c..8601d2b67b9dc 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -4198,13 +4198,6 @@ public class Editor {
int mChangedStart, mChangedEnd, mChangedDelta;
}
- /**
- * @return True iff (start, end) is a valid range within the text.
- */
- private static boolean isValidRange(CharSequence text, int start, int end) {
- return 0 <= start && start <= end && end <= text.length();
- }
-
/**
* An InputFilter that monitors text input to maintain undo history. It does not modify the
* text being typed (and hence always returns null from the filter() method).
@@ -4220,123 +4213,97 @@ public class Editor {
public CharSequence filter(CharSequence source, int start, int end,
Spanned dest, int dstart, int dend) {
if (DEBUG_UNDO) {
- Log.d(TAG, "filter: source=" + source + " (" + start + "-" + end + ") " +
- "dest=" + dest + " (" + dstart + "-" + dend + ")");
+ Log.d(TAG, "filter: source=" + source + " (" + start + "-" + end + ")");
+ Log.d(TAG, "filter: dest=" + dest + " (" + dstart + "-" + dend + ")");
}
final UndoManager um = mEditor.mUndoManager;
if (um.isInUndo()) {
- if (DEBUG_UNDO) Log.d(TAG, "filter: skipping, currently performing undo/redo");
+ if (DEBUG_UNDO) Log.d(TAG, "*** skipping, currently performing undo/redo");
return null;
}
- // Text filters run before input operations are applied. However, some input operations
- // are invalid and will throw exceptions when applied. This is common in tests. Don't
- // attempt to undo invalid operations.
- if (!isValidRange(source, start, end) || !isValidRange(dest, dstart, dend)) {
- if (DEBUG_UNDO) Log.d(TAG, "filter: invalid op");
- return null;
- }
-
- // Earlier filters can rewrite input to be a no-op, for example due to a length limit
- // on an input field. Skip no-op changes.
- if (start == end && dstart == dend) {
- if (DEBUG_UNDO) Log.d(TAG, "filter: skipping no-op");
- return null;
- }
-
- // Build a new operation with all the information from this edit.
- EditOperation edit = new EditOperation(mEditor, source, start, end, dest, dstart, dend);
-
- // Fetch the last edit operation and attempt to merge in the new edit.
um.beginUpdate("Edit text");
- EditOperation lastEdit = um.getLastOperation(
- EditOperation.class, mEditor.mUndoOwner, UndoManager.MERGE_MODE_UNIQUE);
- if (lastEdit == null) {
- // Add this as the first edit.
- if (DEBUG_UNDO) Log.d(TAG, "filter: adding first op " + edit);
- um.addOperation(edit, UndoManager.MERGE_MODE_NONE);
- } else if (lastEdit.mergeWith(edit)) {
- // Merge succeeded, nothing else to do.
- if (DEBUG_UNDO) Log.d(TAG, "filter: merge succeeded, created " + lastEdit);
- } else {
- // Could not merge with the last edit, so commit the last edit and add this edit.
- if (DEBUG_UNDO) Log.d(TAG, "filter: merge failed, adding " + edit);
- um.commitState(mEditor.mUndoOwner);
- um.addOperation(edit, UndoManager.MERGE_MODE_NONE);
+ TextModifyOperation op = um.getLastOperation(
+ TextModifyOperation.class, mEditor.mUndoOwner, UndoManager.MERGE_MODE_UNIQUE);
+ if (op != null) {
+ if (DEBUG_UNDO) Log.d(TAG, "Last op: range=(" + op.mRangeStart + "-" + op.mRangeEnd
+ + "), oldText=" + op.mOldText);
+ // See if we can continue modifying this operation.
+ if (op.mOldText == null) {
+ // The current operation is an add... are we adding more? We are adding
+ // more if we are either appending new text to the end of the last edit or
+ // completely replacing some or all of the last edit.
+ // TODO: This sequence doesn't work right: a, left-arrow, b, undo, undo.
+ // The two edits are incorrectly merged, so there is only one undo available.
+ if (start < end && ((dstart >= op.mRangeStart && dend <= op.mRangeEnd)
+ || (dstart == op.mRangeEnd && dend == op.mRangeEnd))) {
+ op.mRangeEnd = dstart + (end-start);
+ um.endUpdate();
+ if (DEBUG_UNDO) Log.d(TAG, "*** merging with last op, mRangeEnd="
+ + op.mRangeEnd);
+ return null;
+ }
+ } else {
+ // The current operation is a delete... can we delete more?
+ if (start == end && dend == op.mRangeStart-1) {
+ SpannableStringBuilder str;
+ if (op.mOldText instanceof SpannableString) {
+ str = (SpannableStringBuilder)op.mOldText;
+ } else {
+ str = new SpannableStringBuilder(op.mOldText);
+ }
+ str.insert(0, dest, dstart, dend);
+ op.mRangeStart = dstart;
+ op.mOldText = str;
+ um.endUpdate();
+ if (DEBUG_UNDO) Log.d(TAG, "*** merging with last op, range=("
+ + op.mRangeStart + "-" + op.mRangeEnd
+ + "), oldText=" + op.mOldText);
+ return null;
+ }
+ }
+
+ // Couldn't add to the current undo operation, need to start a new
+ // undo state for a new undo operation.
+ um.commitState(null);
+ um.setUndoLabel("Edit text");
}
+
+ // Create a new undo state reflecting the operation being performed.
+ op = new TextModifyOperation(mEditor.mUndoOwner);
+ op.mRangeStart = dstart;
+ if (start < end) {
+ op.mRangeEnd = dstart + (end-start);
+ } else {
+ op.mRangeEnd = dstart;
+ }
+ if (dstart < dend) {
+ op.mOldText = dest.subSequence(dstart, dend);
+ }
+ if (DEBUG_UNDO) Log.d(TAG, "*** adding new op, range=(" + op.mRangeStart
+ + "-" + op.mRangeEnd + "), oldText=" + op.mOldText);
+ um.addOperation(op, UndoManager.MERGE_MODE_NONE);
um.endUpdate();
- return null; // Text not changed.
+ return null;
}
}
/**
* An operation to undo a single "edit" to a text view.
*/
- public static class EditOperation extends UndoOperation {
- private static final int TYPE_INSERT = 0;
- private static final int TYPE_DELETE = 1;
- private static final int TYPE_REPLACE = 2;
+ public static class TextModifyOperation extends UndoOperation {
+ int mRangeStart, mRangeEnd;
+ CharSequence mOldText;
- private int mType;
- private String mOldText;
- private int mOldTextStart;
- private String mNewText;
- private int mNewTextStart;
-
- private int mOldCursorPos;
- private int mNewCursorPos;
-
- /**
- * Constructs an edit operation from a text input operation that replaces the range
- * (dstart, dend) of dest with (start, end) of source. See {@link InputFilter#filter}.
- */
- public EditOperation(Editor editor, CharSequence source, int start, int end,
- Spanned dest, int dstart, int dend) {
- super(editor.mUndoOwner);
-
- mOldText = dest.subSequence(dstart, dend).toString();
- mNewText = source.subSequence(start, end).toString();
-
- // Determine the type of the edit and store where it occurred. Avoid storing
- // irrevelant data (e.g. mNewTextStart for a delete) because that makes the
- // merging logic more complex (e.g. merging deletes could lead to mNewTextStart being
- // outside the bounds of the final text).
- if (mNewText.length() > 0 && mOldText.length() == 0) {
- mType = TYPE_INSERT;
- mNewTextStart = dstart;
- } else if (mNewText.length() == 0 && mOldText.length() > 0) {
- mType = TYPE_DELETE;
- mOldTextStart = dstart;
- } else {
- mType = TYPE_REPLACE;
- mOldTextStart = mNewTextStart = dstart;
- }
-
- // Store cursor data.
- mOldCursorPos = editor.mTextView.getSelectionStart();
- mNewCursorPos = dstart + (end - start);
+ public TextModifyOperation(UndoOwner owner) {
+ super(owner);
}
- public EditOperation(Parcel src, ClassLoader loader) {
+ public TextModifyOperation(Parcel src, ClassLoader loader) {
super(src, loader);
- mType = src.readInt();
- mOldText = src.readString();
- mOldTextStart = src.readInt();
- mNewText = src.readString();
- mNewTextStart = src.readInt();
- mOldCursorPos = src.readInt();
- mNewCursorPos = src.readInt();
- }
-
- @Override
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeInt(mType);
- dest.writeString(mOldText);
- dest.writeInt(mOldTextStart);
- dest.writeString(mNewText);
- dest.writeInt(mNewTextStart);
- dest.writeInt(mOldCursorPos);
- dest.writeInt(mNewCursorPos);
+ mRangeStart = src.readInt();
+ mRangeEnd = src.readInt();
+ mOldText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(src);
}
@Override
@@ -4345,139 +4312,62 @@ public class Editor {
@Override
public void undo() {
- if (DEBUG_UNDO) Log.d(TAG, "undo");
- // Remove the new text and insert the old.
- modifyText(mNewTextStart, getNewTextEnd(), mOldText, mOldTextStart, mOldCursorPos);
+ swapText();
}
@Override
public void redo() {
- if (DEBUG_UNDO) Log.d(TAG, "redo");
- // Remove the old text and insert the new.
- modifyText(mOldTextStart, getOldTextEnd(), mNewText, mNewTextStart, mNewCursorPos);
+ swapText();
}
- /**
- * Attempts to merge this existing operation with a new edit.
- * @param edit The new edit operation.
- * @return If the merge succeeded, returns true. Otherwise returns false and leaves this
- * object unchanged.
- */
- private boolean mergeWith(EditOperation edit) {
- switch (mType) {
- case TYPE_INSERT:
- return mergeInsertWith(edit);
- case TYPE_DELETE:
- return mergeDeleteWith(edit);
- case TYPE_REPLACE:
- return mergeReplaceWith(edit);
- default:
- return false;
- }
- }
-
- private boolean mergeInsertWith(EditOperation edit) {
- if (DEBUG_UNDO) Log.d(TAG, "mergeInsertWith " + edit);
- // Only merge continuous insertions.
- if (edit.mType != TYPE_INSERT) {
- return false;
- }
- // Only merge insertions that are contiguous.
- if (getNewTextEnd() != edit.mNewTextStart) {
- return false;
- }
- mNewText += edit.mNewText;
- mNewCursorPos = edit.mNewCursorPos;
- return true;
- }
-
- // TODO: Support forward delete.
- private boolean mergeDeleteWith(EditOperation edit) {
- if (DEBUG_UNDO) Log.d(TAG, "mergeDeleteWith " + edit);
- // Only merge continuous deletes.
- if (edit.mType != TYPE_DELETE) {
- return false;
- }
- // Only merge deletions that are contiguous.
- if (mOldTextStart != edit.getOldTextEnd()) {
- return false;
- }
- mOldTextStart = edit.mOldTextStart;
- mOldText = edit.mOldText + mOldText;
- mNewCursorPos = edit.mNewCursorPos;
- return true;
- }
-
- private boolean mergeReplaceWith(EditOperation edit) {
- if (DEBUG_UNDO) Log.d(TAG, "mergeReplaceWith " + edit);
- // Replacements can merge only with adjacent inserts and adjacent replacements.
- if (edit.mType == TYPE_DELETE ||
- getNewTextEnd() != edit.mOldTextStart ||
- edit.mOldTextStart != edit.mNewTextStart) {
- return false;
- }
- mOldText += edit.mOldText;
- mNewText += edit.mNewText;
- mNewCursorPos = edit.mNewCursorPos;
- return true;
- }
-
- private int getNewTextEnd() {
- return mNewTextStart + mNewText.length();
- }
-
- private int getOldTextEnd() {
- return mOldTextStart + mOldText.length();
- }
-
- private void modifyText(int deleteFrom, int deleteTo, CharSequence newText,
- int newTextInsertAt, int newCursorPos) {
+ private void swapText() {
+ // Both undo and redo involves swapping the contents of the range
+ // in the text view with our local text.
Editor editor = getOwnerData();
- Editable text = (Editable) editor.mTextView.getText();
- // Apply the edit if it is still valid.
- if (isValidRange(text, deleteFrom, deleteTo) &&
- newTextInsertAt <= text.length() - (deleteTo - deleteFrom)) {
- if (deleteFrom != deleteTo) {
- text.delete(deleteFrom, deleteTo);
- }
- if (newText.length() != 0) {
- text.insert(newTextInsertAt, newText);
- }
+ Editable editable = (Editable)editor.mTextView.getText();
+ CharSequence curText;
+ if (mRangeStart >= mRangeEnd) {
+ curText = null;
+ } else {
+ curText = editable.subSequence(mRangeStart, mRangeEnd);
}
- // Restore the cursor position.
- // TODO: Select all the text that was undone.
- if (newCursorPos <= text.length()) {
- Selection.setSelection(text, newCursorPos);
+ if (DEBUG_UNDO) {
+ Log.d(TAG, "Swap: range=(" + mRangeStart + "-" + mRangeEnd
+ + "), oldText=" + mOldText);
+ Log.d(TAG, "Swap: curText=" + curText);
}
+ if (mOldText == null) {
+ editable.delete(mRangeStart, mRangeEnd);
+ mRangeEnd = mRangeStart;
+ } else {
+ editable.replace(mRangeStart, mRangeEnd, mOldText);
+ mRangeEnd = mRangeStart + mOldText.length();
+ }
+ mOldText = curText;
}
@Override
- public String toString() {
- return "EditOperation: [" +
- "mType=" + mType + ", " +
- "mOldText=" + mOldText + ", " +
- "mOldTextStart=" + mOldTextStart + ", " +
- "mNewText=" + mNewText + ", " +
- "mNewTextStart=" + mNewTextStart + ", " +
- "mOldCursorPos=" + mOldCursorPos + ", " +
- "mNewCursorPos=" + mNewCursorPos + "]";
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(mRangeStart);
+ dest.writeInt(mRangeEnd);
+ TextUtils.writeToParcel(mOldText, dest, flags);
}
- public static final Parcelable.ClassLoaderCreator CREATOR
- = new Parcelable.ClassLoaderCreator() {
+ public static final Parcelable.ClassLoaderCreator CREATOR
+ = new Parcelable.ClassLoaderCreator() {
@Override
- public EditOperation createFromParcel(Parcel in) {
- return new EditOperation(in, null);
+ public TextModifyOperation createFromParcel(Parcel in) {
+ return new TextModifyOperation(in, null);
}
@Override
- public EditOperation createFromParcel(Parcel in, ClassLoader loader) {
- return new EditOperation(in, loader);
+ public TextModifyOperation createFromParcel(Parcel in, ClassLoader loader) {
+ return new TextModifyOperation(in, loader);
}
@Override
- public EditOperation[] newArray(int size) {
- return new EditOperation[size];
+ public TextModifyOperation[] newArray(int size) {
+ return new TextModifyOperation[size];
}
};
}
From 7f2f07934778c242b52836fa1ce43d11829f340a Mon Sep 17 00:00:00 2001
From: James Cook
Date: Thu, 26 Feb 2015 10:55:43 -0800
Subject: [PATCH 69/93] Revert "Add basic support for Ctrl-Z to editable
TextViews"
This reverts commit 9201e797833f35b9afb219f88c10d3b6fda02a4e.
It causes crashes on typing after device orientation change.
Bug: 19332904
Bug: 19505388
Change-Id: I0d9fb728eb6f8d591beb35fab333c0a182e24542
---
api/current.txt | 4 +-
api/system-current.txt | 4 +-
core/java/android/widget/Editor.java | 67 +++------------------
core/java/android/widget/TextView.java | 83 ++++++--------------------
core/res/res/values/ids.xml | 2 -
core/res/res/values/public.xml | 4 --
6 files changed, 30 insertions(+), 134 deletions(-)
diff --git a/api/current.txt b/api/current.txt
index a356307c04003..00a9852950b12 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -1710,10 +1710,9 @@ package android {
field public static final int message = 16908299; // 0x102000b
field public static final int navigationBarBackground = 16908336; // 0x1020030
field public static final int paste = 16908322; // 0x1020022
- field public static final int pasteAsPlainText = 16908339; // 0x1020033
+ field public static final int pasteAsPlainText = 16908337; // 0x1020031
field public static final int primary = 16908300; // 0x102000c
field public static final int progress = 16908301; // 0x102000d
- field public static final int redo = 16908338; // 0x1020032
field public static final int secondaryProgress = 16908303; // 0x102000f
field public static final int selectAll = 16908319; // 0x102001f
field public static final int selectTextMode = 16908333; // 0x102002d
@@ -1730,7 +1729,6 @@ package android {
field public static final int text2 = 16908309; // 0x1020015
field public static final int title = 16908310; // 0x1020016
field public static final int toggle = 16908311; // 0x1020017
- field public static final int undo = 16908337; // 0x1020031
field public static final int widget_frame = 16908312; // 0x1020018
}
diff --git a/api/system-current.txt b/api/system-current.txt
index 7db9c54aff090..8d6a78a3cd79a 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -1786,10 +1786,9 @@ package android {
field public static final int message = 16908299; // 0x102000b
field public static final int navigationBarBackground = 16908336; // 0x1020030
field public static final int paste = 16908322; // 0x1020022
- field public static final int pasteAsPlainText = 16908339; // 0x1020033
+ field public static final int pasteAsPlainText = 16908337; // 0x1020031
field public static final int primary = 16908300; // 0x102000c
field public static final int progress = 16908301; // 0x102000d
- field public static final int redo = 16908338; // 0x1020032
field public static final int secondaryProgress = 16908303; // 0x102000f
field public static final int selectAll = 16908319; // 0x102001f
field public static final int selectTextMode = 16908333; // 0x102002d
@@ -1806,7 +1805,6 @@ package android {
field public static final int text2 = 16908309; // 0x1020015
field public static final int title = 16908310; // 0x1020016
field public static final int toggle = 16908311; // 0x1020017
- field public static final int undo = 16908337; // 0x1020031
field public static final int widget_frame = 16908312; // 0x1020018
}
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 8601d2b67b9dc..4752594e06dd7 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -50,7 +50,6 @@ import android.graphics.drawable.Drawable;
import android.inputmethodservice.ExtractEditText;
import android.os.Bundle;
import android.os.Handler;
-import android.os.ParcelableParcel;
import android.os.SystemClock;
import android.provider.Settings;
import android.text.DynamicLayout;
@@ -119,18 +118,15 @@ import java.util.HashMap;
*/
public class Editor {
private static final String TAG = "Editor";
- private static final boolean DEBUG_UNDO = false;
+ static final boolean DEBUG_UNDO = false;
static final int BLINK = 500;
private static final float[] TEMP_POSITION = new float[2];
private static int DRAG_SHADOW_MAX_TEXT_LENGTH = 20;
- // Tag used when the Editor maintains its own separate UndoManager.
- private static final String UNDO_OWNER_TAG = "Editor";
- // Each Editor manages its own undo stack.
- private final UndoManager mUndoManager = new UndoManager();
- private UndoOwner mUndoOwner = mUndoManager.getOwner(UNDO_OWNER_TAG, this);
- final InputFilter mUndoInputFilter = new UndoInputFilter(this);
+ UndoManager mUndoManager;
+ UndoOwner mUndoOwner;
+ InputFilter mUndoInputFilter;
// Cursor Controllers.
InsertionPointCursorController mInsertionPointCursorController;
@@ -226,39 +222,6 @@ public class Editor {
Editor(TextView textView) {
mTextView = textView;
- // Synchronize the filter list, which places the undo input filter at the end.
- mTextView.setFilters(mTextView.getFilters());
- }
-
- ParcelableParcel saveInstanceState() {
- // For now there is only undo state.
- return (ParcelableParcel) mUndoManager.saveInstanceState();
- }
-
- void restoreInstanceState(ParcelableParcel state) {
- mUndoManager.restoreInstanceState(state);
- // Re-associate this object as the owner of undo state.
- mUndoOwner = mUndoManager.getOwner(UNDO_OWNER_TAG, this);
- }
-
- boolean canUndo() {
- UndoOwner[] owners = { mUndoOwner };
- return mUndoManager.countUndos(owners) > 0;
- }
-
- boolean canRedo() {
- UndoOwner[] owners = { mUndoOwner };
- return mUndoManager.countRedos(owners) > 0;
- }
-
- void undo() {
- UndoOwner[] owners = { mUndoOwner };
- mUndoManager.undo(owners, 1); // Undo 1 action.
- }
-
- void redo() {
- UndoOwner[] owners = { mUndoOwner };
- mUndoManager.redo(owners, 1); // Redo 1 action.
}
void onAttachedToWindow() {
@@ -1743,7 +1706,7 @@ public class Editor {
/**
* Called by the framework in response to a text auto-correction (such as fixing a typo using a
- * a dictionary) from the current input method, provided by it calling
+ * a dictionnary) from the current input method, provided by it calling
* {@link InputConnection#commitCorrection} InputConnection.commitCorrection()}. The default
* implementation flashes the background of the corrected word to provide feedback to the user.
*
@@ -4198,12 +4161,8 @@ public class Editor {
int mChangedStart, mChangedEnd, mChangedDelta;
}
- /**
- * An InputFilter that monitors text input to maintain undo history. It does not modify the
- * text being typed (and hence always returns null from the filter() method).
- */
public static class UndoInputFilter implements InputFilter {
- private final Editor mEditor;
+ final Editor mEditor;
public UndoInputFilter(Editor editor) {
mEditor = editor;
@@ -4233,8 +4192,6 @@ public class Editor {
// The current operation is an add... are we adding more? We are adding
// more if we are either appending new text to the end of the last edit or
// completely replacing some or all of the last edit.
- // TODO: This sequence doesn't work right: a, left-arrow, b, undo, undo.
- // The two edits are incorrectly merged, so there is only one undo available.
if (start < end && ((dstart >= op.mRangeStart && dend <= op.mRangeEnd)
|| (dstart == op.mRangeEnd && dend == op.mRangeEnd))) {
op.mRangeEnd = dstart + (end-start);
@@ -4288,10 +4245,7 @@ public class Editor {
}
}
- /**
- * An operation to undo a single "edit" to a text view.
- */
- public static class TextModifyOperation extends UndoOperation {
+ public static class TextModifyOperation extends UndoOperation {
int mRangeStart, mRangeEnd;
CharSequence mOldText;
@@ -4323,8 +4277,8 @@ public class Editor {
private void swapText() {
// Both undo and redo involves swapping the contents of the range
// in the text view with our local text.
- Editor editor = getOwnerData();
- Editable editable = (Editable)editor.mTextView.getText();
+ TextView tv = getOwnerData();
+ Editable editable = (Editable)tv.getText();
CharSequence curText;
if (mRangeStart >= mRangeEnd) {
curText = null;
@@ -4355,17 +4309,14 @@ public class Editor {
public static final Parcelable.ClassLoaderCreator CREATOR
= new Parcelable.ClassLoaderCreator() {
- @Override
public TextModifyOperation createFromParcel(Parcel in) {
return new TextModifyOperation(in, null);
}
- @Override
public TextModifyOperation createFromParcel(Parcel in, ClassLoader loader) {
return new TextModifyOperation(in, loader);
}
- @Override
public TextModifyOperation[] newArray(int size) {
return new TextModifyOperation[size];
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 2d0a9cbb9d6dd..27603f5ad4e74 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -47,7 +47,6 @@ import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
-import android.os.ParcelableParcel;
import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.Settings;
@@ -1613,8 +1612,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* @hide
*/
public final UndoManager getUndoManager() {
- // TODO: Consider supporting a global undo manager.
- throw new UnsupportedOperationException("not implemented");
+ return mEditor == null ? null : mEditor.mUndoManager;
}
/**
@@ -1632,12 +1630,22 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* @hide
*/
public final void setUndoManager(UndoManager undoManager, String tag) {
- // TODO: Consider supporting a global undo manager. An implementation will need to:
- // * createEditorIfNeeded()
- // * Promote to BufferType.EDITABLE if needed.
- // * Update the UndoManager and UndoOwner.
- // Likewise it will need to be able to restore the default UndoManager.
- throw new UnsupportedOperationException("not implemented");
+ if (undoManager != null) {
+ createEditorIfNeeded();
+ mEditor.mUndoManager = undoManager;
+ mEditor.mUndoOwner = undoManager.getOwner(tag, this);
+ mEditor.mUndoInputFilter = new Editor.UndoInputFilter(mEditor);
+ if (!(mText instanceof Editable)) {
+ setText(mText, BufferType.EDITABLE);
+ }
+
+ setFilters((Editable) mText, mFilters);
+ } else if (mEditor != null) {
+ // XXX need to destroy all associated state.
+ mEditor.mUndoManager = null;
+ mEditor.mUndoOwner = null;
+ mEditor.mUndoInputFilter = null;
+ }
}
/**
@@ -3891,9 +3899,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
ss.error = getError();
- if (mEditor != null) {
- ss.editorState = mEditor.saveInstanceState();
- }
return ss;
}
@@ -3963,11 +3968,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
});
}
-
- if (ss.editorState != null) {
- createEditorIfNeeded();
- mEditor.restoreInstanceState(ss.editorState);
- }
}
/**
@@ -8383,11 +8383,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
return onTextContextMenuItem(ID_SELECT_ALL);
}
break;
- case KeyEvent.KEYCODE_Z:
- if (canUndo()) {
- return onTextContextMenuItem(ID_UNDO);
- }
- break;
case KeyEvent.KEYCODE_X:
if (canCut()) {
return onTextContextMenuItem(ID_CUT);
@@ -8407,15 +8402,11 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
} else if (event.hasModifiers(KeyEvent.META_CTRL_ON | KeyEvent.META_SHIFT_ON)) {
// Handle Ctrl-Shift shortcuts.
switch (keyCode) {
- case KeyEvent.KEYCODE_Z:
- if (canRedo()) {
- return onTextContextMenuItem(ID_REDO);
- }
- break;
case KeyEvent.KEYCODE_V:
if (canPaste()) {
return onTextContextMenuItem(ID_PASTE_AS_PLAIN_TEXT);
}
+ break;
}
}
return super.onKeyShortcut(keyCode, event);
@@ -8793,8 +8784,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
}
static final int ID_SELECT_ALL = android.R.id.selectAll;
- static final int ID_UNDO = android.R.id.undo;
- static final int ID_REDO = android.R.id.redo;
static final int ID_CUT = android.R.id.cut;
static final int ID_COPY = android.R.id.copy;
static final int ID_PASTE = android.R.id.paste;
@@ -8826,18 +8815,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
selectAllText();
return true;
- case ID_UNDO:
- if (mEditor != null) {
- mEditor.undo();
- }
- return true; // Returns true even if nothing was undone.
-
- case ID_REDO:
- if (mEditor != null) {
- mEditor.redo();
- }
- return true; // Returns true even if nothing was undone.
-
case ID_PASTE:
paste(min, max, true /* withFormatting */);
return true;
@@ -8971,17 +8948,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* @hide
*/
protected void stopSelectionActionMode() {
- if (mEditor != null) {
- mEditor.stopSelectionActionMode();
- }
- }
-
- boolean canUndo() {
- return mEditor != null && mEditor.canUndo();
- }
-
- boolean canRedo() {
- return mEditor != null && mEditor.canRedo();
+ mEditor.stopSelectionActionMode();
}
boolean canCut() {
@@ -9358,7 +9325,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
CharSequence text;
boolean frozenWithFocus;
CharSequence error;
- ParcelableParcel editorState; // Optional state from Editor.
SavedState(Parcelable superState) {
super(superState);
@@ -9378,13 +9344,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
out.writeInt(1);
TextUtils.writeToParcel(error, out, flags);
}
-
- if (editorState == null) {
- out.writeInt(0);
- } else {
- out.writeInt(1);
- editorState.writeToParcel(out, flags);
- }
}
@Override
@@ -9420,10 +9379,6 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
if (in.readInt() != 0) {
error = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
}
-
- if (in.readInt() != 0) {
- editorState = ParcelableParcel.CREATOR.createFromParcel(in);
- }
}
}
diff --git a/core/res/res/values/ids.xml b/core/res/res/values/ids.xml
index b6e79ad7618ed..6e2f534940f05 100644
--- a/core/res/res/values/ids.xml
+++ b/core/res/res/values/ids.xml
@@ -89,7 +89,5 @@
-
-
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 46e3d7529afd6..569c6f6407708 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2636,10 +2636,6 @@
-
-
-
-
From e67ad49f6ed4f927b509d75feedd68d072be29e4 Mon Sep 17 00:00:00 2001
From: Alan Viverette
Date: Fri, 27 Feb 2015 12:34:30 -0800
Subject: [PATCH 70/93] Revert "Use ObjectAnimator for fading scrollbars, set
initial duration to 1500"
Bug: 19522833
Bug: 19528265
This reverts commit 72710f11ecd3baf468bf649283453cb7aafe4d74.
Change-Id: I7235ae3ca53696f029cc18f19fe1d373c4f54bbf
---
core/java/android/view/View.java | 532 ++++++++++--------
core/java/android/view/ViewConfiguration.java | 18 +-
.../android/graphics/drawable/Drawable.java | 16 -
3 files changed, 304 insertions(+), 262 deletions(-)
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 502d5eefaca68..f99d2d57e64e1 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -16,9 +16,7 @@
package android.view;
-import android.animation.Animator;
import android.animation.AnimatorInflater;
-import android.animation.ObjectAnimator;
import android.animation.StateListAnimator;
import android.annotation.DrawableRes;
import android.annotation.IdRes;
@@ -34,10 +32,13 @@ import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Insets;
+import android.graphics.Interpolator;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Outline;
import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.PathMeasure;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.PorterDuff;
@@ -4325,7 +4326,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @hide This is the real method; the public one is shimmed to be safe to call from apps.
*/
protected void initializeFadingEdgeInternal(TypedArray a) {
- getScrollCache().fadingEdgeLength = a.getDimensionPixelSize(
+ initScrollCache();
+
+ mScrollCache.fadingEdgeLength = a.getDimensionPixelSize(
R.styleable.View_fadingEdgeLength,
ViewConfiguration.get(mContext).getScaledFadingEdgeLength());
}
@@ -4359,7 +4362,8 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* content in this view is visible.
*/
public void setFadingEdgeLength(int length) {
- getScrollCache().fadingEdgeLength = length;
+ initScrollCache();
+ mScrollCache.fadingEdgeLength = length;
}
/**
@@ -4463,7 +4467,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @hide
*/
protected void initializeScrollbarsInternal(TypedArray a) {
- final ScrollabilityCache scrollabilityCache = getScrollCache();
+ initScrollCache();
+
+ final ScrollabilityCache scrollabilityCache = mScrollCache;
+
if (scrollabilityCache.scrollBar == null) {
scrollabilityCache.scrollBar = new ScrollBarDrawable();
scrollabilityCache.scrollBar.setCallback(this);
@@ -4471,16 +4478,23 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
final boolean fadeScrollbars = a.getBoolean(R.styleable.View_fadeScrollbars, true);
- scrollabilityCache.setFadingEnabled(fadeScrollbars);
+
+ if (!fadeScrollbars) {
+ scrollabilityCache.state = ScrollabilityCache.ON;
+ }
+ scrollabilityCache.fadeScrollBars = fadeScrollbars;
+
scrollabilityCache.scrollBarFadeDuration = a.getInt(
- R.styleable.View_scrollbarFadeDuration,
- ViewConfiguration.getScrollBarFadeDuration());
+ R.styleable.View_scrollbarFadeDuration, ViewConfiguration
+ .getScrollBarFadeDuration());
scrollabilityCache.scrollBarDefaultDelayBeforeFade = a.getInt(
R.styleable.View_scrollbarDefaultDelayBeforeFade,
ViewConfiguration.getScrollDefaultDelay());
+
+
scrollabilityCache.scrollBarSize = a.getDimensionPixelSize(
- R.styleable.View_scrollbarSize,
+ com.android.internal.R.styleable.View_scrollbarSize,
ViewConfiguration.get(mContext).getScaledScrollBarSize());
Drawable track = a.getDrawable(R.styleable.View_scrollbarTrackHorizontal);
@@ -4525,12 +4539,18 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
/**
- * Returns the scrollability cache, initializing a new cache if necessary.
+ *
+ * Initalizes the scrollability cache if necessary.
+ *
*/
- private ScrollabilityCache getScrollCache() {
+ private void initScrollCache() {
if (mScrollCache == null) {
- mScrollCache = new ScrollabilityCache(this);
+ mScrollCache = new ScrollabilityCache(ViewConfiguration.get(mContext), this);
}
+ }
+
+ private ScrollabilityCache getScrollCache() {
+ initScrollCache();
return mScrollCache;
}
@@ -11551,30 +11571,31 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @see #setVerticalScrollBarEnabled(boolean)
*/
protected boolean awakenScrollBars() {
- return mScrollCache != null
- && awakenScrollBars(mScrollCache.scrollBarDefaultDelayBeforeFade, true);
+ return mScrollCache != null &&
+ awakenScrollBars(mScrollCache.scrollBarDefaultDelayBeforeFade, true);
}
/**
* Trigger the scrollbars to draw.
- *
* This method differs from awakenScrollBars() only in its default duration.
* initialAwakenScrollBars() will show the scroll bars for longer than
* usual to give the user more of a chance to notice them.
*
* @return true if the animation is played, false otherwise.
- * @see #awakenScrollBars()
*/
private boolean initialAwakenScrollBars() {
- return mScrollCache != null
- && awakenScrollBars(mScrollCache.scrollBarDelayBeforeInitialFade, true);
+ return mScrollCache != null &&
+ awakenScrollBars(mScrollCache.scrollBarDefaultDelayBeforeFade * 4, true);
}
/**
+ *
* Trigger the scrollbars to draw. When invoked this method starts an
* animation to fade the scrollbars out after a fixed delay. If a subclass
* provides animated scrolling, the start delay should equal the duration of
* the scrolling animation.
+ *
+ *
*
* The animation starts only if at least one of the scrollbars is enabled,
* as specified by {@link #isHorizontalScrollBarEnabled()} and
@@ -11582,14 +11603,18 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* this method returns true, and false otherwise. If the animation is
* started, this method calls {@link #invalidate()}; in that case the caller
* should not call {@link #invalidate()}.
+ *
+ *
*
* This method should be invoked every time a subclass directly updates the
* scroll parameters.
+ *
*
- * @param fadeOutDelay the delay in milliseconds before the fade out
- * animation should start, or 0 to start the animation
- * immediately
+ * @param startDelay the delay, in milliseconds, after which the animation
+ * should start; when the delay is 0, the animation starts
+ * immediately
* @return true if the animation is played, false otherwise
+ *
* @see #scrollBy(int, int)
* @see #scrollTo(int, int)
* @see #isHorizontalScrollBarEnabled()
@@ -11597,15 +11622,18 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @see #setHorizontalScrollBarEnabled(boolean)
* @see #setVerticalScrollBarEnabled(boolean)
*/
- protected boolean awakenScrollBars(int fadeOutDelay) {
- return awakenScrollBars(fadeOutDelay, true);
+ protected boolean awakenScrollBars(int startDelay) {
+ return awakenScrollBars(startDelay, true);
}
/**
+ *
* Trigger the scrollbars to draw. When invoked this method starts an
* animation to fade the scrollbars out after a fixed delay. If a subclass
* provides animated scrolling, the start delay should equal the duration of
* the scrolling animation.
+ *
+ *
*
* The animation starts only if at least one of the scrollbars is enabled,
* as specified by {@link #isHorizontalScrollBarEnabled()} and
@@ -11614,18 +11642,21 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* started, this method calls {@link #invalidate()} if the invalidate parameter
* is set to true; in that case the caller
* should not call {@link #invalidate()}.
+ *
+ *
*
* This method should be invoked every time a subclass directly updates the
* scroll parameters.
- *
- * Note: If the view has not explicitly requested
- * scrollbars prior calling this method, this is a no-op.
+ *
+ *
+ * @param startDelay the delay, in milliseconds, after which the animation
+ * should start; when the delay is 0, the animation starts
+ * immediately
+ *
+ * @param invalidate Whether this method should call invalidate
*
- * @param fadeOutDelay the delay in milliseconds before the fade out
- * animation should start, or 0 to start the animation
- * immediately
- * @param invalidate whether this method should call invalidate
* @return true if the animation is played, false otherwise
+ *
* @see #scrollBy(int, int)
* @see #scrollTo(int, int)
* @see #isHorizontalScrollBarEnabled()
@@ -11633,15 +11664,50 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @see #setHorizontalScrollBarEnabled(boolean)
* @see #setVerticalScrollBarEnabled(boolean)
*/
- protected boolean awakenScrollBars(int fadeOutDelay, boolean invalidate) {
- if (mScrollCache == null
- || (!isHorizontalScrollBarEnabled() && !isVerticalScrollBarEnabled())) {
- // We're not supposed to show scroll bars right now.
+ protected boolean awakenScrollBars(int startDelay, boolean invalidate) {
+ final ScrollabilityCache scrollCache = mScrollCache;
+
+ if (scrollCache == null || !scrollCache.fadeScrollBars) {
return false;
}
- mScrollCache.awakenScrollBars(fadeOutDelay);
- return true;
+ if (scrollCache.scrollBar == null) {
+ scrollCache.scrollBar = new ScrollBarDrawable();
+ scrollCache.scrollBar.setCallback(this);
+ scrollCache.scrollBar.setState(getDrawableState());
+ }
+
+ if (isHorizontalScrollBarEnabled() || isVerticalScrollBarEnabled()) {
+
+ if (invalidate) {
+ // Invalidate to show the scrollbars
+ postInvalidateOnAnimation();
+ }
+
+ if (scrollCache.state == ScrollabilityCache.OFF) {
+ // FIXME: this is copied from WindowManagerService.
+ // We should get this value from the system when it
+ // is possible to do so.
+ final int KEY_REPEAT_FIRST_DELAY = 750;
+ startDelay = Math.max(KEY_REPEAT_FIRST_DELAY, startDelay);
+ }
+
+ // Tell mScrollCache when we should start fading. This may
+ // extend the fade start time if one was already scheduled
+ long fadeStartTime = AnimationUtils.currentAnimationTimeMillis() + startDelay;
+ scrollCache.fadeStartTime = fadeStartTime;
+ scrollCache.state = ScrollabilityCache.ON;
+
+ // Schedule our fader to run, unscheduling any old ones first
+ if (mAttachInfo != null) {
+ mAttachInfo.mHandler.removeCallbacks(scrollCache);
+ mAttachInfo.mHandler.postAtTime(scrollCache, fadeStartTime);
+ }
+
+ return true;
+ }
+
+ return false;
}
/**
@@ -12322,7 +12388,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
public void setHorizontalFadingEdgeEnabled(boolean horizontalFadingEdgeEnabled) {
if (isHorizontalFadingEdgeEnabled() != horizontalFadingEdgeEnabled) {
if (horizontalFadingEdgeEnabled) {
- getScrollCache();
+ initScrollCache();
}
mViewFlags ^= FADING_EDGE_HORIZONTAL;
@@ -12359,7 +12425,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
public void setVerticalFadingEdgeEnabled(boolean verticalFadingEdgeEnabled) {
if (isVerticalFadingEdgeEnabled() != verticalFadingEdgeEnabled) {
if (verticalFadingEdgeEnabled) {
- getScrollCache();
+ initScrollCache();
}
mViewFlags ^= FADING_EDGE_VERTICAL;
@@ -12499,7 +12565,14 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @attr ref android.R.styleable#View_fadeScrollbars
*/
public void setScrollbarFadingEnabled(boolean fadeScrollbars) {
- getScrollCache().setFadingEnabled(fadeScrollbars);
+ initScrollCache();
+ final ScrollabilityCache scrollabilityCache = mScrollCache;
+ scrollabilityCache.fadeScrollBars = fadeScrollbars;
+ if (fadeScrollbars) {
+ scrollabilityCache.state = ScrollabilityCache.OFF;
+ } else {
+ scrollabilityCache.state = ScrollabilityCache.ON;
+ }
}
/**
@@ -12511,7 +12584,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
* @attr ref android.R.styleable#View_fadeScrollbars
*/
public boolean isScrollbarFadingEnabled() {
- return mScrollCache != null && mScrollCache.isFadingEnabled();
+ return mScrollCache != null && mScrollCache.fadeScrollBars;
}
/**
@@ -12793,85 +12866,129 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
/**
- * Request the drawing of the horizontal and the vertical scrollbar. The
- * scrollbars are painted only if they have been awakened first.
+ * Request the drawing of the horizontal and the vertical scrollbar. The
+ * scrollbars are painted only if they have been awakened first.
*
* @param canvas the canvas on which to draw the scrollbars
+ *
* @see #awakenScrollBars(int)
*/
protected final void onDrawScrollBars(Canvas canvas) {
+ // scrollbars are drawn only when the animation is running
final ScrollabilityCache cache = mScrollCache;
- if (cache == null) {
- // This view does not currently support scrolling.
- return;
- }
+ if (cache != null) {
- final int viewFlags = mViewFlags;
- final boolean drawHorizontalScrollBar =
- (viewFlags & SCROLLBARS_HORIZONTAL) == SCROLLBARS_HORIZONTAL;
- final boolean drawVerticalScrollBar =
- (viewFlags & SCROLLBARS_VERTICAL) == SCROLLBARS_VERTICAL
- && !isVerticalScrollBarHidden();
- if (!drawVerticalScrollBar && !drawHorizontalScrollBar) {
- // This view does not currently draw scrollbars.
- return;
- }
+ int state = cache.state;
- final ScrollBarDrawable scrollBar = cache.scrollBar;
- final int width = mRight - mLeft;
- final int height = mBottom - mTop;
- final int scrollX = mScrollX;
- final int scrollY = mScrollY;
- final int inside = (viewFlags & SCROLLBARS_OUTSIDE_MASK) == 0 ? ~0 : 0;
-
- if (drawHorizontalScrollBar) {
- int size = scrollBar.getSize(false);
- if (size <= 0) {
- size = cache.scrollBarSize;
+ if (state == ScrollabilityCache.OFF) {
+ return;
}
- scrollBar.setParameters(computeHorizontalScrollRange(), computeHorizontalScrollOffset(),
- computeHorizontalScrollExtent(), false);
- final int verticalScrollBarGap = drawVerticalScrollBar ?
- getVerticalScrollbarWidth() : 0;
+ boolean invalidate = false;
- final int left = scrollX + (mPaddingLeft & inside);
- final int right = scrollX + width - (mUserPaddingRight & inside) - verticalScrollBarGap;
- final int top = scrollY + height - size - (mUserPaddingBottom & inside);
- final int bottom = top + size;
+ if (state == ScrollabilityCache.FADING) {
+ // We're fading -- get our fade interpolation
+ if (cache.interpolatorValues == null) {
+ cache.interpolatorValues = new float[1];
+ }
- onDrawHorizontalScrollBar(canvas, scrollBar, left, top, right, bottom);
- }
+ float[] values = cache.interpolatorValues;
- if (drawVerticalScrollBar) {
- int size = scrollBar.getSize(true);
- if (size <= 0) {
- size = cache.scrollBarSize;
- }
+ // Stops the animation if we're done
+ if (cache.scrollBarInterpolator.timeToValues(values) ==
+ Interpolator.Result.FREEZE_END) {
+ cache.state = ScrollabilityCache.OFF;
+ } else {
+ cache.scrollBar.mutate().setAlpha(Math.round(values[0]));
+ }
- scrollBar.setParameters(computeVerticalScrollRange(), computeVerticalScrollOffset(),
- computeVerticalScrollExtent(), true);
-
- final int verticalScrollbarPosition;
- if (mVerticalScrollbarPosition == SCROLLBAR_POSITION_DEFAULT) {
- verticalScrollbarPosition = isLayoutRtl() ?
- SCROLLBAR_POSITION_LEFT : SCROLLBAR_POSITION_RIGHT;
+ // This will make the scroll bars inval themselves after
+ // drawing. We only want this when we're fading so that
+ // we prevent excessive redraws
+ invalidate = true;
} else {
- verticalScrollbarPosition = mVerticalScrollbarPosition;
+ // We're just on -- but we may have been fading before so
+ // reset alpha
+ cache.scrollBar.mutate().setAlpha(255);
}
- final int left;
- if (verticalScrollbarPosition == SCROLLBAR_POSITION_LEFT) {
- left = scrollX + (mUserPaddingLeft & inside);
- } else {
- left = scrollX + width - size - (mUserPaddingRight & inside);
+
+ final int viewFlags = mViewFlags;
+
+ final boolean drawHorizontalScrollBar =
+ (viewFlags & SCROLLBARS_HORIZONTAL) == SCROLLBARS_HORIZONTAL;
+ final boolean drawVerticalScrollBar =
+ (viewFlags & SCROLLBARS_VERTICAL) == SCROLLBARS_VERTICAL
+ && !isVerticalScrollBarHidden();
+
+ if (drawVerticalScrollBar || drawHorizontalScrollBar) {
+ final int width = mRight - mLeft;
+ final int height = mBottom - mTop;
+
+ final ScrollBarDrawable scrollBar = cache.scrollBar;
+
+ final int scrollX = mScrollX;
+ final int scrollY = mScrollY;
+ final int inside = (viewFlags & SCROLLBARS_OUTSIDE_MASK) == 0 ? ~0 : 0;
+
+ int left;
+ int top;
+ int right;
+ int bottom;
+
+ if (drawHorizontalScrollBar) {
+ int size = scrollBar.getSize(false);
+ if (size <= 0) {
+ size = cache.scrollBarSize;
+ }
+
+ scrollBar.setParameters(computeHorizontalScrollRange(),
+ computeHorizontalScrollOffset(),
+ computeHorizontalScrollExtent(), false);
+ final int verticalScrollBarGap = drawVerticalScrollBar ?
+ getVerticalScrollbarWidth() : 0;
+ top = scrollY + height - size - (mUserPaddingBottom & inside);
+ left = scrollX + (mPaddingLeft & inside);
+ right = scrollX + width - (mUserPaddingRight & inside) - verticalScrollBarGap;
+ bottom = top + size;
+ onDrawHorizontalScrollBar(canvas, scrollBar, left, top, right, bottom);
+ if (invalidate) {
+ invalidate(left, top, right, bottom);
+ }
+ }
+
+ if (drawVerticalScrollBar) {
+ int size = scrollBar.getSize(true);
+ if (size <= 0) {
+ size = cache.scrollBarSize;
+ }
+
+ scrollBar.setParameters(computeVerticalScrollRange(),
+ computeVerticalScrollOffset(),
+ computeVerticalScrollExtent(), true);
+ int verticalScrollbarPosition = mVerticalScrollbarPosition;
+ if (verticalScrollbarPosition == SCROLLBAR_POSITION_DEFAULT) {
+ verticalScrollbarPosition = isLayoutRtl() ?
+ SCROLLBAR_POSITION_LEFT : SCROLLBAR_POSITION_RIGHT;
+ }
+ switch (verticalScrollbarPosition) {
+ default:
+ case SCROLLBAR_POSITION_RIGHT:
+ left = scrollX + width - size - (mUserPaddingRight & inside);
+ break;
+ case SCROLLBAR_POSITION_LEFT:
+ left = scrollX + (mUserPaddingLeft & inside);
+ break;
+ }
+ top = scrollY + (mPaddingTop & inside);
+ right = left + size;
+ bottom = scrollY + height - (mUserPaddingBottom & inside);
+ onDrawVerticalScrollBar(canvas, scrollBar, left, top, right, bottom);
+ if (invalidate) {
+ invalidate(left, top, right, bottom);
+ }
+ }
}
-
- final int top = scrollY + (mPaddingTop & inside);
- final int right = left + size;
- final int bottom = scrollY + height - (mUserPaddingBottom & inside);
-
- onDrawVerticalScrollBar(canvas, scrollBar, left, top, right, bottom);
}
}
@@ -15235,7 +15352,7 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
canvas.saveLayer(right - length, top, right, bottom, null, flags);
}
} else {
- scrollabilityCache.setFadingEdgeColor(solidColor);
+ scrollabilityCache.setFadeColor(solidColor);
}
// Step 3, draw the content
@@ -15245,9 +15362,9 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
dispatchDraw(canvas);
// Step 5, draw the fade effect and restore layers
- final Paint p = scrollabilityCache.fadingEdgePaint;
+ final Paint p = scrollabilityCache.paint;
final Matrix matrix = scrollabilityCache.matrix;
- final Shader fade = scrollabilityCache.fadingEdgeShader;
+ final Shader fade = scrollabilityCache.shader;
if (drawTop) {
matrix.setScale(1, fadeHeight * topFadeStrength);
@@ -20507,164 +20624,121 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
}
/**
- * ScrollabilityCache holds various fields used by a View when scrolling
+ * ScrollabilityCache holds various fields used by a View when scrolling
* is supported. This avoids keeping too many unused fields in most
- * instances of View.
+ * instances of View.
*/
- private static class ScrollabilityCache {
- public final Paint fadingEdgePaint = new Paint();
- public final Matrix matrix = new Matrix();
-
- /** The view that owns this cache. */
- private final View mHost;
+ private static class ScrollabilityCache implements Runnable {
/**
- * Minimum delay in milliseconds before the fade-out animation begins.
- * Only used if the scrollbar was previously invisible.
+ * Scrollbars are not visible
*/
- private static final int MIN_FADE_DELAY_FROM_OFF = 750;
+ public static final int OFF = 0;
/**
- * Default delay in milliseconds before the fade-out animation begins.
+ * Scrollbars are visible
*/
+ public static final int ON = 1;
+
+ /**
+ * Scrollbars are fading away
+ */
+ public static final int FADING = 2;
+
+ public boolean fadeScrollBars;
+
+ public int fadingEdgeLength;
public int scrollBarDefaultDelayBeforeFade;
-
- /**
- * Delay in milliseconds before the fade-out animation begins. Only
- * used if the scrollbar is being shown to the user for the first time.
- */
- public int scrollBarDelayBeforeInitialFade;
-
- /** Duration in milliseconds of the fade-out animation. */
public int scrollBarFadeDuration;
- public ScrollBarDrawable scrollBar;
- public Shader fadingEdgeShader;
- public int fadingEdgeLength;
public int scrollBarSize;
+ public ScrollBarDrawable scrollBar;
+ public float[] interpolatorValues;
+ public View host;
+
+ public final Paint paint;
+ public final Matrix matrix;
+ public Shader shader;
+
+ public final Interpolator scrollBarInterpolator = new Interpolator(1, 2);
+
+ private static final float[] OPAQUE = { 255 };
+ private static final float[] TRANSPARENT = { 0.0f };
/**
- * Whether scrollbar fading is enabled. If false, scrollbars are always
- * visible.
+ * When fading should start. This time moves into the future every time
+ * a new scroll happens. Measured based on SystemClock.uptimeMillis()
*/
- private boolean mIsFadingEnabled;
+ public long fadeStartTime;
- private Animator mFadeAnim;
- private int mFadingEdgeLastColor;
- public ScrollabilityCache(View host) {
- mHost = host;
+ /**
+ * The current state of the scrollbars: ON, OFF, or FADING
+ */
+ public int state = OFF;
- scrollBarFadeDuration = ViewConfiguration.getScrollBarFadeDuration();
- scrollBarDefaultDelayBeforeFade = ViewConfiguration.getScrollDefaultDelay();
- scrollBarDelayBeforeInitialFade = ViewConfiguration.getScrollDefaultInitialDelay();
+ private int mLastColor;
- final ViewConfiguration configuration = ViewConfiguration.get(host.getContext());
- scrollBarSize = configuration.getScaledScrollBarSize();
+ public ScrollabilityCache(ViewConfiguration configuration, View host) {
fadingEdgeLength = configuration.getScaledFadingEdgeLength();
+ scrollBarSize = configuration.getScaledScrollBarSize();
+ scrollBarDefaultDelayBeforeFade = ViewConfiguration.getScrollDefaultDelay();
+ scrollBarFadeDuration = ViewConfiguration.getScrollBarFadeDuration();
- // Force the fading edge color to change.
- mFadingEdgeLastColor = -1;
- setFadingEdgeColor(0);
+ paint = new Paint();
+ matrix = new Matrix();
+ // use use a height of 1, and then wack the matrix each time we
+ // actually use it.
+ shader = new LinearGradient(0, 0, 0, 1, 0xFF000000, 0, Shader.TileMode.CLAMP);
+ paint.setShader(shader);
+ paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
+
+ this.host = host;
}
- public void setFadingEdgeColor(int color) {
- if (mFadingEdgeLastColor != color) {
- mFadingEdgeLastColor = color;
+ public void setFadeColor(int color) {
+ if (color != mLastColor) {
+ mLastColor = color;
- final int color0;
- final int color1;
- final PorterDuffXfermode xfermode;
if (color != 0) {
- color0 = color | 0xFF000000;
- color1 = color & 0x00FFFFFF;
- xfermode = null;
+ shader = new LinearGradient(0, 0, 0, 1, color | 0xFF000000,
+ color & 0x00FFFFFF, Shader.TileMode.CLAMP);
+ paint.setShader(shader);
+ // Restore the default transfer mode (src_over)
+ paint.setXfermode(null);
} else {
- color0 = 0xFF000000;
- color1 = 0;
- xfermode = new PorterDuffXfermode(PorterDuff.Mode.DST_OUT);
+ shader = new LinearGradient(0, 0, 0, 1, 0xFF000000, 0, Shader.TileMode.CLAMP);
+ paint.setShader(shader);
+ paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
}
-
- // Use a height of 1 and then whack the matrix each time we
- // actually use it.
- fadingEdgeShader = new LinearGradient(
- 0, 0, 0, 1, color0, color1, Shader.TileMode.CLAMP);
- fadingEdgePaint.setShader(fadingEdgeShader);
- fadingEdgePaint.setXfermode(xfermode);
}
}
- public void setFadingEnabled(boolean enabled) {
- if (mIsFadingEnabled != enabled) {
- mIsFadingEnabled = enabled;
+ public void run() {
+ long now = AnimationUtils.currentAnimationTimeMillis();
+ if (now >= fadeStartTime) {
- setFadingAlpha(enabled ? 0 : 255);
+ // the animation fades the scrollbars out by changing
+ // the opacity (alpha) from fully opaque to fully
+ // transparent
+ int nextFrame = (int) now;
+ int framesCount = 0;
+
+ Interpolator interpolator = scrollBarInterpolator;
+
+ // Start opaque
+ interpolator.setKeyFrame(framesCount++, nextFrame, OPAQUE);
+
+ // End transparent
+ nextFrame += scrollBarFadeDuration;
+ interpolator.setKeyFrame(framesCount, nextFrame, TRANSPARENT);
+
+ state = FADING;
+
+ // Kick off the fade animation
+ host.invalidate(true);
}
}
-
- public boolean isFadingEnabled() {
- return mIsFadingEnabled;
- }
-
- /**
- * Cancels any ongoing or pending fade animations and immediately sets
- * the scroll bar alpha value.
- *
- * @param alpha the scrollbar alpha value
- */
- public void setFadingAlpha(int alpha) {
- if (mFadeAnim != null) {
- mFadeAnim.cancel();
- mFadeAnim = null;
- }
- mHost.removeCallbacks(mFadeOutRunnable);
-
- scrollBar.setAlpha(alpha);
- }
-
- /**
- * If fading is enabled, cancels any ongoing or pending fade animations
- * and immediately sets the scroll bar alpha value to the maximum, then
- * posts a delayed fade-out animation.
- *
- * @param fadeOutDelay the delay before the fade-out animation starts
- * @return {@code true} if the scroll bars changed, false otherwise
- */
- public boolean awakenScrollBars(int fadeOutDelay) {
- if (!mIsFadingEnabled) {
- return false;
- }
-
- if (scrollBar == null) {
- scrollBar = new ScrollBarDrawable();
- scrollBar.setCallback(mHost);
- scrollBar.setState(mHost.getDrawableState());
- }
-
- // Removes pending callbacks.
- setFadingAlpha(255);
-
- final int startingAlpha = scrollBar.getAlpha();
- if (startingAlpha == 0) {
- fadeOutDelay = Math.max(ScrollabilityCache.MIN_FADE_DELAY_FROM_OFF, fadeOutDelay);
- }
-
- mHost.postDelayed(mFadeOutRunnable, fadeOutDelay);
-
- return true;
- }
-
- private final Runnable mFadeOutRunnable = new Runnable() {
- @Override
- public void run() {
- final ObjectAnimator anim = ObjectAnimator.ofInt(
- scrollBar, ScrollBarDrawable.ALPHA, 0);
- anim.setDuration(scrollBarFadeDuration);
- anim.start();
-
- mFadeAnim = anim;
- }
- };
}
/**
diff --git a/core/java/android/view/ViewConfiguration.java b/core/java/android/view/ViewConfiguration.java
index d7335137140e9..4e91ad4db9778 100644
--- a/core/java/android/view/ViewConfiguration.java
+++ b/core/java/android/view/ViewConfiguration.java
@@ -46,12 +46,6 @@ public class ViewConfiguration {
*/
private static final int SCROLL_BAR_DEFAULT_DELAY = 300;
- /**
- * Default delay before the scrollbars fade in milliseconds for the first
- * time they are shown to the user.
- */
- private static final int SCROLL_BAR_DEFAULT_INITIAL_DELAY = 1500;
-
/**
* Defines the length of the fading edges in dips
*/
@@ -401,22 +395,12 @@ public class ViewConfiguration {
}
/**
- * @return Default delay in milliseconds before the scrollbars fade out
- * after they have been awoken.
+ * @return Default delay before the scrollbars fade in milliseconds
*/
public static int getScrollDefaultDelay() {
return SCROLL_BAR_DEFAULT_DELAY;
}
- /**
- * @return Default delay in milliseconds before the scrollbars fade out
- * after they are initially shown to the user.
- * @hide Pending cleanup of ViewConfiguration values.
- */
- public static int getScrollDefaultInitialDelay() {
- return SCROLL_BAR_DEFAULT_INITIAL_DELAY;
- }
-
/**
* @return the length of the fading edges in dips
*
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index 98767a700791f..247f94a8debf4 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -39,7 +39,6 @@ import android.graphics.Xfermode;
import android.os.Trace;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
-import android.util.IntProperty;
import android.util.StateSet;
import android.util.TypedValue;
import android.util.Xml;
@@ -1372,20 +1371,5 @@ public abstract class Drawable {
default: return defaultMode;
}
}
-
- /** @hide */
- public static final IntProperty ALPHA = new IntProperty("alpha") {
- @Override
- public void setValue(Drawable object, int value) {
- object.mutate();
- object.setAlpha(value);
- object.invalidateSelf();
- }
-
- @Override
- public Integer get(Drawable object) {
- return object.getAlpha();
- }
- };
}
From d7bc4e4360ddebf23e92a76adfcf0376ffb19e2b Mon Sep 17 00:00:00 2001
From: Winson Chung
Date: Mon, 2 Mar 2015 10:19:23 -0800
Subject: [PATCH 71/93] Force single stack id workaround. (Bug 19560619)
Change-Id: Ia3cbe0ca75b018bf499a814f37d8a532d52981f1
---
.../com/android/systemui/recents/model/RecentsTaskLoadPlan.java | 1 +
1 file changed, 1 insertion(+)
diff --git a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
index 788e473998118..5d98dda71e6c3 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/model/RecentsTaskLoadPlan.java
@@ -156,6 +156,7 @@ public class RecentsTaskLoadPlan {
if (!mConfig.multiStackEnabled ||
Constants.DebugFlags.App.EnableMultiStackToSingleStack) {
+ firstStackId = 0;
ArrayList stackTasks = stacksTasks.get(firstStackId);
if (stackTasks == null) {
stackTasks = new ArrayList();
From 604ed5b757ff814378f32cf9a9bf5b75e42be38a Mon Sep 17 00:00:00 2001
From: Alan Viverette
Date: Mon, 2 Mar 2015 12:40:34 -0800
Subject: [PATCH 72/93] Improve handling of activity destroy during popup exit
animation
Ensures the decor view isn't double-removed and that we don't try to
dereference a null anchor view.
Bug: 19553353
Bug: 19551371
Change-Id: I191a41f9065b68e49d66f96794cb7456f79d2d34
---
core/java/android/widget/PopupWindow.java | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index a929f3dfd5a07..399f4c5a65cac 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -160,14 +160,14 @@ public class PopupWindow {
private final EpicenterCallback mEpicenterCallback = new EpicenterCallback() {
@Override
public Rect onGetEpicenter(Transition transition) {
- final View anchor = mAnchor.get();
+ final View anchor = mAnchor != null ? mAnchor.get() : null;
final View decor = mDecorView;
if (anchor == null || decor == null) {
return null;
}
final Rect anchorBounds = mAnchorBounds;
- final int[] anchorLocation = mAnchor.get().getLocationOnScreen();
+ final int[] anchorLocation = anchor.getLocationOnScreen();
final int[] popupLocation = mDecorView.getLocationOnScreen();
// Compute the position of the anchor relative to the popup.
@@ -1632,8 +1632,14 @@ public class PopupWindow {
* view hierarchy, if necessary.
*/
private void dismissImmediate(View contentView) {
+ if (mDecorView == null || mBackgroundView == null) {
+ throw new RuntimeException("Popup window already dismissed");
+ }
+
try {
- mWindowManager.removeViewImmediate(mDecorView);
+ if (mDecorView.isAttachedToWindow()) {
+ mWindowManager.removeViewImmediate(mDecorView);
+ }
} finally {
mDecorView.removeView(mBackgroundView);
mDecorView = null;
From 698c111af459f055c123e76469c6acdbebc3af56 Mon Sep 17 00:00:00 2001
From: Svetoslav
Date: Mon, 2 Mar 2015 16:21:35 -0800
Subject: [PATCH 73/93] Content and settings shell commands passing invalid
calling package.
Change-Id: Ia80099ba0afba054b70511c0d95265ec303446e0
---
.../com/android/commands/content/Content.java | 26 ++++++++++++++++---
.../commands/settings/SettingsCmd.java | 24 ++++++++++++++---
2 files changed, 42 insertions(+), 8 deletions(-)
diff --git a/cmds/content/src/com/android/commands/content/Content.java b/cmds/content/src/com/android/commands/content/Content.java
index bd34a9c2ed4b5..c0ed8935dc2c7 100644
--- a/cmds/content/src/com/android/commands/content/Content.java
+++ b/cmds/content/src/com/android/commands/content/Content.java
@@ -27,6 +27,7 @@ import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
+import android.os.Process;
import android.os.UserHandle;
import android.text.TextUtils;
@@ -426,6 +427,22 @@ public class Content {
}
}
+ public static String resolveCallingPackage() {
+ switch (Process.myUid()) {
+ case Process.ROOT_UID: {
+ return "root";
+ }
+
+ case Process.SHELL_UID: {
+ return "com.android.shell";
+ }
+
+ default: {
+ return null;
+ }
+ }
+ }
+
protected abstract void onExecute(IContentProvider provider) throws Exception;
}
@@ -439,7 +456,7 @@ public class Content {
@Override
public void onExecute(IContentProvider provider) throws Exception {
- provider.insert(null, mUri, mContentValues);
+ provider.insert(resolveCallingPackage(), mUri, mContentValues);
}
}
@@ -453,7 +470,7 @@ public class Content {
@Override
public void onExecute(IContentProvider provider) throws Exception {
- provider.delete(null, mUri, mWhere, null);
+ provider.delete(resolveCallingPackage(), mUri, mWhere, null);
}
}
@@ -532,7 +549,8 @@ public class Content {
@Override
public void onExecute(IContentProvider provider) throws Exception {
- Cursor cursor = provider.query(null, mUri, mProjection, mWhere, null, mSortOrder, null);
+ Cursor cursor = provider.query(resolveCallingPackage(), mUri, mProjection, mWhere,
+ null, mSortOrder, null);
if (cursor == null) {
System.out.println("No result found.");
return;
@@ -594,7 +612,7 @@ public class Content {
@Override
public void onExecute(IContentProvider provider) throws Exception {
- provider.update(null, mUri, mContentValues, mWhere, null);
+ provider.update(resolveCallingPackage(), mUri, mContentValues, mWhere, null);
}
}
diff --git a/cmds/settings/src/com/android/commands/settings/SettingsCmd.java b/cmds/settings/src/com/android/commands/settings/SettingsCmd.java
index e6847a9946cf8..a31b150dd4fef 100644
--- a/cmds/settings/src/com/android/commands/settings/SettingsCmd.java
+++ b/cmds/settings/src/com/android/commands/settings/SettingsCmd.java
@@ -24,12 +24,12 @@ import android.net.Uri;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
+import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.Settings;
public final class SettingsCmd {
- static final String TAG = "settings";
enum CommandVerb {
UNSPECIFIED,
@@ -188,7 +188,7 @@ public final class SettingsCmd {
try {
Bundle arg = new Bundle();
arg.putInt(Settings.CALL_METHOD_USER_KEY, userHandle);
- Bundle b = provider.call(null, callGetCommand, key, arg);
+ Bundle b = provider.call(resolveCallingPackage(), callGetCommand, key, arg);
if (b != null) {
result = b.getPairValue();
}
@@ -213,7 +213,7 @@ public final class SettingsCmd {
Bundle arg = new Bundle();
arg.putString(Settings.NameValueTable.VALUE, value);
arg.putInt(Settings.CALL_METHOD_USER_KEY, userHandle);
- provider.call(null, callPutCommand, key, arg);
+ provider.call(resolveCallingPackage(), callPutCommand, key, arg);
} catch (RemoteException e) {
System.err.println("Can't set key " + key + " in " + table + " for user " + userHandle);
}
@@ -232,7 +232,7 @@ public final class SettingsCmd {
int num = 0;
try {
- num = provider.delete(null, targetUri, null, null);
+ num = provider.delete(resolveCallingPackage(), targetUri, null, null);
} catch (RemoteException e) {
System.err.println("Can't clear key " + key + " in " + table + " for user "
+ userHandle);
@@ -247,4 +247,20 @@ public final class SettingsCmd {
System.err.println("\n'namespace' is one of {system, secure, global}, case-insensitive");
System.err.println("If '--user NUM' is not given, the operations are performed on the owner user.");
}
+
+ public static String resolveCallingPackage() {
+ switch (android.os.Process.myUid()) {
+ case Process.ROOT_UID: {
+ return "root";
+ }
+
+ case Process.SHELL_UID: {
+ return "com.android.shell";
+ }
+
+ default: {
+ return null;
+ }
+ }
+ }
}
From 0959417220a2243282ea667fbe855e16d6212967 Mon Sep 17 00:00:00 2001
From: Amith Yamasani
Date: Wed, 4 Mar 2015 10:00:11 -0800
Subject: [PATCH 74/93] Fix a regression in UsbDebuggingManager
Catch NPE as well if socket object is null.
Bug: 19602060
Change-Id: I7cf9cb16abc3fde626170c1aefeba5fc91c5734f
---
.../usb/java/com/android/server/usb/UsbDebuggingManager.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/services/usb/java/com/android/server/usb/UsbDebuggingManager.java b/services/usb/java/com/android/server/usb/UsbDebuggingManager.java
index b3900b9062ec4..8849acd11ab12 100644
--- a/services/usb/java/com/android/server/usb/UsbDebuggingManager.java
+++ b/services/usb/java/com/android/server/usb/UsbDebuggingManager.java
@@ -96,7 +96,7 @@ public class UsbDebuggingManager {
}
try {
listenToSocket();
- } catch (IOException e) {
+ } catch (Exception e) {
/* Don't loop too fast if adbd dies, before init restarts it */
SystemClock.sleep(1000);
}
From e9c132a274389ad316a2049148c19943ac0af02a Mon Sep 17 00:00:00 2001
From: Chris Craik
Date: Wed, 4 Mar 2015 14:25:09 -0800
Subject: [PATCH 75/93] Temporarily disable Patch glops
bug:19597454
Change-Id: I9dbe781a714582717a5585113b9a56821265b36e
---
libs/hwui/OpenGLRenderer.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index eef4b73572190..76a42c020e0ae 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -2329,7 +2329,7 @@ void OpenGLRenderer::drawPatch(const SkBitmap* bitmap, const Patch* mesh,
Texture* texture = entry ? entry->texture : mCaches.textureCache.get(bitmap);
if (!texture) return;
- if (USE_GLOPS) {
+ if (false) {
// 9 patches are built for stretching - always filter
int textureFillFlags = static_cast(TextureFillFlags::kForceFilter);
if (bitmap->colorType() == kAlpha_8_SkColorType) {
From 3ca749ba7814428e79a835fb55878c234573f1fd Mon Sep 17 00:00:00 2001
From: George Mount
Date: Thu, 5 Mar 2015 14:09:33 -0800
Subject: [PATCH 76/93] Handle null epicenters in EpicenterClipReveal.
Bug 19617067
Change-Id: Ie288288f7a8e0c95ed07d8beb40b78f80048fa98
---
.../transition/EpicenterClipReveal.java | 33 +++++++++++++++----
1 file changed, 27 insertions(+), 6 deletions(-)
diff --git a/core/java/com/android/internal/transition/EpicenterClipReveal.java b/core/java/com/android/internal/transition/EpicenterClipReveal.java
index d8a7f16b607a8..abb50c1df692e 100644
--- a/core/java/com/android/internal/transition/EpicenterClipReveal.java
+++ b/core/java/com/android/internal/transition/EpicenterClipReveal.java
@@ -16,6 +16,7 @@
package com.android.internal.transition;
import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.RectEvaluator;
import android.content.Context;
@@ -75,13 +76,13 @@ public class EpicenterClipReveal extends Visibility {
return null;
}
- final Rect start = getEpicenter();
final Rect end = getBestRect(endValues);
+ final Rect start = getEpicenterOrCenter(end);
// Prepare the view.
view.setClipBounds(start);
- return createRectAnimator(view, start, end);
+ return createRectAnimator(view, start, end, endValues);
}
@Override
@@ -92,12 +93,23 @@ public class EpicenterClipReveal extends Visibility {
}
final Rect start = getBestRect(startValues);
- final Rect end = getEpicenter();
+ final Rect end = getEpicenterOrCenter(start);
// Prepare the view.
view.setClipBounds(start);
- return createRectAnimator(view, start, end);
+ return createRectAnimator(view, start, end, endValues);
+ }
+
+ private Rect getEpicenterOrCenter(Rect bestRect) {
+ final Rect epicenter = getEpicenter();
+ if (epicenter != null) {
+ return epicenter;
+ }
+
+ int centerX = bestRect.centerX();
+ int centerY = bestRect.centerY();
+ return new Rect(centerX, centerY, centerX, centerY);
}
private Rect getBestRect(TransitionValues values) {
@@ -108,8 +120,17 @@ public class EpicenterClipReveal extends Visibility {
return clipRect;
}
- private Animator createRectAnimator(View view, Rect start, Rect end) {
+ private Animator createRectAnimator(final View view, Rect start, Rect end,
+ TransitionValues endValues) {
+ final Rect terminalClip = (Rect) endValues.values.get(PROPNAME_CLIP);
final RectEvaluator evaluator = new RectEvaluator(new Rect());
- return ObjectAnimator.ofObject(view, "clipBounds", evaluator, start, end);
+ ObjectAnimator anim = ObjectAnimator.ofObject(view, "clipBounds", evaluator, start, end);
+ anim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ view.setClipBounds(terminalClip);
+ }
+ });
+ return anim;
}
}
From 9e011b107a35446d6851d8112bed2540a6a6d9b7 Mon Sep 17 00:00:00 2001
From: John Spurlock
Date: Mon, 9 Mar 2015 14:21:20 -0400
Subject: [PATCH 77/93] AudioService: Fix device dump in dumpsys output.
Bug: 19653026
Change-Id: Id09a502f1507477403c49be32ee0ed0f00ab288f
---
services/core/java/com/android/server/audio/AudioService.java | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 5d386bd5ba487..61a7263935deb 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -3620,7 +3620,9 @@ public class AudioService extends IAudioService.Stub {
pw.print(" Devices: ");
final int devices = AudioSystem.getDevicesForStream(mStreamType);
int device, i = 0, n = 0;
- while ((device = 1 << i) <= AudioSystem.DEVICE_OUT_DEFAULT) {
+ // iterate all devices from 1 to DEVICE_OUT_DEFAULT exclusive
+ // (the default device is not returned by getDevicesForStream)
+ while ((device = 1 << i) != AudioSystem.DEVICE_OUT_DEFAULT) {
if ((devices & device) != 0) {
if (n++ > 0) {
pw.print(", ");
From 794916c129aa18a1dbb8c80dd298b173c7b59e59 Mon Sep 17 00:00:00 2001
From: Chris Craik
Date: Fri, 6 Mar 2015 17:30:11 -0800
Subject: [PATCH 78/93] Rewrite glop texture asserts
bug:19641517
Also switch Glop VertexAttribFlags to use int for group of flags.
Change-Id: Ib7b1934197a62206a55baa6ab484ac59f5bec816
---
libs/hwui/Glop.h | 2 +-
libs/hwui/GlopBuilder.cpp | 51 +++++++++++++++++----------
libs/hwui/renderstate/RenderState.cpp | 12 +++----
3 files changed, 39 insertions(+), 26 deletions(-)
diff --git a/libs/hwui/Glop.h b/libs/hwui/Glop.h
index 62da6e0865318..2c6f6c120d168 100644
--- a/libs/hwui/Glop.h
+++ b/libs/hwui/Glop.h
@@ -78,7 +78,7 @@ struct Glop {
// TODO: enforce mutual exclusion with restricted setters and/or unions
struct Vertices {
GLuint bufferObject;
- VertexAttribFlags flags;
+ int attribFlags;
const void* position;
const void* texCoord;
const void* color;
diff --git a/libs/hwui/GlopBuilder.cpp b/libs/hwui/GlopBuilder.cpp
index 711b11c618966..1d0795166c95c 100644
--- a/libs/hwui/GlopBuilder.cpp
+++ b/libs/hwui/GlopBuilder.cpp
@@ -66,7 +66,7 @@ GlopBuilder& GlopBuilder::setMeshUnitQuad() {
mOutGlop->mesh.indices = { 0, nullptr };
mOutGlop->mesh.vertices = {
mRenderState.meshState().getUnitQuadVBO(),
- VertexAttribFlags::kNone,
+ static_cast(VertexAttribFlags::kNone),
nullptr, nullptr, nullptr,
kTextureVertexStride };
mOutGlop->mesh.elementCount = 4;
@@ -85,7 +85,7 @@ GlopBuilder& GlopBuilder::setMeshTexturedUnitQuad(const UvMapper* uvMapper) {
mOutGlop->mesh.indices = { 0, nullptr };
mOutGlop->mesh.vertices = {
mRenderState.meshState().getUnitQuadVBO(),
- VertexAttribFlags::kTextureCoord,
+ static_cast(VertexAttribFlags::kTextureCoord),
nullptr, (const void*) kMeshTextureOffset, nullptr,
kTextureVertexStride };
mOutGlop->mesh.elementCount = 4;
@@ -105,7 +105,7 @@ GlopBuilder& GlopBuilder::setMeshTexturedUvQuad(const UvMapper* uvMapper, Rect u
mOutGlop->mesh.indices = { 0, nullptr };
mOutGlop->mesh.vertices = {
0,
- VertexAttribFlags::kTextureCoord,
+ static_cast(VertexAttribFlags::kTextureCoord),
&textureVertex[0].x, &textureVertex[0].u, nullptr,
kTextureVertexStride };
mOutGlop->mesh.elementCount = 4;
@@ -119,7 +119,7 @@ GlopBuilder& GlopBuilder::setMeshIndexedQuads(Vertex* vertexData, int quadCount)
mOutGlop->mesh.indices = { mRenderState.meshState().getQuadListIBO(), nullptr };
mOutGlop->mesh.vertices = {
0,
- VertexAttribFlags::kNone,
+ static_cast(VertexAttribFlags::kNone),
vertexData, nullptr, nullptr,
kVertexStride };
mOutGlop->mesh.elementCount = 6 * quadCount;
@@ -133,7 +133,7 @@ GlopBuilder& GlopBuilder::setMeshTexturedIndexedQuads(TextureVertex* vertexData,
mOutGlop->mesh.indices = { mRenderState.meshState().getQuadListIBO(), nullptr };
mOutGlop->mesh.vertices = {
0,
- VertexAttribFlags::kTextureCoord,
+ static_cast(VertexAttribFlags::kTextureCoord),
&vertexData[0].x, &vertexData[0].u, nullptr,
kTextureVertexStride };
mOutGlop->mesh.elementCount = elementCount;
@@ -147,7 +147,7 @@ GlopBuilder& GlopBuilder::setMeshTexturedMesh(TextureVertex* vertexData, int ele
mOutGlop->mesh.indices = { 0, nullptr };
mOutGlop->mesh.vertices = {
0,
- VertexAttribFlags::kTextureCoord,
+ static_cast(VertexAttribFlags::kTextureCoord),
&vertexData[0].x, &vertexData[0].u, nullptr,
kTextureVertexStride };
mOutGlop->mesh.elementCount = elementCount;
@@ -161,7 +161,7 @@ GlopBuilder& GlopBuilder::setMeshColoredTexturedMesh(ColorTextureVertex* vertexD
mOutGlop->mesh.indices = { 0, nullptr };
mOutGlop->mesh.vertices = {
0,
- static_cast(VertexAttribFlags::kTextureCoord | VertexAttribFlags::kColor),
+ VertexAttribFlags::kTextureCoord | VertexAttribFlags::kColor,
&vertexData[0].x, &vertexData[0].u, &vertexData[0].r,
kColorTextureVertexStride };
mOutGlop->mesh.elementCount = elementCount;
@@ -180,7 +180,7 @@ GlopBuilder& GlopBuilder::setMeshVertexBuffer(const VertexBuffer& vertexBuffer,
mOutGlop->mesh.indices = { 0, vertexBuffer.getIndices() };
mOutGlop->mesh.vertices = {
0,
- alphaVertex ? VertexAttribFlags::kAlpha : VertexAttribFlags::kNone,
+ static_cast(alphaVertex ? VertexAttribFlags::kAlpha : VertexAttribFlags::kNone),
vertexBuffer.getBuffer(), nullptr, nullptr,
alphaVertex ? kAlphaVertexStride : kVertexStride };
mOutGlop->mesh.elementCount = indices
@@ -197,7 +197,7 @@ GlopBuilder& GlopBuilder::setMeshPatchQuads(const Patch& patch) {
mOutGlop->mesh.indices = { mRenderState.meshState().getQuadListIBO(), nullptr };
mOutGlop->mesh.vertices = {
mCaches.patchCache.getMeshBuffer(),
- VertexAttribFlags::kTextureCoord,
+ static_cast(VertexAttribFlags::kTextureCoord),
(void*)patch.positionOffset, (void*)patch.textureOffset, nullptr,
kTextureVertexStride };
mOutGlop->mesh.elementCount = patch.indexCount;
@@ -230,7 +230,7 @@ void GlopBuilder::setFill(int color, float alphaScale, SkXfermode::Mode mode,
mOutGlop->blend = { GL_ZERO, GL_ZERO };
if (mOutGlop->fill.color.a < 1.0f
- || (mOutGlop->mesh.vertices.flags & VertexAttribFlags::kAlpha)
+ || (mOutGlop->mesh.vertices.attribFlags & VertexAttribFlags::kAlpha)
|| (mOutGlop->fill.texture.texture && mOutGlop->fill.texture.texture->blend)
|| mOutGlop->roundRectClipState
|| PaintUtils::isBlendedShader(shader)
@@ -324,7 +324,7 @@ GlopBuilder& GlopBuilder::setFillTexturePaint(Texture& texture, int textureFillF
const bool SWAP_SRC_DST = false;
if (alphaScale < 1.0f
- || (mOutGlop->mesh.vertices.flags & VertexAttribFlags::kAlpha)
+ || (mOutGlop->mesh.vertices.attribFlags & VertexAttribFlags::kAlpha)
|| texture.blend
|| mOutGlop->roundRectClipState) {
Blend::getFactors(SkXfermode::kSrcOver_Mode, SWAP_SRC_DST,
@@ -540,12 +540,25 @@ GlopBuilder& GlopBuilder::setRoundRectClipState(const RoundRectClipState* roundR
////////////////////////////////////////////////////////////////////////////////
void verify(const ProgramDescription& description, const Glop& glop) {
- bool hasTexture = glop.fill.texture.texture != nullptr;
- LOG_ALWAYS_FATAL_IF(description.hasTexture && description.hasExternalTexture);
- LOG_ALWAYS_FATAL_IF((description.hasTexture || description.hasExternalTexture )!= hasTexture);
- LOG_ALWAYS_FATAL_IF((glop.mesh.vertices.flags & VertexAttribFlags::kTextureCoord) != hasTexture);
+ if (glop.fill.texture.texture != nullptr) {
+ LOG_ALWAYS_FATAL_IF(((description.hasTexture && description.hasExternalTexture)
+ || (!description.hasTexture && !description.hasExternalTexture)
+ || ((glop.mesh.vertices.attribFlags & VertexAttribFlags::kTextureCoord) == 0)),
+ "Texture %p, hT%d, hET %d, attribFlags %x",
+ glop.fill.texture.texture,
+ description.hasTexture, description.hasExternalTexture,
+ glop.mesh.vertices.attribFlags);
+ } else {
+ LOG_ALWAYS_FATAL_IF((description.hasTexture
+ || description.hasExternalTexture
+ || ((glop.mesh.vertices.attribFlags & VertexAttribFlags::kTextureCoord) != 0)),
+ "No texture, hT%d, hET %d, attribFlags %x",
+ description.hasTexture, description.hasExternalTexture,
+ glop.mesh.vertices.attribFlags);
+ }
- if ((glop.mesh.vertices.flags & VertexAttribFlags::kAlpha) && glop.mesh.vertices.bufferObject) {
+ if ((glop.mesh.vertices.attribFlags & VertexAttribFlags::kAlpha)
+ && glop.mesh.vertices.bufferObject) {
LOG_ALWAYS_FATAL("VBO and alpha attributes are not currently compatible");
}
@@ -556,12 +569,12 @@ void verify(const ProgramDescription& description, const Glop& glop) {
void GlopBuilder::build() {
REQUIRE_STAGES(kAllStages);
- if (mOutGlop->mesh.vertices.flags & VertexAttribFlags::kTextureCoord) {
+ if (mOutGlop->mesh.vertices.attribFlags & VertexAttribFlags::kTextureCoord) {
mDescription.hasTexture = mOutGlop->fill.texture.target == GL_TEXTURE_2D;
mDescription.hasExternalTexture = mOutGlop->fill.texture.target == GL_TEXTURE_EXTERNAL_OES;
}
- mDescription.hasColors = mOutGlop->mesh.vertices.flags & VertexAttribFlags::kColor;
- mDescription.hasVertexAlpha = mOutGlop->mesh.vertices.flags & VertexAttribFlags::kAlpha;
+ mDescription.hasColors = mOutGlop->mesh.vertices.attribFlags & VertexAttribFlags::kColor;
+ mDescription.hasVertexAlpha = mOutGlop->mesh.vertices.attribFlags & VertexAttribFlags::kAlpha;
// serialize shader info into ShaderData
GLuint textureUnit = mOutGlop->fill.texture.texture ? 1 : 0;
diff --git a/libs/hwui/renderstate/RenderState.cpp b/libs/hwui/renderstate/RenderState.cpp
index ca3a4c2f2f307..7b44d6db9a819 100644
--- a/libs/hwui/renderstate/RenderState.cpp
+++ b/libs/hwui/renderstate/RenderState.cpp
@@ -259,7 +259,7 @@ void RenderState::render(const Glop& glop) {
// indices
meshState().bindIndicesBufferInternal(indices.bufferObject);
- if (vertices.flags & VertexAttribFlags::kTextureCoord) {
+ if (vertices.attribFlags & VertexAttribFlags::kTextureCoord) {
const Glop::Fill::TextureData& texture = fill.texture;
// texture always takes slot 0, shader samplers increment from there
mCaches->textureState().activateTexture(0);
@@ -283,13 +283,13 @@ void RenderState::render(const Glop& glop) {
meshState().disableTexCoordsVertexArray();
}
int colorLocation = -1;
- if (vertices.flags & VertexAttribFlags::kColor) {
+ if (vertices.attribFlags & VertexAttribFlags::kColor) {
colorLocation = fill.program->getAttrib("colors");
glEnableVertexAttribArray(colorLocation);
glVertexAttribPointer(colorLocation, 4, GL_FLOAT, GL_FALSE, vertices.stride, vertices.color);
}
int alphaLocation = -1;
- if (vertices.flags & VertexAttribFlags::kAlpha) {
+ if (vertices.attribFlags & VertexAttribFlags::kAlpha) {
// NOTE: alpha vertex position is computed assuming no VBO
const void* alphaCoords = ((const GLbyte*) vertices.position) + kVertexAlphaOffset;
alphaLocation = fill.program->getAttrib("vtxAlpha");
@@ -317,7 +317,7 @@ void RenderState::render(const Glop& glop) {
// rebind pointers without forcing, since initial bind handled above
meshState().bindPositionVertexPointer(false, vertexData, vertices.stride);
- if (vertices.flags & VertexAttribFlags::kTextureCoord) {
+ if (vertices.attribFlags & VertexAttribFlags::kTextureCoord) {
meshState().bindTexCoordsVertexPointer(false,
vertexData + kMeshTextureOffset, vertices.stride);
}
@@ -335,10 +335,10 @@ void RenderState::render(const Glop& glop) {
// -----------------------------------
// ---------- Mesh teardown ----------
// -----------------------------------
- if (vertices.flags & VertexAttribFlags::kAlpha) {
+ if (vertices.attribFlags & VertexAttribFlags::kAlpha) {
glDisableVertexAttribArray(alphaLocation);
}
- if (vertices.flags & VertexAttribFlags::kColor) {
+ if (vertices.attribFlags & VertexAttribFlags::kColor) {
glDisableVertexAttribArray(colorLocation);
}
}
From 26c5750e3c59a991632e330eeee3a4c44f786d41 Mon Sep 17 00:00:00 2001
From: Alan Viverette
Date: Mon, 9 Mar 2015 18:01:19 -0700
Subject: [PATCH 79/93] Revert RelativeLayout's baseline view to API 22 and
below behavior
The previous behavior used the top-start-most view, rather than the view
with the bottom-most baseline. Which doesn't really make sense, but
that's what it did.
Bug: 19653790
Change-Id: Ia23476f1d2de5313fd82aac037e90d45b0af8972
---
core/java/android/widget/RelativeLayout.java | 46 +++++++++++++-------
1 file changed, 31 insertions(+), 15 deletions(-)
diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java
index a224f5e5670a4..d12739fe3e36e 100644
--- a/core/java/android/widget/RelativeLayout.java
+++ b/core/java/android/widget/RelativeLayout.java
@@ -515,6 +515,23 @@ public class RelativeLayout extends ViewGroup {
}
}
+ // Use the top-start-most laid out view as the baseline. RTL offsets are
+ // applied later, so we can use the left-most edge as the starting edge.
+ View baselineView = null;
+ LayoutParams baselineParams = null;
+ for (int i = 0; i < count; i++) {
+ final View child = getChildAt(i);
+ if (child.getVisibility() != GONE) {
+ final LayoutParams childParams = (LayoutParams) child.getLayoutParams();
+ if (baselineView == null || baselineParams == null
+ || compareLayoutPosition(childParams, baselineParams) < 0) {
+ baselineView = child;
+ baselineParams = childParams;
+ }
+ }
+ }
+ mBaselineView = baselineView;
+
if (isWrapContentWidth) {
// Width already has left padding in it since it was calculated by looking at
// the right of each child view
@@ -616,24 +633,23 @@ public class RelativeLayout extends ViewGroup {
}
}
- // Use the bottom-most laid out view as the baseline.
- View baselineView = null;
- int baseline = 0;
- for (int i = 0; i < count; i++) {
- final View child = getChildAt(i);
- if (child.getVisibility() != GONE) {
- final int childBaseline = child.getBaseline();
- if (childBaseline >= baseline) {
- baselineView = child;
- baseline = childBaseline;
- }
- }
- }
- mBaselineView = baselineView;
-
setMeasuredDimension(width, height);
}
+ /**
+ * @return a negative number if the top of {@code p1} is above the top of
+ * {@code p2} or if they have identical top values and the left of
+ * {@code p1} is to the left of {@code p2}, or a positive number
+ * otherwise
+ */
+ private int compareLayoutPosition(LayoutParams p1, LayoutParams p2) {
+ final int topDiff = p1.mTop - p2.mTop;
+ if (topDiff != 0) {
+ return topDiff;
+ }
+ return p1.mLeft - p2.mLeft;
+ }
+
/**
* Measure a child. The child should have left, top, right and bottom information
* stored in its LayoutParams. If any of these values is VALUE_NOT_SET it means
From dcdeec28dc82e527115932b3975652d5ae1ecb86 Mon Sep 17 00:00:00 2001
From: Raph Levien
Date: Wed, 11 Mar 2015 11:02:33 -0700
Subject: [PATCH 80/93] Fix
android.text.cts.StaticLayoutTest#testGetEllipsisCount
The "moreChars" predicate (which is used in ellipsis computation) was
slightly incorrect, sometimes being computed as false when the line
break is at the end of a paragraph but not the end of the buffer.
This patch makes the behavior consistent with shipping versions.
Bug: 19676414
Change-Id: I72e16794e895c2eb765b21feaf59fcdccc4857f1
---
core/java/android/text/StaticLayout.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/core/java/android/text/StaticLayout.java b/core/java/android/text/StaticLayout.java
index 967e80c4d7b8f..0d35f9c1567aa 100644
--- a/core/java/android/text/StaticLayout.java
+++ b/core/java/android/text/StaticLayout.java
@@ -540,7 +540,7 @@ public class StaticLayout extends Layout {
while (breakIndex < breakCount && paraStart + breaks[breakIndex] <= spanEnd) {
int endPos = paraStart + breaks[breakIndex];
- boolean moreChars = (endPos < paraEnd); // XXX is this the right way to calculate this?
+ boolean moreChars = (endPos < bufEnd);
v = out(source, here, endPos,
fmAscent, fmDescent, fmTop, fmBottom,
From 2955ca27146014f655a8a4e5b50e1821e4268386 Mon Sep 17 00:00:00 2001
From: Alan Viverette
Date: Wed, 11 Mar 2015 12:21:30 -0700
Subject: [PATCH 81/93] Various fixes for popup monkey testing
Ensures PopupMenu works correctly when multiple calls are made to show
and dismiss. Ensure PopupWindow works correctly when multiple calls are
made to showAsDropDown and dismiss (fixes multiple clicks on Spinner).
Bug: 19672907
Bug: 19671831
Change-Id: Ib92accd8fd70a1ff1f8cda27155347b007a4d25b
---
core/java/android/widget/PopupWindow.java | 260 +++++++++++-------
.../internal/view/menu/MenuPopupHelper.java | 15 +-
2 files changed, 169 insertions(+), 106 deletions(-)
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index 399f4c5a65cac..f67625457708b 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -29,6 +29,8 @@ import android.os.Build;
import android.os.IBinder;
import android.transition.Transition;
import android.transition.Transition.EpicenterCallback;
+import android.transition.Transition.TransitionListener;
+import android.transition.Transition.TransitionListenerAdapter;
import android.transition.TransitionInflater;
import android.transition.TransitionManager;
import android.transition.TransitionSet;
@@ -39,12 +41,13 @@ import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.ViewGroup;
+import android.view.ViewParent;
import android.view.ViewTreeObserver;
+import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.view.ViewTreeObserver.OnScrollChangedListener;
import android.view.WindowManager;
import java.lang.ref.WeakReference;
-import java.util.List;
/**
* A popup window that can be used to display an arbitrary view. The popup
@@ -96,14 +99,12 @@ public class PopupWindow {
private WindowManager mWindowManager;
private boolean mIsShowing;
+ private boolean mIsTransitioningToDismiss;
private boolean mIsDropdown;
/** View that handles event dispatch and content transitions. */
private PopupDecorView mDecorView;
- /** View that holds the popup background. May be the content view. */
- private View mBackgroundView;
-
/** The contents of the popup. */
private View mContentView;
@@ -1183,23 +1184,30 @@ public class PopupWindow {
+ "calling setContentView() before attempting to show the popup.");
}
- // When a background is available, we embed the content view within
- // another view that owns the background drawable.
- if (mBackground != null) {
- mBackgroundView = createBackgroundView(mContentView);
- mBackgroundView.setBackground(mBackground);
- } else {
- mBackgroundView = mContentView;
+ // The old decor view may be transitioning out. Make sure it finishes
+ // and cleans up before we try to create another one.
+ if (mDecorView != null) {
+ mDecorView.cancelTransitions();
}
- mDecorView = createDecorView(mBackgroundView);
+ // When a background is available, we embed the content view within
+ // another view that owns the background drawable.
+ final View backgroundView;
+ if (mBackground != null) {
+ backgroundView = createBackgroundView(mContentView);
+ backgroundView.setBackground(mBackground);
+ } else {
+ backgroundView = mContentView;
+ }
+
+ mDecorView = createDecorView(backgroundView);
// The background owner should be elevated so that it casts a shadow.
- mBackgroundView.setElevation(mElevation);
+ backgroundView.setElevation(mElevation);
// We may wrap that in another view, so we'll need to manually specify
// the surface insets.
- final int surfaceInset = (int) Math.ceil(mBackgroundView.getZ() * 2);
+ final int surfaceInset = (int) Math.ceil(backgroundView.getZ() * 2);
p.surfaceInsets.set(surfaceInset, surfaceInset, surfaceInset, surfaceInset);
p.hasManualSurfaceInsets = true;
@@ -1268,26 +1276,13 @@ public class PopupWindow {
p.packageName = mContext.getPackageName();
}
- final View rootView = mContentView.getRootView();
- rootView.setFitsSystemWindows(mLayoutInsetDecor);
+ final PopupDecorView decorView = mDecorView;
+ decorView.setFitsSystemWindows(mLayoutInsetDecor);
+ decorView.requestEnterTransition(mEnterTransition);
+
setLayoutDirectionFromAnchor();
- mWindowManager.addView(rootView, p);
-
- // Postpone enter transition until the scene root has been laid out.
- if (mEnterTransition != null) {
- mEnterTransition.addTarget(mBackgroundView);
- mEnterTransition.addListener(new Transition.TransitionListenerAdapter() {
- @Override
- public void onTransitionEnd(Transition transition) {
- transition.removeListener(this);
- transition.removeTarget(mBackgroundView);
- }
- });
-
- mDecorView.getViewTreeObserver().addOnGlobalLayoutListener(
- new PostLayoutTransitionListener(mDecorView, mEnterTransition));
- }
+ mWindowManager.addView(decorView, p);
}
private void setLayoutDirectionFromAnchor() {
@@ -1591,35 +1586,38 @@ public class PopupWindow {
* @see #showAsDropDown(android.view.View)
*/
public void dismiss() {
- if (!isShowing()) {
+ if (!isShowing() || mIsTransitioningToDismiss) {
return;
}
+ final PopupDecorView decorView = mDecorView;
+ final View contentView = mContentView;
+
+ final ViewGroup contentHolder;
+ final ViewParent contentParent = contentView.getParent();
+ if (contentParent instanceof ViewGroup) {
+ contentHolder = ((ViewGroup) contentParent);
+ } else {
+ contentHolder = null;
+ }
+
+ // Ensure any ongoing or pending transitions are canceled.
+ decorView.cancelTransitions();
+
unregisterForScrollChanged();
mIsShowing = false;
+ mIsTransitioningToDismiss = true;
- if (mExitTransition != null) {
- // Cache the content view, since it may change without notice.
- final View contentView = mContentView;
-
- mExitTransition.addTarget(mBackgroundView);
- mExitTransition.addListener(new Transition.TransitionListenerAdapter() {
+ if (mExitTransition != null && decorView.isLaidOut()) {
+ decorView.startExitTransition(mExitTransition, new TransitionListenerAdapter() {
@Override
public void onTransitionEnd(Transition transition) {
- transition.removeListener(this);
- transition.removeTarget(mBackgroundView);
-
- dismissImmediate(contentView);
+ dismissImmediate(decorView, contentHolder, contentView);
}
});
-
- TransitionManager.beginDelayedTransition(mDecorView, mExitTransition);
-
- // Transition to invisible.
- mBackgroundView.setVisibility(View.INVISIBLE);
} else {
- dismissImmediate(mContentView);
+ dismissImmediate(decorView, contentHolder, contentView);
}
if (mOnDismissListener != null) {
@@ -1631,24 +1629,22 @@ public class PopupWindow {
* Removes the popup from the window manager and tears down the supporting
* view hierarchy, if necessary.
*/
- private void dismissImmediate(View contentView) {
- if (mDecorView == null || mBackgroundView == null) {
- throw new RuntimeException("Popup window already dismissed");
+ private void dismissImmediate(View decorView, ViewGroup contentHolder, View contentView) {
+ // If this method gets called and the decor view doesn't have a parent,
+ // then it was either never added or was already removed. That should
+ // never happen, but it's worth checking to avoid potential crashes.
+ if (decorView.getParent() != null) {
+ mWindowManager.removeViewImmediate(decorView);
}
- try {
- if (mDecorView.isAttachedToWindow()) {
- mWindowManager.removeViewImmediate(mDecorView);
- }
- } finally {
- mDecorView.removeView(mBackgroundView);
- mDecorView = null;
-
- if (mBackgroundView != contentView) {
- ((ViewGroup) mBackgroundView).removeView(contentView);
- }
- mBackgroundView = null;
+ if (contentHolder != null) {
+ contentHolder.removeView(contentView);
}
+
+ // This needs to stay until after all transitions have ended since we
+ // need the reference to cancel transitions in preparePopup().
+ mDecorView = null;
+ mIsTransitioningToDismiss = false;
}
/**
@@ -1909,47 +1905,9 @@ public class PopupWindow {
mAnchoredGravity = gravity;
}
- /**
- * Layout listener used to run a transition immediately after a view is
- * laid out. Forces the view to transition from invisible to visible.
- */
- private static class PostLayoutTransitionListener implements
- ViewTreeObserver.OnGlobalLayoutListener {
- private final ViewGroup mSceneRoot;
- private final Transition mTransition;
-
- public PostLayoutTransitionListener(ViewGroup sceneRoot, Transition transition) {
- mSceneRoot = sceneRoot;
- mTransition = transition;
- }
-
- @Override
- public void onGlobalLayout() {
- final ViewTreeObserver observer = mSceneRoot.getViewTreeObserver();
- if (observer == null) {
- // View has been detached.
- return;
- }
-
- observer.removeOnGlobalLayoutListener(this);
-
- // Set all targets to be initially invisible.
- final List targets = mTransition.getTargets();
- final int N = targets.size();
- for (int i = 0; i < N; i++) {
- targets.get(i).setVisibility(View.INVISIBLE);
- }
-
- TransitionManager.beginDelayedTransition(mSceneRoot, mTransition);
-
- // Transition targets to visible.
- for (int i = 0; i < N; i++) {
- targets.get(i).setVisibility(View.VISIBLE);
- }
- }
- }
-
private class PopupDecorView extends FrameLayout {
+ private TransitionListenerAdapter mPendingExitListener;
+
public PopupDecorView(Context context) {
super(context);
}
@@ -2004,6 +1962,100 @@ public class PopupWindow {
return super.onTouchEvent(event);
}
}
+
+ /**
+ * Requests that an enter transition run after the next layout pass.
+ */
+ public void requestEnterTransition(Transition transition) {
+ final ViewTreeObserver observer = getViewTreeObserver();
+ if (observer != null && transition != null) {
+ final Transition enterTransition = transition.clone();
+
+ // Postpone the enter transition after the first layout pass.
+ observer.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
+ @Override
+ public void onGlobalLayout() {
+ final ViewTreeObserver observer = getViewTreeObserver();
+ if (observer != null) {
+ observer.removeOnGlobalLayoutListener(this);
+ }
+
+ startEnterTransition(enterTransition);
+ }
+ });
+ }
+ }
+
+ /**
+ * Starts the pending enter transition, if one is set.
+ */
+ private void startEnterTransition(Transition enterTransition) {
+ final int count = getChildCount();
+ for (int i = 0; i < count; i++) {
+ final View child = getChildAt(i);
+ enterTransition.addTarget(child);
+ child.setVisibility(View.INVISIBLE);
+ }
+
+ TransitionManager.beginDelayedTransition(this, enterTransition);
+
+ for (int i = 0; i < count; i++) {
+ final View child = getChildAt(i);
+ child.setVisibility(View.VISIBLE);
+ }
+ }
+
+ /**
+ * Starts an exit transition immediately.
+ *
+ * Note: The transition listener is guaranteed to have
+ * its {@code onTransitionEnd} method called even if the transition
+ * never starts; however, it may be called with a {@code null} argument.
+ */
+ public void startExitTransition(Transition transition, final TransitionListener listener) {
+ if (transition == null) {
+ return;
+ }
+
+ // The exit listener MUST be called for cleanup, even if the
+ // transition never starts or ends. Stash it for later.
+ mPendingExitListener = new TransitionListenerAdapter() {
+ @Override
+ public void onTransitionEnd(Transition transition) {
+ listener.onTransitionEnd(transition);
+
+ // The listener was called. Our job here is done.
+ mPendingExitListener = null;
+ }
+ };
+
+ final Transition exitTransition = transition.clone();
+ exitTransition.addListener(mPendingExitListener);
+
+ final int count = getChildCount();
+ for (int i = 0; i < count; i++) {
+ final View child = getChildAt(i);
+ exitTransition.addTarget(child);
+ }
+
+ TransitionManager.beginDelayedTransition(this, exitTransition);
+
+ for (int i = 0; i < count; i++) {
+ final View child = getChildAt(i);
+ child.setVisibility(View.INVISIBLE);
+ }
+ }
+
+ /**
+ * Cancels all pending or current transitions.
+ */
+ public void cancelTransitions() {
+ TransitionManager.endTransitions(this);
+
+ if (mPendingExitListener != null) {
+ mPendingExitListener.onTransitionEnd(null);
+ }
+ }
}
private class PopupBackgroundView extends FrameLayout {
diff --git a/core/java/com/android/internal/view/menu/MenuPopupHelper.java b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
index 2b20b386058af..7d4507150f8e8 100644
--- a/core/java/com/android/internal/view/menu/MenuPopupHelper.java
+++ b/core/java/com/android/internal/view/menu/MenuPopupHelper.java
@@ -43,8 +43,6 @@ import java.util.ArrayList;
public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.OnKeyListener,
ViewTreeObserver.OnGlobalLayoutListener, PopupWindow.OnDismissListener,
View.OnAttachStateChangeListener, MenuPresenter {
- private static final String TAG = "MenuPopupHelper";
-
static final int ITEM_LAYOUT = com.android.internal.R.layout.popup_menu_item_layout;
private final Context mContext;
@@ -132,7 +130,18 @@ public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.On
return mPopup;
}
+ /**
+ * Attempts to show the popup anchored to the view specified by
+ * {@link #setAnchorView(View)}.
+ *
+ * @return {@code true} if the popup was shown or was already showing prior
+ * to calling this method, {@code false} otherwise
+ */
public boolean tryShow() {
+ if (isShowing()) {
+ return true;
+ }
+
mPopup = new ListPopupWindow(mContext, null, mPopupStyleAttr, mPopupStyleRes);
mPopup.setOnDismissListener(this);
mPopup.setOnItemClickListener(this);
@@ -169,6 +178,7 @@ public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.On
}
}
+ @Override
public void onDismiss() {
mPopup = null;
mMenu.close();
@@ -190,6 +200,7 @@ public class MenuPopupHelper implements AdapterView.OnItemClickListener, View.On
adapter.mAdapterMenu.performItemAction(adapter.getItem(position), 0);
}
+ @Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_MENU) {
dismiss();
From da278708e1d12a7776e2f997a20f4f96c2785ec2 Mon Sep 17 00:00:00 2001
From: Raph Levien
Date: Wed, 11 Mar 2015 14:09:26 -0700
Subject: [PATCH 82/93] Fix XML parsing crash in SettingsProvider
A previous change added more whitespace to settings_global.xml to
improve human readability, but the parser is overly picky in ignoring
whitespace. This patch makes it accept all whitespace strings.
Bug: 19696812
Change-Id: I3ebb8f6df2e25f4e6b6841da743be3f3a91e2442
---
.../src/com/android/providers/settings/SettingsState.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
index 3a8216d9029a0..3bf6828e37b12 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsState.java
@@ -470,7 +470,7 @@ final class SettingsState {
private void skipEmptyTextTags(XmlPullParser parser)
throws IOException, XmlPullParserException {
while (accept(parser, XmlPullParser.TEXT, null)
- && "\n".equals(parser.getText())) {
+ && parser.isWhitespace()) {
parser.next();
}
}
From bfa4e813e764e307c56164012067a615202872fe Mon Sep 17 00:00:00 2001
From: Jeff Brown
Date: Thu, 12 Mar 2015 21:25:00 +0000
Subject: [PATCH 83/93] Revert "Update ParcelFileDescriptor to use non-blocking
I/O."
Bug: 19715279
This reverts commit a34a3bdcbf2e7057d294a8699bbe1be880500f6d.
Change-Id: Ief03dee1c0a2b4d906797a5c279663c17439c347
---
.../java/android/os/ParcelFileDescriptor.java | 70 +++++++++++--------
1 file changed, 39 insertions(+), 31 deletions(-)
diff --git a/core/java/android/os/ParcelFileDescriptor.java b/core/java/android/os/ParcelFileDescriptor.java
index ba1699eb898ec..4e8ec890b44d9 100644
--- a/core/java/android/os/ParcelFileDescriptor.java
+++ b/core/java/android/os/ParcelFileDescriptor.java
@@ -19,13 +19,11 @@ package android.os;
import static android.system.OsConstants.AF_UNIX;
import static android.system.OsConstants.SEEK_SET;
import static android.system.OsConstants.SOCK_STREAM;
-import static android.system.OsConstants.SOCK_SEQPACKET;
import static android.system.OsConstants.S_ISLNK;
import static android.system.OsConstants.S_ISREG;
import android.content.BroadcastReceiver;
import android.content.ContentProvider;
-import android.os.MessageQueue.FileDescriptorCallback;
import android.system.ErrnoException;
import android.system.Os;
import android.system.OsConstants;
@@ -33,6 +31,7 @@ import android.system.StructStat;
import android.util.Log;
import dalvik.system.CloseGuard;
+
import libcore.io.IoUtils;
import libcore.io.Memory;
@@ -221,8 +220,8 @@ public class ParcelFileDescriptor implements Parcelable, Closeable {
* be opened with the requested mode.
* @see #parseMode(String)
*/
- public static ParcelFileDescriptor open(File file, int mode, Handler handler,
- final OnCloseListener listener) throws IOException {
+ public static ParcelFileDescriptor open(
+ File file, int mode, Handler handler, OnCloseListener listener) throws IOException {
if (handler == null) {
throw new IllegalArgumentException("Handler must not be null");
}
@@ -236,25 +235,10 @@ public class ParcelFileDescriptor implements Parcelable, Closeable {
final FileDescriptor[] comm = createCommSocketPair();
final ParcelFileDescriptor pfd = new ParcelFileDescriptor(fd, comm[0]);
- handler.getLooper().getQueue().registerFileDescriptorCallback(comm[1],
- FileDescriptorCallback.EVENT_INPUT, new FileDescriptorCallback() {
- @Override
- public int onFileDescriptorEvents(FileDescriptor fd, int events) {
- Status status = null;
- if ((events & FileDescriptorCallback.EVENT_INPUT) != 0) {
- final byte[] buf = new byte[MAX_STATUS];
- status = readCommStatus(fd, buf);
- } else if ((events & FileDescriptorCallback.EVENT_ERROR) != 0) {
- status = new Status(Status.DEAD);
- }
- if (status != null) {
- IoUtils.closeQuietly(fd);
- listener.onClose(status.asIOException());
- return 0; // unregister the callback
- }
- return EVENT_INPUT;
- }
- });
+ // Kick off thread to watch for status updates
+ IoUtils.setBlocking(comm[1], true);
+ final ListenerBridge bridge = new ListenerBridge(comm[1], handler.getLooper(), listener);
+ bridge.start();
return pfd;
}
@@ -462,12 +446,9 @@ public class ParcelFileDescriptor implements Parcelable, Closeable {
private static FileDescriptor[] createCommSocketPair() throws IOException {
try {
- // Use SOCK_SEQPACKET so that we have a guarantee that the status
- // is written and read atomically as one unit and is not split
- // across multiple IO operations.
final FileDescriptor comm1 = new FileDescriptor();
final FileDescriptor comm2 = new FileDescriptor();
- Os.socketpair(AF_UNIX, SOCK_SEQPACKET, 0, comm1, comm2);
+ Os.socketpair(AF_UNIX, SOCK_STREAM, 0, comm1, comm2);
IoUtils.setBlocking(comm1, false);
IoUtils.setBlocking(comm2, false);
return new FileDescriptor[] { comm1, comm2 };
@@ -728,7 +709,6 @@ public class ParcelFileDescriptor implements Parcelable, Closeable {
writePtr += len;
}
- // Must write the entire status as a single operation.
Os.write(mCommFd, buf, 0, writePtr);
} catch (ErrnoException e) {
// Reporting status is best-effort
@@ -746,7 +726,6 @@ public class ParcelFileDescriptor implements Parcelable, Closeable {
private static Status readCommStatus(FileDescriptor comm, byte[] buf) {
try {
- // Must read the entire status as a single operation.
final int n = Os.read(comm, buf, 0, buf.length);
if (n == 0) {
// EOF means they're dead
@@ -1035,10 +1014,39 @@ public class ParcelFileDescriptor implements Parcelable, Closeable {
return new IOException("Unknown status: " + status);
}
}
+ }
+
+ /**
+ * Bridge to watch for remote status, and deliver to listener. Currently
+ * requires that communication socket is blocking.
+ */
+ private static final class ListenerBridge extends Thread {
+ // TODO: switch to using Looper to avoid burning a thread
+
+ private FileDescriptor mCommFd;
+ private final Handler mHandler;
+
+ public ListenerBridge(FileDescriptor comm, Looper looper, final OnCloseListener listener) {
+ mCommFd = comm;
+ mHandler = new Handler(looper) {
+ @Override
+ public void handleMessage(Message msg) {
+ final Status s = (Status) msg.obj;
+ listener.onClose(s != null ? s.asIOException() : null);
+ }
+ };
+ }
@Override
- public String toString() {
- return "{" + status + ": " + msg + "}";
+ public void run() {
+ try {
+ final byte[] buf = new byte[MAX_STATUS];
+ final Status status = readCommStatus(mCommFd, buf);
+ mHandler.obtainMessage(0, status).sendToTarget();
+ } finally {
+ IoUtils.closeQuietly(mCommFd);
+ mCommFd = null;
+ }
}
}
}
From a4a8fc4a7d6ceaa4cdab62e3b266df92ffcb6f1a Mon Sep 17 00:00:00 2001
From: Derek Sollenberger
Date: Mon, 16 Mar 2015 14:35:55 -0400
Subject: [PATCH 84/93] Add conic support to HWUI path tessellator.
bug: 19732872
Change-Id: Ic3ae46f746325468ab972c9daf829099165eb596
---
libs/hwui/PathTessellator.cpp | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/libs/hwui/PathTessellator.cpp b/libs/hwui/PathTessellator.cpp
index 3d8a7491a434b..c1f61d696b006 100644
--- a/libs/hwui/PathTessellator.cpp
+++ b/libs/hwui/PathTessellator.cpp
@@ -37,6 +37,7 @@
#include
#include
+#include // WARNING: Internal Skia Header
#include
#include
@@ -951,6 +952,21 @@ bool PathTessellator::approximatePathOutlineVertices(const SkPath& path, bool fo
pts[2].x(), pts[2].y(),
sqrInvScaleX, sqrInvScaleY, thresholdSquared, outputVertices);
break;
+ case SkPath::kConic_Verb: {
+ ALOGV("kConic_Verb");
+ SkAutoConicToQuads converter;
+ const SkPoint* quads = converter.computeQuads(pts, iter.conicWeight(),
+ thresholdSquared);
+ for (int i = 0; i < converter.countQuads(); ++i) {
+ const int offset = 2 * i;
+ recursiveQuadraticBezierVertices(
+ quads[offset].x(), quads[offset].y(),
+ quads[offset+2].x(), quads[offset+2].y(),
+ quads[offset+1].x(), quads[offset+1].y(),
+ sqrInvScaleX, sqrInvScaleY, thresholdSquared, outputVertices);
+ }
+ break;
+ }
default:
break;
}
From c3db8677792992415e727ee2f2039284f71d4f44 Mon Sep 17 00:00:00 2001
From: Wale Ogunwale
Date: Tue, 17 Mar 2015 11:36:24 -0700
Subject: [PATCH 85/93] Recompute focus stack if cleared while starting an
activity.
When starting an activity with Intent.FLAG_ACTIVITY_CLEAR_TOP flag,
the activity is destoried which can also cause its task to be removed
from its current stack if the activity process record is null. We now
recompute the stack for the activity task when this occurs so we
don't NPE later on.
Bug: 19552874
Change-Id: I50f51ca6dc32d4642f78d59cae93b0774bc6cdb7
---
.../server/am/ActivityStackSupervisor.java | 21 ++++++++++++-------
1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index f56f65fa8ec9e..ff90df589fe99 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -1971,15 +1971,22 @@ public final class ActivityStackSupervisor implements DisplayListener {
r, top.task);
top.deliverNewIntentLocked(callingUid, r.intent, r.launchedFromPackage);
} else {
- // A special case: we need to
- // start the activity because it is not currently
- // running, and the caller has asked to clear the
- // current task to have this activity at the top.
+ // A special case: we need to start the activity because it is not
+ // currently running, and the caller has asked to clear the current
+ // task to have this activity at the top.
addingToTask = true;
- // Now pretend like this activity is being started
- // by the top of its task, so it is put in the
- // right place.
+ // Now pretend like this activity is being started by the top of its
+ // task, so it is put in the right place.
sourceRecord = intentActivity;
+ TaskRecord task = sourceRecord.task;
+ if (task != null && task.stack == null) {
+ // Target stack got cleared when we all activities were removed
+ // above. Go ahead and reset it.
+ targetStack = computeStackFocus(sourceRecord, false /* newTask */);
+ targetStack.addTask(
+ task, !launchTaskBehind /* toTop */, false /* moving */);
+ }
+
}
} else if (r.realActivity.equals(intentActivity.task.realActivity)) {
// In this case the top activity on the task is the
From 480195759a6f6c50459fff209f9593a7a82feab5 Mon Sep 17 00:00:00 2001
From: Guang Zhu
Date: Wed, 18 Mar 2015 20:54:46 -0700
Subject: [PATCH 86/93] pass stream contents in separate thread for
executeShellCommand
Doing it in binder thread will cause deadlock if stdout of
process under execution is larger than buffer of
java.lang.Runtime#exec(String).
Bug: 19829679
Change-Id: Icf0fccd3e2e80b0db4cc1115e501f79066adf091
---
.../android/app/UiAutomationConnection.java | 47 ++++++++++---------
1 file changed, 26 insertions(+), 21 deletions(-)
diff --git a/core/java/android/app/UiAutomationConnection.java b/core/java/android/app/UiAutomationConnection.java
index 81bcb3913aa27..9ba6a8ef12675 100644
--- a/core/java/android/app/UiAutomationConnection.java
+++ b/core/java/android/app/UiAutomationConnection.java
@@ -227,7 +227,7 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub {
}
@Override
- public void executeShellCommand(String command, ParcelFileDescriptor sink)
+ public void executeShellCommand(final String command, final ParcelFileDescriptor sink)
throws RemoteException {
synchronized (mLock) {
throwIfCalledByNotTrustedUidLocked();
@@ -235,30 +235,35 @@ public final class UiAutomationConnection extends IUiAutomationConnection.Stub {
throwIfNotConnectedLocked();
}
- InputStream in = null;
- OutputStream out = null;
+ Thread streamReader = new Thread() {
+ public void run() {
+ InputStream in = null;
+ OutputStream out = null;
- try {
- java.lang.Process process = Runtime.getRuntime().exec(command);
+ try {
+ java.lang.Process process = Runtime.getRuntime().exec(command);
- in = process.getInputStream();
- out = new FileOutputStream(sink.getFileDescriptor());
+ in = process.getInputStream();
+ out = new FileOutputStream(sink.getFileDescriptor());
- final byte[] buffer = new byte[8192];
- while (true) {
- final int readByteCount = in.read(buffer);
- if (readByteCount < 0) {
- break;
+ final byte[] buffer = new byte[8192];
+ while (true) {
+ final int readByteCount = in.read(buffer);
+ if (readByteCount < 0) {
+ break;
+ }
+ out.write(buffer, 0, readByteCount);
+ }
+ } catch (IOException ioe) {
+ throw new RuntimeException("Error running shell command", ioe);
+ } finally {
+ IoUtils.closeQuietly(in);
+ IoUtils.closeQuietly(out);
+ IoUtils.closeQuietly(sink);
}
- out.write(buffer, 0, readByteCount);
- }
- } catch (IOException ioe) {
- throw new RuntimeException("Error running shell command", ioe);
- } finally {
- IoUtils.closeQuietly(in);
- IoUtils.closeQuietly(out);
- IoUtils.closeQuietly(sink);
- }
+ };
+ };
+ streamReader.start();
}
@Override
From 64328443ab6a490330e8aca64e5b6091b06b48a0 Mon Sep 17 00:00:00 2001
From: Andres Morales
Date: Thu, 19 Mar 2015 08:34:55 -0700
Subject: [PATCH 87/93] Write correct checksum when formatting partition
OEM unlock enabled bit is not computed in the checksum,
causing OEM Unlocking to be disabled after the second
reboot.
Bug: 19829441
Change-Id: I100bf5d3958b89323ee35b9e97b19c162209fcd7
---
.../com/android/server/PersistentDataBlockService.java | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/services/core/java/com/android/server/PersistentDataBlockService.java b/services/core/java/com/android/server/PersistentDataBlockService.java
index e5ace1bae9cf6..97d16c00d6c4a 100644
--- a/services/core/java/com/android/server/PersistentDataBlockService.java
+++ b/services/core/java/com/android/server/PersistentDataBlockService.java
@@ -110,8 +110,7 @@ public class PersistentDataBlockService extends SystemService {
private void formatIfOemUnlockEnabled() {
if (doGetOemUnlockEnabled()) {
synchronized (mLock) {
- formatPartitionLocked();
- doSetOemUnlockEnabledLocked(true);
+ formatPartitionLocked(true);
}
}
}
@@ -165,7 +164,7 @@ public class PersistentDataBlockService extends SystemService {
byte[] digest = computeDigestLocked(storedDigest);
if (digest == null || !Arrays.equals(storedDigest, digest)) {
Slog.i(TAG, "Formatting FRP partition...");
- formatPartitionLocked();
+ formatPartitionLocked(false);
return false;
}
}
@@ -242,7 +241,7 @@ public class PersistentDataBlockService extends SystemService {
return md.digest();
}
- private void formatPartitionLocked() {
+ private void formatPartitionLocked(boolean setOemUnlockEnabled) {
DataOutputStream outputStream;
try {
outputStream = new DataOutputStream(new FileOutputStream(new File(mDataBlockFile)));
@@ -264,7 +263,7 @@ public class PersistentDataBlockService extends SystemService {
IoUtils.closeQuietly(outputStream);
}
- doSetOemUnlockEnabledLocked(false);
+ doSetOemUnlockEnabledLocked(setOemUnlockEnabled);
computeAndWriteDigestLocked();
}
From 248f91b25745adb787eef1ee22a42b4ff407417f Mon Sep 17 00:00:00 2001
From: Chris Craik
Date: Thu, 19 Mar 2015 15:11:36 -0700
Subject: [PATCH 88/93] Avoid throwing ISE in Canvas#restore underflow
bug:19829784
Change-Id: I5829a7783ad912c09c83dee17bad10b90f42aace
---
core/jni/android_graphics_Canvas.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/core/jni/android_graphics_Canvas.cpp b/core/jni/android_graphics_Canvas.cpp
index 47af5e67857ca..49ee6c528f6cf 100644
--- a/core/jni/android_graphics_Canvas.cpp
+++ b/core/jni/android_graphics_Canvas.cpp
@@ -89,7 +89,7 @@ static jint saveLayerAlpha(JNIEnv* env, jobject, jlong canvasHandle, jfloat l, j
static void restore(JNIEnv* env, jobject, jlong canvasHandle) {
Canvas* canvas = get_canvas(canvasHandle);
if (canvas->getSaveCount() <= 1) { // cannot restore anymore
- doThrowISE(env, "Underflow in restore");
+ // fail silently on underflow, so as not to break existing apps that miscount
return;
}
canvas->restore();
@@ -98,7 +98,7 @@ static void restore(JNIEnv* env, jobject, jlong canvasHandle) {
static void restoreToCount(JNIEnv* env, jobject, jlong canvasHandle, jint restoreCount) {
Canvas* canvas = get_canvas(canvasHandle);
if (restoreCount < 1 || restoreCount > canvas->getSaveCount()) {
- doThrowIAE(env, "Underflow in restoreToCount");
+ // fail silently on underflow, so as not to break existing apps that miscount
return;
}
canvas->restoreToCount(restoreCount);
From df882cdb498b8c74dd3a9c145b8f44328f6eefe7 Mon Sep 17 00:00:00 2001
From: Adam Lesinski
Date: Thu, 19 Mar 2015 18:10:16 -0700
Subject: [PATCH 89/93] Disable WiFi energy data collection to avoid deadlock
This is a temporary fix to prevent deadlocking in the
system. Need to come up with a better solution for
accessing WiFi and other subsystems from BatteryStats.
b/19729960
Change-Id: I464e7490c9780249d2a3eef05ce084a7d84372c0
---
core/java/com/android/internal/os/BatteryStatsImpl.java | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index f9b1ca11922c8..fb3462ec4f432 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -7361,7 +7361,9 @@ public final class BatteryStatsImpl extends BatteryStats {
updateNetworkActivityLocked(NET_UPDATE_ALL, SystemClock.elapsedRealtime());
// TODO(adamlesinski): enable when bluedroid stops deadlocking. b/19248786
// updateBluetoothControllerActivityLocked();
- updateWifiControllerActivityLocked();
+ // TODO(adamlesinski): disabled to avoid deadlock. Need to change how external
+ // data is pulled/accessed from BatteryStats. b/19729960
+ // updateWifiControllerActivityLocked();
if (mOnBatteryInternal) {
final boolean screenOn = mScreenState == Display.STATE_ON;
updateDischargeScreenLevelsLocked(screenOn, screenOn);
From 71d121353ec770b6de465e9c8f24666e5c7bfe8a Mon Sep 17 00:00:00 2001
From: Alan Viverette
Date: Mon, 23 Mar 2015 13:42:06 -0700
Subject: [PATCH 90/93] Refactor theme colors, fix dialog background, accent in
light Settings
Bug: 19706726
Change-Id: If81c0a4775c366ae1a278d79f6353670182f7d27
---
core/res/res/values/colors_material.xml | 48 +++++++++++++++----------
core/res/res/values/themes_material.xml | 6 +---
2 files changed, 31 insertions(+), 23 deletions(-)
diff --git a/core/res/res/values/colors_material.xml b/core/res/res/values/colors_material.xml
index da68c920ea50f..1cb39f0de592a 100644
--- a/core/res/res/values/colors_material.xml
+++ b/core/res/res/values/colors_material.xml
@@ -16,16 +16,19 @@
- #ff303030
- #fffafafa
- #ff424242
- #ffffffff
+ @color/white
+ @color/black
- #ff212121
- #fff5f5f5
- #ff000000
- #ff757575
- #ffe0e0e0
+ @color/material_grey_850
+ @color/material_grey_50
+ @color/material_grey_800
+ @color/white
+
+ @color/material_grey_900
+ @color/material_grey_100
+ @color/black
+ @color/material_grey_600
+ @color/material_grey_300
@color/material_deep_teal_500
@color/material_deep_teal_200
@@ -38,19 +41,20 @@
#ff616161
#ffbdbdbd
- @color/white
- @color/black
-
- @color/material_deep_teal_200
@color/material_deep_teal_500
+ @color/material_deep_teal_200
+
#de000000
+
#8a000000
+
#ffffffff
+
#b3ffffff
- 0.50
@@ -66,6 +70,14 @@
+ #ff212121
+ #ff303030
+ #ff424242
+ #ff757575
+ #ffe0e0e0
+ #fff5f5f5
+ #fffafafa
+
#ff80cbc4
#ff009688
@@ -98,16 +110,16 @@
#80999999
#80999999
- #33b5e5
- #33b5e5
+ #ff33b5e5
+ #ff33b5e5
- #0099cc
- #0099cc
+ #ff0099cc
+ #ff0099cc
@color/material_deep_teal_500
@color/material_deep_teal_200
- #f2f2f2
+ #fff2f2f2
#ff303030
diff --git a/core/res/res/values/themes_material.xml b/core/res/res/values/themes_material.xml
index 38cfecde00d76..9931d00ef90c0 100644
--- a/core/res/res/values/themes_material.xml
+++ b/core/res/res/values/themes_material.xml
@@ -857,6 +857,7 @@ please see themes_device_defaults.xml.
@@ -1289,7 +1288,6 @@ please see themes_device_defaults.xml.
@@ -1297,7 +1295,6 @@ please see themes_device_defaults.xml.
From f626f00ca90b3d7f2402d7e0f821c42759029dd9 Mon Sep 17 00:00:00 2001
From: Derek Sollenberger
Date: Wed, 25 Mar 2015 11:32:17 -0400
Subject: [PATCH 91/93] Update ShadowTesslator to support conics
bug:19732872
Change-Id: I8b539ab3677219fa5bb7de7caf0aad9fc47ef7e9
---
libs/hwui/ShadowTessellator.cpp | 1 +
1 file changed, 1 insertion(+)
diff --git a/libs/hwui/ShadowTessellator.cpp b/libs/hwui/ShadowTessellator.cpp
index 9509c48038cfd..30d3f41b0eed1 100644
--- a/libs/hwui/ShadowTessellator.cpp
+++ b/libs/hwui/ShadowTessellator.cpp
@@ -197,6 +197,7 @@ bool ShadowTessellator::isClockwisePath(const SkPath& path) {
case SkPath::kLine_Verb:
arrayForDirection.add((Vector2){pts[1].x(), pts[1].y()});
break;
+ case SkPath::kConic_Verb:
case SkPath::kQuad_Verb:
arrayForDirection.add((Vector2){pts[1].x(), pts[1].y()});
arrayForDirection.add((Vector2){pts[2].x(), pts[2].y()});
From 9d0afcd9dce9329dab40055552fe1ac65d0018d6 Mon Sep 17 00:00:00 2001
From: ztenghui
Date: Wed, 25 Mar 2015 15:01:56 -0700
Subject: [PATCH 92/93] Don't draw when bounds are negative
b/19922909
Change-Id: I68559ed683031f57538439e0a3e4979fe9f430a5
---
graphics/java/android/graphics/drawable/VectorDrawable.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/graphics/java/android/graphics/drawable/VectorDrawable.java b/graphics/java/android/graphics/drawable/VectorDrawable.java
index 39a33ce05e872..56477394d0a19 100644
--- a/graphics/java/android/graphics/drawable/VectorDrawable.java
+++ b/graphics/java/android/graphics/drawable/VectorDrawable.java
@@ -249,8 +249,8 @@ public class VectorDrawable extends Drawable {
@Override
public void draw(Canvas canvas) {
final Rect bounds = getBounds();
- if (bounds.width() == 0 || bounds.height() == 0) {
- // too small to draw
+ if (bounds.width() <= 0 || bounds.height() <= 0) {
+ // Nothing to draw
return;
}
From 99d0d393077236aebd5774ff78c2d8ec4ae5e2d8 Mon Sep 17 00:00:00 2001
From: Craig Mautner
Date: Thu, 26 Mar 2015 14:22:34 -0700
Subject: [PATCH 93/93] Do not set visibility of unstarted activities.
If an activity is started in the stopped state then it shouldn't have
its window manager visibility set to visible. It also should not have
its screen frozen.
Fixes bug 19823482.
Change-Id: I74637a8eefcc97d1ef4d8ea3c661dc7c0c322f59
---
.../com/android/server/am/ActivityStack.java | 3 +-
.../server/am/ActivityStackSupervisor.java | 58 ++++++++++---------
.../server/wm/WindowManagerService.java | 6 +-
3 files changed, 35 insertions(+), 32 deletions(-)
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index f5fef63152174..066ff372522a0 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -3896,8 +3896,7 @@ final class ActivityStack {
return true;
}
- private boolean relaunchActivityLocked(ActivityRecord r,
- int changes, boolean andResume) {
+ private boolean relaunchActivityLocked(ActivityRecord r, int changes, boolean andResume) {
List results = null;
List newIntents = null;
if (andResume) {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index cb966800d45e5..f874244df07b3 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -273,8 +273,8 @@ public final class ActivityStackSupervisor implements DisplayListener {
* until the task exits or #stopLockTaskMode() is called. */
TaskRecord mLockTaskModeTask;
/** Store the current lock task mode. Possible values:
- * {@link ActivityManager#LOCK_TASK_MODE_NONE}, {@link ActicityManager#LOCK_TASK_MODE_LOCKED},
- * {@link ActicityManager#LOCK_TASK_MODE_PINNED}
+ * {@link ActivityManager#LOCK_TASK_MODE_NONE}, {@link ActivityManager#LOCK_TASK_MODE_LOCKED},
+ * {@link ActivityManager#LOCK_TASK_MODE_PINNED}
*/
private int mLockTaskModeState;
/**
@@ -1132,12 +1132,13 @@ public final class ActivityStackSupervisor implements DisplayListener {
ProcessRecord app, boolean andResume, boolean checkConfig)
throws RemoteException {
- r.startFreezingScreenLocked(app, 0);
- if (false) Slog.d(TAG, "realStartActivity: setting app visibility true");
- mWindowManager.setAppVisibility(r.appToken, true);
+ if (andResume) {
+ r.startFreezingScreenLocked(app, 0);
+ mWindowManager.setAppVisibility(r.appToken, true);
- // schedule launch ticks to collect information about slow apps.
- r.startLaunchTickingLocked();
+ // schedule launch ticks to collect information about slow apps.
+ r.startLaunchTickingLocked();
+ }
// Have the window manager re-evaluate the orientation of
// the screen based on the new activity order. Note that
@@ -1195,34 +1196,37 @@ public final class ActivityStackSupervisor implements DisplayListener {
r.forceNewConfig = false;
mService.showAskCompatModeDialogLocked(r);
r.compat = mService.compatibilityInfoForPackageLocked(r.info.applicationInfo);
- String profileFile = null;
- ParcelFileDescriptor profileFd = null;
+ ProfilerInfo profilerInfo = null;
if (mService.mProfileApp != null && mService.mProfileApp.equals(app.processName)) {
if (mService.mProfileProc == null || mService.mProfileProc == app) {
mService.mProfileProc = app;
- profileFile = mService.mProfileFile;
- profileFd = mService.mProfileFd;
- }
- }
- app.hasShownUi = true;
- app.pendingUiClean = true;
- if (profileFd != null) {
- try {
- profileFd = profileFd.dup();
- } catch (IOException e) {
- if (profileFd != null) {
- try {
- profileFd.close();
- } catch (IOException o) {
+ final String profileFile = mService.mProfileFile;
+ if (profileFile != null) {
+ ParcelFileDescriptor profileFd = mService.mProfileFd;
+ if (profileFd != null) {
+ try {
+ profileFd = profileFd.dup();
+ } catch (IOException e) {
+ if (profileFd != null) {
+ try {
+ profileFd.close();
+ } catch (IOException o) {
+ }
+ profileFd = null;
+ }
+ }
}
- profileFd = null;
+
+ profilerInfo = new ProfilerInfo(profileFile, profileFd,
+ mService.mSamplingInterval, mService.mAutoStopProfiler);
}
}
}
- ProfilerInfo profilerInfo = profileFile != null
- ? new ProfilerInfo(profileFile, profileFd, mService.mSamplingInterval,
- mService.mAutoStopProfiler) : null;
+ if (andResume) {
+ app.hasShownUi = true;
+ app.pendingUiClean = true;
+ }
app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_TOP);
app.thread.scheduleLaunchActivity(new Intent(r.intent), r.appToken,
System.identityHashCode(r), r.info, new Configuration(mService.mConfiguration),
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 09bc2abe19f13..957eb9ef18aa0 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -3056,7 +3056,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- if (DEBUG_LAYOUT) Slog.v(TAG, "Relayout " + win + ": viewVisibility=" + viewVisibility
+ if (true || DEBUG_LAYOUT) Slog.v(TAG, "Relayout " + win + ": viewVisibility=" + viewVisibility
+ " req=" + requestedWidth + "x" + requestedHeight + " " + win.mAttrs);
win.mEnforceSizeCompat =
@@ -4171,8 +4171,8 @@ public class WindowManagerService extends IWindowManager.Stub
}
synchronized(mWindowMap) {
- if (DEBUG_APP_TRANSITIONS) Slog.w(TAG, "Execute app transition: " + mAppTransition,
- new RuntimeException("here").fillInStackTrace());
+ if (DEBUG_APP_TRANSITIONS) Slog.w(TAG, "Execute app transition: " + mAppTransition
+ + " Callers=" + Debug.getCallers(5));
if (mAppTransition.isTransitionSet()) {
mAppTransition.setReady();
final long origId = Binder.clearCallingIdentity();