Merge "Update theme colors, fix EditText state transition" into lmp-preview-dev
diff --git a/api/current.txt b/api/current.txt
index 3e9ceb4..cc3c0ab 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -132,7 +132,6 @@
field public static final java.lang.String SET_WALLPAPER = "android.permission.SET_WALLPAPER";
field public static final java.lang.String SET_WALLPAPER_HINTS = "android.permission.SET_WALLPAPER_HINTS";
field public static final java.lang.String SIGNAL_PERSISTENT_PROCESSES = "android.permission.SIGNAL_PERSISTENT_PROCESSES";
- field public static final java.lang.String SIM_COMMUNICATION = "android.permission.SIM_COMMUNICATION";
field public static final java.lang.String STATUS_BAR = "android.permission.STATUS_BAR";
field public static final java.lang.String SUBSCRIBED_FEEDS_READ = "android.permission.SUBSCRIBED_FEEDS_READ";
field public static final java.lang.String SUBSCRIBED_FEEDS_WRITE = "android.permission.SUBSCRIBED_FEEDS_WRITE";
@@ -27761,12 +27760,8 @@
method public java.lang.String getVoiceMailAlphaTag();
method public java.lang.String getVoiceMailNumber();
method public boolean hasIccCard();
- method public boolean iccCloseLogicalChannel(int);
- method public int iccOpenLogicalChannel(java.lang.String);
- method public java.lang.String iccTransmitApduLogicalChannel(int, int, int, int, int, int, java.lang.String);
method public boolean isNetworkRoaming();
method public void listen(android.telephony.PhoneStateListener, int);
- method public java.lang.String sendEnvelopeWithStatus(java.lang.String);
field public static final java.lang.String ACTION_PHONE_STATE_CHANGED = "android.intent.action.PHONE_STATE";
field public static final java.lang.String ACTION_RESPOND_VIA_MESSAGE = "android.intent.action.RESPOND_VIA_MESSAGE";
field public static final int CALL_STATE_IDLE = 0; // 0x0
diff --git a/core/java/android/content/res/Resources.java b/core/java/android/content/res/Resources.java
index ed3f9aa..9625578 100644
--- a/core/java/android/content/res/Resources.java
+++ b/core/java/android/content/res/Resources.java
@@ -2239,9 +2239,7 @@
}
// 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 @@
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 @@
ArrayMap<String, LongSparseArray<WeakReference<ConstantState>>> caches,
long key, Theme theme) {
synchronized (mAccessLock) {
- final int themeKey = theme != null ? theme.mThemeResId : 0;
+ final String themeKey = theme != null ? theme.mKey : "";
final LongSparseArray<WeakReference<ConstantState>> themedCache = caches.get(themeKey);
if (themedCache != null) {
final Drawable themedDrawable = getCachedDrawableLocked(themedCache, key);
diff --git a/core/java/android/hardware/hdmi/HdmiCec.java b/core/java/android/hardware/hdmi/HdmiCec.java
index a71a74d..723eda1 100644
--- a/core/java/android/hardware/hdmi/HdmiCec.java
+++ b/core/java/android/hardware/hdmi/HdmiCec.java
@@ -194,6 +194,8 @@
DEVICE_RECORDER, // ADDR_RECORDER_3
DEVICE_TUNER, // ADDR_TUNER_4
DEVICE_PLAYBACK, // ADDR_PLAYBACK_3
+ DEVICE_RESERVED,
+ DEVICE_RESERVED,
DEVICE_TV, // ADDR_SPECIFIC_USE
};
@@ -210,6 +212,8 @@
"Recorder_3",
"Tuner_4",
"Playback_3",
+ "Reserved_1",
+ "Reserved_2",
"Secondary_TV",
};
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 2f2aba3..a48a388 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -40,6 +40,7 @@
import android.util.Log;
import com.android.internal.telephony.ITelephony;
+import com.android.internal.telephony.PhoneConstants;
import com.android.internal.util.Protocol;
import java.net.InetAddress;
@@ -807,11 +808,34 @@
* @deprecated Deprecated in favor of the cleaner {@link #requestNetwork} api.
*/
public int startUsingNetworkFeature(int networkType, String feature) {
- try {
- return mService.startUsingNetworkFeature(networkType, feature,
- new Binder());
- } catch (RemoteException e) {
- return -1;
+ NetworkCapabilities netCap = networkCapabilitiesForFeature(networkType, feature);
+ if (netCap == null) {
+ Log.d(TAG, "Can't satisfy startUsingNetworkFeature for " + networkType + ", " +
+ feature);
+ return PhoneConstants.APN_REQUEST_FAILED;
+ }
+
+ NetworkRequest request = null;
+ synchronized (sLegacyRequests) {
+ LegacyRequest l = sLegacyRequests.get(netCap);
+ if (l != null) {
+ Log.d(TAG, "renewing startUsingNetworkFeature request " + l.networkRequest);
+ renewRequestLocked(l);
+ if (l.currentNetwork != null) {
+ return PhoneConstants.APN_ALREADY_ACTIVE;
+ } else {
+ return PhoneConstants.APN_REQUEST_STARTED;
+ }
+ }
+
+ request = requestNetworkForFeatureLocked(netCap);
+ }
+ if (request != null) {
+ Log.d(TAG, "starting startUsingNeworkFeature for request " + request);
+ return PhoneConstants.APN_REQUEST_STARTED;
+ } else {
+ Log.d(TAG, " request Failed");
+ return PhoneConstants.APN_REQUEST_FAILED;
}
}
@@ -831,11 +855,172 @@
* @deprecated Deprecated in favor of the cleaner {@link #requestNetwork} api.
*/
public int stopUsingNetworkFeature(int networkType, String feature) {
- try {
- return mService.stopUsingNetworkFeature(networkType, feature);
- } catch (RemoteException e) {
+ NetworkCapabilities netCap = networkCapabilitiesForFeature(networkType, feature);
+ if (netCap == null) {
+ Log.d(TAG, "Can't satisfy stopUsingNetworkFeature for " + networkType + ", " +
+ feature);
return -1;
}
+
+ NetworkRequest request = removeRequestForFeature(netCap);
+ if (request != null) {
+ Log.d(TAG, "stopUsingNetworkFeature for " + networkType + ", " + feature);
+ releaseNetworkRequest(request);
+ }
+ return 1;
+ }
+
+ private NetworkCapabilities networkCapabilitiesForFeature(int networkType, String feature) {
+ if (networkType == TYPE_MOBILE) {
+ int cap = -1;
+ if ("enableMMS".equals(feature)) {
+ cap = NetworkCapabilities.NET_CAPABILITY_MMS;
+ } else if ("enableSUPL".equals(feature)) {
+ cap = NetworkCapabilities.NET_CAPABILITY_SUPL;
+ } else if ("enableDUN".equals(feature) || "enableDUNAlways".equals(feature)) {
+ cap = NetworkCapabilities.NET_CAPABILITY_DUN;
+ } else if ("enableHIPRI".equals(feature)) {
+ cap = NetworkCapabilities.NET_CAPABILITY_INTERNET;
+ } else if ("enableFOTA".equals(feature)) {
+ cap = NetworkCapabilities.NET_CAPABILITY_FOTA;
+ } else if ("enableIMS".equals(feature)) {
+ cap = NetworkCapabilities.NET_CAPABILITY_IMS;
+ } else if ("enableCBS".equals(feature)) {
+ cap = NetworkCapabilities.NET_CAPABILITY_CBS;
+ } else {
+ return null;
+ }
+ NetworkCapabilities netCap = new NetworkCapabilities();
+ netCap.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
+ netCap.addNetworkCapability(cap);
+ 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);
+ return netCap;
+ }
+ }
+ return null;
+ }
+
+ private int legacyTypeForNetworkCapabilities(NetworkCapabilities netCap) {
+ if (netCap == null) return TYPE_NONE;
+ if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_CBS)) {
+ return TYPE_MOBILE_CBS;
+ }
+ if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)) {
+ return TYPE_MOBILE_IMS;
+ }
+ if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_FOTA)) {
+ return TYPE_MOBILE_FOTA;
+ }
+ if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_DUN)) {
+ return TYPE_MOBILE_DUN;
+ }
+ if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_SUPL)) {
+ return TYPE_MOBILE_SUPL;
+ }
+ if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_MMS)) {
+ return TYPE_MOBILE_MMS;
+ }
+ if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)) {
+ return TYPE_MOBILE_HIPRI;
+ }
+ if (netCap.hasCapability(NetworkCapabilities.NET_CAPABILITY_WIFI_P2P)) {
+ return TYPE_WIFI_P2P;
+ }
+ return TYPE_NONE;
+ }
+
+ private static class LegacyRequest {
+ NetworkCapabilities networkCapabilities;
+ NetworkRequest networkRequest;
+ int expireSequenceNumber;
+ Network currentNetwork;
+ int delay = -1;
+ NetworkCallbackListener networkCallbackListener = new NetworkCallbackListener() {
+ @Override
+ public void onAvailable(NetworkRequest request, Network network) {
+ currentNetwork = network;
+ Log.d(TAG, "startUsingNetworkFeature got Network:" + network);
+ network.bindProcessForHostResolution();
+ }
+ @Override
+ public void onLost(NetworkRequest request, Network network) {
+ if (network.equals(currentNetwork)) {
+ currentNetwork = null;
+ network.unbindProcessForHostResolution();
+ }
+ Log.d(TAG, "startUsingNetworkFeature lost Network:" + network);
+ }
+ };
+ }
+
+ private HashMap<NetworkCapabilities, LegacyRequest> sLegacyRequests =
+ new HashMap<NetworkCapabilities, LegacyRequest>();
+
+ private NetworkRequest findRequestForFeature(NetworkCapabilities netCap) {
+ synchronized (sLegacyRequests) {
+ LegacyRequest l = sLegacyRequests.get(netCap);
+ if (l != null) return l.networkRequest;
+ }
+ return null;
+ }
+
+ private void renewRequestLocked(LegacyRequest l) {
+ l.expireSequenceNumber++;
+ Log.d(TAG, "renewing request to seqNum " + l.expireSequenceNumber);
+ sendExpireMsgForFeature(l.networkCapabilities, l.expireSequenceNumber, l.delay);
+ }
+
+ private void expireRequest(NetworkCapabilities netCap, int sequenceNum) {
+ int ourSeqNum = -1;
+ synchronized (sLegacyRequests) {
+ LegacyRequest l = sLegacyRequests.get(netCap);
+ if (l == null) return;
+ ourSeqNum = l.expireSequenceNumber;
+ if (l.expireSequenceNumber == sequenceNum) {
+ releaseNetworkRequest(l.networkRequest);
+ sLegacyRequests.remove(netCap);
+ }
+ }
+ Log.d(TAG, "expireRequest with " + ourSeqNum + ", " + sequenceNum);
+ }
+
+ private NetworkRequest requestNetworkForFeatureLocked(NetworkCapabilities netCap) {
+ int delay = -1;
+ int type = legacyTypeForNetworkCapabilities(netCap);
+ try {
+ delay = mService.getRestoreDefaultNetworkDelay(type);
+ } catch (RemoteException e) {}
+ LegacyRequest l = new LegacyRequest();
+ l.networkCapabilities = netCap;
+ l.delay = delay;
+ l.expireSequenceNumber = 0;
+ l.networkRequest = sendRequestForNetwork(netCap, l.networkCallbackListener, 0,
+ REQUEST, type);
+ if (l.networkRequest == null) return null;
+ sLegacyRequests.put(netCap, l);
+ sendExpireMsgForFeature(netCap, l.expireSequenceNumber, delay);
+ return l.networkRequest;
+ }
+
+ private void sendExpireMsgForFeature(NetworkCapabilities netCap, int seqNum, int delay) {
+ if (delay >= 0) {
+ Log.d(TAG, "sending expire msg with seqNum " + seqNum + " and delay " + delay);
+ Message msg = sCallbackHandler.obtainMessage(EXPIRE_LEGACY_REQUEST, seqNum, 0, netCap);
+ sCallbackHandler.sendMessageDelayed(msg, delay);
+ }
+ }
+
+ private NetworkRequest removeRequestForFeature(NetworkCapabilities netCap) {
+ synchronized (sLegacyRequests) {
+ LegacyRequest l = sLegacyRequests.remove(netCap);
+ if (l == null) return null;
+ return l.networkRequest;
+ }
}
/**
@@ -1782,8 +1967,10 @@
public static final int CALLBACK_RELEASED = BASE + 8;
/** @hide */
public static final int CALLBACK_EXIT = BASE + 9;
+ /** @hide obj = NetworkCapabilities, arg1 = seq number */
+ private static final int EXPIRE_LEGACY_REQUEST = BASE + 10;
- private static class CallbackHandler extends Handler {
+ private class CallbackHandler extends Handler {
private final HashMap<NetworkRequest, NetworkCallbackListener>mCallbackMap;
private final AtomicInteger mRefCount;
private static final String TAG = "ConnectivityManager.CallbackHandler";
@@ -1903,6 +2090,10 @@
getLooper().quit();
break;
}
+ case EXPIRE_LEGACY_REQUEST: {
+ expireRequest((NetworkCapabilities)message.obj, message.arg1);
+ break;
+ }
}
}
@@ -1954,8 +2145,9 @@
private final static int LISTEN = 1;
private final static int REQUEST = 2;
- private NetworkRequest somethingForNetwork(NetworkCapabilities need,
- NetworkCallbackListener networkCallbackListener, int timeoutSec, int action) {
+ private NetworkRequest sendRequestForNetwork(NetworkCapabilities need,
+ NetworkCallbackListener networkCallbackListener, int timeoutSec, int action,
+ int legacyType) {
NetworkRequest networkRequest = null;
if (networkCallbackListener == null) {
throw new IllegalArgumentException("null NetworkCallbackListener");
@@ -1968,7 +2160,7 @@
new Binder());
} else {
networkRequest = mService.requestNetwork(need, new Messenger(sCallbackHandler),
- timeoutSec, new Binder());
+ timeoutSec, new Binder(), legacyType);
}
if (networkRequest != null) {
synchronized(sNetworkCallbackListener) {
@@ -1998,7 +2190,7 @@
*/
public NetworkRequest requestNetwork(NetworkCapabilities need,
NetworkCallbackListener networkCallbackListener) {
- return somethingForNetwork(need, networkCallbackListener, 0, REQUEST);
+ return sendRequestForNetwork(need, networkCallbackListener, 0, REQUEST, TYPE_NONE);
}
/**
@@ -2021,7 +2213,8 @@
*/
public NetworkRequest requestNetwork(NetworkCapabilities need,
NetworkCallbackListener networkCallbackListener, int timeoutSec) {
- return somethingForNetwork(need, networkCallbackListener, timeoutSec, REQUEST);
+ return sendRequestForNetwork(need, networkCallbackListener, timeoutSec, REQUEST,
+ TYPE_NONE);
}
/**
@@ -2099,7 +2292,7 @@
*/
public NetworkRequest listenForNetwork(NetworkCapabilities need,
NetworkCallbackListener networkCallbackListener) {
- return somethingForNetwork(need, networkCallbackListener, 0, LISTEN);
+ return sendRequestForNetwork(need, networkCallbackListener, 0, LISTEN, TYPE_NONE);
}
/**
diff --git a/core/java/android/net/ConnectivityServiceProtocol.java b/core/java/android/net/ConnectivityServiceProtocol.java
deleted file mode 100644
index 74096b4..0000000
--- a/core/java/android/net/ConnectivityServiceProtocol.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * 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 android.net;
-
-import static com.android.internal.util.Protocol.BASE_CONNECTIVITY_SERVICE;
-
-/**
- * Describes the Internal protocols used to communicate with ConnectivityService.
- * @hide
- */
-public class ConnectivityServiceProtocol {
-
- private static final int BASE = BASE_CONNECTIVITY_SERVICE;
-
- private ConnectivityServiceProtocol() {}
-
- /**
- * This is a contract between ConnectivityService and various bearers.
- * A NetworkFactory is an abstract entity that creates NetworkAgent objects.
- * The bearers register with ConnectivityService using
- * ConnectivityManager.registerNetworkFactory, where they pass in a Messenger
- * to be used to deliver the following Messages.
- */
- public static class NetworkFactoryProtocol {
- private NetworkFactoryProtocol() {}
- /**
- * Pass a network request to the bearer. If the bearer believes it can
- * satisfy the request it should connect to the network and create a
- * NetworkAgent. Once the NetworkAgent is fully functional it will
- * register itself with ConnectivityService using registerNetworkAgent.
- * If the bearer cannot immediately satisfy the request (no network,
- * user disabled the radio, lower-scored network) it should remember
- * any NetworkRequests it may be able to satisfy in the future. It may
- * disregard any that it will never be able to service, for example
- * those requiring a different bearer.
- * msg.obj = NetworkRequest
- * msg.arg1 = score - the score of the any network currently satisfying this
- * request. If this bearer knows in advance it cannot
- * exceed this score it should not try to connect, holding the request
- * for the future.
- * Note that subsequent events may give a different (lower
- * or higher) score for this request, transmitted to each
- * NetworkFactory through additional CMD_REQUEST_NETWORK msgs
- * with the same NetworkRequest but an updated score.
- * Also, network conditions may change for this bearer
- * allowing for a better score in the future.
- */
- public static final int CMD_REQUEST_NETWORK = BASE;
-
- /**
- * Cancel a network request
- * msg.obj = NetworkRequest
- */
- public static final int CMD_CANCEL_REQUEST = BASE + 1;
- }
-}
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index baec36a..5f1ff3e 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -158,7 +158,7 @@
in NetworkCapabilities nc, int score);
NetworkRequest requestNetwork(in NetworkCapabilities networkCapabilities,
- in Messenger messenger, int timeoutSec, in IBinder binder);
+ in Messenger messenger, int timeoutSec, in IBinder binder, int legacy);
NetworkRequest pendingRequestForNetwork(in NetworkCapabilities networkCapabilities,
in PendingIntent operation);
@@ -170,4 +170,6 @@
in PendingIntent operation);
void releaseNetworkRequest(in NetworkRequest networkRequest);
+
+ int getRestoreDefaultNetworkDelay(int networkType);
}
diff --git a/core/java/android/net/NetworkAgent.java b/core/java/android/net/NetworkAgent.java
index 1c18ba5..7e8b1f1 100644
--- a/core/java/android/net/NetworkAgent.java
+++ b/core/java/android/net/NetworkAgent.java
@@ -24,85 +24,39 @@
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
-import android.util.SparseArray;
import com.android.internal.util.AsyncChannel;
import com.android.internal.util.Protocol;
+import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
/**
- * A Utility class for handling NetworkRequests.
- *
- * Created by bearer-specific code to handle tracking requests, scores,
- * network data and handle communicating with ConnectivityService. Two
- * abstract methods: connect and disconnect are used to act on the
- * underlying bearer code. Connect is called when we have a NetworkRequest
- * and our score is better than the current handling network's score, while
- * disconnect is used when ConnectivityService requests a disconnect.
+ * A Utility class for handling for communicating between bearer-specific
+ * code and ConnectivityService.
*
* A bearer may have more than one NetworkAgent if it can simultaneously
* support separate networks (IMS / Internet / MMS Apns on cellular, or
- * perhaps connections with different SSID or P2P for Wi-Fi). The bearer
- * code should pass its NetworkAgents the NetworkRequests each NetworkAgent
- * can handle, demultiplexing for different network types. The bearer code
- * can also filter out requests it can never handle.
+ * perhaps connections with different SSID or P2P for Wi-Fi).
*
- * Each NetworkAgent needs to be given a score and NetworkCapabilities for
- * their potential network. While disconnected, the NetworkAgent will check
- * each time its score changes or a NetworkRequest changes to see if
- * the NetworkAgent can provide a higher scored network for a NetworkRequest
- * that the NetworkAgent's NetworkCapabilties can satisfy. This condition will
- * trigger a connect request via connect(). After connection, connection data
- * should be given to the NetworkAgent by the bearer, including LinkProperties
- * NetworkCapabilties and NetworkInfo. After that the NetworkAgent will register
- * with ConnectivityService and forward the data on.
* @hide
*/
public abstract class NetworkAgent extends Handler {
- private final SparseArray<NetworkRequestAndScore> mNetworkRequests = new SparseArray<>();
- private boolean mConnectionRequested = false;
-
- private AsyncChannel mAsyncChannel;
+ private volatile AsyncChannel mAsyncChannel;
private final String LOG_TAG;
private static final boolean DBG = true;
private static final boolean VDBG = true;
- // TODO - this class shouldn't cache data or it runs the risk of getting out of sync
- // Make the API require each of these when any is updated so we have the data we need,
- // without caching.
- private LinkProperties mLinkProperties;
- private NetworkInfo mNetworkInfo;
- private NetworkCapabilities mNetworkCapabilities;
- private int mNetworkScore;
- private boolean mRegistered = false;
private final Context mContext;
- private AtomicBoolean mHasRequests = new AtomicBoolean(false);
-
- // TODO - add a name member for logging purposes.
-
- protected final Object mLockObj = new Object();
-
+ private final ArrayList<Message>mPreConnectedQueue = new ArrayList<Message>();
private static final int BASE = Protocol.BASE_NETWORK_AGENT;
/**
- * Sent by self to queue up a new/modified request.
- * obj = NetworkRequestAndScore
- */
- private static final int CMD_ADD_REQUEST = BASE + 1;
-
- /**
- * Sent by self to queue up the removal of a request.
- * obj = NetworkRequest
- */
- private static final int CMD_REMOVE_REQUEST = BASE + 2;
-
- /**
* Sent by ConnectivityService to the NetworkAgent to inform it of
* suspected connectivity problems on its network. The NetworkAgent
* should take steps to verify and correct connectivity.
*/
- public static final int CMD_SUSPECT_BAD = BASE + 3;
+ public static final int CMD_SUSPECT_BAD = BASE;
/**
* Sent by the NetworkAgent (note the EVENT vs CMD prefix) to
@@ -110,84 +64,63 @@
* Sent when the NetworkInfo changes, mainly due to change of state.
* obj = NetworkInfo
*/
- public static final int EVENT_NETWORK_INFO_CHANGED = BASE + 4;
+ public static final int EVENT_NETWORK_INFO_CHANGED = BASE + 1;
/**
* Sent by the NetworkAgent to ConnectivityService to pass the current
* NetworkCapabilties.
* obj = NetworkCapabilities
*/
- public static final int EVENT_NETWORK_CAPABILITIES_CHANGED = BASE + 5;
+ public static final int EVENT_NETWORK_CAPABILITIES_CHANGED = BASE + 2;
/**
* Sent by the NetworkAgent to ConnectivityService to pass the current
* NetworkProperties.
* obj = NetworkProperties
*/
- public static final int EVENT_NETWORK_PROPERTIES_CHANGED = BASE + 6;
+ public static final int EVENT_NETWORK_PROPERTIES_CHANGED = BASE + 3;
/**
* Sent by the NetworkAgent to ConnectivityService to pass the current
* network score.
- * arg1 = network score int
+ * obj = network score Integer
*/
- public static final int EVENT_NETWORK_SCORE_CHANGED = BASE + 7;
+ public static final int EVENT_NETWORK_SCORE_CHANGED = BASE + 4;
- public NetworkAgent(Looper looper, Context context, String logTag) {
+ public NetworkAgent(Looper looper, Context context, String logTag, NetworkInfo ni,
+ NetworkCapabilities nc, LinkProperties lp, int score) {
super(looper);
LOG_TAG = logTag;
mContext = context;
- }
-
- /**
- * When conditions are right, register with ConnectivityService.
- * Connditions include having a well defined network and a request
- * that justifies it. The NetworkAgent will remain registered until
- * disconnected.
- * TODO - this should have all data passed in rather than caching
- */
- private void registerSelf() {
- synchronized(mLockObj) {
- if (!mRegistered && mConnectionRequested &&
- mNetworkInfo != null && mNetworkInfo.isConnected() &&
- mNetworkCapabilities != null &&
- mLinkProperties != null &&
- mNetworkScore != 0) {
- if (DBG) log("Registering NetworkAgent");
- mRegistered = true;
- ConnectivityManager cm = (ConnectivityManager)mContext.getSystemService(
- Context.CONNECTIVITY_SERVICE);
- cm.registerNetworkAgent(new Messenger(this), new NetworkInfo(mNetworkInfo),
- new LinkProperties(mLinkProperties),
- new NetworkCapabilities(mNetworkCapabilities), mNetworkScore);
- } else if (DBG && !mRegistered) {
- String err = "Not registering due to ";
- if (mConnectionRequested == false) err += "no Connect requested ";
- if (mNetworkInfo == null) err += "null NetworkInfo ";
- if (mNetworkInfo != null && mNetworkInfo.isConnected() == false) {
- err += "NetworkInfo disconnected ";
- }
- if (mLinkProperties == null) err += "null LinkProperties ";
- if (mNetworkCapabilities == null) err += "null NetworkCapabilities ";
- if (mNetworkScore == 0) err += "null NetworkScore";
- log(err);
- }
+ if (ni == null || nc == null || lp == null) {
+ throw new IllegalArgumentException();
}
+
+ if (DBG) log("Registering NetworkAgent");
+ ConnectivityManager cm = (ConnectivityManager)mContext.getSystemService(
+ Context.CONNECTIVITY_SERVICE);
+ cm.registerNetworkAgent(new Messenger(this), new NetworkInfo(ni),
+ new LinkProperties(lp), new NetworkCapabilities(nc), score);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case AsyncChannel.CMD_CHANNEL_FULL_CONNECTION: {
- synchronized (mLockObj) {
- if (mAsyncChannel != null) {
- log("Received new connection while already connected!");
- } else {
- if (DBG) log("NetworkAgent fully connected");
- mAsyncChannel = new AsyncChannel();
- mAsyncChannel.connected(null, this, msg.replyTo);
- mAsyncChannel.replyToMessage(msg, AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED,
- AsyncChannel.STATUS_SUCCESSFUL);
+ if (mAsyncChannel != null) {
+ log("Received new connection while already connected!");
+ } else {
+ if (DBG) log("NetworkAgent fully connected");
+ AsyncChannel ac = new AsyncChannel();
+ ac.connected(null, this, msg.replyTo);
+ ac.replyToMessage(msg, AsyncChannel.CMD_CHANNEL_FULLY_CONNECTED,
+ AsyncChannel.STATUS_SUCCESSFUL);
+ synchronized (mPreConnectedQueue) {
+ mAsyncChannel = ac;
+ for (Message m : mPreConnectedQueue) {
+ ac.sendMessage(m);
+ }
+ mPreConnectedQueue.clear();
}
}
break;
@@ -199,213 +132,69 @@
}
case AsyncChannel.CMD_CHANNEL_DISCONNECTED: {
if (DBG) log("NetworkAgent channel lost");
- disconnect();
- clear();
+ // let the client know CS is done with us.
+ unwanted();
+ synchronized (mPreConnectedQueue) {
+ mAsyncChannel = null;
+ }
break;
}
case CMD_SUSPECT_BAD: {
log("Unhandled Message " + msg);
break;
}
- case CMD_ADD_REQUEST: {
- handleAddRequest(msg);
- break;
- }
- case CMD_REMOVE_REQUEST: {
- handleRemoveRequest(msg);
- break;
- }
}
}
- private void clear() {
- synchronized(mLockObj) {
- mNetworkRequests.clear();
- mHasRequests.set(false);
- mConnectionRequested = false;
- mAsyncChannel = null;
- mRegistered = false;
- }
- }
-
- private static class NetworkRequestAndScore {
- NetworkRequest req;
- int score;
-
- NetworkRequestAndScore(NetworkRequest networkRequest, int score) {
- req = networkRequest;
- this.score = score;
- }
- }
-
- private void handleAddRequest(Message msg) {
- NetworkRequestAndScore n = (NetworkRequestAndScore)msg.obj;
- // replaces old request, updating score
- mNetworkRequests.put(n.req.requestId, n);
- mHasRequests.set(true);
- evalScores();
- }
-
- private void handleRemoveRequest(Message msg) {
- NetworkRequest networkRequest = (NetworkRequest)msg.obj;
-
- if (mNetworkRequests.get(networkRequest.requestId) != null) {
- mNetworkRequests.remove(networkRequest.requestId);
- if (mNetworkRequests.size() == 0) mHasRequests.set(false);
- evalScores();
- }
- }
-
- /**
- * Called to go through our list of requests and see if we're
- * good enough to try connecting, or if we have gotten worse and
- * need to disconnect.
- *
- * Once we are registered, does nothing: we disconnect when requested via
- * CMD_CHANNEL_DISCONNECTED, generated by either a loss of connection
- * between modules (bearer or ConnectivityService dies) or more commonly
- * when the NetworkInfo reports to ConnectivityService it is disconnected.
- */
- private void evalScores() {
- synchronized(mLockObj) {
- if (mRegistered) {
- if (VDBG) log("evalScores - already connected - size=" + mNetworkRequests.size());
- // already trying
- return;
- }
- if (VDBG) log("evalScores!");
- for (int i=0; i < mNetworkRequests.size(); i++) {
- int score = mNetworkRequests.valueAt(i).score;
- if (VDBG) log(" checking request Min " + score + " vs my score " + mNetworkScore);
- if (score < mNetworkScore) {
- // have a request that has a lower scored network servicing it
- // (or no network) than we could provide, so let's connect!
- mConnectionRequested = true;
- connect();
- return;
- }
- }
- // Our score is not high enough to satisfy any current request.
- // This can happen if our score goes down after a connection is
- // requested but before we actually connect. In this case, disconnect
- // rather than continue trying - there's no point connecting if we know
- // we'll just be torn down as soon as we do.
- if (mConnectionRequested) {
- mConnectionRequested = false;
- disconnect();
+ private void queueOrSendMessage(int what, Object obj) {
+ synchronized (mPreConnectedQueue) {
+ if (mAsyncChannel != null) {
+ mAsyncChannel.sendMessage(what, obj);
+ } else {
+ Message msg = Message.obtain();
+ msg.what = what;
+ msg.obj = obj;
+ mPreConnectedQueue.add(msg);
}
}
}
- public void addNetworkRequest(NetworkRequest networkRequest, int score) {
- if (DBG) log("adding NetworkRequest " + networkRequest + " with score " + score);
- sendMessage(obtainMessage(CMD_ADD_REQUEST,
- new NetworkRequestAndScore(networkRequest, score)));
- }
-
- public void removeNetworkRequest(NetworkRequest networkRequest) {
- if (DBG) log("removing NetworkRequest " + networkRequest);
- sendMessage(obtainMessage(CMD_REMOVE_REQUEST, networkRequest));
- }
-
/**
* Called by the bearer code when it has new LinkProperties data.
- * If we're a registered NetworkAgent, this new data will get forwarded on,
- * otherwise we store a copy in anticipation of registering. This call
- * may also prompt registration if it causes the NetworkAgent to meet
- * the conditions (fully configured, connected, satisfys a request and
- * has sufficient score).
*/
public void sendLinkProperties(LinkProperties linkProperties) {
- linkProperties = new LinkProperties(linkProperties);
- synchronized(mLockObj) {
- mLinkProperties = linkProperties;
- if (mAsyncChannel != null) {
- mAsyncChannel.sendMessage(EVENT_NETWORK_PROPERTIES_CHANGED, linkProperties);
- } else {
- registerSelf();
- }
- }
+ queueOrSendMessage(EVENT_NETWORK_PROPERTIES_CHANGED, new LinkProperties(linkProperties));
}
/**
* Called by the bearer code when it has new NetworkInfo data.
- * If we're a registered NetworkAgent, this new data will get forwarded on,
- * otherwise we store a copy in anticipation of registering. This call
- * may also prompt registration if it causes the NetworkAgent to meet
- * the conditions (fully configured, connected, satisfys a request and
- * has sufficient score).
*/
public void sendNetworkInfo(NetworkInfo networkInfo) {
- networkInfo = new NetworkInfo(networkInfo);
- synchronized(mLockObj) {
- mNetworkInfo = networkInfo;
- if (mAsyncChannel != null) {
- mAsyncChannel.sendMessage(EVENT_NETWORK_INFO_CHANGED, networkInfo);
- } else {
- registerSelf();
- }
- }
+ queueOrSendMessage(EVENT_NETWORK_INFO_CHANGED, new NetworkInfo(networkInfo));
}
/**
* Called by the bearer code when it has new NetworkCapabilities data.
- * If we're a registered NetworkAgent, this new data will get forwarded on,
- * otherwise we store a copy in anticipation of registering. This call
- * may also prompt registration if it causes the NetworkAgent to meet
- * the conditions (fully configured, connected, satisfys a request and
- * has sufficient score).
- * Note that if these capabilities make the network non-useful,
- * ConnectivityServce will tear this network down.
*/
public void sendNetworkCapabilities(NetworkCapabilities networkCapabilities) {
- networkCapabilities = new NetworkCapabilities(networkCapabilities);
- synchronized(mLockObj) {
- mNetworkCapabilities = networkCapabilities;
- if (mAsyncChannel != null) {
- mAsyncChannel.sendMessage(EVENT_NETWORK_CAPABILITIES_CHANGED, networkCapabilities);
- } else {
- registerSelf();
- }
- }
- }
-
- public NetworkCapabilities getNetworkCapabilities() {
- synchronized(mLockObj) {
- return new NetworkCapabilities(mNetworkCapabilities);
- }
+ queueOrSendMessage(EVENT_NETWORK_CAPABILITIES_CHANGED,
+ new NetworkCapabilities(networkCapabilities));
}
/**
* Called by the bearer code when it has a new score for this network.
- * If we're a registered NetworkAgent, this new data will get forwarded on,
- * otherwise we store a copy.
*/
- public synchronized void sendNetworkScore(int score) {
- synchronized(mLockObj) {
- mNetworkScore = score;
- evalScores();
- if (mAsyncChannel != null) {
- mAsyncChannel.sendMessage(EVENT_NETWORK_SCORE_CHANGED, mNetworkScore);
- } else {
- registerSelf();
- }
- }
+ public void sendNetworkScore(int score) {
+ queueOrSendMessage(EVENT_NETWORK_SCORE_CHANGED, new Integer(score));
}
- public boolean hasRequests() {
- return mHasRequests.get();
- }
-
- public boolean isConnectionRequested() {
- synchronized(mLockObj) {
- return mConnectionRequested;
- }
- }
-
-
- abstract protected void connect();
- abstract protected void disconnect();
+ /**
+ * Called when ConnectivityService has indicated they no longer want this network.
+ * The parent factory should (previously) have received indication of the change
+ * as well, either canceling NetworkRequests or altering their score such that this
+ * network won't be immediately requested again.
+ */
+ abstract protected void unwanted();
protected void log(String s) {
Log.d(LOG_TAG, "NetworkAgent: " + s);
diff --git a/core/java/android/net/NetworkFactory.java b/core/java/android/net/NetworkFactory.java
new file mode 100644
index 0000000..a20e8e7
--- /dev/null
+++ b/core/java/android/net/NetworkFactory.java
@@ -0,0 +1,275 @@
+/*
+ * 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 android.net;
+
+import android.content.Context;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Messenger;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+import android.util.SparseArray;
+
+import com.android.internal.util.AsyncChannel;
+import com.android.internal.util.Protocol;
+
+/**
+ * A NetworkFactory is an entity that creates NetworkAgent objects.
+ * The bearers register with ConnectivityService using {@link #register} and
+ * their factory will start receiving scored NetworkRequests. NetworkRequests
+ * can be filtered 3 ways: by NetworkCapabilities, by score and more complexly by
+ * overridden function. All of these can be dynamic - changing NetworkCapabilities
+ * or score forces re-evaluation of all current requests.
+ *
+ * If any requests pass the filter some overrideable functions will be called.
+ * If the bearer only cares about very simple start/stopNetwork callbacks, those
+ * functions can be overridden. If the bearer needs more interaction, it can
+ * override addNetworkRequest and removeNetworkRequest which will give it each
+ * request that passes their current filters.
+ * @hide
+ **/
+public class NetworkFactory extends Handler {
+ private static final boolean DBG = true;
+
+ private static final int BASE = Protocol.BASE_NETWORK_FACTORY;
+ /**
+ * Pass a network request to the bearer. If the bearer believes it can
+ * satisfy the request it should connect to the network and create a
+ * NetworkAgent. Once the NetworkAgent is fully functional it will
+ * register itself with ConnectivityService using registerNetworkAgent.
+ * If the bearer cannot immediately satisfy the request (no network,
+ * user disabled the radio, lower-scored network) it should remember
+ * any NetworkRequests it may be able to satisfy in the future. It may
+ * disregard any that it will never be able to service, for example
+ * those requiring a different bearer.
+ * msg.obj = NetworkRequest
+ * msg.arg1 = score - the score of the any network currently satisfying this
+ * request. If this bearer knows in advance it cannot
+ * exceed this score it should not try to connect, holding the request
+ * for the future.
+ * Note that subsequent events may give a different (lower
+ * or higher) score for this request, transmitted to each
+ * NetworkFactory through additional CMD_REQUEST_NETWORK msgs
+ * with the same NetworkRequest but an updated score.
+ * Also, network conditions may change for this bearer
+ * allowing for a better score in the future.
+ */
+ public static final int CMD_REQUEST_NETWORK = BASE;
+
+ /**
+ * Cancel a network request
+ * msg.obj = NetworkRequest
+ */
+ public static final int CMD_CANCEL_REQUEST = BASE + 1;
+
+ /**
+ * Internally used to set our best-guess score.
+ * msg.arg1 = new score
+ */
+ private static final int CMD_SET_SCORE = BASE + 2;
+
+ /**
+ * Internally used to set our current filter for coarse bandwidth changes with
+ * technology changes.
+ * msg.obj = new filter
+ */
+ private static final int CMD_SET_FILTER = BASE + 3;
+
+ private final Context mContext;
+ private final String LOG_TAG;
+
+ private final SparseArray<NetworkRequestInfo> mNetworkRequests =
+ new SparseArray<NetworkRequestInfo>();
+
+ private int mScore;
+ private NetworkCapabilities mCapabilityFilter;
+
+ private int mRefCount = 0;
+ private Messenger mMessenger = null;
+
+ public NetworkFactory(Looper looper, Context context, String logTag,
+ NetworkCapabilities filter) {
+ super(looper);
+ LOG_TAG = logTag;
+ mContext = context;
+ mCapabilityFilter = filter;
+ }
+
+ public void register() {
+ if (DBG) log("Registering NetworkFactory");
+ if (mMessenger == null) {
+ mMessenger = new Messenger(this);
+ ConnectivityManager.from(mContext).registerNetworkFactory(mMessenger, LOG_TAG);
+ }
+ }
+
+ public void unregister() {
+ if (DBG) log("Unregistering NetworkFactory");
+ if (mMessenger != null) {
+ ConnectivityManager.from(mContext).unregisterNetworkFactory(mMessenger);
+ mMessenger = null;
+ }
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case CMD_REQUEST_NETWORK: {
+ handleAddRequest((NetworkRequest)msg.obj, msg.arg1);
+ break;
+ }
+ case CMD_CANCEL_REQUEST: {
+ handleRemoveRequest((NetworkRequest) msg.obj);
+ break;
+ }
+ case CMD_SET_SCORE: {
+ handleSetScore(msg.arg1);
+ break;
+ }
+ case CMD_SET_FILTER: {
+ handleSetFilter((NetworkCapabilities) msg.obj);
+ break;
+ }
+ }
+ }
+
+ private class NetworkRequestInfo {
+ public final NetworkRequest request;
+ public int score;
+ public boolean requested; // do we have a request outstanding, limited by score
+
+ public NetworkRequestInfo(NetworkRequest request, int score) {
+ this.request = request;
+ this.score = score;
+ this.requested = false;
+ }
+ }
+
+ private void handleAddRequest(NetworkRequest request, int score) {
+ NetworkRequestInfo n = mNetworkRequests.get(request.requestId);
+ if (n == null) {
+ n = new NetworkRequestInfo(request, score);
+ mNetworkRequests.put(n.request.requestId, n);
+ } else {
+ n.score = score;
+ }
+ if (DBG) log("got request " + request + " with score " + score);
+ if (DBG) log(" my score=" + mScore + ", my filter=" + mCapabilityFilter);
+
+ evalRequest(n);
+ }
+
+ private void handleRemoveRequest(NetworkRequest request) {
+ NetworkRequestInfo n = mNetworkRequests.get(request.requestId);
+ if (n != null && n.requested) {
+ mNetworkRequests.remove(request.requestId);
+ releaseNetworkFor(n.request);
+ }
+ }
+
+ private void handleSetScore(int score) {
+ mScore = score;
+ evalRequests();
+ }
+
+ private void handleSetFilter(NetworkCapabilities netCap) {
+ mCapabilityFilter = netCap;
+ evalRequests();
+ }
+
+ /**
+ * Overridable function to provide complex filtering.
+ * Called for every request every time a new NetworkRequest is seen
+ * and whenever the filterScore or filterNetworkCapabilities change.
+ *
+ * acceptRequest can be overriden to provide complex filter behavior
+ * for the incoming requests
+ *
+ * For output, this class will call {@link #needNetworkFor} and
+ * {@link #releaseNetworkFor} for every request that passes the filters.
+ * If you don't need to see every request, you can leave the base
+ * implementations of those two functions and instead override
+ * {@link #startNetwork} and {@link #stopNetwork}.
+ *
+ * If you want to see every score fluctuation on every request, set
+ * your score filter to a very high number and watch {@link #needNetworkFor}.
+ *
+ * @return {@code true} to accept the request.
+ */
+ public boolean acceptRequest(NetworkRequest request, int score) {
+ return true;
+ }
+
+ private void evalRequest(NetworkRequestInfo n) {
+ if (n.requested == false && n.score < mScore &&
+ n.request.networkCapabilities.satisfiedByNetworkCapabilities(
+ mCapabilityFilter) && acceptRequest(n.request, n.score)) {
+ needNetworkFor(n.request, n.score);
+ n.requested = true;
+ } else if (n.requested == true &&
+ (n.score > mScore || n.request.networkCapabilities.satisfiedByNetworkCapabilities(
+ mCapabilityFilter) == false || acceptRequest(n.request, n.score) == false)) {
+ releaseNetworkFor(n.request);
+ n.requested = false;
+ }
+ }
+
+ private void evalRequests() {
+ for (int i = 0; i < mNetworkRequests.size(); i++) {
+ NetworkRequestInfo n = mNetworkRequests.valueAt(i);
+
+ evalRequest(n);
+ }
+ }
+
+ // override to do simple mode (request independent)
+ protected void startNetwork() { }
+ protected void stopNetwork() { }
+
+ // override to do fancier stuff
+ protected void needNetworkFor(NetworkRequest networkRequest, int score) {
+ if (++mRefCount == 1) startNetwork();
+ }
+
+ protected void releaseNetworkFor(NetworkRequest networkRequest) {
+ if (--mRefCount == 0) stopNetwork();
+ }
+
+
+ public void addNetworkRequest(NetworkRequest networkRequest, int score) {
+ sendMessage(obtainMessage(CMD_REQUEST_NETWORK,
+ new NetworkRequestInfo(networkRequest, score)));
+ }
+
+ public void removeNetworkRequest(NetworkRequest networkRequest) {
+ sendMessage(obtainMessage(CMD_CANCEL_REQUEST, networkRequest));
+ }
+
+ public void setScoreFilter(int score) {
+ sendMessage(obtainMessage(CMD_SET_SCORE, score, 0));
+ }
+
+ public void setCapabilityFilter(NetworkCapabilities netCap) {
+ sendMessage(obtainMessage(CMD_SET_FILTER, new NetworkCapabilities(netCap)));
+ }
+
+ protected void log(String s) {
+ Log.d(LOG_TAG, s);
+ }
+}
diff --git a/core/java/android/net/NetworkInfo.java b/core/java/android/net/NetworkInfo.java
index 9e656ee..d279412 100644
--- a/core/java/android/net/NetworkInfo.java
+++ b/core/java/android/net/NetworkInfo.java
@@ -188,6 +188,15 @@
}
/**
+ * @hide
+ */
+ public void setType(int type) {
+ synchronized (this) {
+ mNetworkType = type;
+ }
+ }
+
+ /**
* Return a network-type-specific integer describing the subtype
* of the network.
* @return the network subtype
@@ -198,7 +207,10 @@
}
}
- void setSubtype(int subtype, String subtypeName) {
+ /**
+ * @hide
+ */
+ public void setSubtype(int subtype, String subtypeName) {
synchronized (this) {
mSubtype = subtype;
mSubtypeName = subtypeName;
diff --git a/core/java/android/net/NetworkRequest.java b/core/java/android/net/NetworkRequest.java
index 480cb057..47377e9 100644
--- a/core/java/android/net/NetworkRequest.java
+++ b/core/java/android/net/NetworkRequest.java
@@ -47,19 +47,19 @@
public final int requestId;
/**
- * Set for legacy requests and the default.
+ * Set for legacy requests and the default. Set to TYPE_NONE for none.
* Causes CONNECTIVITY_ACTION broadcasts to be sent.
* @hide
*/
- public final boolean needsBroadcasts;
+ public final int legacyType;
/**
* @hide
*/
- public NetworkRequest(NetworkCapabilities nc, boolean needsBroadcasts, int rId) {
+ public NetworkRequest(NetworkCapabilities nc, int legacyType, int rId) {
requestId = rId;
networkCapabilities = nc;
- this.needsBroadcasts = needsBroadcasts;
+ this.legacyType = legacyType;
}
/**
@@ -68,7 +68,7 @@
public NetworkRequest(NetworkRequest that) {
networkCapabilities = new NetworkCapabilities(that.networkCapabilities);
requestId = that.requestId;
- needsBroadcasts = that.needsBroadcasts;
+ this.legacyType = that.legacyType;
}
// implement the Parcelable interface
@@ -77,16 +77,16 @@
}
public void writeToParcel(Parcel dest, int flags) {
dest.writeParcelable(networkCapabilities, flags);
- dest.writeInt(needsBroadcasts ? 1 : 0);
+ dest.writeInt(legacyType);
dest.writeInt(requestId);
}
public static final Creator<NetworkRequest> CREATOR =
new Creator<NetworkRequest>() {
public NetworkRequest createFromParcel(Parcel in) {
NetworkCapabilities nc = (NetworkCapabilities)in.readParcelable(null);
- boolean needsBroadcasts = (in.readInt() == 1);
+ int legacyType = in.readInt();
int requestId = in.readInt();
- NetworkRequest result = new NetworkRequest(nc, needsBroadcasts, requestId);
+ NetworkRequest result = new NetworkRequest(nc, legacyType, requestId);
return result;
}
public NetworkRequest[] newArray(int size) {
@@ -95,14 +95,14 @@
};
public String toString() {
- return "NetworkRequest [ id=" + requestId + ", needsBroadcasts=" + needsBroadcasts +
+ return "NetworkRequest [ id=" + requestId + ", legacyType=" + legacyType +
", " + networkCapabilities.toString() + " ]";
}
public boolean equals(Object obj) {
if (obj instanceof NetworkRequest == false) return false;
NetworkRequest that = (NetworkRequest)obj;
- return (that.needsBroadcasts == this.needsBroadcasts &&
+ return (that.legacyType == this.legacyType &&
that.requestId == this.requestId &&
((that.networkCapabilities == null && this.networkCapabilities == null) ||
(that.networkCapabilities != null &&
@@ -110,7 +110,7 @@
}
public int hashCode() {
- return requestId + (needsBroadcasts ? 1013 : 2026) +
+ return requestId + (legacyType * 1013) +
(networkCapabilities.hashCode() * 1051);
}
}
diff --git a/core/java/com/android/internal/util/Protocol.java b/core/java/com/android/internal/util/Protocol.java
index 81e67d8..af966b1 100644
--- a/core/java/com/android/internal/util/Protocol.java
+++ b/core/java/com/android/internal/util/Protocol.java
@@ -57,9 +57,9 @@
public static final int BASE_DNS_PINGER = 0x00050000;
public static final int BASE_NSD_MANAGER = 0x00060000;
public static final int BASE_NETWORK_STATE_TRACKER = 0x00070000;
- public static final int BASE_CONNECTIVITY_SERVICE = 0x00080000;
+ public static final int BASE_CONNECTIVITY_MANAGER = 0x00080000;
public static final int BASE_NETWORK_AGENT = 0x00081000;
public static final int BASE_NETWORK_MONITOR = 0x00082000;
- public static final int BASE_CONNECTIVITY_MANAGER = 0x00083000;
+ public static final int BASE_NETWORK_FACTORY = 0x00083000;
//TODO: define all used protocols
}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 6d0b325..55f52da 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1006,14 +1006,6 @@
android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
android:protectionLevel="signature" />
- <!-- Allows an application to communicate with a SIM card using logical
- channels. -->
- <permission android:name="android.permission.SIM_COMMUNICATION"
- android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
- android:label="@string/permlab_sim_communication"
- android:description="@string/permdesc_sim_communication"
- android:protectionLevel="dangerous" />
-
<!-- Allows TvInputService to access underlying TV input hardware such as
built-in tuners and HDMI-in's.
@hide This should only be used by OEM's TvInputService's.
diff --git a/core/res/res/drawable-hdpi/tab_indicator_normal_qntm_alpha.9.png b/core/res/res/drawable-hdpi/tab_indicator_normal_qntm_alpha.9.png
deleted file mode 100644
index 233d409..0000000
--- a/core/res/res/drawable-hdpi/tab_indicator_normal_qntm_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-hdpi/tab_indicator_qntm_alpha.9.png b/core/res/res/drawable-hdpi/tab_indicator_qntm_alpha.9.png
new file mode 100644
index 0000000..21b2135
--- /dev/null
+++ b/core/res/res/drawable-hdpi/tab_indicator_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/tab_indicator_selected_qntm_alpha.9.png b/core/res/res/drawable-hdpi/tab_indicator_selected_qntm_alpha.9.png
deleted file mode 100644
index 68b1dd7..0000000
--- a/core/res/res/drawable-hdpi/tab_indicator_selected_qntm_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldpi/tab_indicator_normal_qntm_alpha.9.png b/core/res/res/drawable-ldpi/tab_indicator_normal_qntm_alpha.9.png
deleted file mode 100644
index 2244362..0000000
--- a/core/res/res/drawable-ldpi/tab_indicator_normal_qntm_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-ldpi/tab_indicator_selected_qntm_alpha.9.png b/core/res/res/drawable-ldpi/tab_indicator_selected_qntm_alpha.9.png
deleted file mode 100644
index 22ea80e..0000000
--- a/core/res/res/drawable-ldpi/tab_indicator_selected_qntm_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/tab_indicator_normal_qntm_alpha.9.png b/core/res/res/drawable-mdpi/tab_indicator_normal_qntm_alpha.9.png
deleted file mode 100644
index fd668ee..0000000
--- a/core/res/res/drawable-mdpi/tab_indicator_normal_qntm_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-mdpi/tab_indicator_qntm_alpha.9.png b/core/res/res/drawable-mdpi/tab_indicator_qntm_alpha.9.png
new file mode 100644
index 0000000..b69529c
--- /dev/null
+++ b/core/res/res/drawable-mdpi/tab_indicator_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/tab_indicator_selected_qntm_alpha.9.png b/core/res/res/drawable-mdpi/tab_indicator_selected_qntm_alpha.9.png
deleted file mode 100644
index ace579f..0000000
--- a/core/res/res/drawable-mdpi/tab_indicator_selected_qntm_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/tab_indicator_normal_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/tab_indicator_normal_qntm_alpha.9.png
deleted file mode 100644
index a677f9a..0000000
--- a/core/res/res/drawable-xhdpi/tab_indicator_normal_qntm_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/tab_indicator_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/tab_indicator_qntm_alpha.9.png
new file mode 100644
index 0000000..5610d8c
--- /dev/null
+++ b/core/res/res/drawable-xhdpi/tab_indicator_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/tab_indicator_selected_qntm_alpha.9.png b/core/res/res/drawable-xhdpi/tab_indicator_selected_qntm_alpha.9.png
deleted file mode 100644
index 7de791d..0000000
--- a/core/res/res/drawable-xhdpi/tab_indicator_selected_qntm_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/tab_indicator_normal_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/tab_indicator_normal_qntm_alpha.9.png
deleted file mode 100644
index 0a14025..0000000
--- a/core/res/res/drawable-xxhdpi/tab_indicator_normal_qntm_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/tab_indicator_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/tab_indicator_qntm_alpha.9.png
new file mode 100644
index 0000000..248f4f8
--- /dev/null
+++ b/core/res/res/drawable-xxhdpi/tab_indicator_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable-xxhdpi/tab_indicator_selected_qntm_alpha.9.png b/core/res/res/drawable-xxhdpi/tab_indicator_selected_qntm_alpha.9.png
deleted file mode 100644
index 20e291a..0000000
--- a/core/res/res/drawable-xxhdpi/tab_indicator_selected_qntm_alpha.9.png
+++ /dev/null
Binary files differ
diff --git a/core/res/res/drawable-xxxhdpi/tab_indicator_qntm_alpha.9.png b/core/res/res/drawable-xxxhdpi/tab_indicator_qntm_alpha.9.png
new file mode 100644
index 0000000..5813179
--- /dev/null
+++ b/core/res/res/drawable-xxxhdpi/tab_indicator_qntm_alpha.9.png
Binary files differ
diff --git a/core/res/res/drawable/tab_indicator_quantum.xml b/core/res/res/drawable/tab_indicator_quantum.xml
index 6fabe23..ff14d9c 100644
--- a/core/res/res/drawable/tab_indicator_quantum.xml
+++ b/core/res/res/drawable/tab_indicator_quantum.xml
@@ -15,29 +15,9 @@
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:state_selected="true" android:state_pressed="true">
- <nine-patch android:src="@drawable/tab_indicator_selected_qntm_alpha"
- android:tint="?attr/colorControlActivated" />
- </item>
- <item android:state_selected="true" android:state_focused="true">
- <nine-patch android:src="@drawable/tab_indicator_selected_qntm_alpha"
- android:tint="?attr/colorControlActivated" />
- </item>
<item android:state_selected="true">
- <nine-patch android:src="@drawable/tab_indicator_selected_qntm_alpha"
- android:tint="?attr/colorControlNormal" />
- </item>
-
- <item android:state_pressed="true">
- <nine-patch android:src="@drawable/tab_indicator_normal_qntm_alpha"
+ <nine-patch android:src="@drawable/tab_indicator_qntm_alpha"
android:tint="?attr/colorControlActivated" />
</item>
- <item android:state_focused="true">
- <nine-patch android:src="@drawable/tab_indicator_normal_qntm_alpha"
- android:tint="?attr/colorControlActivated" />
- </item>
- <item>
- <nine-patch android:src="@drawable/tab_indicator_normal_qntm_alpha"
- android:tint="?attr/colorControlNormal" />
- </item>
+ <item android:drawable="@color/transparent" />
</selector>
diff --git a/core/res/res/values/arrays.xml b/core/res/res/values/arrays.xml
index f01f10e..042af41 100644
--- a/core/res/res/values/arrays.xml
+++ b/core/res/res/values/arrays.xml
@@ -298,6 +298,191 @@
<item>@drawable/quickcontact_badge_overlay_light</item>
<item>@drawable/quickcontact_badge_overlay_normal_light</item>
<item>@drawable/quickcontact_badge_overlay_pressed_light</item>
+
+ <!-- Quantum assets -->
+ <item>@drawable/ab_share_pack_qntm_alpha</item>
+ <item>@drawable/ab_solid_shadow_qntm_alpha</item>
+ <item>@drawable/btn_cab_done_qntm_alpha</item>
+ <item>@drawable/btn_check_to_off_qntm_000</item>
+ <item>@drawable/btn_check_to_off_qntm_001</item>
+ <item>@drawable/btn_check_to_off_qntm_002</item>
+ <item>@drawable/btn_check_to_off_qntm_003</item>
+ <item>@drawable/btn_check_to_off_qntm_004</item>
+ <item>@drawable/btn_check_to_off_qntm_005</item>
+ <item>@drawable/btn_check_to_off_qntm_006</item>
+ <item>@drawable/btn_check_to_off_qntm_007</item>
+ <item>@drawable/btn_check_to_off_qntm_008</item>
+ <item>@drawable/btn_check_to_off_qntm_009</item>
+ <item>@drawable/btn_check_to_off_qntm_010</item>
+ <item>@drawable/btn_check_to_off_qntm_011</item>
+ <item>@drawable/btn_check_to_off_qntm_012</item>
+ <item>@drawable/btn_check_to_off_qntm_013</item>
+ <item>@drawable/btn_check_to_off_qntm_014</item>
+ <item>@drawable/btn_check_to_off_qntm_015</item>
+ <item>@drawable/btn_check_to_on_qntm_000</item>
+ <item>@drawable/btn_check_to_on_qntm_001</item>
+ <item>@drawable/btn_check_to_on_qntm_002</item>
+ <item>@drawable/btn_check_to_on_qntm_003</item>
+ <item>@drawable/btn_check_to_on_qntm_004</item>
+ <item>@drawable/btn_check_to_on_qntm_005</item>
+ <item>@drawable/btn_check_to_on_qntm_006</item>
+ <item>@drawable/btn_check_to_on_qntm_007</item>
+ <item>@drawable/btn_check_to_on_qntm_008</item>
+ <item>@drawable/btn_check_to_on_qntm_009</item>
+ <item>@drawable/btn_check_to_on_qntm_010</item>
+ <item>@drawable/btn_check_to_on_qntm_011</item>
+ <item>@drawable/btn_check_to_on_qntm_012</item>
+ <item>@drawable/btn_check_to_on_qntm_013</item>
+ <item>@drawable/btn_check_to_on_qntm_014</item>
+ <item>@drawable/btn_check_to_on_qntm_015</item>
+ <item>@drawable/btn_qntm_alpha</item>
+ <item>@drawable/btn_radio_anim_00000_qntm_alpha</item>
+ <item>@drawable/btn_radio_anim_00001_qntm_alpha</item>
+ <item>@drawable/btn_radio_anim_00002_qntm_alpha</item>
+ <item>@drawable/btn_radio_anim_00003_qntm_alpha</item>
+ <item>@drawable/btn_radio_anim_00004_qntm_alpha</item>
+ <item>@drawable/btn_radio_anim_00005_qntm_alpha</item>
+ <item>@drawable/btn_radio_anim_00006_qntm_alpha</item>
+ <item>@drawable/btn_radio_anim_00007_qntm_alpha</item>
+ <item>@drawable/btn_radio_anim_00008_qntm_alpha</item>
+ <item>@drawable/btn_radio_anim_00009_qntm_alpha</item>
+ <item>@drawable/btn_radio_anim_00010_qntm_alpha</item>
+ <item>@drawable/btn_radio_anim_00011_qntm_alpha</item>
+ <item>@drawable/btn_radio_anim_00012_qntm_alpha</item>
+ <item>@drawable/btn_radio_anim_00013_qntm_alpha</item>
+ <item>@drawable/btn_radio_anim_00014_qntm_alpha</item>
+ <item>@drawable/btn_radio_anim_00015_qntm_alpha</item>
+ <item>@drawable/btn_radio_to_off_qntm_000</item>
+ <item>@drawable/btn_radio_to_off_qntm_001</item>
+ <item>@drawable/btn_radio_to_off_qntm_002</item>
+ <item>@drawable/btn_radio_to_off_qntm_003</item>
+ <item>@drawable/btn_radio_to_off_qntm_004</item>
+ <item>@drawable/btn_radio_to_off_qntm_005</item>
+ <item>@drawable/btn_radio_to_off_qntm_006</item>
+ <item>@drawable/btn_radio_to_off_qntm_007</item>
+ <item>@drawable/btn_radio_to_off_qntm_008</item>
+ <item>@drawable/btn_radio_to_off_qntm_009</item>
+ <item>@drawable/btn_radio_to_off_qntm_010</item>
+ <item>@drawable/btn_radio_to_off_qntm_011</item>
+ <item>@drawable/btn_radio_to_off_qntm_012</item>
+ <item>@drawable/btn_radio_to_off_qntm_013</item>
+ <item>@drawable/btn_radio_to_off_qntm_014</item>
+ <item>@drawable/btn_radio_to_off_qntm_015</item>
+ <item>@drawable/btn_radio_to_on_qntm_000</item>
+ <item>@drawable/btn_radio_to_on_qntm_001</item>
+ <item>@drawable/btn_radio_to_on_qntm_002</item>
+ <item>@drawable/btn_radio_to_on_qntm_003</item>
+ <item>@drawable/btn_radio_to_on_qntm_004</item>
+ <item>@drawable/btn_radio_to_on_qntm_005</item>
+ <item>@drawable/btn_radio_to_on_qntm_006</item>
+ <item>@drawable/btn_radio_to_on_qntm_007</item>
+ <item>@drawable/btn_radio_to_on_qntm_008</item>
+ <item>@drawable/btn_radio_to_on_qntm_009</item>
+ <item>@drawable/btn_radio_to_on_qntm_010</item>
+ <item>@drawable/btn_radio_to_on_qntm_011</item>
+ <item>@drawable/btn_radio_to_on_qntm_012</item>
+ <item>@drawable/btn_radio_to_on_qntm_013</item>
+ <item>@drawable/btn_radio_to_on_qntm_014</item>
+ <item>@drawable/btn_radio_to_on_qntm_015</item>
+ <item>@drawable/btn_rating_star_off_qntm_alpha</item>
+ <item>@drawable/btn_rating_star_on_qntm_alpha</item>
+ <item>@drawable/btn_star_qntm_alpha</item>
+ <item>@drawable/btn_switch_to_off_qntm_000</item>
+ <item>@drawable/btn_switch_to_off_qntm_001</item>
+ <item>@drawable/btn_switch_to_off_qntm_002</item>
+ <item>@drawable/btn_switch_to_off_qntm_003</item>
+ <item>@drawable/btn_switch_to_off_qntm_004</item>
+ <item>@drawable/btn_switch_to_off_qntm_005</item>
+ <item>@drawable/btn_switch_to_off_qntm_006</item>
+ <item>@drawable/btn_switch_to_off_qntm_007</item>
+ <item>@drawable/btn_switch_to_off_qntm_008</item>
+ <item>@drawable/btn_switch_to_off_qntm_009</item>
+ <item>@drawable/btn_switch_to_off_qntm_010</item>
+ <item>@drawable/btn_switch_to_off_qntm_011</item>
+ <item>@drawable/btn_switch_to_off_qntm_012</item>
+ <item>@drawable/btn_switch_to_off_qntm_013</item>
+ <item>@drawable/btn_switch_to_off_qntm_014</item>
+ <item>@drawable/btn_switch_to_on_qntm_000</item>
+ <item>@drawable/btn_switch_to_on_qntm_001</item>
+ <item>@drawable/btn_switch_to_on_qntm_002</item>
+ <item>@drawable/btn_switch_to_on_qntm_003</item>
+ <item>@drawable/btn_switch_to_on_qntm_004</item>
+ <item>@drawable/btn_switch_to_on_qntm_005</item>
+ <item>@drawable/btn_switch_to_on_qntm_006</item>
+ <item>@drawable/btn_switch_to_on_qntm_007</item>
+ <item>@drawable/btn_switch_to_on_qntm_008</item>
+ <item>@drawable/btn_switch_to_on_qntm_009</item>
+ <item>@drawable/btn_switch_to_on_qntm_010</item>
+ <item>@drawable/btn_switch_to_on_qntm_011</item>
+ <item>@drawable/btn_switch_to_on_qntm_012</item>
+ <item>@drawable/btn_switch_to_on_qntm_013</item>
+ <item>@drawable/btn_switch_to_on_qntm_014</item>
+ <item>@drawable/btn_toggle_indicator_qntm_alpha</item>
+ <item>@drawable/btn_toggle_qntm_alpha</item>
+ <item>@drawable/expander_close_qntm_alpha</item>
+ <item>@drawable/expander_open_qntm_alpha</item>
+ <item>@drawable/fastscroll_thumb_qntm_alpha</item>
+ <item>@drawable/fastscroll_track_qntm_alpha</item>
+ <item>@drawable/ic_ab_back_qntm_am_alpha</item>
+ <item>@drawable/ic_cab_done_qntm_alpha</item>
+ <item>@drawable/ic_clear_qntm_alpha</item>
+ <item>@drawable/ic_commit_search_api_qntm_alpha</item>
+ <item>@drawable/ic_dialog_alert_qntm_alpha</item>
+ <item>@drawable/ic_find_next_qntm_alpha</item>
+ <item>@drawable/ic_find_previous_qntm_alpha</item>
+ <item>@drawable/ic_go_search_api_qntm_alpha</item>
+ <item>@drawable/ic_media_route_disabled_qntm_alpha</item>
+ <item>@drawable/ic_media_route_off_qntm_alpha</item>
+ <item>@drawable/ic_media_route_on_0_qntm_alpha</item>
+ <item>@drawable/ic_media_route_on_1_qntm_alpha</item>
+ <item>@drawable/ic_media_route_on_2_qntm_alpha</item>
+ <item>@drawable/ic_media_route_on_qntm_alpha</item>
+ <item>@drawable/ic_menu_copy_qntm_am_alpha</item>
+ <item>@drawable/ic_menu_cut_qntm_alpha</item>
+ <item>@drawable/ic_menu_find_qntm_alpha</item>
+ <item>@drawable/ic_menu_moreoverflow_qntm_alpha</item>
+ <item>@drawable/ic_menu_paste_qntm_am_alpha</item>
+ <item>@drawable/ic_menu_search_qntm_alpha</item>
+ <item>@drawable/ic_menu_selectall_qntm_alpha</item>
+ <item>@drawable/ic_menu_share_qntm_alpha</item>
+ <item>@drawable/ic_search_api_qntm_alpha</item>
+ <item>@drawable/ic_voice_search_api_qntm_alpha</item>
+ <item>@drawable/list_divider_qntm_alpha</item>
+ <item>@drawable/list_section_divider_qntm_alpha</item>
+ <item>@drawable/popup_background_qntm_mult</item>
+ <item>@drawable/progress_primary_qntm_alpha</item>
+ <item>@drawable/progress_qntm_alpha</item>
+ <item>@drawable/scrollbar_handle_qntm_alpha</item>
+ <item>@drawable/scrubber_control_from_pressed_qntm_000</item>
+ <item>@drawable/scrubber_control_from_pressed_qntm_001</item>
+ <item>@drawable/scrubber_control_from_pressed_qntm_002</item>
+ <item>@drawable/scrubber_control_from_pressed_qntm_003</item>
+ <item>@drawable/scrubber_control_from_pressed_qntm_004</item>
+ <item>@drawable/scrubber_control_from_pressed_qntm_005</item>
+ <item>@drawable/scrubber_control_off_pressed_qntm_alpha</item>
+ <item>@drawable/scrubber_control_off_qntm_alpha</item>
+ <item>@drawable/scrubber_control_on_pressed_qntm_alpha</item>
+ <item>@drawable/scrubber_control_on_qntm_alpha</item>
+ <item>@drawable/scrubber_control_to_pressed_qntm_000</item>
+ <item>@drawable/scrubber_control_to_pressed_qntm_001</item>
+ <item>@drawable/scrubber_control_to_pressed_qntm_002</item>
+ <item>@drawable/scrubber_control_to_pressed_qntm_003</item>
+ <item>@drawable/scrubber_control_to_pressed_qntm_004</item>
+ <item>@drawable/scrubber_control_to_pressed_qntm_005</item>
+ <item>@drawable/scrubber_primary_qntm_alpha</item>
+ <item>@drawable/scrubber_track_qntm_alpha</item>
+ <item>@drawable/spinner_qntm_am_alpha</item>
+ <item>@drawable/switch_track_qntm_alpha</item>
+ <item>@drawable/tab_indicator_normal_qntm_alpha</item>
+ <item>@drawable/tab_indicator_selected_qntm_alpha</item>
+ <item>@drawable/text_cursor_qntm_alpha</item>
+ <item>@drawable/textfield_activated_qntm_alpha</item>
+ <item>@drawable/textfield_default_qntm_alpha</item>
+ <item>@drawable/textfield_search_activated_qntm_alpha</item>
+ <item>@drawable/textfield_search_default_qntm_alpha</item>
+ <item>@drawable/text_select_handle_left_qntm_alpha</item>
+ <item>@drawable/text_select_handle_middle_qntm_alpha</item>
+ <item>@drawable/text_select_handle_right_qntm_alpha</item>
</array>
<!-- Do not translate. These are all of the color state list resources that should be
@@ -334,6 +519,18 @@
<item>#ff000000</item>
<item>#00000000</item>
<item>#ffffffff</item>
+
+ <!-- Quantum color state lists -->
+ <item>@color/background_cache_hint_selector_quantum_dark</item>
+ <item>@color/background_cache_hint_selector_quantum_light</item>
+ <item>@color/btn_default_quantum_dark</item>
+ <item>@color/btn_default_quantum_light</item>
+ <item>@color/primary_text_disable_only_quantum_dark</item>
+ <item>@color/primary_text_disable_only_quantum_light</item>
+ <item>@color/primary_text_quantum_dark</item>
+ <item>@color/primary_text_quantum_light</item>
+ <item>@color/search_url_text_quantum_dark</item>
+ <item>@color/search_url_text_quantum_light</item>
</array>
<!-- Used in LocalePicker -->
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index f6732d3..8af45db 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -858,6 +858,14 @@
<!-- Boolean indicating if current platform supports BLE peripheral mode -->
<bool name="config_bluetooth_le_peripheral_mode_supported">false</bool>
+ <!-- Max number of scan filters supported by blutooth controller. 0 if the
+ device does not support hardware scan filters-->
+ <integer translatable="false" name="config_bluetooth_max_scan_filters">0</integer>
+
+ <!-- Max number of advertisers supported by bluetooth controller. 0 if the
+ device does not support multiple advertisement-->
+ <integer translatable="false" name="config_bluetooth_max_advertisers">0</integer>
+
<!-- The default data-use polling period. -->
<integer name="config_datause_polling_period_sec">600</integer>
diff --git a/core/res/res/values/dimens_quantum.xml b/core/res/res/values/dimens_quantum.xml
index b5ba1ca..6390667 100644
--- a/core/res/res/values/dimens_quantum.xml
+++ b/core/res/res/values/dimens_quantum.xml
@@ -21,10 +21,6 @@
<dimen name="action_bar_default_padding_quantum">4dp</dimen>
<!-- Vertical padding around action bar icons. -->
<dimen name="action_bar_icon_vertical_padding_quantum">16dp</dimen>
- <!-- Text size for action bar titles -->
- <dimen name="action_bar_title_text_size_quantum">20sp</dimen>
- <!-- Text size for action bar subtitles -->
- <dimen name="action_bar_subtitle_text_size_quantum">16sp</dimen>
<!-- Top margin for action bar subtitles -->
<dimen name="action_bar_subtitle_top_margin_quantum">-3dp</dimen>
<!-- Bottom margin for action bar subtitles -->
@@ -57,6 +53,6 @@
<dimen name="floating_window_margin_right">16dp</dimen>
<dimen name="floating_window_margin_bottom">32dp</dimen>
- <!-- the amount of elevation for pressed button state-->
+ <!-- Amount of elevation for pressed button state -->
<dimen name="button_pressed_z">2dp</dimen>
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 7234911..5d6987c 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1583,11 +1583,6 @@
without your confirmation.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permlab_sim_communication">sim communication</string>
- <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permdesc_sim_communication">Allows the app to send commands to the SIM. This is very dangerous.</string>
-
- <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_camera">take pictures and videos</string>
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_camera">Allows the app to take pictures and videos
diff --git a/core/res/res/values/styles_quantum.xml b/core/res/res/values/styles_quantum.xml
index afb3a39..8c2e14e 100644
--- a/core/res/res/values/styles_quantum.xml
+++ b/core/res/res/values/styles_quantum.xml
@@ -91,10 +91,10 @@
<!-- Text styles -->
<style name="TextAppearance.Quantum">
- <item name="textColor">?textColorPrimary</item>
- <item name="textColorHint">?textColorHint</item>
- <item name="textColorHighlight">?textColorHighlight</item>
- <item name="textColorLink">?textColorLink</item>
+ <item name="textColor">?attr/textColorPrimary</item>
+ <item name="textColorHint">?attr/textColorHint</item>
+ <item name="textColorHighlight">?attr/textColorHighlight</item>
+ <item name="textColorLink">?attr/textColorLink</item>
<item name="textSize">@dimen/text_size_body_1_quantum</item>
<item name="fontFamily">@string/font_family_body_1_quantum</item>
<item name="elegantTextHeight">true</item>
@@ -103,74 +103,94 @@
<style name="TextAppearance.Quantum.Display4">
<item name="textSize">@dimen/text_size_display_4_quantum</item>
<item name="fontFamily">@string/font_family_display_4_quantum</item>
- <item name="textColor">?textColorSecondary</item>
+ <item name="textColor">?attr/textColorSecondary</item>
</style>
<style name="TextAppearance.Quantum.Display3">
<item name="textSize">@dimen/text_size_display_3_quantum</item>
<item name="fontFamily">@string/font_family_display_3_quantum</item>
- <item name="textColor">?textColorSecondary</item>
+ <item name="textColor">?attr/textColorSecondary</item>
</style>
<style name="TextAppearance.Quantum.Display2">
<item name="textSize">@dimen/text_size_display_2_quantum</item>
<item name="fontFamily">@string/font_family_display_2_quantum</item>
- <item name="textColor">?textColorSecondary</item>
+ <item name="textColor">?attr/textColorSecondary</item>
</style>
<style name="TextAppearance.Quantum.Display1">
<item name="textSize">@dimen/text_size_display_1_quantum</item>
<item name="fontFamily">@string/font_family_display_1_quantum</item>
- <item name="textColor">?textColorSecondary</item>
+ <item name="textColor">?attr/textColorSecondary</item>
</style>
<style name="TextAppearance.Quantum.Headline">
<item name="textSize">@dimen/text_size_headline_quantum</item>
<item name="fontFamily">@string/font_family_headline_quantum</item>
- <item name="textColor">?textColorPrimary</item>
+ <item name="textColor">?attr/textColorPrimary</item>
</style>
<style name="TextAppearance.Quantum.Title">
<item name="textSize">@dimen/text_size_title_quantum</item>
<item name="fontFamily">@string/font_family_title_quantum</item>
- <item name="textColor">?textColorPrimary</item>
+ <item name="textColor">?attr/textColorPrimary</item>
+ </style>
+
+ <style name="TextAppearance.Quantum.Title.Inverse">
+ <item name="textColor">?attr/textColorPrimaryInverse</item>
+ <item name="textColorHint">?attr/textColorHintInverse</item>
+ <item name="textColorHighlight">?attr/textColorHighlightInverse</item>
+ <item name="textColorLink">?attr/textColorLinkInverse</item>
</style>
<style name="TextAppearance.Quantum.Subhead">
<item name="textSize">@dimen/text_size_subhead_quantum</item>
<item name="fontFamily">@string/font_family_subhead_quantum</item>
- <item name="textColor">?textColorPrimary</item>
+ <item name="textColor">?attr/textColorPrimary</item>
+ </style>
+
+ <style name="TextAppearance.Quantum.Subhead.Inverse">
+ <item name="textColor">?attr/textColorSecondaryInverse</item>
+ <item name="textColorHint">?attr/textColorHintInverse</item>
+ <item name="textColorHighlight">?attr/textColorHighlightInverse</item>
+ <item name="textColorLink">?attr/textColorLinkInverse</item>
</style>
<style name="TextAppearance.Quantum.Body2">
<item name="textSize">@dimen/text_size_body_2_quantum</item>
<item name="fontFamily">@string/font_family_body_2_quantum</item>
- <item name="textColor">?textColorPrimary</item>
+ <item name="textColor">?attr/textColorPrimary</item>
</style>
<style name="TextAppearance.Quantum.Body1">
<item name="textSize">@dimen/text_size_body_1_quantum</item>
<item name="fontFamily">@string/font_family_body_1_quantum</item>
- <item name="textColor">?textColorPrimary</item>
+ <item name="textColor">?attr/textColorPrimary</item>
</style>
<style name="TextAppearance.Quantum.Caption">
<item name="textSize">@dimen/text_size_caption_quantum</item>
<item name="fontFamily">@string/font_family_caption_quantum</item>
- <item name="textColor">?textColorSecondary</item>
+ <item name="textColor">?attr/textColorSecondary</item>
</style>
<style name="TextAppearance.Quantum.Menu">
<item name="textSize">@dimen/text_size_menu_quantum</item>
<item name="fontFamily">@string/font_family_menu_quantum</item>
- <item name="textColor">?textColorPrimary</item>
+ </style>
+
+ <style name="TextAppearance.Quantum.Menu.Inverse">
+ <item name="textColor">?attr/textColorSecondaryInverse</item>
+ <item name="textColorHint">?attr/textColorHintInverse</item>
+ <item name="textColorHighlight">?attr/textColorHighlightInverse</item>
+ <item name="textColorLink">?attr/textColorLinkInverse</item>
</style>
<style name="TextAppearance.Quantum.Button">
<item name="textSize">@dimen/text_size_button_quantum</item>
<item name="fontFamily">@string/font_family_button_quantum</item>
<item name="textAllCaps">true</item>
- <item name="textColor">?textColorPrimary</item>
+ <item name="textColor">?attr/textColorPrimary</item>
</style>
<!-- Deprecated text styles -->
@@ -218,9 +238,7 @@
<item name="textColorLink">?attr/textColorLinkInverse</item>
</style>
- <style name="TextAppearance.Quantum.SearchResult">
- </style>
-
+ <style name="TextAppearance.Quantum.SearchResult" />
<style name="TextAppearance.Quantum.SearchResult.Title" parent="TextAppearance.Quantum.Title" />
<style name="TextAppearance.Quantum.SearchResult.Subtitle" parent="TextAppearance.Quantum.Subhead" />
@@ -232,116 +250,55 @@
<item name="textColorHint">?attr/textColorHintInverse</item>
</style>
- <style name="TextAppearance.Quantum.Widget.Switch">
- <item name="textSize">14sp</item>
- </style>
+ <style name="TextAppearance.Quantum.Widget.Switch" parent="TextAppearance.Quantum.Button" />
<style name="TextAppearance.Quantum.Widget.PopupMenu"/>
+ <style name="TextAppearance.Quantum.Widget.PopupMenu.Large" parent="TextAppearance.Quantum.Menu" />
+ <style name="TextAppearance.Quantum.Widget.PopupMenu.Small" parent="TextAppearance.Quantum.Menu" />
- <style name="TextAppearance.Quantum.Widget.PopupMenu.Large">
- <item name="fontFamily">@string/font_family_menu_quantum</item>
- <item name="textSize">@dimen/text_size_menu_quantum</item>>
- </style>
-
- <style name="TextAppearance.Quantum.Widget.PopupMenu.Small">
- <item name="fontFamily">@string/font_family_menu_quantum</item>
- <item name="textSize">@dimen/text_size_menu_quantum</item>>
- </style>
-
- <style name="TextAppearance.Quantum.Widget.DropDownHint">
- <item name="fontFamily">@string/font_family_menu_quantum</item>
- <item name="textSize">@dimen/text_size_menu_quantum</item>>
- </style>
+ <style name="TextAppearance.Quantum.Widget.DropDownHint" parent="TextAppearance.Quantum.Menu" />
<style name="TextAppearance.Quantum.Widget.IconMenu.Item" parent="TextAppearance.Quantum.Small">
<item name="textColor">?attr/textColorPrimary</item>
</style>
- <!-- This style is for smaller screens; values-xlarge defines a version
- for larger screens. -->
- <style name="TextAppearance.Quantum.Widget.TabWidget">
- <item name="textSize">14sp</item>
- <item name="textStyle">normal</item>
- <item name="textColor">@color/tab_indicator_text</item>
- </style>
+ <style name="TextAppearance.Quantum.Widget.TabWidget" parent="TextAppearance.Quantum.Button" />
<style name="TextAppearance.Quantum.Widget.TextView">
<item name="textColor">?attr/textColorPrimaryDisableOnly</item>
<item name="textColorHint">?attr/textColorHint</item>
</style>
- <style name="TextAppearance.Quantum.Widget.TextView.PopupMenu">
- <item name="fontFamily">@string/font_family_menu_quantum</item>
- <item name="textSize">@dimen/text_size_menu_quantum</item>
- </style>
-
- <style name="TextAppearance.Quantum.Widget.TextView.SpinnerItem"/>
+ <style name="TextAppearance.Quantum.Widget.TextView.PopupMenu" parent="TextAppearance.Quantum.Menu" />
+ <style name="TextAppearance.Quantum.Widget.TextView.SpinnerItem" />
<style name="TextAppearance.Quantum.Widget.DropDownItem">
<item name="textColor">?attr/textColorPrimaryDisableOnly</item>
</style>
<style name="TextAppearance.Quantum.Widget.ActionMode"/>
+ <style name="TextAppearance.Quantum.Widget.ActionMode.Title" parent="TextAppearance.Quantum.Title" />
+ <style name="TextAppearance.Quantum.Widget.ActionMode.Title.Inverse" parent="TextAppearance.Quantum.Title.Inverse" />
+ <style name="TextAppearance.Quantum.Widget.ActionMode.Subtitle" parent="TextAppearance.Quantum.Subhead" />
+ <style name="TextAppearance.Quantum.Widget.ActionMode.Subtitle.Inverse" parent="TextAppearance.Quantum.Subhead.Inverse" />
- <style name="TextAppearance.Quantum.Widget.ActionMode.Title" parent="TextAppearance.Quantum.Medium">
- <item name="textSize">@dimen/action_bar_title_text_size_quantum</item>
- </style>
+ <style name="TextAppearance.Quantum.Widget.ActionBar.Title" parent="TextAppearance.Quantum.Title" />
+ <style name="TextAppearance.Quantum.Widget.ActionBar.Title.Inverse" parent="TextAppearance.Quantum.Title.Inverse" />
+ <style name="TextAppearance.Quantum.Widget.ActionBar.Subtitle" parent="TextAppearance.Quantum.Subhead" />
+ <style name="TextAppearance.Quantum.Widget.ActionBar.Subtitle.Inverse" parent="TextAppearance.Quantum.Subhead.Inverse" />
- <style name="TextAppearance.Quantum.Widget.ActionMode.Title.Inverse" parent="TextAppearance.Quantum.Medium.Inverse">
- <item name="textSize">@dimen/action_bar_title_text_size_quantum</item>
- </style>
-
- <style name="TextAppearance.Quantum.Widget.ActionMode.Subtitle" parent="TextAppearance.Quantum.Small">
- <item name="textSize">@dimen/action_bar_subtitle_text_size_quantum</item>
- </style>
-
- <style name="TextAppearance.Quantum.Widget.ActionMode.Subtitle.Inverse" parent="TextAppearance.Quantum.Small.Inverse">
- <item name="textSize">@dimen/action_bar_subtitle_text_size_quantum</item>
- </style>
-
- <!-- Text styles with no light versions -->
-
- <style name="TextAppearance.Quantum.Widget.ActionBar.Title" parent="TextAppearance.Quantum.Medium">
- <item name="textSize">@dimen/action_bar_title_text_size_quantum</item>
- </style>
-
- <style name="TextAppearance.Quantum.Widget.ActionBar.Title.Inverse" parent="TextAppearance.Quantum.Medium.Inverse">
- <item name="textSize">@dimen/action_bar_title_text_size_quantum</item>
- </style>
-
- <style name="TextAppearance.Quantum.Widget.ActionBar.Subtitle" parent="TextAppearance.Quantum.Small">
- <item name="textSize">@dimen/action_bar_subtitle_text_size_quantum</item>
- </style>
-
- <style name="TextAppearance.Quantum.Widget.ActionBar.Subtitle.Inverse" parent="TextAppearance.Quantum.Small.Inverse">
- <item name="textSize">@dimen/action_bar_subtitle_text_size_quantum</item>
- </style>
-
- <style name="TextAppearance.Quantum.Widget.ActionBar.Menu" parent="TextAppearance.Quantum.Small">
- <item name="fontFamily">@string/font_family_menu_quantum</item>
- <item name="textSize">@dimen/text_size_menu_quantum</item>>
+ <style name="TextAppearance.Quantum.Widget.ActionBar.Menu" parent="TextAppearance.Quantum.Menu">
<item name="textColor">?attr/actionMenuTextColor</item>
<item name="textAllCaps">@bool/config_actionMenuItemAllCaps</item>
</style>
- <style name="TextAppearance.Quantum.Widget.ActionBar.Menu.Inverse" parent="TextAppearance.Quantum.Small.Inverse">
- <item name="fontFamily">@string/font_family_menu_quantum</item>
- <item name="textSize">@dimen/text_size_menu_quantum</item>>
+ <style name="TextAppearance.Quantum.Widget.ActionBar.Menu.Inverse" parent="TextAppearance.Quantum.Menu.Inverse">
<item name="textColor">?attr/actionMenuTextColor</item>
<item name="textAllCaps">@bool/config_actionMenuItemAllCaps</item>
</style>
- <style name="TextAppearance.Quantum.WindowTitle">
- <item name="textColor">?attr/textColorPrimary</item>
- <item name="fontFamily">@string/font_family_headline_quantum</item>
- <item name="textSize">@dimen/text_size_headline_quantum</item>
- </style>
-
- <style name="TextAppearance.Quantum.DialogWindowTitle">
- <item name="fontFamily">@string/font_family_headline_quantum</item>
- <item name="textSize">@dimen/text_size_headline_quantum</item>
- <item name="textColor">?attr/textColorPrimary</item>
- </style>
+ <style name="TextAppearance.Quantum.WindowTitle" parent="TextAppearance.Quantum.Headline" />
+ <style name="TextAppearance.Quantum.DialogWindowTitle" parent="TextAppearance.Quantum.Headline" />
<style name="TextAppearance.Quantum.CalendarViewWeekDayView" parent="TextAppearance.Quantum.Small">
<item name="textStyle">bold</item>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 8b1ca31..9e6588f 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -287,6 +287,8 @@
<java-symbol type="bool" name="config_disableUsbPermissionDialogs"/>
<java-symbol type="bool" name="config_windowIsRound" />
+ <java-symbol type="integer" name="config_bluetooth_max_advertisers" />
+ <java-symbol type="integer" name="config_bluetooth_max_scan_filters" />
<java-symbol type="integer" name="config_cursorWindowSize" />
<java-symbol type="integer" name="config_extraFreeKbytesAdjust" />
<java-symbol type="integer" name="config_extraFreeKbytesAbsolute" />
diff --git a/graphics/java/android/graphics/drawable/Ripple.java b/graphics/java/android/graphics/drawable/Ripple.java
index ada741b..55d01ed 100644
--- a/graphics/java/android/graphics/drawable/Ripple.java
+++ b/graphics/java/android/graphics/drawable/Ripple.java
@@ -408,6 +408,7 @@
outerFadeOutAnim.setDuration(outerDuration);
outerFadeOutAnim.setInterpolator(LINEAR_INTERPOLATOR);
outerFadeOutAnim.setStartDelay(outerInflection);
+ outerFadeOutAnim.setStartValue(inflectionOpacity);
outerFadeOutAnim.addListener(mAnimationListener);
mPendingAnimations.add(outerFadeOutAnim);
diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java
index 557d54f..6f29825 100644
--- a/graphics/java/android/graphics/drawable/RippleDrawable.java
+++ b/graphics/java/android/graphics/drawable/RippleDrawable.java
@@ -441,8 +441,11 @@
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;
diff --git a/media/java/android/media/tv/ITvInputClient.aidl b/media/java/android/media/tv/ITvInputClient.aidl
index dc79a73..011da35 100644
--- a/media/java/android/media/tv/ITvInputClient.aidl
+++ b/media/java/android/media/tv/ITvInputClient.aidl
@@ -31,5 +31,7 @@
void onAvailabilityChanged(in String inputId, boolean isAvailable);
void onSessionReleased(int seq);
void onSessionEvent(in String name, in Bundle args, int seq);
- void onVideoSizeChanged(int width, int height, int seq);
+ void onVideoStreamChanged(int width, int height, boolean interlaced, int seq);
+ void onAudioStreamChanged(int channelCount, int seq);
+ void onClosedCaptionStreamChanged(boolean hasClosedCaption, int seq);
}
diff --git a/media/java/android/media/tv/ITvInputSessionCallback.aidl b/media/java/android/media/tv/ITvInputSessionCallback.aidl
index 71f2d07..00f2922a 100644
--- a/media/java/android/media/tv/ITvInputSessionCallback.aidl
+++ b/media/java/android/media/tv/ITvInputSessionCallback.aidl
@@ -27,5 +27,7 @@
oneway interface ITvInputSessionCallback {
void onSessionCreated(ITvInputSession session);
void onSessionEvent(in String name, in Bundle args);
- void onVideoSizeChanged(int width, int height);
+ void onVideoStreamChanged(int width, int height, boolean interlaced);
+ void onAudioStreamChanged(int channelCount);
+ void onClosedCaptionStreamChanged(boolean hasClosedCaption);
}
diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java
index 1335a1b..698a861 100644
--- a/media/java/android/media/tv/TvInputManager.java
+++ b/media/java/android/media/tv/TvInputManager.java
@@ -88,15 +88,39 @@
}
/**
- * This is called at the beginning of the playback of a channel and later when the size of
- * the video has been changed.
+ * This is called at the beginning of the playback of a channel and later when the format of
+ * the video stream has been changed.
*
* @param session A {@link TvInputManager.Session} associated with this callback
- * @param width the width of the video
- * @param height the height of the video
+ * @param width The width of the video.
+ * @param height The height of the video.
+ * @param interlaced whether the video is interlaced mode or planer mode.
* @hide
*/
- public void onVideoSizeChanged(Session session, int width, int height) {
+ public void onVideoStreamChanged(Session session, int width, int height,
+ boolean interlaced) {
+ }
+
+ /**
+ * This is called at the beginning of the playback of a channel and later when the format of
+ * the audio stream has been changed.
+ *
+ * @param session A {@link TvInputManager.Session} associated with this callback
+ * @param channelCount The number of channels in the audio stream.
+ * @hide
+ */
+ public void onAudioStreamChanged(Session session, int channelCount) {
+ }
+
+ /**
+ * This is called at the beginning of the playback of a channel and later when the closed
+ * caption stream has been changed.
+ *
+ * @param session A {@link TvInputManager.Session} associated with this callback
+ * @param hasClosedCaption Whether the stream has closed caption or not.
+ * @hide
+ */
+ public void onClosedCaptionStreamChanged(Session session, boolean hasClosedCaption) {
}
/**
@@ -141,11 +165,30 @@
});
}
- public void postVideoSizeChanged(final int width, final int height) {
+ public void postVideoStreamChanged(final int width, final int height,
+ final boolean interlaced) {
mHandler.post(new Runnable() {
@Override
public void run() {
- mSessionCallback.onVideoSizeChanged(mSession, width, height);
+ mSessionCallback.onVideoStreamChanged(mSession, width, height, interlaced);
+ }
+ });
+ }
+
+ public void postAudioStreamChanged(final int channelCount) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mSessionCallback.onAudioStreamChanged(mSession, channelCount);
+ }
+ });
+ }
+
+ public void postClosedCaptionStreamChanged(final boolean hasClosedCaption) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mSessionCallback.onClosedCaptionStreamChanged(mSession, hasClosedCaption);
}
});
}
@@ -238,14 +281,38 @@
}
@Override
- public void onVideoSizeChanged(int width, int height, int seq) {
+ public void onVideoStreamChanged(int width, int height, boolean interlaced, int seq) {
synchronized (mSessionCallbackRecordMap) {
SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
if (record == null) {
Log.e(TAG, "Callback not found for seq " + seq);
return;
}
- record.postVideoSizeChanged(width, height);
+ record.postVideoStreamChanged(width, height, interlaced);
+ }
+ }
+
+ @Override
+ public void onAudioStreamChanged(int channelCount, int seq) {
+ synchronized (mSessionCallbackRecordMap) {
+ SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
+ if (record == null) {
+ Log.e(TAG, "Callback not found for seq " + seq);
+ return;
+ }
+ record.postAudioStreamChanged(channelCount);
+ }
+ }
+
+ @Override
+ public void onClosedCaptionStreamChanged(boolean hasClosedCaption, int seq) {
+ synchronized (mSessionCallbackRecordMap) {
+ SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
+ if (record == null) {
+ Log.e(TAG, "Callback not found for seq " + seq);
+ return;
+ }
+ record.postClosedCaptionStreamChanged(hasClosedCaption);
}
}
diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java
index 3213019..8ba0e20 100644
--- a/media/java/android/media/tv/TvInputService.java
+++ b/media/java/android/media/tv/TvInputService.java
@@ -223,20 +223,22 @@
}
/**
- * Sends the change on the size of the video. This is expected to be called at the
- * beginning of the playback and later when the size has been changed.
+ * Sends the change on the format of the video stream. This is expected to be called at the
+ * beginning of the playback and later when the format has been changed.
*
* @param width The width of the video.
* @param height The height of the video.
+ * @param interlaced Whether the video is interlaced mode or planer mode.
* @hide
*/
- public void dispatchVideoSizeChanged(final int width, final int height) {
+ public void dispatchVideoStreamChanged(final int width, final int height,
+ final boolean interlaced) {
mHandler.post(new Runnable() {
@Override
public void run() {
try {
if (DEBUG) Log.d(TAG, "dispatchVideoSizeChanged");
- mSessionCallback.onVideoSizeChanged(width, height);
+ mSessionCallback.onVideoStreamChanged(width, height, interlaced);
} catch (RemoteException e) {
Log.w(TAG, "error in dispatchVideoSizeChanged");
}
@@ -245,6 +247,48 @@
}
/**
+ * Sends the change on the format of the audio stream. This is expected to be called at the
+ * beginning of the playback and later when the format has been changed.
+ *
+ * @param channelNumber The number of channels in the audio stream.
+ * @hide
+ */
+ public void dispatchAudioStreamChanged(final int channelNumber) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ if (DEBUG) Log.d(TAG, "dispatchAudioStreamChanged");
+ mSessionCallback.onAudioStreamChanged(channelNumber);
+ } catch (RemoteException e) {
+ Log.w(TAG, "error in dispatchAudioStreamChanged");
+ }
+ }
+ });
+ }
+
+ /**
+ * Sends the change on the closed caption stream. This is expected to be called at the
+ * beginning of the playback and later when the stream has been changed.
+ *
+ * @param hasClosedCaption Whether the stream has closed caption or not.
+ * @hide
+ */
+ public void dispatchClosedCaptionStreamChanged(final boolean hasClosedCaption) {
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ if (DEBUG) Log.d(TAG, "dispatchClosedCaptionStreamChanged");
+ mSessionCallback.onClosedCaptionStreamChanged(hasClosedCaption);
+ } catch (RemoteException e) {
+ Log.w(TAG, "error in dispatchClosedCaptionStreamChanged");
+ }
+ }
+ });
+ }
+
+ /**
* Called when the session is released.
*/
public abstract void onRelease();
diff --git a/media/java/android/media/tv/TvView.java b/media/java/android/media/tv/TvView.java
index 126d739..d8b362d 100644
--- a/media/java/android/media/tv/TvView.java
+++ b/media/java/android/media/tv/TvView.java
@@ -382,12 +382,33 @@
}
@Override
- public void onVideoSizeChanged(Session session, int width, int height) {
+ public void onVideoStreamChanged(Session session, int width, int height,
+ boolean interlaced) {
if (DEBUG) {
Log.d(TAG, "onVideoSizeChanged(" + width + ", " + height + ")");
}
if (mExternalCallback != null) {
- mExternalCallback.onVideoSizeChanged(session, width, height);
+ mExternalCallback.onVideoStreamChanged(session, width, height, interlaced);
+ }
+ }
+
+ @Override
+ public void onAudioStreamChanged(Session session, int channelCount) {
+ if (DEBUG) {
+ Log.d(TAG, "onAudioStreamChanged(" + channelCount + ")");
+ }
+ if (mExternalCallback != null) {
+ mExternalCallback.onAudioStreamChanged(session, channelCount);
+ }
+ }
+
+ @Override
+ public void onClosedCaptionStreamChanged(Session session, boolean hasClosedCaption) {
+ if (DEBUG) {
+ Log.d(TAG, "onClosedCaptionStreamChanged(" + hasClosedCaption + ")");
+ }
+ if (mExternalCallback != null) {
+ mExternalCallback.onClosedCaptionStreamChanged(session, hasClosedCaption);
}
}
diff --git a/packages/Keyguard/res/layout/keyguard_status_view.xml b/packages/Keyguard/res/layout/keyguard_status_view.xml
index 112e371a..2917faa 100644
--- a/packages/Keyguard/res/layout/keyguard_status_view.xml
+++ b/packages/Keyguard/res/layout/keyguard_status_view.xml
@@ -48,5 +48,18 @@
android:layout_marginBottom="@dimen/bottom_text_spacing_digital" />
<include layout="@layout/keyguard_status_area" />
+ <TextView
+ android:id="@+id/owner_info"
+ android:layout_marginLeft="16dp"
+ android:layout_marginRight="16dp"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/date_owner_info_margin"
+ android:layout_gravity="center_horizontal"
+ android:textColor="#99ffffff"
+ android:textSize="@dimen/widget_label_font_size"
+ android:ellipsize="marquee"
+ android:singleLine="true" />
+
</LinearLayout>
</com.android.keyguard.KeyguardStatusView>
diff --git a/packages/Keyguard/res/values-sw600dp/dimens.xml b/packages/Keyguard/res/values-sw600dp/dimens.xml
index b954792..e9e9b89 100644
--- a/packages/Keyguard/res/values-sw600dp/dimens.xml
+++ b/packages/Keyguard/res/values-sw600dp/dimens.xml
@@ -70,4 +70,7 @@
<!-- EmergencyCarrierArea overlap - amount to overlap the emergency button and carrier text.
Should be 0 on devices with plenty of room (e.g. tablets) -->
<dimen name="eca_overlap">0dip</dimen>
+
+ <!-- The vertical margin between the date and the owner info. -->
+ <dimen name="date_owner_info_margin">4dp</dimen>
</resources>
diff --git a/packages/Keyguard/res/values/dimens.xml b/packages/Keyguard/res/values/dimens.xml
index e9cdfcd..f971522 100644
--- a/packages/Keyguard/res/values/dimens.xml
+++ b/packages/Keyguard/res/values/dimens.xml
@@ -163,4 +163,7 @@
<!-- The y translation to apply at the start in appear animations. -->
<dimen name="appear_y_translation_start">32dp</dimen>
+
+ <!-- The vertical margin between the date and the owner info. -->
+ <dimen name="date_owner_info_margin">2dp</dimen>
</resources>
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java b/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java
index d589283..9bc2a4d 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java
@@ -186,42 +186,16 @@
*/
void update() {
MutableInt icon = new MutableInt(0);
- CharSequence status = concat(getOwnerInfo(), getCurrentMessage());
+ CharSequence status = getCurrentMessage();
setCompoundDrawablesWithIntrinsicBounds(icon.value, 0, 0, 0);
setText(status);
}
- private CharSequence concat(CharSequence... args) {
- StringBuilder b = new StringBuilder();
- if (!TextUtils.isEmpty(args[0])) {
- b.append(args[0]);
- }
- for (int i = 1; i < args.length; i++) {
- CharSequence text = args[i];
- if (!TextUtils.isEmpty(text)) {
- if (b.length() > 0) {
- b.append(mSeparator);
- }
- b.append(text);
- }
- }
- return b.toString();
- }
CharSequence getCurrentMessage() {
return mShowingMessage ? mMessage : null;
}
- String getOwnerInfo() {
- ContentResolver res = getContext().getContentResolver();
- String info = null;
- final boolean ownerInfoEnabled = mLockPatternUtils.isOwnerInfoEnabled();
- if (ownerInfoEnabled && !mShowingMessage) {
- info = mLockPatternUtils.getOwnerInfo(mLockPatternUtils.getCurrentUser());
- }
- return info;
- }
-
private void hideMessage(int duration, boolean thenUpdate) {
if (duration > 0) {
Animator anim = ObjectAnimator.ofFloat(this, "alpha", 0f);
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
index bef94fa..7918755 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
@@ -16,6 +16,7 @@
package com.android.keyguard;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.res.Resources;
import android.text.TextUtils;
@@ -41,6 +42,7 @@
private TextView mAlarmStatusView;
private TextClock mDateView;
private TextClock mClockView;
+ private TextView mOwnerInfo;
private KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
@@ -54,6 +56,7 @@
if (showing) {
if (DEBUG) Slog.v(TAG, "refresh statusview showing:" + showing);
refresh();
+ updateOwnerInfo();
}
}
@@ -83,6 +86,7 @@
private void setEnableMarquee(boolean enabled) {
if (DEBUG) Log.v(TAG, (enabled ? "Enable" : "Disable") + " transport text marquee");
if (mAlarmStatusView != null) mAlarmStatusView.setSelected(enabled);
+ mOwnerInfo.setSelected(enabled);
}
@Override
@@ -91,10 +95,12 @@
mAlarmStatusView = (TextView) findViewById(R.id.alarm_status);
mDateView = (TextClock) findViewById(R.id.date_view);
mClockView = (TextClock) findViewById(R.id.clock_view);
+ mOwnerInfo = (TextView) findViewById(R.id.owner_info);
mLockPatternUtils = new LockPatternUtils(getContext());
final boolean screenOn = KeyguardUpdateMonitor.getInstance(mContext).isScreenOn();
setEnableMarquee(screenOn);
refresh();
+ updateOwnerInfo();
// Disable elegant text height because our fancy colon makes the ymin value huge for no
// reason.
@@ -124,6 +130,16 @@
}
}
+ private void updateOwnerInfo() {
+ String ownerInfo = getOwnerInfo();
+ if (!TextUtils.isEmpty(ownerInfo)) {
+ mOwnerInfo.setVisibility(View.VISIBLE);
+ mOwnerInfo.setText(ownerInfo);
+ } else {
+ mOwnerInfo.setVisibility(View.GONE);
+ }
+ }
+
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
@@ -140,6 +156,16 @@
return LockPatternUtils.ID_DEFAULT_STATUS_WIDGET;
}
+ private String getOwnerInfo() {
+ ContentResolver res = getContext().getContentResolver();
+ String info = null;
+ final boolean ownerInfoEnabled = mLockPatternUtils.isOwnerInfoEnabled();
+ if (ownerInfoEnabled) {
+ info = mLockPatternUtils.getOwnerInfo(mLockPatternUtils.getCurrentUser());
+ }
+ return info;
+ }
+
// DateFormat.getBestDateTimePattern is extremely expensive, and refresh is called often.
// This is an optimization to ensure we only recompute the patterns when the inputs change.
private static final class Patterns {
diff --git a/packages/SystemUI/res/drawable-hdpi/recents_nav_bar_background.9.png b/packages/SystemUI/res/drawable-hdpi/recents_nav_bar_background.9.png
new file mode 100644
index 0000000..6cd1176
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/recents_nav_bar_background.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/recents_nav_bar_background.9.png b/packages/SystemUI/res/drawable-mdpi/recents_nav_bar_background.9.png
new file mode 100644
index 0000000..7237f09
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/recents_nav_bar_background.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/recents_nav_bar_background.9.png b/packages/SystemUI/res/drawable-xhdpi/recents_nav_bar_background.9.png
new file mode 100644
index 0000000..8d56a1d
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xhdpi/recents_nav_bar_background.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/recents_nav_bar_background.9.png b/packages/SystemUI/res/drawable-xxhdpi/recents_nav_bar_background.9.png
new file mode 100644
index 0000000..aed300b
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xxhdpi/recents_nav_bar_background.9.png
Binary files differ
diff --git a/packages/SystemUI/res/layout/recents_nav_bar_scrim.xml b/packages/SystemUI/res/layout/recents_nav_bar_scrim.xml
new file mode 100644
index 0000000..463fee8
--- /dev/null
+++ b/packages/SystemUI/res/layout/recents_nav_bar_scrim.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<ImageView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal|bottom"
+ android:scaleType="fitXY"
+ android:src="@drawable/recents_nav_bar_background" />
\ No newline at end of file
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 0184df2..79a1df4 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -113,17 +113,20 @@
<!-- The min animation duration for animating views that are newly visible. -->
<integer name="recents_filter_animate_new_views_min_duration">125</integer>
<!-- The min animation duration for animating the task bar in. -->
- <integer name="recents_animate_task_bar_enter_duration">300</integer>
+ <integer name="recents_animate_task_bar_enter_duration">250</integer>
+ <!-- The animation delay for animating the first task in. This should roughly be the animation
+ duration of the transition in to recents. -->
+ <integer name="recents_animate_task_bar_enter_delay">225</integer>
<!-- The min animation duration for animating the task bar out. -->
- <integer name="recents_animate_task_bar_exit_duration">150</integer>
- <!-- The animation duration for animating in the info pane. -->
- <integer name="recents_animate_task_view_info_pane_duration">150</integer>
+ <integer name="recents_animate_task_bar_exit_duration">125</integer>
+ <!-- The min animation duration for animating the nav bar scrim in. -->
+ <integer name="recents_nav_bar_scrim_enter_duration">400</integer>
<!-- The animation duration for animating the removal of a task view. -->
<integer name="recents_animate_task_view_remove_duration">250</integer>
<!-- The minimum alpha for the dim applied to cards that go deeper into the stack. -->
<integer name="recents_max_task_stack_view_dim">96</integer>
- <!-- Transposes the search bar layout in landscape -->
- <bool name="recents_transpose_search_layout_with_orientation">true</bool>
+ <!-- Transposes the recents layout in landscape. -->
+ <bool name="recents_transpose_layout_with_orientation">true</bool>
<!-- Whether to enable KeyguardService or not -->
<bool name="config_enableKeyguardService">true</bool>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 60a5643..9f12124 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -322,6 +322,17 @@
<!-- Distance between notifications and header when they are considered to be colliding. -->
<dimen name="header_notifications_collide_distance">24dp</dimen>
- <!-- Move distance for the hint animations on the lockscreen (unlock, phone, camera)-->
+ <!-- Distance the user needs to drag vertically such that a swipe is accepted to unlock the
+ device. -->
+ <dimen name="unlock_move_distance">75dp</dimen>
+
+ <!-- Move distance for the unlock hint animation on the lockscreen -->
<dimen name="hint_move_distance">75dp</dimen>
+
+ <!-- Move distance for the other hint animations on the lockscreen (phone, camera)-->
+ <dimen name="hint_move_distance_sideways">60dp</dimen>
+
+ <!-- The width of the region on the left/right edge of the screen for performing the camera/
+ phone hints. -->
+ <dimen name="edge_tap_area_width">48dp</dimen>
</resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 373f11f..7ab010a 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -572,6 +572,12 @@
<!-- Shows when people have pressed the unlock icon to explain how to unlock. [CHAR LIMIT=60] -->
<string name="keyguard_unlock">Swipe up to unlock</string>
+ <!-- Shows when people have clicked at the left edge of the screen to explain how to open the phone. In right-to-left languages, this is the opposite direction. [CHAR LIMIT=60] -->
+ <string name="phone_hint">Swipe right for phone</string>
+
+ <!-- Shows when people have clicked at the right edge of the screen to explain how to open the phone. In right-to-left languages, this is the opposite direction. [CHAR LIMIT=60] -->
+ <string name="camera_hint">Swipe left for camera</string>
+
<string name="bugreport_tile_extended" translatable="false">%s\n%s (%s)</string>
<!-- Zen mode condition: no exit criteria. [CHAR LIMIT=NONE] -->
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index f7b4994..c006c88 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -117,7 +117,7 @@
public class KeyguardViewMediator extends SystemUI {
private static final int KEYGUARD_DISPLAY_TIMEOUT_DELAY_DEFAULT = 30000;
final static boolean DEBUG = false;
- private static final boolean ENABLE_ANALYTICS = Build.IS_DEBUGGABLE;
+ private static final boolean ENABLE_ANALYTICS = false;
private final static boolean DBG_WAKE = false;
private final static String TAG = "KeyguardViewMediator";
@@ -906,6 +906,7 @@
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;
}
@@ -1219,9 +1220,17 @@
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);
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
index ca9bb94..bb19415 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
@@ -152,6 +152,7 @@
// Recents service binding
Messenger mService = null;
Messenger mMessenger;
+ RecentsMessageHandler mHandler;
boolean mServiceIsBound = false;
boolean mToggleRecentsUponServiceBound;
RecentsServiceConnection mConnection = new RecentsServiceConnection();
@@ -168,7 +169,8 @@
public AlternateRecentsComponent(Context context) {
mContext = context;
mSystemServicesProxy = new SystemServicesProxy(context);
- mMessenger = new Messenger(new RecentsMessageHandler());
+ mHandler = new RecentsMessageHandler();
+ mMessenger = new Messenger(mHandler);
}
public void onStart() {
@@ -507,7 +509,7 @@
if (!useThumbnailTransition) {
ActivityOptions opts = ActivityOptions.makeCustomAnimation(mContext,
R.anim.recents_from_launcher_enter,
- R.anim.recents_from_launcher_exit);
+ R.anim.recents_from_launcher_exit, mHandler, this);
startAlternateRecentsActivity(opts, false);
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index df387c1..fa85234 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -26,11 +26,14 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.res.Configuration;
import android.os.Bundle;
import android.util.Pair;
+import android.view.Gravity;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
+import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.FrameLayout;
import com.android.systemui.R;
@@ -67,6 +70,7 @@
FrameLayout mContainerView;
RecentsView mRecentsView;
View mEmptyView;
+ View mNavBarScrimView;
AppWidgetHost mAppWidgetHost;
AppWidgetProviderInfo mSearchAppWidgetInfo;
@@ -99,7 +103,7 @@
dismissRecentsIfVisible();
}
} else if (action.equals(RecentsService.ACTION_START_ENTER_ANIMATION)) {
- // Try and start the enter animation
+ // Try and start the enter animation (or restart it on configuration changed)
mRecentsView.startOnEnterAnimation();
}
}
@@ -129,6 +133,9 @@
mRecentsView.setBSP(root);
}
+ // Hide the scrim by default when we enter recents
+ mNavBarScrimView.setVisibility(View.INVISIBLE);
+
// Add the default no-recents layout
if (stacks.size() == 1 && stacks.get(0).getTaskCount() == 0) {
mEmptyView.setVisibility(View.VISIBLE);
@@ -269,10 +276,12 @@
// Create the empty view
LayoutInflater inflater = LayoutInflater.from(this);
mEmptyView = inflater.inflate(R.layout.recents_empty, mContainerView, false);
+ mNavBarScrimView = inflater.inflate(R.layout.recents_nav_bar_scrim, mContainerView, false);
mContainerView = new FrameLayout(this);
mContainerView.addView(mRecentsView);
mContainerView.addView(mEmptyView);
+ mContainerView.addView(mNavBarScrimView);
setContentView(mContainerView);
// Update the recent tasks
@@ -282,6 +291,16 @@
bindSearchBarAppWidget();
// Add the search bar layout
addSearchBarAppWidgetView();
+
+ // Update if we are getting a configuration change
+ if (savedInstanceState != null) {
+ onConfigurationChange();
+ }
+ }
+
+ void onConfigurationChange() {
+ // Try and start the enter animation (or restart it on configuration changed)
+ mRecentsView.startOnEnterAnimation();
}
@Override
@@ -433,8 +452,6 @@
@Override
public void onBackPressed() {
- boolean interceptedByInfoPanelClose = false;
-
// Unfilter any stacks
if (!mRecentsView.unfilterFilteredStacks()) {
super.onBackPressed();
@@ -442,8 +459,35 @@
}
@Override
- public void onTaskLaunching() {
+ public void onEnterAnimationTriggered() {
+ // Fade in the scrim
+ RecentsConfiguration config = RecentsConfiguration.getInstance();
+ if (config.hasNavBarScrim()) {
+ mNavBarScrimView.setVisibility(View.VISIBLE);
+ mNavBarScrimView.setAlpha(0f);
+ mNavBarScrimView.animate().alpha(1f)
+ .setStartDelay(config.taskBarEnterAnimDelay)
+ .setDuration(config.navBarScrimEnterDuration)
+ .setInterpolator(config.fastOutSlowInInterpolator)
+ .withLayer()
+ .start();
+ }
+ }
+
+ @Override
+ public void onTaskLaunching(boolean isTaskInStackBounds) {
mTaskLaunched = true;
+
+ // Fade out the scrim
+ RecentsConfiguration config = RecentsConfiguration.getInstance();
+ if (!isTaskInStackBounds && config.hasNavBarScrim()) {
+ mNavBarScrimView.animate().alpha(0f)
+ .setStartDelay(0)
+ .setDuration(config.taskBarExitAnimDuration)
+ .setInterpolator(config.fastOutSlowInInterpolator)
+ .withLayer()
+ .start();
+ }
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
index 6391685..0cf6ee6 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
@@ -41,7 +41,7 @@
public Rect displayRect = new Rect();
boolean isLandscape;
- boolean transposeSearchLayoutWithOrientation;
+ boolean transposeRecentsLayoutWithOrientation;
int searchBarAppWidgetId = -1;
public float animationPxMovementPerSecond;
@@ -58,7 +58,6 @@
public float taskStackWidthPaddingPct;
public int taskStackTopPaddingPx;
- public int taskViewInfoPaneAnimDuration;
public int taskViewRemoveAnimDuration;
public int taskViewRemoveAnimTranslationXPx;
public int taskViewTranslationZMinPx;
@@ -76,8 +75,11 @@
public int taskBarViewHighlightColor;
public int taskBarEnterAnimDuration;
+ public int taskBarEnterAnimDelay;
public int taskBarExitAnimDuration;
+ public int navBarScrimEnterDuration;
+
public boolean launchedFromAltTab;
public boolean launchedWithThumbnailAnimation;
@@ -108,8 +110,8 @@
isLandscape = res.getConfiguration().orientation ==
Configuration.ORIENTATION_LANDSCAPE;
- transposeSearchLayoutWithOrientation =
- res.getBoolean(R.bool.recents_transpose_search_layout_with_orientation);
+ transposeRecentsLayoutWithOrientation =
+ res.getBoolean(R.bool.recents_transpose_layout_with_orientation);
if (Console.Enabled) {
Console.log(Constants.Log.UI.MeasureAndLayout,
"[RecentsConfiguration|orientation]", isLandscape ? "Landscape" : "Portrait",
@@ -133,8 +135,6 @@
taskStackWidthPaddingPct = widthPaddingPctValue.getFloat();
taskStackTopPaddingPx = res.getDimensionPixelSize(R.dimen.recents_stack_top_padding);
- taskViewInfoPaneAnimDuration =
- res.getInteger(R.integer.recents_animate_task_view_info_pane_duration);
taskViewRemoveAnimDuration =
res.getInteger(R.integer.recents_animate_task_view_remove_duration);
taskViewRemoveAnimTranslationXPx =
@@ -163,9 +163,14 @@
taskBarEnterAnimDuration =
res.getInteger(R.integer.recents_animate_task_bar_enter_duration);
+ taskBarEnterAnimDelay =
+ res.getInteger(R.integer.recents_animate_task_bar_enter_delay);
taskBarExitAnimDuration =
res.getInteger(R.integer.recents_animate_task_bar_exit_duration);
+ navBarScrimEnterDuration =
+ res.getInteger(R.integer.recents_nav_bar_scrim_enter_duration);
+
fastOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
com.android.internal.R.interpolator.fast_out_slow_in);
fastOutLinearInInterpolator = AnimationUtils.loadInterpolator(context,
@@ -203,11 +208,16 @@
launchedWithThumbnailAnimation = false;
}
- /** Returns whether the search bar app widget exists */
+ /** Returns whether the search bar app widget exists. */
public boolean hasSearchBarAppWidget() {
return searchBarAppWidgetId >= 0;
}
+ /** Returns whether the nav bar scrim should be visible. */
+ public boolean hasNavBarScrim() {
+ return !transposeRecentsLayoutWithOrientation || !isLandscape;
+ }
+
/**
* Returns the task stack bounds in the current orientation. These bounds do not account for
* the system insets.
@@ -216,7 +226,7 @@
if (hasSearchBarAppWidget()) {
Rect searchBarBounds = new Rect();
getSearchBarBounds(width, height, searchBarBounds);
- if (isLandscape && transposeSearchLayoutWithOrientation) {
+ if (isLandscape && transposeRecentsLayoutWithOrientation) {
// In landscape, the search bar appears on the left, so shift the task rect right
taskStackBounds.set(searchBarBounds.width(), 0, width, height);
} else {
@@ -239,7 +249,7 @@
return;
}
- if (isLandscape && transposeSearchLayoutWithOrientation) {
+ if (isLandscape && transposeRecentsLayoutWithOrientation) {
// In landscape, the search bar appears on the left
searchBarSpaceBounds.set(0, 0, searchBarSpaceHeightPx, height);
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsPackageMonitor.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsPackageMonitor.java
index 4e620b6..8bcc7f5 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsPackageMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsPackageMonitor.java
@@ -38,6 +38,7 @@
PackageCallbacks mCb;
List<ActivityManager.RecentTaskInfo> mTasks;
SystemServicesProxy mSsp;
+ boolean mRegistered;
public RecentsPackageMonitor(Context context) {
mSsp = new SystemServicesProxy(context);
@@ -46,13 +47,19 @@
/** Registers the broadcast receivers with the specified callbacks. */
public void register(Context context, PackageCallbacks cb) {
mCb = cb;
- register(context, Looper.getMainLooper(), false);
+ if (!mRegistered) {
+ register(context, Looper.getMainLooper(), false);
+ mRegistered = true;
+ }
}
/** Unregisters the broadcast receivers. */
@Override
public void unregister() {
- super.unregister();
+ if (mRegistered) {
+ super.unregister();
+ mRegistered = false;
+ }
mTasks.clear();
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index 6005275..db398b1 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -54,7 +54,8 @@
/** The RecentsView callbacks */
public interface RecentsViewCallbacks {
- public void onTaskLaunching();
+ public void onTaskLaunching(boolean isTaskInStackBounds);
+ public void onEnterAnimationTriggered();
}
// The space partitioning root of this container
@@ -160,6 +161,9 @@
/** Requests all task stacks to start their enter-recents animation */
public void startOnEnterAnimation() {
+ // Notify callbacks that we are starting the enter animation
+ mCb.onEnterAnimationTriggered();
+
int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
View child = getChildAt(i);
@@ -351,7 +355,11 @@
final TaskStack stack, final Task task) {
// Notify any callbacks of the launching of a new task
if (mCb != null) {
- mCb.onTaskLaunching();
+ boolean isTaskInStackBounds = false;
+ if (stackView != null && tv != null) {
+ isTaskInStackBounds = stackView.isTaskInStackBounds(tv);
+ }
+ mCb.onTaskLaunching(isTaskInStackBounds);
}
final Runnable launchRunnable = new Runnable() {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
index 053f122..5830e37 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -430,6 +430,13 @@
return getScrollAmountOutOfBounds(getStackScroll()) != 0;
}
+ /** Returns whether the task view is in the stack bounds or not */
+ boolean isTaskInStackBounds(TaskView tv) {
+ Rect r = new Rect();
+ tv.getHitRect(r);
+ return r.bottom <= mRect.bottom;
+ }
+
/** Updates the min and max virtual scroll bounds */
void updateMinMaxScroll(boolean boundScrollToNewMinMax) {
// Compute the min and max scroll values
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
index ffa181d..632c816 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -234,7 +234,7 @@
mBarView.setTranslationY(-mBarView.getMeasuredHeight());
mBarView.animate()
.translationY(0)
- .setStartDelay(200)
+ .setStartDelay(config.taskBarEnterAnimDelay)
.setInterpolator(config.fastOutSlowInInterpolator)
.setDuration(config.taskBarEnterAnimDuration)
.withLayer()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java b/packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java
index de27119f..4233ab8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java
@@ -52,7 +52,7 @@
for (int i = 0; i < n; i++) {
final StatusBarNotification sbn = mIntercepted.valueAt(i);
mReleased.add(sbn.getKey());
- mBar.addNotificationInternal(sbn, null);
+ mBar.displayNotification(sbn, null);
}
mIntercepted.clear();
updateSyntheticNotification();
@@ -71,16 +71,17 @@
public void retryIntercepts(Ranking ranking) {
if (ranking == null) return;
- boolean changed = false;
final int N = mIntercepted.size();
+ final ArraySet<String> removed = new ArraySet<String>(N);
for (int i = 0; i < N; i++) {
final StatusBarNotification sbn = mIntercepted.valueAt(i);
if (!tryIntercept(sbn, ranking)) {
- changed = true;
- mBar.addNotificationInternal(sbn, ranking);
+ removed.add(sbn.getKey());
+ mBar.displayNotification(sbn, ranking);
}
}
- if (changed) {
+ if (!removed.isEmpty()) {
+ mIntercepted.removeAll(removed);
updateSyntheticNotification();
}
}
@@ -96,12 +97,6 @@
return ent.key.equals(mSynKey);
}
- public void update(StatusBarNotification notification) {
- if (mIntercepted.containsKey(notification.getKey())) {
- mIntercepted.put(notification.getKey(), notification);
- }
- }
-
private boolean shouldDisplayIntercepted() {
return Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.DISPLAY_INTERCEPTED_NOTIFICATIONS, 0) != 0;
@@ -129,7 +124,7 @@
mBar.getCurrentUserHandle());
if (mSynKey == null) {
mSynKey = sbn.getKey();
- mBar.addNotificationInternal(sbn, null);
+ mBar.displayNotification(sbn, null);
} else {
mBar.updateNotificationInternal(sbn, null);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BounceInterpolator.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BounceInterpolator.java
index 367d326..0fdc185 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BounceInterpolator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BounceInterpolator.java
@@ -27,6 +27,7 @@
@Override
public float getInterpolation(float t) {
+ t *= 11f / 10f;
if (t < 4f / 11f) {
return SCALE_FACTOR * t * t;
} else if (t < 8f / 11f) {
@@ -36,8 +37,7 @@
float t2 = t - 9f / 11f;
return SCALE_FACTOR * t2 * t2 + 15f / 16f;
} else {
- float t2 = t - 21f / 22f;
- return SCALE_FACTOR * t2 * t2 + 63f / 64f;
+ return 1;
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardPageSwipeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardPageSwipeHelper.java
index b4f4865..086a266 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardPageSwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardPageSwipeHelper.java
@@ -28,6 +28,7 @@
import android.view.ViewPropertyAnimator;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
+
import com.android.systemui.R;
import com.android.systemui.statusbar.FlingAnimationUtils;
@@ -39,7 +40,10 @@
public class KeyguardPageSwipeHelper {
private static final float SWIPE_MAX_ICON_SCALE_AMOUNT = 2.0f;
- private static final float SWIPE_RESTING_ALPHA_AMOUNT = 0.7f;
+ public static final float SWIPE_RESTING_ALPHA_AMOUNT = 0.5f;
+ public static final long HINT_PHASE1_DURATION = 250;
+ private static final long HINT_PHASE2_DURATION = 450;
+
private final Context mContext;
private FlingAnimationUtils mFlingAnimationUtils;
@@ -54,11 +58,13 @@
private int mTouchSlop;
private int mMinTranslationAmount;
private int mMinFlingVelocity;
+ private int mHintDistance;
private PowerManager mPowerManager;
private final View mLeftIcon;
private final View mCenterIcon;
private final View mRightIcon;
private Interpolator mFastOutSlowIn;
+ private Interpolator mBounceInterpolator;
private Animator mSwipeAnimator;
private boolean mCallbackCalled;
@@ -81,9 +87,12 @@
mMinFlingVelocity = configuration.getScaledMinimumFlingVelocity();
mMinTranslationAmount = mContext.getResources().getDimensionPixelSize(
R.dimen.keyguard_min_swipe_amount);
+ mHintDistance =
+ mContext.getResources().getDimensionPixelSize(R.dimen.hint_move_distance_sideways);
mFlingAnimationUtils = new FlingAnimationUtils(mContext, 0.4f);
mFastOutSlowIn = AnimationUtils.loadInterpolator(mContext,
android.R.interpolator.fast_out_slow_in);
+ mBounceInterpolator = new BounceInterpolator();
}
public boolean onTouchEvent(MotionEvent event) {
@@ -168,6 +177,83 @@
return false;
}
+ public void startHintAnimation(boolean right, Runnable onFinishedListener) {
+ startHintAnimationPhase1(right, onFinishedListener);
+ }
+
+ /**
+ * Phase 1: Move everything sidewards.
+ */
+ private void startHintAnimationPhase1(boolean right, final Runnable onFinishedListener) {
+ float target = right ? -mHintDistance : mHintDistance;
+ startHintTranslationAnimations(target, HINT_PHASE1_DURATION, mFastOutSlowIn);
+ ValueAnimator animator = ValueAnimator.ofFloat(mTranslation, target);
+ animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ mTranslation = (float) animation.getAnimatedValue();
+ }
+ });
+ animator.addListener(new AnimatorListenerAdapter() {
+ private boolean mCancelled;
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ mCancelled = true;
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ if (mCancelled) {
+ mSwipeAnimator = null;
+ onFinishedListener.run();
+ } else {
+ startUnlockHintAnimationPhase2(onFinishedListener);
+ }
+ }
+ });
+ animator.setInterpolator(mFastOutSlowIn);
+ animator.setDuration(HINT_PHASE1_DURATION);
+ animator.start();
+ mSwipeAnimator = animator;
+ }
+
+ /**
+ * Phase 2: Move back.
+ */
+ private void startUnlockHintAnimationPhase2(final Runnable onFinishedListener) {
+ startHintTranslationAnimations(0f /* target */, HINT_PHASE2_DURATION, mBounceInterpolator);
+ ValueAnimator animator = ValueAnimator.ofFloat(mTranslation, 0f);
+ animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ mTranslation = (float) animation.getAnimatedValue();
+ }
+ });
+ animator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mSwipeAnimator = null;
+ onFinishedListener.run();
+ }
+ });
+ animator.setInterpolator(mBounceInterpolator);
+ animator.setDuration(HINT_PHASE2_DURATION);
+ animator.start();
+ mSwipeAnimator = animator;
+ }
+
+ private void startHintTranslationAnimations(float target, long duration,
+ Interpolator interpolator) {
+ ArrayList<View> targetViews = mCallback.getTranslationViews();
+ for (View targetView : targetViews) {
+ targetView.animate()
+ .setDuration(duration)
+ .setInterpolator(interpolator)
+ .translationX(target);
+ }
+ }
+
private void onUserActivity(long when) {
mPowerManager.userActivity(when, false);
}
@@ -180,7 +266,6 @@
View targetView = mTranslation > 0 ? mLeftIcon : mRightIcon;
targetView.animate().cancel();
if (mSwipeAnimator != null) {
- mSwipeAnimator.removeAllListeners();
mSwipeAnimator.cancel();
hideInactiveIcons(true);
}
@@ -218,11 +303,18 @@
}
});
animator.addListener(new AnimatorListenerAdapter() {
+ private boolean mCancelled;
+
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ mCancelled = true;
+ }
+
@Override
public void onAnimationEnd(Animator animation) {
mSwipeAnimator = null;
mSwipingInProgress = false;
- if (!snapBack && !mCallbackCalled) {
+ if (!snapBack && !mCallbackCalled && !mCancelled) {
// ensure that the callback is called eventually
mCallback.onAnimationToSideStarted(mTranslation < 0);
@@ -281,7 +373,7 @@
private void setTranslation(float translation, boolean isReset) {
translation = rightSwipePossible() ? translation : Math.max(0, translation);
translation = leftSwipePossible() ? translation : Math.min(0, translation);
- if (translation != mTranslation) {
+ if (translation != mTranslation || isReset) {
ArrayList<View> translatedViews = mCallback.getTranslationViews();
for (View view : translatedViews) {
view.setTranslationX(translation);
@@ -307,7 +399,7 @@
}
}
- private void showAllIcons(boolean animate) {
+ public void showAllIcons(boolean animate) {
float scale = 1.0f;
float alpha = SWIPE_RESTING_ALPHA_AMOUNT;
updateIcon(mRightIcon, scale, alpha, animate);
@@ -315,6 +407,11 @@
updateIcon(mLeftIcon, scale, alpha, animate);
}
+ public void animateHideLeftRightIcon() {
+ updateIcon(mRightIcon, 0f, 0f, true);
+ updateIcon(mLeftIcon, 0f, 0f, true);
+ }
+
private void hideInactiveIcons(boolean animate){
View otherView = mTranslation < 0 ? mLeftIcon : mRightIcon;
updateIcon(otherView, 0, 0, animate);
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 ee6d369..dbce718 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -23,7 +23,6 @@
import android.content.Context;
import android.content.res.Configuration;
import android.util.AttributeSet;
-import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
@@ -49,7 +48,8 @@
View.OnClickListener, NotificationStackScrollLayout.OnOverscrollTopChangedListener,
KeyguardPageSwipeHelper.Callback {
- private static float EXPANSION_RUBBER_BAND_EXTRA_FACTOR = 0.6f;
+ private static final float EXPANSION_RUBBER_BAND_EXTRA_FACTOR = 0.6f;
+ private static final float LOCK_ICON_ACTIVE_SCALE = 1.2f;
private KeyguardPageSwipeHelper mPageSwiper;
private StatusBarHeaderView mHeader;
@@ -93,7 +93,9 @@
private FlingAnimationUtils mFlingAnimationUtils;
private int mStatusBarMinHeight;
private boolean mHeaderHidden;
+ private boolean mUnlockIconActive;
private int mNotificationsHeaderCollideDistance;
+ private int mUnlockMoveDistance;
private Interpolator mFastOutSlowInInterpolator;
private Interpolator mFastOutLinearInterpolator;
@@ -170,6 +172,7 @@
mQsPeekHeight = getResources().getDimensionPixelSize(R.dimen.qs_peek_height);
mNotificationsHeaderCollideDistance =
getResources().getDimensionPixelSize(R.dimen.header_notifications_collide_distance);
+ mUnlockMoveDistance = getResources().getDimensionPixelOffset(R.dimen.unlock_move_distance);
mClockPositionAlgorithm.loadDimens(getResources());
}
@@ -242,8 +245,8 @@
mClockAnimator.removeAllListeners();
mClockAnimator.cancel();
}
- mClockAnimator =
- ObjectAnimator.ofFloat(mKeyguardStatusView, View.Y, mClockAnimationTarget);
+ mClockAnimator = ObjectAnimator
+ .ofFloat(mKeyguardStatusView, View.Y, mClockAnimationTarget);
mClockAnimator.setInterpolator(mFastOutSlowInInterpolator);
mClockAnimator.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
mClockAnimator.addListener(new AnimatorListenerAdapter() {
@@ -288,6 +291,7 @@
@Override
public void resetViews() {
mBlockTouches = false;
+ mUnlockIconActive = false;
mPageSwiper.reset();
closeQs();
}
@@ -422,7 +426,9 @@
}
// TODO: Handle doublefinger swipe to notifications again. Look at history for a reference
// implementation.
- if (!mIsExpanding && !mQsExpanded && mStatusBar.getBarState() != StatusBarState.SHADE) {
+ if ((!mIsExpanding || mHintAnimationRunning)
+ && !mQsExpanded
+ && mStatusBar.getBarState() != StatusBarState.SHADE) {
mPageSwiper.onTouchEvent(event);
if (mPageSwiper.isSwipingInProgress()) {
return true;
@@ -548,9 +554,7 @@
mHeader.setExpanded(expandVisually, mStackScrollerOverscrolling);
mNotificationStackScroller.setEnabled(!mQsExpanded);
mQsPanel.setVisibility(expandVisually ? View.VISIBLE : View.INVISIBLE);
- mQsContainer.setVisibility(mKeyguardShowing && !mQsExpanded
- ? View.INVISIBLE
- : View.VISIBLE);
+ mQsContainer.setVisibility(mKeyguardShowing && !mQsExpanded ? View.INVISIBLE : View.VISIBLE);
mScrollView.setTouchEnabled(mQsExpanded);
}
@@ -720,6 +724,30 @@
}
mNotificationStackScroller.setStackHeight(expandedHeight);
updateKeyguardHeaderVisibility();
+ updateUnlockIcon();
+ }
+
+ private void updateUnlockIcon() {
+ if (mStatusBar.getBarState() == StatusBarState.KEYGUARD
+ || mStatusBar.getBarState() == StatusBarState.SHADE_LOCKED) {
+ boolean active = getMaxPanelHeight() - getExpandedHeight() > mUnlockMoveDistance;
+ if (active && !mUnlockIconActive && mTracking) {
+ mKeyguardBottomArea.getLockIcon().animate()
+ .alpha(1f)
+ .scaleY(LOCK_ICON_ACTIVE_SCALE)
+ .scaleX(LOCK_ICON_ACTIVE_SCALE)
+ .setInterpolator(mFastOutLinearInterpolator)
+ .setDuration(150);
+ } else if (!active && mUnlockIconActive && mTracking) {
+ mKeyguardBottomArea.getLockIcon().animate()
+ .alpha(KeyguardPageSwipeHelper.SWIPE_RESTING_ALPHA_AMOUNT)
+ .scaleY(1f)
+ .scaleX(1f)
+ .setInterpolator(mFastOutLinearInterpolator)
+ .setDuration(150);
+ }
+ mUnlockIconActive = active;
+ }
}
/**
@@ -728,8 +756,20 @@
private void updateKeyguardHeaderVisibility() {
if (mStatusBar.getBarState() == StatusBarState.KEYGUARD
|| mStatusBar.getBarState() == StatusBarState.SHADE_LOCKED) {
- boolean hidden = mNotificationStackScroller.getNotificationsTopY()
- <= mHeader.getBottom() + mNotificationsHeaderCollideDistance;
+ boolean hidden;
+ if (mStatusBar.getBarState() == StatusBarState.KEYGUARD) {
+
+ // When on Keyguard, we hide the header as soon as the top card of the notification
+ // stack scroller is close enough (collision distance) to the bottom of the header.
+ hidden = mNotificationStackScroller.getNotificationsTopY()
+ <= mHeader.getBottom() + mNotificationsHeaderCollideDistance;
+ } else {
+
+ // In SHADE_LOCKED, the top card is already really close to the header. Hide it as
+ // soon as we start translating the stack.
+ hidden = mNotificationStackScroller.getTranslationY() < 0;
+ }
+
if (hidden && !mHeaderHidden) {
mHeader.animate()
.alpha(0f)
@@ -784,14 +824,34 @@
}
@Override
+ protected void onTrackingStarted() {
+ super.onTrackingStarted();
+ if (mStatusBar.getBarState() == StatusBarState.KEYGUARD
+ || mStatusBar.getBarState() == StatusBarState.SHADE_LOCKED) {
+ mPageSwiper.animateHideLeftRightIcon();
+ }
+ }
+
+ @Override
protected void onTrackingStopped(boolean expand) {
super.onTrackingStopped(expand);
mOverExpansion = 0.0f;
- mNotificationStackScroller.setOverScrolledPixels(0.0f, true /* onTop */,
- true /* animate */);
+ mNotificationStackScroller.setOverScrolledPixels(0.0f, true /* onTop */, true /* animate */);
+ if (expand && (mStatusBar.getBarState() == StatusBarState.KEYGUARD
+ || mStatusBar.getBarState() == StatusBarState.SHADE_LOCKED)) {
+ mPageSwiper.showAllIcons(true);
+ }
+ if (!expand && (mStatusBar.getBarState() == StatusBarState.KEYGUARD
+ || mStatusBar.getBarState() == StatusBarState.SHADE_LOCKED)) {
+ mKeyguardBottomArea.getLockIcon().animate()
+ .alpha(0f)
+ .scaleX(2f)
+ .scaleY(2f)
+ .setInterpolator(mFastOutLinearInterpolator)
+ .setDuration(100);
+ }
}
-
@Override
public void onHeightChanged(ExpandableView view) {
requestPanelHeightUpdate();
@@ -825,14 +885,61 @@
@Override
public void onAnimationToSideStarted(boolean rightPage) {
- if (rightPage) {
- mKeyguardBottomArea.launchCamera();
- } else {
+ boolean start = getLayoutDirection() == LAYOUT_DIRECTION_RTL ? rightPage : !rightPage;
+ if (start) {
mKeyguardBottomArea.launchPhone();
+ } else {
+ mKeyguardBottomArea.launchCamera();
}
mBlockTouches = true;
}
+ @Override
+ protected void onEdgeClicked(boolean right) {
+ if ((right && getRightIcon().getVisibility() != View.VISIBLE)
+ || (!right && getLeftIcon().getVisibility() != View.VISIBLE)) {
+ return;
+ }
+ mHintAnimationRunning = true;
+ mPageSwiper.startHintAnimation(right, new Runnable() {
+ @Override
+ public void run() {
+ mHintAnimationRunning = false;
+ mStatusBar.onHintFinished();
+ }
+ });
+ startHighlightIconAnimation(right ? getRightIcon() : getLeftIcon());
+ boolean start = getLayoutDirection() == LAYOUT_DIRECTION_RTL ? right : !right;
+ if (start) {
+ mStatusBar.onPhoneHintStarted();
+ } else {
+ mStatusBar.onCameraHintStarted();
+ }
+ }
+
+ @Override
+ protected void startUnlockHintAnimation() {
+ super.startUnlockHintAnimation();
+ startHighlightIconAnimation(getCenterIcon());
+ }
+
+ /**
+ * Starts the highlight (making it fully opaque) animation on an icon.
+ */
+ private void startHighlightIconAnimation(final View icon) {
+ icon.animate()
+ .alpha(1.0f)
+ .setDuration(KeyguardPageSwipeHelper.HINT_PHASE1_DURATION)
+ .setInterpolator(mFastOutSlowInInterpolator)
+ .withEndAction(new Runnable() {
+ @Override
+ public void run() {
+ icon.animate().alpha(KeyguardPageSwipeHelper.SWIPE_RESTING_ALPHA_AMOUNT)
+ .setDuration(KeyguardPageSwipeHelper.HINT_PHASE1_DURATION)
+ .setInterpolator(mFastOutSlowInInterpolator);
+ }
+ });
+ }
@Override
public float getPageWidth() {
@@ -846,7 +953,9 @@
@Override
public View getLeftIcon() {
- return mKeyguardBottomArea.getPhoneImageView();
+ return getLayoutDirection() == LAYOUT_DIRECTION_RTL
+ ? mKeyguardBottomArea.getCameraImageView()
+ : mKeyguardBottomArea.getPhoneImageView();
}
@Override
@@ -856,6 +965,8 @@
@Override
public View getRightIcon() {
- return mKeyguardBottomArea.getCameraImageView();
+ return getLayoutDirection() == LAYOUT_DIRECTION_RTL
+ ? mKeyguardBottomArea.getPhoneImageView()
+ : mKeyguardBottomArea.getCameraImageView();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index 4686933..f43f348 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -50,15 +50,17 @@
protected PhoneStatusBar mStatusBar;
private float mPeekHeight;
private float mHintDistance;
+ private int mEdgeTapAreaWidth;
private float mInitialOffsetOnTouch;
private float mExpandedFraction = 0;
private float mExpandedHeight = 0;
private boolean mJustPeeked;
private boolean mClosing;
- private boolean mTracking;
+ protected boolean mTracking;
private boolean mTouchSlopExceeded;
private int mTrackingPointer;
protected int mTouchSlop;
+ protected boolean mHintAnimationRunning;
private ValueAnimator mHeightAnimator;
private ObjectAnimator mPeekAnimator;
@@ -111,6 +113,7 @@
final ViewConfiguration configuration = ViewConfiguration.get(getContext());
mTouchSlop = configuration.getScaledTouchSlop();
mHintDistance = res.getDimension(R.dimen.hint_move_distance);
+ mEdgeTapAreaWidth = res.getDimensionPixelSize(R.dimen.edge_tap_area_width);
}
private void trackMovement(MotionEvent event) {
@@ -147,7 +150,6 @@
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
-
mInitialTouchY = y;
mInitialTouchX = x;
mInitialOffsetOnTouch = mExpandedHeight;
@@ -156,10 +158,11 @@
initVelocityTracker();
}
trackMovement(event);
- if (!waitForTouchSlop || mHeightAnimator != null) {
+ if (!waitForTouchSlop || (mHeightAnimator != null && !mHintAnimationRunning)) {
if (mHeightAnimator != null) {
mHeightAnimator.cancel(); // end any outstanding animations
}
+ mTouchSlopExceeded = true;
onTrackingStarted();
}
if (mExpandedHeight == 0) {
@@ -222,7 +225,7 @@
onTrackingStopped(expand);
fling(vel, expand);
} else {
- boolean expands = onEmptySpaceClick();
+ boolean expands = onEmptySpaceClick(mInitialTouchX);
onTrackingStopped(expands);
}
if (mVelocityTracker != null) {
@@ -279,8 +282,9 @@
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
- if (mHeightAnimator != null) {
+ if (mHeightAnimator != null && !mHintAnimationRunning) {
mHeightAnimator.cancel(); // end any outstanding animations
+ mTouchSlopExceeded = true;
return true;
}
mInitialTouchY = y;
@@ -305,6 +309,9 @@
trackMovement(event);
if (scrolledToBottom) {
if (h < -mTouchSlop && h < -Math.abs(x - mInitialTouchX)) {
+ if (mHeightAnimator != null) {
+ mHeightAnimator.cancel();
+ }
mInitialOffsetOnTouch = mExpandedHeight;
mInitialTouchY = y;
mInitialTouchX = x;
@@ -550,14 +557,22 @@
}
cancelPeek();
onExpandingStarted();
- startUnlockHintAnimationPhase1();
+ startUnlockHintAnimationPhase1(new Runnable() {
+ @Override
+ public void run() {
+ onExpandingFinished();
+ mStatusBar.onHintFinished();
+ mHintAnimationRunning = false;
+ }
+ });
mStatusBar.onUnlockHintStarted();
+ mHintAnimationRunning = true;
}
/**
* Phase 1: Move everything upwards.
*/
- private void startUnlockHintAnimationPhase1() {
+ private void startUnlockHintAnimationPhase1(final Runnable onAnimationFinished) {
float target = Math.max(0, getMaxPanelHeight() - mHintDistance);
ValueAnimator animator = createHeightAnimator(target);
animator.setDuration(250);
@@ -574,10 +589,9 @@
public void onAnimationEnd(Animator animation) {
if (mCancelled) {
mHeightAnimator = null;
- onExpandingFinished();
- mStatusBar.onUnlockHintFinished();
+ onAnimationFinished.run();
} else {
- startUnlockHintAnimationPhase2();
+ startUnlockHintAnimationPhase2(onAnimationFinished);
}
}
});
@@ -588,7 +602,7 @@
/**
* Phase 2: Bounce down.
*/
- private void startUnlockHintAnimationPhase2() {
+ private void startUnlockHintAnimationPhase2(final Runnable onAnimationFinished) {
ValueAnimator animator = createHeightAnimator(getMaxPanelHeight());
animator.setDuration(450);
animator.setInterpolator(mBounceInterpolator);
@@ -596,8 +610,7 @@
@Override
public void onAnimationEnd(Animator animation) {
mHeightAnimator = null;
- onExpandingFinished();
- mStatusBar.onUnlockHintFinished();
+ onAnimationFinished.run();
}
});
animator.start();
@@ -620,7 +633,22 @@
*
* @return whether the panel will be expanded after the action performed by this method
*/
- private boolean onEmptySpaceClick() {
+ private boolean onEmptySpaceClick(float x) {
+ if (mHintAnimationRunning) {
+ return true;
+ }
+ if (x < mEdgeTapAreaWidth) {
+ onEdgeClicked(false /* right */);
+ return true;
+ } else if (x > getWidth() - mEdgeTapAreaWidth) {
+ onEdgeClicked(true /* right */);
+ return true;
+ } else {
+ return onMiddleClicked();
+ }
+ }
+
+ private boolean onMiddleClicked() {
switch (mStatusBar.getBarState()) {
case StatusBarState.KEYGUARD:
startUnlockHintAnimation();
@@ -636,6 +664,8 @@
}
}
+ protected abstract void onEdgeClicked(boolean right);
+
public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
pw.println(String.format("[PanelView(%s): expandedHeight=%f maxPanelHeight=%d closing=%s"
+ " tracking=%s justPeeked=%s peekAnim=%s%s timeAnim=%s%s"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index b1216e69..082fe3a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -174,6 +174,11 @@
/** The minimum delay in ms between reports of notification visibility. */
private static final int VISIBILITY_REPORT_MIN_DELAY_MS = 500;
+ /**
+ * The delay to reset the hint text when the hint animation is finished running.
+ */
+ private static final int HINT_RESET_DELAY_MS = 1200;
+
// fling gesture tuning parameters, scaled to display density
private float mSelfExpandVelocityPx; // classic value: 2000px/s
private float mSelfCollapseVelocityPx; // classic value: 2000px/s (will be negated to collapse "up")
@@ -491,6 +496,13 @@
}
};
+ private final Runnable mResetIndicationRunnable = new Runnable() {
+ @Override
+ public void run() {
+ mKeyguardIndicationTextView.switchIndication(mKeyguardHotwordPhrase);
+ }
+ };
+
@Override
public void setZenMode(int mode) {
super.setZenMode(mode);
@@ -1047,16 +1059,22 @@
@Override
public void addNotificationInternal(StatusBarNotification notification, Ranking ranking) {
- if (DEBUG) Log.d(TAG, "addNotification score=" + notification.getScore());
- Entry shadeEntry = createNotificationViews(notification);
- if (shadeEntry == null) {
- return;
- }
+ if (DEBUG) Log.d(TAG, "addNotification key=" + notification.getKey());
if (mZenMode != Global.ZEN_MODE_OFF && mIntercepted.tryIntercept(notification, ranking)) {
// Forward the ranking so we can sort the new notification.
mNotificationData.updateRanking(ranking);
return;
}
+ mIntercepted.remove(notification.getKey());
+ displayNotification(notification, ranking);
+ }
+
+ public void displayNotification(StatusBarNotification notification,
+ Ranking ranking) {
+ Entry shadeEntry = createNotificationViews(notification);
+ if (shadeEntry == null) {
+ return;
+ }
if (mUseHeadsUp && shouldInterrupt(notification)) {
if (DEBUG) Log.d(TAG, "launching notification in heads up mode");
Entry interruptionCandidate = new Entry(notification, null);
@@ -1112,7 +1130,8 @@
@Override
public void updateNotificationInternal(StatusBarNotification notification, Ranking ranking) {
super.updateNotificationInternal(notification, ranking);
- mIntercepted.update(notification);
+ // if we're here, then the notification is already in the shade
+ mIntercepted.remove(notification.getKey());
}
@Override
@@ -2960,11 +2979,24 @@
}
public void onUnlockHintStarted() {
+ mStatusBarView.removeCallbacks(mResetIndicationRunnable);
mKeyguardIndicationTextView.switchIndication(R.string.keyguard_unlock);
}
- public void onUnlockHintFinished() {
- mKeyguardIndicationTextView.switchIndication(mKeyguardHotwordPhrase);
+ public void onHintFinished() {
+
+ // Delay the reset a bit so the user can read the text.
+ mStatusBarView.postDelayed(mResetIndicationRunnable, HINT_RESET_DELAY_MS);
+ }
+
+ public void onCameraHintStarted() {
+ mStatusBarView.removeCallbacks(mResetIndicationRunnable);
+ mKeyguardIndicationTextView.switchIndication(R.string.camera_hint);
+ }
+
+ public void onPhoneHintStarted() {
+ mStatusBarView.removeCallbacks(mResetIndicationRunnable);
+ mKeyguardIndicationTextView.switchIndication(R.string.phone_hint);
}
public void onTrackingStopped(boolean expand) {
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index 30282dd..3146e16 100644
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -3000,7 +3000,7 @@
public void layoutWindowLw(WindowState win, WindowManager.LayoutParams attrs,
WindowState attached) {
// we've already done the status bar
- if (win == mStatusBar || win == mNavigationBar) {
+ if ((win == mStatusBar && !doesForceHide(attrs)) || win == mNavigationBar) {
return;
}
final boolean isDefaultDisplay = win.isDefaultDisplay();
@@ -3278,7 +3278,8 @@
= mOverscanScreenTop + mOverscanScreenHeight;
} else if (canHideNavigationBar()
&& (sysUiFl & View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) != 0
- && (attrs.type == TYPE_TOAST
+ && (attrs.type == TYPE_STATUS_BAR
+ || attrs.type == TYPE_TOAST
|| (attrs.type >= WindowManager.LayoutParams.FIRST_APPLICATION_WINDOW
&& attrs.type <= WindowManager.LayoutParams.LAST_SUB_WINDOW))) {
// Asking for layout as if the nav bar is hidden, lets the
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index d7a19ad..b2b4217 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -38,7 +38,6 @@
import static android.net.ConnectivityManager.TYPE_PROXY;
import static android.net.ConnectivityManager.getNetworkTypeName;
import static android.net.ConnectivityManager.isNetworkTypeValid;
-import static android.net.ConnectivityServiceProtocol.NetworkFactoryProtocol;
import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL;
import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
@@ -80,6 +79,7 @@
import android.net.NetworkConfig;
import android.net.NetworkInfo;
import android.net.NetworkInfo.DetailedState;
+import android.net.NetworkFactory;
import android.net.NetworkQuotaInfo;
import android.net.NetworkRequest;
import android.net.NetworkState;
@@ -258,17 +258,6 @@
*/
private NetworkStateTracker mNetTrackers[];
- /**
- * Holds references to all NetworkAgentInfos claiming to support the legacy
- * NetworkType. We used to have a static set of of NetworkStateTrackers
- * for each network type. This is the new model.
- * Supports synchronous inspection of state.
- * These are built out at startup such that an unsupported network
- * doesn't get an ArrayList instance, making this a tristate:
- * unsupported, supported but not active and active.
- */
- private ArrayList<NetworkAgentInfo> mNetworkAgentInfoForType[];
-
/* Handles captive portal check on a network */
private CaptivePortalTracker mCaptivePortalTracker;
@@ -516,6 +505,118 @@
private static final int UID_UNUSED = -1;
+ /**
+ * Implements support for the legacy "one network per network type" model.
+ *
+ * We used to have a static array of NetworkStateTrackers, one for each
+ * network type, but that doesn't work any more now that we can have,
+ * for example, more that one wifi network. This class stores all the
+ * NetworkAgentInfo objects that support a given type, but the legacy
+ * API will only see the first one.
+ *
+ * It serves two main purposes:
+ *
+ * 1. Provide information about "the network for a given type" (since this
+ * API only supports one).
+ * 2. Send legacy connectivity change broadcasts. Broadcasts are sent if
+ * the first network for a given type changes, or if the default network
+ * changes.
+ */
+ private class LegacyTypeTracker {
+ /**
+ * Array of lists, one per legacy network type (e.g., TYPE_MOBILE_MMS).
+ * Each list holds references to all NetworkAgentInfos that are used to
+ * satisfy requests for that network type.
+ *
+ * This array is built out at startup such that an unsupported network
+ * doesn't get an ArrayList instance, making this a tristate:
+ * unsupported, supported but not active and active.
+ *
+ * The actual lists are populated when we scan the network types that
+ * are supported on this device.
+ */
+ private ArrayList<NetworkAgentInfo> mTypeLists[];
+
+ public LegacyTypeTracker() {
+ mTypeLists = (ArrayList<NetworkAgentInfo>[])
+ new ArrayList[ConnectivityManager.MAX_NETWORK_TYPE + 1];
+ }
+
+ public void addSupportedType(int type) {
+ if (mTypeLists[type] != null) {
+ throw new IllegalStateException(
+ "legacy list for type " + type + "already initialized");
+ }
+ mTypeLists[type] = new ArrayList<NetworkAgentInfo>();
+ }
+
+ private boolean isDefaultNetwork(NetworkAgentInfo nai) {
+ return mNetworkForRequestId.get(mDefaultRequest.requestId) == nai;
+ }
+
+ public boolean isTypeSupported(int type) {
+ return isNetworkTypeValid(type) && mTypeLists[type] != null;
+ }
+
+ public NetworkAgentInfo getNetworkForType(int type) {
+ if (isTypeSupported(type) && !mTypeLists[type].isEmpty()) {
+ return mTypeLists[type].get(0);
+ } else {
+ return null;
+ }
+ }
+
+ public void add(int type, NetworkAgentInfo nai) {
+ if (!isTypeSupported(type)) {
+ return; // Invalid network type.
+ }
+ if (VDBG) log("Adding agent " + nai + " for legacy network type " + type);
+
+ ArrayList<NetworkAgentInfo> list = mTypeLists[type];
+ if (list.contains(nai)) {
+ loge("Attempting to register duplicate agent for type " + type + ": " + nai);
+ return;
+ }
+
+ if (list.isEmpty() || isDefaultNetwork(nai)) {
+ if (VDBG) log("Sending connected broadcast for type " + type +
+ "isDefaultNetwork=" + isDefaultNetwork(nai));
+ sendLegacyNetworkBroadcast(nai, true, type);
+ }
+ list.add(nai);
+ }
+
+ public void remove(NetworkAgentInfo nai) {
+ if (VDBG) log("Removing agent " + nai);
+ for (int type = 0; type < mTypeLists.length; type++) {
+ ArrayList<NetworkAgentInfo> list = mTypeLists[type];
+ if (list == null || list.isEmpty()) {
+ continue;
+ }
+
+ boolean wasFirstNetwork = false;
+ if (list.get(0).equals(nai)) {
+ // This network was the first in the list. Send broadcast.
+ wasFirstNetwork = true;
+ }
+ list.remove(nai);
+
+ if (wasFirstNetwork || isDefaultNetwork(nai)) {
+ if (VDBG) log("Sending disconnected broadcast for type " + type +
+ "isDefaultNetwork=" + isDefaultNetwork(nai));
+ sendLegacyNetworkBroadcast(nai, false, type);
+ }
+
+ if (!list.isEmpty() && wasFirstNetwork) {
+ if (VDBG) log("Other network available for type " + type +
+ ", sending connected broadcast");
+ sendLegacyNetworkBroadcast(list.get(0), false, type);
+ }
+ }
+ }
+ }
+ private LegacyTypeTracker mLegacyTypeTracker = new LegacyTypeTracker();
+
public ConnectivityService(Context context, INetworkManagementService netd,
INetworkStatsService statsService, INetworkPolicyManager policyManager) {
// Currently, omitting a NetworkFactory will create one internally
@@ -531,7 +632,7 @@
NetworkCapabilities netCap = new NetworkCapabilities();
netCap.addNetworkCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
netCap.addNetworkCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED);
- mDefaultRequest = new NetworkRequest(netCap, true, nextNetworkRequestId());
+ mDefaultRequest = new NetworkRequest(netCap, TYPE_NONE, nextNetworkRequestId());
NetworkRequestInfo nri = new NetworkRequestInfo(null, mDefaultRequest, new Binder(),
NetworkRequestInfo.REQUEST);
mNetworkRequests.put(mDefaultRequest, nri);
@@ -587,9 +688,6 @@
mNetTransitionWakeLockTimeout = mContext.getResources().getInteger(
com.android.internal.R.integer.config_networkTransitionTimeout);
- mNetworkAgentInfoForType = (ArrayList<NetworkAgentInfo>[])
- new ArrayList[ConnectivityManager.MAX_NETWORK_TYPE + 1];
-
mNetTrackers = new NetworkStateTracker[
ConnectivityManager.MAX_NETWORK_TYPE+1];
mCurrentLinkProperties = new LinkProperties[ConnectivityManager.MAX_NETWORK_TYPE+1];
@@ -644,7 +742,7 @@
"radio " + n.radio + " in network type " + n.type);
continue;
}
- mNetworkAgentInfoForType[n.type] = new ArrayList<NetworkAgentInfo>();
+ mLegacyTypeTracker.addSupportedType(n.type);
mNetConfigs[n.type] = n;
mNetworksDefined++;
@@ -2843,7 +2941,8 @@
}
}
- private int getRestoreDefaultNetworkDelay(int networkType) {
+ @Override
+ public int getRestoreDefaultNetworkDelay(int networkType) {
String restoreDefaultNetworkDelayStr = SystemProperties.get(
NETWORK_RESTORE_DELAY_PROP_NAME);
if(restoreDefaultNetworkDelayStr != null &&
@@ -2994,6 +3093,16 @@
updateNetworkInfo(nai, info);
break;
}
+ case NetworkAgent.EVENT_NETWORK_SCORE_CHANGED: {
+ NetworkAgentInfo nai = mNetworkAgentInfos.get(msg.replyTo);
+ if (nai == null) {
+ loge("EVENT_NETWORK_SCORE_CHANGED from unknown NetworkAgent");
+ break;
+ }
+ Integer score = (Integer) msg.obj;
+ updateNetworkScore(nai, score);
+ break;
+ }
case NetworkMonitor.EVENT_NETWORK_VALIDATED: {
NetworkAgentInfo nai = (NetworkAgentInfo)msg.obj;
handleConnectionValidated(nai);
@@ -3098,7 +3207,7 @@
for (NetworkRequestInfo nri : mNetworkRequests.values()) {
if (nri.isRequest == false) continue;
NetworkAgentInfo nai = mNetworkForRequestId.get(nri.request.requestId);
- ac.sendMessage(NetworkFactoryProtocol.CMD_REQUEST_NETWORK,
+ ac.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK,
(nai != null ? nai.currentScore : 0), 0, nri.request);
}
} else {
@@ -3114,11 +3223,9 @@
} else {
loge("Error connecting NetworkAgent");
NetworkAgentInfo nai = mNetworkAgentInfos.remove(msg.replyTo);
- try {
- mNetworkAgentInfoForType[nai.networkInfo.getType()].remove(nai);
- } catch (NullPointerException e) {}
if (nai != null) {
mNetworkForNetId.remove(nai.network.netId);
+ mLegacyTypeTracker.remove(nai);
}
}
}
@@ -3137,14 +3244,19 @@
} catch (Exception e) {
loge("Exception removing network: " + e);
}
+ // TODO - if we move the logic to the network agent (have them disconnect
+ // because they lost all their requests or because their score isn't good)
+ // then they would disconnect organically, report their new state and then
+ // disconnect the channel.
+ if (nai.networkInfo.isConnected()) {
+ nai.networkInfo.setDetailedState(NetworkInfo.DetailedState.DISCONNECTED,
+ null, null);
+ }
notifyNetworkCallbacks(nai, ConnectivityManager.CALLBACK_LOST);
nai.networkMonitor.sendMessage(NetworkMonitor.CMD_NETWORK_DISCONNECTED);
mNetworkAgentInfos.remove(msg.replyTo);
updateClat(null, nai.linkProperties, nai);
- try {
- mNetworkAgentInfoForType[nai.networkInfo.getType()].remove(nai);
- } catch (NullPointerException e) {}
-
+ mLegacyTypeTracker.remove(nai);
mNetworkForNetId.remove(nai.network.netId);
// Since we've lost the network, go through all the requests that
// it was satisfying and see if any other factory can satisfy them.
@@ -3154,7 +3266,7 @@
NetworkAgentInfo currentNetwork = mNetworkForRequestId.get(request.requestId);
if (VDBG) {
log(" checking request " + request + ", currentNetwork = " +
- currentNetwork != null ? currentNetwork.name() : "null");
+ (currentNetwork != null ? currentNetwork.name() : "null"));
}
if (currentNetwork != null && currentNetwork.network.netId == nai.network.netId) {
mNetworkForRequestId.remove(request.requestId);
@@ -3203,7 +3315,11 @@
}
if (bestNetwork != null) {
if (VDBG) log("using " + bestNetwork.name());
- bestNetwork.networkRequests.put(nri.request.requestId, nri.request);
+ bestNetwork.addRequest(nri.request);
+ int legacyType = nri.request.legacyType;
+ if (legacyType != TYPE_NONE) {
+ mLegacyTypeTracker.add(legacyType, bestNetwork);
+ }
notifyNetworkCallback(bestNetwork, nri);
score = bestNetwork.currentScore;
}
@@ -3211,7 +3327,8 @@
if (msg.what == EVENT_REGISTER_NETWORK_REQUEST) {
if (DBG) log("sending new NetworkRequest to factories");
for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) {
- nfi.asyncChannel.sendMessage(NetworkFactoryProtocol.CMD_REQUEST_NETWORK, score, 0, nri.request);
+ nfi.asyncChannel.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK, score,
+ 0, nri.request);
}
}
}
@@ -3233,7 +3350,8 @@
if (nri.isRequest) {
for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) {
- nfi.asyncChannel.sendMessage(NetworkFactoryProtocol.CMD_CANCEL_REQUEST, nri.request);
+ nfi.asyncChannel.sendMessage(android.net.NetworkFactory.CMD_CANCEL_REQUEST,
+ nri.request);
}
if (affectedNetwork != null) {
@@ -5279,7 +5397,7 @@
@Override
public NetworkRequest requestNetwork(NetworkCapabilities networkCapabilities,
- Messenger messenger, int timeoutSec, IBinder binder) {
+ Messenger messenger, int timeoutSec, IBinder binder, int legacyType) {
if (networkCapabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
== false) {
enforceConnectivityInternalPermission();
@@ -5291,7 +5409,7 @@
throw new IllegalArgumentException("Bad timeout specified");
}
NetworkRequest networkRequest = new NetworkRequest(new NetworkCapabilities(
- networkCapabilities), false, nextNetworkRequestId());
+ networkCapabilities), legacyType, nextNetworkRequestId());
if (DBG) log("requestNetwork for " + networkRequest);
NetworkRequestInfo nri = new NetworkRequestInfo(messenger, networkRequest, binder,
NetworkRequestInfo.REQUEST);
@@ -5317,7 +5435,7 @@
enforceAccessPermission();
NetworkRequest networkRequest = new NetworkRequest(new NetworkCapabilities(
- networkCapabilities), false, nextNetworkRequestId());
+ networkCapabilities), TYPE_NONE, nextNetworkRequestId());
if (DBG) log("listenForNetwork for " + networkRequest);
NetworkRequestInfo nri = new NetworkRequestInfo(messenger, networkRequest, binder,
NetworkRequestInfo.LISTEN);
@@ -5392,18 +5510,13 @@
NetworkAgentInfo nai = new NetworkAgentInfo(messenger, new AsyncChannel(), nextNetId(),
new NetworkInfo(networkInfo), new LinkProperties(linkProperties),
new NetworkCapabilities(networkCapabilities), currentScore, mContext, mTrackerHandler);
-
+ if (VDBG) log("registerNetworkAgent " + nai);
mHandler.sendMessage(mHandler.obtainMessage(EVENT_REGISTER_NETWORK_AGENT, nai));
}
private void handleRegisterNetworkAgent(NetworkAgentInfo na) {
if (VDBG) log("Got NetworkAgent Messenger");
mNetworkAgentInfos.put(na.messenger, na);
- try {
- mNetworkAgentInfoForType[na.networkInfo.getType()].add(na);
- } catch (NullPointerException e) {
- loge("registered NetworkAgent for unsupported type: " + na);
- }
mNetworkForNetId.put(na.network.netId, na);
na.asyncChannel.connect(mContext, mTrackerHandler, na.messenger);
NetworkInfo networkInfo = na.networkInfo;
@@ -5439,7 +5552,7 @@
mClat.stopClat();
}
// If the link requires clat to be running, then start the daemon now.
- if (newLp != null && na.networkInfo.isConnected()) {
+ if (na.networkInfo.isConnected()) {
mClat.startClat(na);
} else {
mClat.stopClat();
@@ -5555,7 +5668,8 @@
private void sendUpdatedScoreToFactories(NetworkRequest networkRequest, int score) {
if (VDBG) log("sending new Min Network Score(" + score + "): " + networkRequest.toString());
for (NetworkFactoryInfo nfi : mNetworkFactoryInfos.values()) {
- nfi.asyncChannel.sendMessage(NetworkFactoryProtocol.CMD_REQUEST_NETWORK, score, 0, networkRequest);
+ nfi.asyncChannel.sendMessage(android.net.NetworkFactory.CMD_REQUEST_NETWORK, score, 0,
+ networkRequest);
}
}
@@ -5658,7 +5772,11 @@
if (VDBG) log(" accepting network in place of null");
}
mNetworkForRequestId.put(nri.request.requestId, newNetwork);
- newNetwork.networkRequests.put(nri.request.requestId, nri.request);
+ newNetwork.addRequest(nri.request);
+ int legacyType = nri.request.legacyType;
+ if (legacyType != TYPE_NONE) {
+ mLegacyTypeTracker.add(legacyType, newNetwork);
+ }
keep = true;
// TODO - this could get expensive if we have alot of requests for this
// network. Think about if there is a way to reduce this. Push
@@ -5672,6 +5790,7 @@
} else {
setDefaultDnsSystemProperties(new ArrayList<InetAddress>());
}
+ mLegacyTypeTracker.add(newNetwork.networkInfo.getType(), newNetwork);
}
}
}
@@ -5792,6 +5911,11 @@
}
}
+ private void updateNetworkScore(NetworkAgentInfo nai, Integer scoreInteger) {
+ int score = scoreInteger.intValue();
+ // TODO
+ }
+
// notify only this one new request of the current state
protected void notifyNetworkCallback(NetworkAgentInfo nai, NetworkRequestInfo nri) {
int notifyType = ConnectivityManager.CALLBACK_AVAILABLE;
@@ -5801,93 +5925,88 @@
// } else if (nai.networkMonitor.isEvaluating()) {
// notifyType = NetworkCallbacks.callCallbackForRequest(request, nai, notifyType);
// }
- if (nri.request.needsBroadcasts) {
- // TODO
-// sendNetworkBroadcast(nai, notifyType);
- }
callCallbackForRequest(nri, nai, notifyType);
}
- protected void notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType) {
- if (VDBG) log("notifyType " + notifyType + " for " + networkAgent.name());
- boolean needsBroadcasts = false;
- for (int i = 0; i < networkAgent.networkRequests.size(); i++) {
- NetworkRequest nr = networkAgent.networkRequests.valueAt(i);
- NetworkRequestInfo nri = mNetworkRequests.get(nr);
- if (VDBG) log(" sending notification for " + nr);
- if (nr.needsBroadcasts) needsBroadcasts = true;
- callCallbackForRequest(nri, networkAgent, notifyType);
- }
- if (needsBroadcasts) {
- if (notifyType == ConnectivityManager.CALLBACK_AVAILABLE) {
- sendConnectedBroadcastDelayed(networkAgent.networkInfo,
- getConnectivityChangeDelay());
- } else if (notifyType == ConnectivityManager.CALLBACK_LOST) {
- NetworkInfo info = new NetworkInfo(networkAgent.networkInfo);
- Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION);
- intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, info);
- intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, info.getType());
- if (info.isFailover()) {
- intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true);
- networkAgent.networkInfo.setFailover(false);
- }
- if (info.getReason() != null) {
- intent.putExtra(ConnectivityManager.EXTRA_REASON, info.getReason());
- }
- if (info.getExtraInfo() != null) {
- intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO, info.getExtraInfo());
- }
- NetworkAgentInfo newDefaultAgent = null;
- if (networkAgent.networkRequests.get(mDefaultRequest.requestId) != null) {
- newDefaultAgent = mNetworkForRequestId.get(mDefaultRequest.requestId);
- if (newDefaultAgent != null) {
- intent.putExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO,
- newDefaultAgent.networkInfo);
- } else {
- intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true);
- }
- }
- intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION,
- mDefaultInetConditionPublished);
- final Intent immediateIntent = new Intent(intent);
- immediateIntent.setAction(CONNECTIVITY_ACTION_IMMEDIATE);
- sendStickyBroadcast(immediateIntent);
- sendStickyBroadcastDelayed(intent, getConnectivityChangeDelay());
+ private void sendLegacyNetworkBroadcast(NetworkAgentInfo nai, boolean connected, int type) {
+ if (connected) {
+ NetworkInfo info = new NetworkInfo(nai.networkInfo);
+ info.setType(type);
+ sendConnectedBroadcastDelayed(info, getConnectivityChangeDelay());
+ } else {
+ NetworkInfo info = new NetworkInfo(nai.networkInfo);
+ info.setType(type);
+ Intent intent = new Intent(ConnectivityManager.CONNECTIVITY_ACTION);
+ intent.putExtra(ConnectivityManager.EXTRA_NETWORK_INFO, info);
+ intent.putExtra(ConnectivityManager.EXTRA_NETWORK_TYPE, info.getType());
+ if (info.isFailover()) {
+ intent.putExtra(ConnectivityManager.EXTRA_IS_FAILOVER, true);
+ nai.networkInfo.setFailover(false);
+ }
+ if (info.getReason() != null) {
+ intent.putExtra(ConnectivityManager.EXTRA_REASON, info.getReason());
+ }
+ if (info.getExtraInfo() != null) {
+ intent.putExtra(ConnectivityManager.EXTRA_EXTRA_INFO, info.getExtraInfo());
+ }
+ NetworkAgentInfo newDefaultAgent = null;
+ if (nai.networkRequests.get(mDefaultRequest.requestId) != null) {
+ newDefaultAgent = mNetworkForRequestId.get(mDefaultRequest.requestId);
if (newDefaultAgent != null) {
- sendConnectedBroadcastDelayed(newDefaultAgent.networkInfo,
- getConnectivityChangeDelay());
+ intent.putExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO,
+ newDefaultAgent.networkInfo);
+ } else {
+ intent.putExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, true);
}
}
+ intent.putExtra(ConnectivityManager.EXTRA_INET_CONDITION,
+ mDefaultInetConditionPublished);
+ final Intent immediateIntent = new Intent(intent);
+ immediateIntent.setAction(CONNECTIVITY_ACTION_IMMEDIATE);
+ sendStickyBroadcast(immediateIntent);
+ sendStickyBroadcastDelayed(intent, getConnectivityChangeDelay());
+ if (newDefaultAgent != null) {
+ sendConnectedBroadcastDelayed(newDefaultAgent.networkInfo,
+ getConnectivityChangeDelay());
+ }
}
}
- private LinkProperties getLinkPropertiesForTypeInternal(int networkType) {
- ArrayList<NetworkAgentInfo> list = mNetworkAgentInfoForType[networkType];
- if (list == null) return null;
- try {
- return new LinkProperties(list.get(0).linkProperties);
- } catch (IndexOutOfBoundsException e) {
- return new LinkProperties();
+ protected void notifyNetworkCallbacks(NetworkAgentInfo networkAgent, int notifyType) {
+ if (VDBG) log("notifyType " + notifyType + " for " + networkAgent.name());
+ for (int i = 0; i < networkAgent.networkRequests.size(); i++) {
+ NetworkRequest nr = networkAgent.networkRequests.valueAt(i);
+ NetworkRequestInfo nri = mNetworkRequests.get(nr);
+ if (VDBG) log(" sending notification for " + nr);
+ callCallbackForRequest(nri, networkAgent, notifyType);
}
}
+ private LinkProperties getLinkPropertiesForTypeInternal(int networkType) {
+ NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
+ return (nai != null) ?
+ new LinkProperties(nai.linkProperties) :
+ new LinkProperties();
+ }
+
private NetworkInfo getNetworkInfoForType(int networkType) {
- ArrayList<NetworkAgentInfo> list = mNetworkAgentInfoForType[networkType];
- if (list == null) return null;
- try {
- return new NetworkInfo(list.get(0).networkInfo);
- } catch (IndexOutOfBoundsException e) {
- return new NetworkInfo(networkType, 0, "Unknown", "");
+ if (!mLegacyTypeTracker.isTypeSupported(networkType))
+ return null;
+
+ NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
+ if (nai != null) {
+ NetworkInfo result = new NetworkInfo(nai.networkInfo);
+ result.setType(networkType);
+ return result;
+ } else {
+ return new NetworkInfo(networkType, 0, "Unknown", "");
}
}
private NetworkCapabilities getNetworkCapabilitiesForType(int networkType) {
- ArrayList<NetworkAgentInfo> list = mNetworkAgentInfoForType[networkType];
- if (list == null) return null;
- try {
- return new NetworkCapabilities(list.get(0).networkCapabilities);
- } catch (IndexOutOfBoundsException e) {
- return new NetworkCapabilities();
- }
+ NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
+ return (nai != null) ?
+ new NetworkCapabilities(nai.networkCapabilities) :
+ new NetworkCapabilities();
}
}
diff --git a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
index 8102591..b03c247 100644
--- a/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
+++ b/services/core/java/com/android/server/connectivity/NetworkAgentInfo.java
@@ -45,7 +45,6 @@
public int currentScore;
public final NetworkMonitor networkMonitor;
-
// The list of NetworkRequests being satisfied by this Network.
public final SparseArray<NetworkRequest> networkRequests = new SparseArray<NetworkRequest>();
public final ArrayList<NetworkRequest> networkLingered = new ArrayList<NetworkRequest>();
@@ -66,6 +65,10 @@
networkMonitor = new NetworkMonitor(context, handler, this);
}
+ public void addRequest(NetworkRequest networkRequest) {
+ networkRequests.put(networkRequest.requestId, networkRequest);
+ }
+
public String toString() {
return "NetworkAgentInfo{ ni{" + networkInfo + "} network{" +
network + "} lp{" +
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index cb78a45..5f37443 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1486,6 +1486,11 @@
pkg, opPkg, id, tag, callingUid, callingPid, score, notification,
user);
NotificationRecord r = new NotificationRecord(n);
+ NotificationRecord old = mNotificationsByKey.get(n.getKey());
+ if (old != null) {
+ // Retain ranking information from previous record
+ r.copyRankingInformation(old);
+ }
if (!mSignalExtractors.isEmpty()) {
for (NotificationSignalExtractor extractor : mSignalExtractors) {
try {
@@ -1514,15 +1519,6 @@
}
synchronized (mNotificationList) {
- applyZenModeLocked(r);
-
- // Should this notification make noise, vibe, or use the LED?
- final boolean canInterrupt = (score >= SCORE_INTERRUPTION_THRESHOLD) &&
- !r.isIntercepted();
- if (DBG || r.isIntercepted()) Slog.v(TAG,
- "pkg=" + pkg + " canInterrupt=" + canInterrupt +
- " intercept=" + r.isIntercepted());
- NotificationRecord old = null;
int index = indexOfNotificationLocked(n.getKey());
if (index < 0) {
mNotificationList.add(r);
@@ -1534,12 +1530,18 @@
// Make sure we don't lose the foreground service state.
notification.flags |=
old.getNotification().flags & Notification.FLAG_FOREGROUND_SERVICE;
- // Retain ranking information from previous record
- r.copyRankingInformation(old);
mNotificationsByKey.remove(old.sbn.getKey());
}
mNotificationsByKey.put(n.getKey(), r);
+ applyZenModeLocked(r);
+ // Should this notification make noise, vibe, or use the LED?
+ final boolean canInterrupt = (score >= SCORE_INTERRUPTION_THRESHOLD) &&
+ !r.isIntercepted();
+ if (DBG || r.isIntercepted()) Slog.v(TAG,
+ "pkg=" + pkg + " canInterrupt=" + canInterrupt +
+ " intercept=" + r.isIntercepted());
+
Collections.sort(mNotificationList, mRankingComparator);
// Ensure if this is a foreground service that the proper additional
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index 5eb3305..1c277a8 100644
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -372,18 +372,54 @@
}
@Override
- public void onVideoSizeChanged(int width, int height) throws RemoteException {
+ public void onVideoStreamChanged(int width, int height, boolean interlaced) {
synchronized (mLock) {
if (DEBUG) {
- Slog.d(TAG, "onVideoSizeChanged(" + width + ", " + height + ")");
+ Slog.d(TAG, "onVideoStreamChanged(" + width + ", " + height + ")");
}
if (sessionState.mSession == null || sessionState.mClient == null) {
return;
}
try {
- sessionState.mClient.onVideoSizeChanged(width, height, sessionState.mSeq);
+ sessionState.mClient.onVideoStreamChanged(width, height, interlaced,
+ sessionState.mSeq);
} catch (RemoteException e) {
- Slog.e(TAG, "error in onSessionEvent");
+ Slog.e(TAG, "error in onVideoStreamChanged");
+ }
+ }
+ }
+
+ @Override
+ public void onAudioStreamChanged(int channelCount) {
+ synchronized (mLock) {
+ if (DEBUG) {
+ Slog.d(TAG, "onAudioStreamChanged(" + channelCount + ")");
+ }
+ if (sessionState.mSession == null || sessionState.mClient == null) {
+ return;
+ }
+ try {
+ sessionState.mClient.onAudioStreamChanged(channelCount, sessionState.mSeq);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "error in onAudioStreamChanged");
+ }
+ }
+ }
+
+ @Override
+ public void onClosedCaptionStreamChanged(boolean hasClosedCaption) {
+ synchronized (mLock) {
+ if (DEBUG) {
+ Slog.d(TAG, "onClosedCaptionStreamChanged(" + hasClosedCaption + ")");
+ }
+ if (sessionState.mSession == null || sessionState.mClient == null) {
+ return;
+ }
+ try {
+ sessionState.mClient.onClosedCaptionStreamChanged(hasClosedCaption,
+ sessionState.mSeq);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "error in onClosedCaptionStreamChanged");
}
}
}
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 525441d72..68bf628 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -1743,216 +1743,6 @@
}
/**
- * Opens a logical channel to the ICC card.
- *
- * Input parameters equivalent to TS 27.007 AT+CCHO command.
- *
- * <p>Requires Permission:
- * {@link android.Manifest.permission#SIM_COMMUNICATION SIM_COMMUNICATION}
- *
- * @param AID Application id. See ETSI 102.221 and 101.220.
- * @return The logical channel id which is negative on error.
- */
- public int iccOpenLogicalChannel(String AID) {
- try {
- return getITelephony().iccOpenLogicalChannel(AID);
- } catch (RemoteException ex) {
- } catch (NullPointerException ex) {
- }
- return -1;
- }
-
- /**
- * Closes a previously opened logical channel to the ICC card.
- *
- * Input parameters equivalent to TS 27.007 AT+CCHC command.
- *
- * <p>Requires Permission:
- * {@link android.Manifest.permission#SIM_COMMUNICATION SIM_COMMUNICATION}
- *
- * @param channel is the channel id to be closed as retruned by a successful
- * iccOpenLogicalChannel.
- * @return true if the channel was closed successfully.
- */
- public boolean iccCloseLogicalChannel(int channel) {
- try {
- return getITelephony().iccCloseLogicalChannel(channel);
- } catch (RemoteException ex) {
- } catch (NullPointerException ex) {
- }
- return false;
- }
-
- /**
- * Transmit an APDU to the ICC card over a logical channel.
- *
- * Input parameters equivalent to TS 27.007 AT+CGLA command.
- *
- * <p>Requires Permission:
- * {@link android.Manifest.permission#SIM_COMMUNICATION SIM_COMMUNICATION}
- *
- * @param channel is the channel id to be closed as returned by a successful
- * iccOpenLogicalChannel.
- * @param cla Class of the APDU command.
- * @param instruction Instruction of the APDU command.
- * @param p1 P1 value of the APDU command.
- * @param p2 P2 value of the APDU command.
- * @param p3 P3 value of the APDU command. If p3 is negative a 4 byte APDU
- * is sent to the SIM.
- * @param data Data to be sent with the APDU.
- * @return The APDU response from the ICC card with the status appended at
- * the end. If an error occurs, an empty string is returned.
- */
- public String iccTransmitApduLogicalChannel(int channel, int cla,
- int instruction, int p1, int p2, int p3, String data) {
- try {
- return getITelephony().iccTransmitApduLogicalChannel(channel, cla,
- instruction, p1, p2, p3, data);
- } catch (RemoteException ex) {
- } catch (NullPointerException ex) {
- }
- return "";
- }
-
- /**
- * Send ENVELOPE to the SIM and return the response.
- *
- * <p>Requires Permission:
- * {@link android.Manifest.permission#SIM_COMMUNICATION SIM_COMMUNICATION}
- *
- * @param content String containing SAT/USAT response in hexadecimal
- * format starting with command tag. See TS 102 223 for
- * details.
- * @return The APDU response from the ICC card, with the last 4 bytes
- * being the status word. If the command fails, returns an empty
- * string.
- */
- public String sendEnvelopeWithStatus(String content) {
- try {
- return getITelephony().sendEnvelopeWithStatus(content);
- } catch (RemoteException ex) {
- } catch (NullPointerException ex) {
- }
- return "";
- }
-
- /**
- * Read one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}.
- * Used for device configuration by some CDMA operators.
- *
- * @param itemID the ID of the item to read.
- * @return the NV item as a String, or null on any failure.
- * @hide
- */
- public String nvReadItem(int itemID) {
- try {
- return getITelephony().nvReadItem(itemID);
- } catch (RemoteException ex) {
- Rlog.e(TAG, "nvReadItem RemoteException", ex);
- } catch (NullPointerException ex) {
- Rlog.e(TAG, "nvReadItem NPE", ex);
- }
- return "";
- }
-
-
- /**
- * Write one of the NV items defined in {@link com.android.internal.telephony.RadioNVItems}.
- * Used for device configuration by some CDMA operators.
- *
- * @param itemID the ID of the item to read.
- * @param itemValue the value to write, as a String.
- * @return true on success; false on any failure.
- * @hide
- */
- public boolean nvWriteItem(int itemID, String itemValue) {
- try {
- return getITelephony().nvWriteItem(itemID, itemValue);
- } catch (RemoteException ex) {
- Rlog.e(TAG, "nvWriteItem RemoteException", ex);
- } catch (NullPointerException ex) {
- Rlog.e(TAG, "nvWriteItem NPE", ex);
- }
- return false;
- }
-
- /**
- * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage.
- * Used for device configuration by some CDMA operators.
- *
- * @param preferredRoamingList byte array containing the new PRL.
- * @return true on success; false on any failure.
- * @hide
- */
- public boolean nvWriteCdmaPrl(byte[] preferredRoamingList) {
- try {
- return getITelephony().nvWriteCdmaPrl(preferredRoamingList);
- } catch (RemoteException ex) {
- Rlog.e(TAG, "nvWriteCdmaPrl RemoteException", ex);
- } catch (NullPointerException ex) {
- Rlog.e(TAG, "nvWriteCdmaPrl NPE", ex);
- }
- return false;
- }
-
- /**
- * Perform the specified type of NV config reset. The radio will be taken offline
- * and the device must be rebooted after the operation. Used for device
- * configuration by some CDMA operators.
- *
- * @param resetType reset type: 1: reload NV reset, 2: erase NV reset, 3: factory NV reset
- * @return true on success; false on any failure.
- * @hide
- */
- public boolean nvResetConfig(int resetType) {
- try {
- return getITelephony().nvResetConfig(resetType);
- } catch (RemoteException ex) {
- Rlog.e(TAG, "nvResetConfig RemoteException", ex);
- } catch (NullPointerException ex) {
- Rlog.e(TAG, "nvResetConfig NPE", ex);
- }
- return false;
- }
-
- /**
- * Get the preferred network type.
- * Used for device configuration by some CDMA operators.
- *
- * @return the preferred network type, defined in RILConstants.java.
- * @hide
- */
- public int getPreferredNetworkType() {
- try {
- return getITelephony().getPreferredNetworkType();
- } catch (RemoteException ex) {
- Rlog.e(TAG, "getPreferredNetworkType RemoteException", ex);
- } catch (NullPointerException ex) {
- Rlog.e(TAG, "getPreferredNetworkType NPE", ex);
- }
- return -1;
- }
-
- /**
- * Set the preferred network type.
- * Used for device configuration by some CDMA operators.
- *
- * @param networkType the preferred network type, defined in RILConstants.java.
- * @return true on success; false on any failure.
- * @hide
- */
- public boolean setPreferredNetworkType(int networkType) {
- try {
- return getITelephony().setPreferredNetworkType(networkType);
- } catch (RemoteException ex) {
- Rlog.e(TAG, "setPreferredNetworkType RemoteException", ex);
- } catch (NullPointerException ex) {
- Rlog.e(TAG, "setPreferredNetworkType NPE", ex);
- }
- return false;
- }
-
- /**
* Expose the rest of ITelephony to @PrivateApi
*/
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index acaa8de..f9462f2 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -308,114 +308,6 @@
void setCellInfoListRate(int rateInMillis);
/**
- * Opens a logical channel to the ICC card.
- *
- * Input parameters equivalent to TS 27.007 AT+CCHO command.
- *
- * @param AID Application id. See ETSI 102.221 and 101.220.
- * @return The logical channel id which is set to -1 on error.
- */
- int iccOpenLogicalChannel(String AID);
-
- /**
- * Closes a previously opened logical channel to the ICC card.
- *
- * Input parameters equivalent to TS 27.007 AT+CCHC command.
- *
- * @param channel is the channel id to be closed as retruned by a
- * successful iccOpenLogicalChannel.
- * @return true if the channel was closed successfully.
- */
- boolean iccCloseLogicalChannel(int channel);
-
- /**
- * Transmit an APDU to the ICC card over a logical channel.
- *
- * Input parameters equivalent to TS 27.007 AT+CGLA command.
- *
- * @param channel is the channel id to be closed as retruned by a
- * successful iccOpenLogicalChannel.
- * @param cla Class of the APDU command.
- * @param instruction Instruction of the APDU command.
- * @param p1 P1 value of the APDU command.
- * @param p2 P2 value of the APDU command.
- * @param p3 P3 value of the APDU command. If p3 is negative a 4 byte APDU
- * is sent to the SIM.
- * @param data Data to be sent with the APDU.
- * @return The APDU response from the ICC card with the status appended at
- * the end. If an error occurs, an empty string is returned.
- */
- String iccTransmitApduLogicalChannel(int channel, int cla, int instruction,
- int p1, int p2, int p3, String data);
-
- /**
- * Send ENVELOPE to the SIM and returns the response.
- *
- * @param contents String containing SAT/USAT response in hexadecimal
- * format starting with command tag. See TS 102 223 for
- * details.
- * @return The APDU response from the ICC card, with the last 4 bytes
- * being the status word. If the command fails, returns an empty
- * string.
- */
- String sendEnvelopeWithStatus(String content);
-
- /**
- * Read one of the NV items defined in {@link RadioNVItems} / {@code ril_nv_items.h}.
- * Used for device configuration by some CDMA operators.
- *
- * @param itemID the ID of the item to read.
- * @return the NV item as a String, or null on any failure.
- */
- String nvReadItem(int itemID);
-
- /**
- * Write one of the NV items defined in {@link RadioNVItems} / {@code ril_nv_items.h}.
- * Used for device configuration by some CDMA operators.
- *
- * @param itemID the ID of the item to read.
- * @param itemValue the value to write, as a String.
- * @return true on success; false on any failure.
- */
- boolean nvWriteItem(int itemID, String itemValue);
-
- /**
- * Update the CDMA Preferred Roaming List (PRL) in the radio NV storage.
- * Used for device configuration by some CDMA operators.
- *
- * @param preferredRoamingList byte array containing the new PRL.
- * @return true on success; false on any failure.
- */
- boolean nvWriteCdmaPrl(in byte[] preferredRoamingList);
-
- /**
- * Perform the specified type of NV config reset. The radio will be taken offline
- * and the device must be rebooted after the operation. Used for device
- * configuration by some CDMA operators.
- *
- * @param resetType the type of reset to perform (1 == factory reset; 2 == NV-only reset).
- * @return true on success; false on any failure.
- */
- boolean nvResetConfig(int resetType);
-
- /*
- * Get the preferred network type.
- * Used for device configuration by some CDMA operators.
- *
- * @return the preferred network type, defined in RILConstants.java.
- */
- int getPreferredNetworkType();
-
- /**
- * Set the preferred network type.
- * Used for device configuration by some CDMA operators.
- *
- * @param networkType the preferred network type, defined in RILConstants.java.
- * @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
@@ -429,3 +321,4 @@
*/
boolean getDataEnabled();
}
+
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 963117c..5dfc318 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -324,6 +324,24 @@
/**
* @hide
+ * Uid of app creating the configuration
+ */
+ public int creatorUid;
+
+ /**
+ * @hide
+ * Uid of last app issuing a connection related command
+ */
+ public int lastConnectUid;
+
+ /**
+ * @hide
+ * Uid of last app modifying the configuration
+ */
+ public int lastUpdateUid;
+
+ /**
+ * @hide
* BSSID list on which this configuration was seen.
* TODO: prevent this list to grow infinitely, age-out the results
*/
@@ -441,10 +459,17 @@
/** @hide
* if this is set, the WifiConfiguration cannot use linkages so as to bump
* it's relative priority.
+ * - status between and 128 indicate various level of blacklisting depending
+ * on the severity or frequency of the connection error
+ * - deleted status indicates that the user is deleting the configuration, and so
+ * although it may have been self added we will not re-self-add it, ignore it,
+ * not return it to applications, and not connect to it
* */
public static final int AUTO_JOIN_TEMPORARY_DISABLED = 1;
/** @hide */
- public static final int AUTO_JOIN_DISABLED_ON_AUTH_FAILURE = 2;
+ public static final int AUTO_JOIN_DISABLED_ON_AUTH_FAILURE = 128;
+ /** @hide */
+ public static final int AUTO_JOIN_DELETED = 200;
/**
* @hide
@@ -453,11 +478,29 @@
/**
* Set if the configuration was self added by the framework
+ * This boolean is cleared if we get a connect/save/ update or
+ * any wifiManager command that indicate the user interacted with the configuration
+ * since we will now consider that the configuration belong to him.
* @hide
*/
public boolean selfAdded;
/**
+ * Set if the configuration was self added by the framework
+ * This boolean is set once and never cleared. It is used
+ * so as we never loose track of who created the
+ * configuration in the first place.
+ * @hide
+ */
+ public boolean didSelfAdd;
+
+ /**
+ * peer WifiConfiguration this WifiConfiguration was added for
+ * @hide
+ */
+ public String peerWifiConfiguration;
+
+ /**
* @hide
* Indicate that a WifiConfiguration is temporary and should not be saved
* nor considered by AutoJoin.
@@ -513,6 +556,7 @@
enterpriseConfig = new WifiEnterpriseConfig();
autoJoinStatus = AUTO_JOIN_ENABLED;
selfAdded = false;
+ didSelfAdd = false;
ephemeral = false;
mIpConfiguration = new IpConfiguration();
}
@@ -650,6 +694,10 @@
sbuf.append(mIpConfiguration.toString());
+ if (selfAdded) sbuf.append("selfAdded");
+ if (creatorUid != 0) sbuf.append("uid=" + Integer.toString(creatorUid));
+
+
return sbuf.toString();
}
@@ -883,6 +931,7 @@
networkId = source.networkId;
status = source.status;
disableReason = source.disableReason;
+ disableReason = source.disableReason;
SSID = source.SSID;
BSSID = source.BSSID;
FQDN = source.FQDN;
@@ -933,6 +982,11 @@
}
lastFailure = source.lastFailure;
+ didSelfAdd = source.didSelfAdd;
+ lastConnectUid = source.lastConnectUid;
+ lastUpdateUid = source.lastUpdateUid;
+ creatorUid = source.creatorUid;
+ peerWifiConfiguration = source.peerWifiConfiguration;
}
}
@@ -972,6 +1026,10 @@
dest.writeString(defaultGwMacAddress);
dest.writeInt(autoJoinStatus);
dest.writeInt(selfAdded ? 1 : 0);
+ dest.writeInt(didSelfAdd ? 1 : 0);
+ dest.writeInt(creatorUid);
+ dest.writeInt(lastConnectUid);
+ dest.writeInt(lastUpdateUid);
/*
TODO: should we write the cache results to the parcel?
if (scanResultCache != null) {
@@ -1017,6 +1075,10 @@
config.defaultGwMacAddress = in.readString();
config.autoJoinStatus = in.readInt();
config.selfAdded = in.readInt() != 0;
+ config.didSelfAdd = in.readInt() != 0;
+ config.creatorUid = in.readInt();
+ config.lastConnectUid = in.readInt();
+ config.lastUpdateUid = in.readInt();
/*
TODO: should we write the cache results to the parcel?
boolean done = false;