Merge "Fix AccessibilityNode's isVisibleToUser behavior." into lmp-dev
diff --git a/api/current.txt b/api/current.txt
index 5e14236..5607d08 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -3915,6 +3915,7 @@
field public static final int MODE_IGNORED = 1; // 0x1
field public static final java.lang.String OPSTR_COARSE_LOCATION = "android:coarse_location";
field public static final java.lang.String OPSTR_FINE_LOCATION = "android:fine_location";
+ field public static final java.lang.String OPSTR_GET_USAGE_STATS = "android:get_usage_stats";
field public static final java.lang.String OPSTR_MONITOR_HIGH_POWER_LOCATION = "android:monitor_location_high_power";
field public static final java.lang.String OPSTR_MONITOR_LOCATION = "android:monitor_location";
}
@@ -17950,23 +17951,6 @@
enum_constant public static final android.net.wifi.SupplicantState UNINITIALIZED;
}
- public class WifiAdapter implements android.os.Parcelable {
- method public int describeContents();
- method public java.lang.String getName();
- method public boolean is5GHzBandSupported();
- method public boolean isDeviceToApRttSupported();
- method public boolean isDeviceToDeviceRttSupported();
- method public boolean isEnhancedPowerReportingSupported();
- method public boolean isOffChannelTdlsSupported();
- method public boolean isP2pSupported();
- method public boolean isPasspointSupported();
- method public boolean isPortableHotspotSupported();
- method public boolean isPreferredNetworkOffloadSupported();
- method public boolean isTdlsSupported();
- method public boolean isWifiScannerSupported();
- method public void writeToParcel(android.os.Parcel, int);
- }
-
public class WifiConfiguration implements android.os.Parcelable {
ctor public WifiConfiguration();
method public int describeContents();
@@ -18100,7 +18084,7 @@
public class WifiManager {
method public int addNetwork(android.net.wifi.WifiConfiguration);
method public static int calculateSignalLevel(int, int);
- method public void cancelWps(android.net.wifi.WifiManager.ActionListener);
+ method public void cancelWps(android.net.wifi.WifiManager.WpsCallback);
method public static int compareSignalLevel(int, int);
method public android.net.wifi.WifiManager.MulticastLock createMulticastLock(java.lang.String);
method public android.net.wifi.WifiManager.WifiLock createWifiLock(int, java.lang.String);
@@ -18108,13 +18092,18 @@
method public boolean disableNetwork(int);
method public boolean disconnect();
method public boolean enableNetwork(int, boolean);
- method public java.util.List<android.net.wifi.WifiAdapter> getAdapters();
method public java.util.List<android.net.wifi.WifiConfiguration> getConfiguredNetworks();
method public android.net.wifi.WifiInfo getConnectionInfo();
method public android.net.DhcpInfo getDhcpInfo();
method public java.util.List<android.net.wifi.ScanResult> getScanResults();
method public int getWifiState();
+ method public boolean is5GHzBandSupported();
+ method public boolean isDeviceToApRttSupported();
+ method public boolean isEnhancedPowerReportingSupported();
+ method public boolean isP2pSupported();
+ method public boolean isPreferredNetworkOffloadSupported();
method public boolean isScanAlwaysAvailable();
+ method public boolean isTdlsSupported();
method public boolean isWifiEnabled();
method public boolean pingSupplicant();
method public boolean reassociate();
@@ -18125,12 +18114,10 @@
method public void setTdlsEnabledWithMacAddress(java.lang.String, boolean);
method public boolean setWifiEnabled(boolean);
method public boolean startScan();
- method public void startWps(android.net.wifi.WpsInfo, android.net.wifi.WifiManager.WpsListener);
+ method public void startWps(android.net.wifi.WpsInfo, android.net.wifi.WifiManager.WpsCallback);
method public int updateNetwork(android.net.wifi.WifiConfiguration);
field public static final java.lang.String ACTION_PICK_WIFI_NETWORK = "android.net.wifi.PICK_WIFI_NETWORK";
field public static final java.lang.String ACTION_REQUEST_SCAN_ALWAYS_AVAILABLE = "android.net.wifi.action.REQUEST_SCAN_ALWAYS_AVAILABLE";
- field public static final int BUSY = 2; // 0x2
- field public static final int ERROR = 0; // 0x0
field public static final int ERROR_AUTHENTICATING = 1; // 0x1
field public static final java.lang.String EXTRA_BSSID = "bssid";
field public static final java.lang.String EXTRA_NETWORK_INFO = "networkInfo";
@@ -18141,8 +18128,6 @@
field public static final java.lang.String EXTRA_SUPPLICANT_ERROR = "supplicantError";
field public static final java.lang.String EXTRA_WIFI_INFO = "wifiInfo";
field public static final java.lang.String EXTRA_WIFI_STATE = "wifi_state";
- field public static final int INVALID_ARGS = 8; // 0x8
- field public static final int IN_PROGRESS = 1; // 0x1
field public static final java.lang.String NETWORK_IDS_CHANGED_ACTION = "android.net.wifi.NETWORK_IDS_CHANGED";
field public static final java.lang.String NETWORK_STATE_CHANGED_ACTION = "android.net.wifi.STATE_CHANGE";
field public static final java.lang.String RSSI_CHANGED_ACTION = "android.net.wifi.RSSI_CHANGED";
@@ -18165,11 +18150,6 @@
field public static final int WPS_WEP_PROHIBITED = 4; // 0x4
}
- public static abstract interface WifiManager.ActionListener {
- method public abstract void onFailure(int);
- method public abstract void onSuccess();
- }
-
public class WifiManager.MulticastLock {
method public void acquire();
method public boolean isHeld();
@@ -18185,10 +18165,11 @@
method public void setWorkSource(android.os.WorkSource);
}
- public static abstract interface WifiManager.WpsListener {
- method public abstract void onCompletion();
- method public abstract void onFailure(int);
- method public abstract void onStartSuccess(java.lang.String);
+ public static abstract class WifiManager.WpsCallback {
+ ctor public WifiManager.WpsCallback();
+ method public abstract void onFailed(int);
+ method public abstract void onStarted(java.lang.String);
+ method public abstract void onSucceeded();
}
public class WpsInfo implements android.os.Parcelable {
@@ -28700,44 +28681,6 @@
field public static int STATUS_UNKNOWN_ERROR;
}
- public class MessagingConfigurationManager {
- method public boolean getCarrierConfigBoolean(java.lang.String, boolean);
- method public boolean getCarrierConfigBoolean(long, java.lang.String, boolean);
- method public int getCarrierConfigInt(java.lang.String, int);
- method public int getCarrierConfigInt(long, java.lang.String, int);
- method public java.lang.String getCarrierConfigString(java.lang.String, java.lang.String);
- method public java.lang.String getCarrierConfigString(long, java.lang.String, java.lang.String);
- method public static android.telephony.MessagingConfigurationManager getDefault();
- field public static final java.lang.String CONF_ALIAS_ENABLED = "aliasEnabled";
- field public static final java.lang.String CONF_ALIAS_MAX_CHARS = "aliasMaxChars";
- field public static final java.lang.String CONF_ALIAS_MIN_CHARS = "aliasMinChars";
- field public static final java.lang.String CONF_ALLOW_ATTACH_AUDIO = "allowAttachAudio";
- field public static final java.lang.String CONF_APPEND_TRANSACTION_ID = "enabledTransID";
- field public static final java.lang.String CONF_EMAIL_GATEWAY_NUMBER = "emailGatewayNumber";
- field public static final java.lang.String CONF_HTTP_PARAMS = "httpParams";
- field public static final java.lang.String CONF_HTTP_SOCKET_TIMEOUT = "httpSocketTimeout";
- field public static final java.lang.String CONF_MAX_IMAGE_HEIGHT = "maxImageHeight";
- field public static final java.lang.String CONF_MAX_IMAGE_WIDTH = "maxImageWidth";
- field public static final java.lang.String CONF_MAX_MESSAGE_SIZE = "maxMessageSize";
- field public static final java.lang.String CONF_MESSAGE_TEXT_MAX_SIZE = "maxMessageTextSize";
- field public static final java.lang.String CONF_MMS_DELIVERY_REPORT_ENABLED = "enableMMSDeliveryReports";
- field public static final java.lang.String CONF_MMS_ENABLED = "enabledMMS";
- field public static final java.lang.String CONF_MMS_READ_REPORT_ENABLED = "enableMMSReadReports";
- field public static final java.lang.String CONF_MULTIPART_SMS_ENABLED = "enableMultipartSMS";
- field public static final java.lang.String CONF_NAI_SUFFIX = "naiSuffix";
- field public static final java.lang.String CONF_NOTIFY_WAP_MMSC_ENABLED = "enabledNotifyWapMMSC";
- field public static final java.lang.String CONF_RECIPIENT_LIMIT = "recipientLimit";
- field public static final java.lang.String CONF_SEND_MULTIPART_SMS_AS_SEPARATE_MESSAGES = "sendMultipartSmsAsSeparateMessages";
- field public static final java.lang.String CONF_SMS_DELIVERY_REPORT_ENABLED = "enableSMSDeliveryReports";
- field public static final java.lang.String CONF_SMS_TO_MMS_TEXT_LENGTH_THRESHOLD = "smsToMmsTextLengthThreshold";
- field public static final java.lang.String CONF_SMS_TO_MMS_TEXT_THRESHOLD = "smsToMmsTextThreshold";
- field public static final java.lang.String CONF_SUBJECT_MAX_LENGTH = "maxSubjectLength";
- field public static final java.lang.String CONF_SUPPORT_MMS_CONTENT_DISPOSITION = "supportMmsContentDisposition";
- field public static final java.lang.String CONF_UA_PROF_TAG_NAME = "uaProfTagName";
- field public static final java.lang.String CONF_UA_PROF_URL = "uaProfUrl";
- field public static final java.lang.String CONF_USER_AGENT = "userAgent";
- }
-
public class NeighboringCellInfo implements android.os.Parcelable {
ctor public deprecated NeighboringCellInfo();
ctor public deprecated NeighboringCellInfo(int, int);
@@ -28887,28 +28830,54 @@
method public boolean deleteStoredMessage(android.net.Uri);
method public java.util.ArrayList<java.lang.String> divideMessage(java.lang.String);
method public void downloadMultimediaMessage(java.lang.String, android.content.ContentValues, android.app.PendingIntent);
- method public void downloadMultimediaMessage(long, java.lang.String, android.content.ContentValues, android.app.PendingIntent);
method public boolean getAutoPersisting();
+ method public android.os.Bundle getCarrierConfigValues();
method public static android.telephony.SmsManager getDefault();
+ method public static android.telephony.SmsManager getSmsManagerForSubId(long);
+ method public long getSubId();
method public android.net.Uri importMultimediaMessage(byte[], java.lang.String, long, boolean, boolean);
method public android.net.Uri importTextMessage(java.lang.String, int, java.lang.String, long, boolean, boolean);
method public void injectSmsPdu(byte[], java.lang.String, android.app.PendingIntent);
method public void sendDataMessage(java.lang.String, java.lang.String, short, byte[], android.app.PendingIntent, android.app.PendingIntent);
method public void sendMultimediaMessage(byte[], java.lang.String, android.content.ContentValues, android.app.PendingIntent);
- method public void sendMultimediaMessage(long, byte[], java.lang.String, android.content.ContentValues, android.app.PendingIntent);
method public void sendMultipartTextMessage(java.lang.String, java.lang.String, java.util.ArrayList<java.lang.String>, java.util.ArrayList<android.app.PendingIntent>, java.util.ArrayList<android.app.PendingIntent>);
method public void sendStoredMultimediaMessage(android.net.Uri, android.content.ContentValues, android.app.PendingIntent);
- method public void sendStoredMultimediaMessage(long, android.net.Uri, android.content.ContentValues, android.app.PendingIntent);
method public void sendStoredMultipartTextMessage(android.net.Uri, java.lang.String, java.util.ArrayList<android.app.PendingIntent>, java.util.ArrayList<android.app.PendingIntent>);
- method public void sendStoredMultipartTextMessage(long, android.net.Uri, java.lang.String, java.util.ArrayList<android.app.PendingIntent>, java.util.ArrayList<android.app.PendingIntent>);
method public void sendStoredTextMessage(android.net.Uri, java.lang.String, android.app.PendingIntent, android.app.PendingIntent);
- method public void sendStoredTextMessage(long, android.net.Uri, java.lang.String, android.app.PendingIntent, android.app.PendingIntent);
method public void sendTextMessage(java.lang.String, java.lang.String, java.lang.String, android.app.PendingIntent, android.app.PendingIntent);
method public void setAutoPersisting(boolean);
method public void updateMmsDownloadStatus(int, byte[]);
method public void updateMmsSendStatus(int, boolean);
method public void updateSmsSendStatus(int, boolean);
method public boolean updateStoredMessageStatus(android.net.Uri, android.content.ContentValues);
+ field public static final java.lang.String MMS_CONFIG_ALIAS_ENABLED = "aliasEnabled";
+ field public static final java.lang.String MMS_CONFIG_ALIAS_MAX_CHARS = "aliasMaxChars";
+ field public static final java.lang.String MMS_CONFIG_ALIAS_MIN_CHARS = "aliasMinChars";
+ field public static final java.lang.String MMS_CONFIG_ALLOW_ATTACH_AUDIO = "allowAttachAudio";
+ field public static final java.lang.String MMS_CONFIG_APPEND_TRANSACTION_ID = "enabledTransID";
+ field public static final java.lang.String MMS_CONFIG_EMAIL_GATEWAY_NUMBER = "emailGatewayNumber";
+ field public static final java.lang.String MMS_CONFIG_HTTP_PARAMS = "httpParams";
+ field public static final java.lang.String MMS_CONFIG_HTTP_SOCKET_TIMEOUT = "httpSocketTimeout";
+ field public static final java.lang.String MMS_CONFIG_MAX_IMAGE_HEIGHT = "maxImageHeight";
+ field public static final java.lang.String MMS_CONFIG_MAX_IMAGE_WIDTH = "maxImageWidth";
+ field public static final java.lang.String MMS_CONFIG_MAX_MESSAGE_SIZE = "maxMessageSize";
+ field public static final java.lang.String MMS_CONFIG_MESSAGE_TEXT_MAX_SIZE = "maxMessageTextSize";
+ field public static final java.lang.String MMS_CONFIG_MMS_DELIVERY_REPORT_ENABLED = "enableMMSDeliveryReports";
+ field public static final java.lang.String MMS_CONFIG_MMS_ENABLED = "enabledMMS";
+ field public static final java.lang.String MMS_CONFIG_MMS_READ_REPORT_ENABLED = "enableMMSReadReports";
+ field public static final java.lang.String MMS_CONFIG_MULTIPART_SMS_ENABLED = "enableMultipartSMS";
+ field public static final java.lang.String MMS_CONFIG_NAI_SUFFIX = "naiSuffix";
+ field public static final java.lang.String MMS_CONFIG_NOTIFY_WAP_MMSC_ENABLED = "enabledNotifyWapMMSC";
+ field public static final java.lang.String MMS_CONFIG_RECIPIENT_LIMIT = "recipientLimit";
+ field public static final java.lang.String MMS_CONFIG_SEND_MULTIPART_SMS_AS_SEPARATE_MESSAGES = "sendMultipartSmsAsSeparateMessages";
+ field public static final java.lang.String MMS_CONFIG_SMS_DELIVERY_REPORT_ENABLED = "enableSMSDeliveryReports";
+ field public static final java.lang.String MMS_CONFIG_SMS_TO_MMS_TEXT_LENGTH_THRESHOLD = "smsToMmsTextLengthThreshold";
+ field public static final java.lang.String MMS_CONFIG_SMS_TO_MMS_TEXT_THRESHOLD = "smsToMmsTextThreshold";
+ field public static final java.lang.String MMS_CONFIG_SUBJECT_MAX_LENGTH = "maxSubjectLength";
+ field public static final java.lang.String MMS_CONFIG_SUPPORT_MMS_CONTENT_DISPOSITION = "supportMmsContentDisposition";
+ field public static final java.lang.String MMS_CONFIG_UA_PROF_TAG_NAME = "uaProfTagName";
+ field public static final java.lang.String MMS_CONFIG_UA_PROF_URL = "uaProfUrl";
+ field public static final java.lang.String MMS_CONFIG_USER_AGENT = "userAgent";
field public static final java.lang.String MESSAGE_STATUS_READ = "read";
field public static final java.lang.String MESSAGE_STATUS_SEEN = "seen";
field public static final int MMS_ERROR_HTTP_FAILURE = 4; // 0x4
@@ -35868,20 +35837,16 @@
method public int getComposingTextStart();
method public float getInsertionMarkerBaseline();
method public float getInsertionMarkerBottom();
+ method public int getInsertionMarkerFlags();
method public float getInsertionMarkerHorizontal();
method public float getInsertionMarkerTop();
method public android.graphics.Matrix getMatrix();
method public int getSelectionEnd();
method public int getSelectionStart();
- method public boolean isInsertionMarkerClipped();
method public void writeToParcel(android.os.Parcel, int);
- field public static final int CHARACTER_RECT_TYPE_FULLY_VISIBLE = 1; // 0x1
- field public static final int CHARACTER_RECT_TYPE_INVISIBLE = 3; // 0x3
- field public static final int CHARACTER_RECT_TYPE_MASK = 15; // 0xf
- field public static final int CHARACTER_RECT_TYPE_NOT_FEASIBLE = 4; // 0x4
- field public static final int CHARACTER_RECT_TYPE_PARTIALLY_VISIBLE = 2; // 0x2
- field public static final int CHARACTER_RECT_TYPE_UNSPECIFIED = 0; // 0x0
field public static final android.os.Parcelable.Creator CREATOR;
+ field public static final int FLAG_HAS_INVISIBLE_REGION = 2; // 0x2
+ field public static final int FLAG_HAS_VISIBLE_REGION = 1; // 0x1
}
public static final class CursorAnchorInfo.Builder {
@@ -35890,7 +35855,7 @@
method public android.view.inputmethod.CursorAnchorInfo build();
method public void reset();
method public android.view.inputmethod.CursorAnchorInfo.Builder setComposingText(int, java.lang.CharSequence);
- method public android.view.inputmethod.CursorAnchorInfo.Builder setInsertionMarkerLocation(float, float, float, float, boolean);
+ method public android.view.inputmethod.CursorAnchorInfo.Builder setInsertionMarkerLocation(float, float, float, float, int);
method public android.view.inputmethod.CursorAnchorInfo.Builder setMatrix(android.graphics.Matrix);
method public android.view.inputmethod.CursorAnchorInfo.Builder setSelectionRange(int, int);
}
diff --git a/api/removed.txt b/api/removed.txt
index 8915fc3..36f8920 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -48,6 +48,24 @@
}
+package android.view.inputmethod {
+
+ public final class CursorAnchorInfo implements android.os.Parcelable {
+ method public boolean isInsertionMarkerClipped();
+ field public static final int CHARACTER_RECT_TYPE_FULLY_VISIBLE = 1; // 0x1
+ field public static final int CHARACTER_RECT_TYPE_INVISIBLE = 3; // 0x3
+ field public static final int CHARACTER_RECT_TYPE_MASK = 15; // 0xf
+ field public static final int CHARACTER_RECT_TYPE_NOT_FEASIBLE = 4; // 0x4
+ field public static final int CHARACTER_RECT_TYPE_PARTIALLY_VISIBLE = 2; // 0x2
+ field public static final int CHARACTER_RECT_TYPE_UNSPECIFIED = 0; // 0x0
+ }
+
+ public static final class CursorAnchorInfo.Builder {
+ method public android.view.inputmethod.CursorAnchorInfo.Builder setInsertionMarkerLocation(float, float, float, float, boolean);
+ }
+
+}
+
package com.android.internal {
public static final class R.attr {
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index 66928ca..ba9c9d6 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -220,6 +220,9 @@
/** Continually monitoring location data with a relatively high power request. */
public static final String OPSTR_MONITOR_HIGH_POWER_LOCATION
= "android:monitor_location_high_power";
+ /** Access to {@link android.app.usage.UsageStatsManager}. */
+ public static final String OPSTR_GET_USAGE_STATS
+ = "android:get_usage_stats";
/** Activate a VPN connection without user intervention. @hide */
@SystemApi
public static final String OPSTR_ACTIVATE_VPN = "android:activate_vpn";
@@ -331,7 +334,7 @@
null,
OPSTR_MONITOR_LOCATION,
OPSTR_MONITOR_HIGH_POWER_LOCATION,
- null,
+ OPSTR_GET_USAGE_STATS,
null,
null,
null,
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index 4bfef41..3c219fd 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -685,6 +685,23 @@
}
/**
+ * Returns the {@link Network} object currently serving a given type, or
+ * null if the given type is not connected.
+ *
+ * <p>This method requires the caller to hold the permission
+ * {@link android.Manifest.permission#ACCESS_NETWORK_STATE}.
+ *
+ * @hide
+ */
+ public Network getNetworkForType(int networkType) {
+ try {
+ return mService.getNetworkForType(networkType);
+ } catch (RemoteException e) {
+ return null;
+ }
+ }
+
+ /**
* Returns an array of all {@link Network} currently tracked by the
* framework.
*
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index b2fc3be..974c4cd 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -48,6 +48,7 @@
NetworkInfo getNetworkInfo(int networkType);
NetworkInfo getNetworkInfoForNetwork(in Network network);
NetworkInfo[] getAllNetworkInfo();
+ Network getNetworkForType(int networkType);
Network[] getAllNetworks();
NetworkInfo getProvisioningOrActiveNetworkInfo();
diff --git a/core/java/android/net/Network.java b/core/java/android/net/Network.java
index d2a4728..e686be7 100644
--- a/core/java/android/net/Network.java
+++ b/core/java/android/net/Network.java
@@ -35,6 +35,7 @@
import java.util.concurrent.atomic.AtomicReference;
import javax.net.SocketFactory;
+import com.android.okhttp.ConnectionPool;
import com.android.okhttp.HostResolver;
import com.android.okhttp.OkHttpClient;
@@ -60,6 +61,17 @@
private volatile OkHttpClient mOkHttpClient = null;
private Object mLock = new Object();
+ // Default connection pool values. These are evaluated at startup, just
+ // like the OkHttp code. Also like the OkHttp code, we will throw parse
+ // exceptions at class loading time if the properties are set but are not
+ // valid integers.
+ private static final boolean httpKeepAlive =
+ Boolean.parseBoolean(System.getProperty("http.keepAlive", "true"));
+ private static final int httpMaxConnections =
+ httpKeepAlive ? Integer.parseInt(System.getProperty("http.maxConnections", "5")) : 0;
+ private static final long httpKeepAliveDurationMs =
+ Long.parseLong(System.getProperty("http.keepAliveDuration", "300000")); // 5 minutes.
+
/**
* @hide
*/
@@ -183,6 +195,20 @@
return mNetworkBoundSocketFactory;
}
+ // TODO: This creates an OkHttpClient with its own connection pool for
+ // every Network object, instead of one for every NetId. This is
+ // suboptimal, because an app could potentially have more than one
+ // Network object for the same NetId, causing increased memory footprint
+ // and performance penalties due to lack of connection reuse (connection
+ // setup time, congestion window growth time, etc.).
+ //
+ // Instead, investigate only having one OkHttpClient for every NetId,
+ // perhaps by using a static HashMap of NetIds to OkHttpClient objects. The
+ // tricky part is deciding when to remove an OkHttpClient; a WeakHashMap
+ // shouldn't be used because whether a Network is referenced doesn't
+ // correlate with whether a new Network will be instantiated in the near
+ // future with the same NetID. A good solution would involve purging empty
+ // (or when all connections are timed out) ConnectionPools.
private void maybeInitHttpClient() {
if (mOkHttpClient == null) {
synchronized (mLock) {
@@ -193,9 +219,12 @@
return Network.this.getAllByName(host);
}
};
+ ConnectionPool pool = new ConnectionPool(httpMaxConnections,
+ httpKeepAliveDurationMs);
mOkHttpClient = new OkHttpClient()
.setSocketFactory(getSocketFactory())
- .setHostResolver(hostResolver);
+ .setHostResolver(hostResolver)
+ .setConnectionPool(pool);
}
}
}
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index 6d4a302..b3e28ea 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -19,6 +19,7 @@
import android.net.InterfaceConfiguration;
import android.net.INetworkManagementEventObserver;
+import android.net.Network;
import android.net.NetworkStats;
import android.net.RouteInfo;
import android.net.UidRange;
@@ -164,10 +165,10 @@
/**
* Sets the list of DNS forwarders (in order of priority)
*/
- void setDnsForwarders(in String[] dns);
+ void setDnsForwarders(in Network network, in String[] dns);
/**
- * Returns the list of DNS fowarders (in order of priority)
+ * Returns the list of DNS forwarders (in order of priority)
*/
String[] getDnsForwarders();
diff --git a/core/java/android/preference/CheckBoxPreference.java b/core/java/android/preference/CheckBoxPreference.java
index 1ce98b8..fee3f0f1 100644
--- a/core/java/android/preference/CheckBoxPreference.java
+++ b/core/java/android/preference/CheckBoxPreference.java
@@ -66,7 +66,6 @@
View checkboxView = view.findViewById(com.android.internal.R.id.checkbox);
if (checkboxView != null && checkboxView instanceof Checkable) {
((Checkable) checkboxView).setChecked(mChecked);
- sendAccessibilityEvent(checkboxView);
}
syncSummaryView(view);
diff --git a/core/java/android/preference/SwitchPreference.java b/core/java/android/preference/SwitchPreference.java
index 46be928..53b5aad 100644
--- a/core/java/android/preference/SwitchPreference.java
+++ b/core/java/android/preference/SwitchPreference.java
@@ -130,8 +130,6 @@
((Checkable) checkableView).setChecked(mChecked);
- sendAccessibilityEvent(checkableView);
-
if (checkableView instanceof Switch) {
final Switch switchView = (Switch) checkableView;
switchView.setTextOn(mSwitchOn);
diff --git a/core/java/android/preference/TwoStatePreference.java b/core/java/android/preference/TwoStatePreference.java
index 6f8be1f..3823b27 100644
--- a/core/java/android/preference/TwoStatePreference.java
+++ b/core/java/android/preference/TwoStatePreference.java
@@ -24,8 +24,6 @@
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
-import android.view.accessibility.AccessibilityEvent;
-import android.view.accessibility.AccessibilityManager;
import android.widget.TextView;
/**
@@ -39,7 +37,6 @@
private CharSequence mSummaryOff;
boolean mChecked;
private boolean mCheckedSet;
- private boolean mSendClickAccessibilityEvent;
private boolean mDisableDependentsState;
public TwoStatePreference(
@@ -63,15 +60,10 @@
protected void onClick() {
super.onClick();
- boolean newValue = !isChecked();
-
- mSendClickAccessibilityEvent = true;
-
- if (!callChangeListener(newValue)) {
- return;
+ final boolean newValue = !isChecked();
+ if (callChangeListener(newValue)) {
+ setChecked(newValue);
}
-
- setChecked(newValue);
}
/**
@@ -196,21 +188,6 @@
: (Boolean) defaultValue);
}
- void sendAccessibilityEvent(View view) {
- // Since the view is still not attached we create, populate,
- // and send the event directly since we do not know when it
- // will be attached and posting commands is not as clean.
- AccessibilityManager accessibilityManager = AccessibilityManager.getInstance(getContext());
- if (mSendClickAccessibilityEvent && accessibilityManager.isEnabled()) {
- AccessibilityEvent event = AccessibilityEvent.obtain();
- event.setEventType(AccessibilityEvent.TYPE_VIEW_CLICKED);
- view.onInitializeAccessibilityEvent(event);
- view.dispatchPopulateAccessibilityEvent(event);
- accessibilityManager.sendAccessibilityEvent(event);
- }
- mSendClickAccessibilityEvent = false;
- }
-
/**
* Sync a summary view contained within view's subhierarchy with the correct summary text.
* @param view View where a summary should be located
diff --git a/core/java/android/view/PointerIcon.java b/core/java/android/view/PointerIcon.java
index 063a08d..7dcad68 100644
--- a/core/java/android/view/PointerIcon.java
+++ b/core/java/android/view/PointerIcon.java
@@ -149,9 +149,9 @@
* Creates a custom pointer from the given bitmap and hotspot information.
*
* @param bitmap The bitmap for the icon.
- * @param hotspotX The X offset of the pointer icon hotspot in the bitmap.
+ * @param hotSpotX The X offset of the pointer icon hotspot in the bitmap.
* Must be within the [0, bitmap.getWidth()) range.
- * @param hotspotY The Y offset of the pointer icon hotspot in the bitmap.
+ * @param hotSpotY The Y offset of the pointer icon hotspot in the bitmap.
* Must be within the [0, bitmap.getHeight()) range.
* @return A pointer icon for this bitmap.
*
@@ -374,18 +374,18 @@
}
private void loadResource(Context context, Resources resources, int resourceId) {
- XmlResourceParser parser = resources.getXml(resourceId);
+ final XmlResourceParser parser = resources.getXml(resourceId);
final int bitmapRes;
final float hotSpotX;
final float hotSpotY;
try {
XmlUtils.beginDocument(parser, "pointer-icon");
- TypedArray a = resources.obtainAttributes(
+ final TypedArray a = resources.obtainAttributes(
parser, com.android.internal.R.styleable.PointerIcon);
bitmapRes = a.getResourceId(com.android.internal.R.styleable.PointerIcon_bitmap, 0);
- hotSpotX = a.getFloat(com.android.internal.R.styleable.PointerIcon_hotSpotX, 0);
- hotSpotY = a.getFloat(com.android.internal.R.styleable.PointerIcon_hotSpotY, 0);
+ hotSpotX = a.getDimension(com.android.internal.R.styleable.PointerIcon_hotSpotX, 0);
+ hotSpotY = a.getDimension(com.android.internal.R.styleable.PointerIcon_hotSpotY, 0);
a.recycle();
} catch (Exception ex) {
throw new IllegalArgumentException("Exception parsing pointer icon resource.", ex);
diff --git a/core/java/android/view/inputmethod/CursorAnchorInfo.java b/core/java/android/view/inputmethod/CursorAnchorInfo.java
index 0492824..fe0f5b9 100644
--- a/core/java/android/view/inputmethod/CursorAnchorInfo.java
+++ b/core/java/android/view/inputmethod/CursorAnchorInfo.java
@@ -45,9 +45,9 @@
private final CharSequence mComposingText;
/**
- * {@code True} if the insertion marker is partially or entirely clipped by other UI elements.
+ * Flags of the insertion marker. See {@link #FLAG_HAS_VISIBLE_REGION} for example.
*/
- private final boolean mInsertionMarkerClipped;
+ private final int mInsertionMarkerFlags;
/**
* Horizontal position of the insertion marker, in the local coordinates that will be
* transformed with the transformation matrix when rendered on the screen. This should be
@@ -90,27 +90,47 @@
*/
private final Matrix mMatrix;
+ /**
+ * Flag for {@link #getInsertionMarkerFlags()} and {@link #getCharacterRectFlags(int)}: the
+ * insertion marker or character bounds have at least one visible region.
+ */
+ public static final int FLAG_HAS_VISIBLE_REGION = 0x01;
+
+ /**
+ * Flag for {@link #getInsertionMarkerFlags()} and {@link #getCharacterRectFlags(int)}: the
+ * insertion marker or character bounds have at least one invisible (clipped) region.
+ */
+ public static final int FLAG_HAS_INVISIBLE_REGION = 0x02;
+
+ /**
+ * @removed
+ */
public static final int CHARACTER_RECT_TYPE_MASK = 0x0f;
/**
* Type for {@link #CHARACTER_RECT_TYPE_MASK}: the editor did not specify any type of this
* character. Editor authors should not use this flag.
+ * @removed
*/
public static final int CHARACTER_RECT_TYPE_UNSPECIFIED = 0;
/**
* Type for {@link #CHARACTER_RECT_TYPE_MASK}: the character is entirely visible.
+ * @removed
*/
public static final int CHARACTER_RECT_TYPE_FULLY_VISIBLE = 1;
/**
* Type for {@link #CHARACTER_RECT_TYPE_MASK}: some area of the character is invisible.
+ * @removed
*/
public static final int CHARACTER_RECT_TYPE_PARTIALLY_VISIBLE = 2;
/**
* Type for {@link #CHARACTER_RECT_TYPE_MASK}: the character is entirely invisible.
+ * @removed
*/
public static final int CHARACTER_RECT_TYPE_INVISIBLE = 3;
/**
* Type for {@link #CHARACTER_RECT_TYPE_MASK}: the editor gave up to calculate the rectangle
* for this character. Input method authors should ignore the returned rectangle.
+ * @removed
*/
public static final int CHARACTER_RECT_TYPE_NOT_FEASIBLE = 4;
@@ -119,7 +139,7 @@
mSelectionEnd = source.readInt();
mComposingTextStart = source.readInt();
mComposingText = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
- mInsertionMarkerClipped = (source.readInt() != 0);
+ mInsertionMarkerFlags = source.readInt();
mInsertionMarkerHorizontal = source.readFloat();
mInsertionMarkerTop = source.readFloat();
mInsertionMarkerBaseline = source.readFloat();
@@ -141,7 +161,7 @@
dest.writeInt(mSelectionEnd);
dest.writeInt(mComposingTextStart);
TextUtils.writeToParcel(mComposingText, dest, flags);
- dest.writeInt(mInsertionMarkerClipped ? 1 : 0);
+ dest.writeInt(mInsertionMarkerFlags);
dest.writeFloat(mInsertionMarkerHorizontal);
dest.writeFloat(mInsertionMarkerTop);
dest.writeFloat(mInsertionMarkerBaseline);
@@ -159,7 +179,7 @@
+ mInsertionMarkerBaseline + mInsertionMarkerBottom;
int hash = floatHash > 0 ? (int) floatHash : (int)(-floatHash);
hash *= 31;
- hash += (mInsertionMarkerClipped ? 2 : 1);
+ hash += mInsertionMarkerFlags;
hash *= 31;
hash += mSelectionStart + mSelectionEnd + mComposingTextStart;
hash *= 31;
@@ -204,7 +224,7 @@
|| !Objects.equals(mComposingText, that.mComposingText)) {
return false;
}
- if (mInsertionMarkerClipped != that.mInsertionMarkerClipped
+ if (mInsertionMarkerFlags != that.mInsertionMarkerFlags
|| !areSameFloatImpl(mInsertionMarkerHorizontal, that.mInsertionMarkerHorizontal)
|| !areSameFloatImpl(mInsertionMarkerTop, that.mInsertionMarkerTop)
|| !areSameFloatImpl(mInsertionMarkerBaseline, that.mInsertionMarkerBaseline)
@@ -225,7 +245,7 @@
return "SelectionInfo{mSelection=" + mSelectionStart + "," + mSelectionEnd
+ " mComposingTextStart=" + mComposingTextStart
+ " mComposingText=" + Objects.toString(mComposingText)
- + " mInsertionMarkerClipped=" + mInsertionMarkerClipped
+ + " mInsertionMarkerFlags=" + mInsertionMarkerFlags
+ " mInsertionMarkerHorizontal=" + mInsertionMarkerHorizontal
+ " mInsertionMarkerTop=" + mInsertionMarkerTop
+ " mInsertionMarkerBaseline=" + mInsertionMarkerBaseline
@@ -272,6 +292,20 @@
private CharSequence mComposingText = null;
/**
+ * @removed
+ */
+ public Builder setInsertionMarkerLocation(final float horizontalPosition,
+ final float lineTop, final float lineBaseline, final float lineBottom,
+ final boolean clipped){
+ mInsertionMarkerHorizontal = horizontalPosition;
+ mInsertionMarkerTop = lineTop;
+ mInsertionMarkerBaseline = lineBaseline;
+ mInsertionMarkerBottom = lineBottom;
+ mInsertionMarkerFlags = clipped ? FLAG_HAS_INVISIBLE_REGION : 0;
+ return this;
+ }
+
+ /**
* Sets the location of the text insertion point (zero width cursor) as a rectangle in
* local coordinates. Calling this can be skipped when there is no text insertion point;
* however if there is an insertion point, editors must call this method.
@@ -288,24 +322,24 @@
* @param lineBottom vertical position of the insertion marker, in the local coordinates
* that will be transformed with the transformation matrix when rendered on the screen. This
* should be calculated or compatible with {@link Layout#getLineBottom(int)}.
- * @param clipped {@code true} is the insertion marker is partially or entierly clipped by
- * other UI elements.
+ * @param flags flags of the insertion marker. See {@link #FLAG_HAS_VISIBLE_REGION} for
+ * example.
*/
public Builder setInsertionMarkerLocation(final float horizontalPosition,
final float lineTop, final float lineBaseline, final float lineBottom,
- final boolean clipped){
+ final int flags){
mInsertionMarkerHorizontal = horizontalPosition;
mInsertionMarkerTop = lineTop;
mInsertionMarkerBaseline = lineBaseline;
mInsertionMarkerBottom = lineBottom;
- mInsertionMarkerClipped = clipped;
+ mInsertionMarkerFlags = flags;
return this;
}
private float mInsertionMarkerHorizontal = Float.NaN;
private float mInsertionMarkerTop = Float.NaN;
private float mInsertionMarkerBaseline = Float.NaN;
private float mInsertionMarkerBottom = Float.NaN;
- private boolean mInsertionMarkerClipped = false;
+ private int mInsertionMarkerFlags = 0;
/**
* Adds the bounding box of the character specified with the index.
@@ -320,8 +354,8 @@
* coordinates, that is, right edge for LTR text and left edge for RTL text.
* @param trailingEdgeY y coordinate of the trailing edge of the character in local
* coordinates.
- * @param flags type and flags for this character. See
- * {@link #CHARACTER_RECT_TYPE_FULLY_VISIBLE} for example.
+ * @param flags flags for this character rect. See {@link #FLAG_HAS_VISIBLE_REGION} for
+ * example.
* @throws IllegalArgumentException If the index is a negative value, or not greater than
* all of the previously called indices.
*/
@@ -331,11 +365,6 @@
if (index < 0) {
throw new IllegalArgumentException("index must not be a negative integer.");
}
- final int type = flags & CHARACTER_RECT_TYPE_MASK;
- if (type == CHARACTER_RECT_TYPE_UNSPECIFIED) {
- throw new IllegalArgumentException("Type except for "
- + "CHARACTER_RECT_TYPE_UNSPECIFIED must be specified.");
- }
if (mCharacterRectBuilder == null) {
mCharacterRectBuilder = new SparseRectFArrayBuilder();
}
@@ -388,7 +417,7 @@
mSelectionEnd = -1;
mComposingTextStart = -1;
mComposingText = null;
- mInsertionMarkerClipped = false;
+ mInsertionMarkerFlags = 0;
mInsertionMarkerHorizontal = Float.NaN;
mInsertionMarkerTop = Float.NaN;
mInsertionMarkerBaseline = Float.NaN;
@@ -406,7 +435,7 @@
mSelectionEnd = builder.mSelectionEnd;
mComposingTextStart = builder.mComposingTextStart;
mComposingText = builder.mComposingText;
- mInsertionMarkerClipped = builder.mInsertionMarkerClipped;
+ mInsertionMarkerFlags = builder.mInsertionMarkerFlags;
mInsertionMarkerHorizontal = builder.mInsertionMarkerHorizontal;
mInsertionMarkerTop = builder.mInsertionMarkerTop;
mInsertionMarkerBaseline = builder.mInsertionMarkerBaseline;
@@ -449,11 +478,20 @@
}
/**
+ * Returns the flag of the insertion marker.
+ * @return the flag of the insertion marker. {@code 0} if no flag is specified.
+ */
+ public int getInsertionMarkerFlags() {
+ return mInsertionMarkerFlags;
+ }
+
+ /**
* Returns the visibility of the insertion marker.
* @return {@code true} if the insertion marker is partially or entirely clipped.
+ * @removed
*/
public boolean isInsertionMarkerClipped() {
- return mInsertionMarkerClipped;
+ return (mInsertionMarkerFlags & FLAG_HAS_VISIBLE_REGION) != 0;
}
/**
@@ -522,17 +560,17 @@
}
/**
- * Returns the flags associated with the character specified with the index.
+ * Returns the flags associated with the character rect specified with the index.
* @param index index of the character in a Java chars.
- * @return {@link #CHARACTER_RECT_TYPE_UNSPECIFIED} if no flag is specified.
+ * @return {@code 0} if no flag is specified.
*/
// TODO: Prepare a document about the expected behavior for surrogate pairs, combining
// characters, and non-graphical chars.
public int getCharacterRectFlags(final int index) {
if (mCharacterRects == null) {
- return CHARACTER_RECT_TYPE_UNSPECIFIED;
+ return 0;
}
- return mCharacterRects.getFlags(index, CHARACTER_RECT_TYPE_UNSPECIFIED);
+ return mCharacterRects.getFlags(index, 0);
}
/**
diff --git a/core/java/android/widget/AdapterView.java b/core/java/android/widget/AdapterView.java
index 1da22ca..b9f891c 100644
--- a/core/java/android/widget/AdapterView.java
+++ b/core/java/android/widget/AdapterView.java
@@ -297,10 +297,10 @@
public boolean performItemClick(View view, int position, long id) {
if (mOnItemClickListener != null) {
playSoundEffect(SoundEffectConstants.CLICK);
+ mOnItemClickListener.onItemClick(this, view, position, id);
if (view != null) {
view.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_CLICKED);
}
- mOnItemClickListener.onItemClick(this, view, position, id);
return true;
}
diff --git a/core/java/android/widget/Editor.java b/core/java/android/widget/Editor.java
index 46b225d..22138d0 100644
--- a/core/java/android/widget/Editor.java
+++ b/core/java/android/widget/Editor.java
@@ -3089,13 +3089,12 @@
final boolean isLeadingEdgeTopVisible = isPositionVisible(leadingEdgeX, top);
final boolean isTrailingEdgeBottomVisible =
isPositionVisible(trailingEdgeX, bottom);
- final int characterRectFlags;
- if (isLeadingEdgeTopVisible && isTrailingEdgeBottomVisible) {
- characterRectFlags = CursorAnchorInfo.CHARACTER_RECT_TYPE_FULLY_VISIBLE;
- } else if (isLeadingEdgeTopVisible || isTrailingEdgeBottomVisible) {
- characterRectFlags = CursorAnchorInfo.CHARACTER_RECT_TYPE_PARTIALLY_VISIBLE;
- } else {
- characterRectFlags = CursorAnchorInfo.CHARACTER_RECT_TYPE_INVISIBLE;
+ int characterRectFlags = 0;
+ if (isLeadingEdgeTopVisible || isTrailingEdgeBottomVisible) {
+ characterRectFlags |= CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION;
+ }
+ if (!isLeadingEdgeTopVisible || !isTrailingEdgeBottomVisible) {
+ characterRectFlags |= CursorAnchorInfo.FLAG_HAS_INVISIBLE_REGION;
}
// Here offset is the index in Java chars.
// TODO: We must have a well-defined specification. For example, how
@@ -3117,11 +3116,19 @@
+ viewportToContentVerticalOffset;
final float insertionMarkerBottom = layout.getLineBottom(line)
+ viewportToContentVerticalOffset;
- // Take TextView's padding and scroll into account.
- final boolean isClipped = !isPositionVisible(insertionMarkerX, insertionMarkerTop)
- || !isPositionVisible(insertionMarkerX, insertionMarkerBottom);
+ final boolean isTopVisible =
+ isPositionVisible(insertionMarkerX, insertionMarkerTop);
+ final boolean isBottomVisible =
+ isPositionVisible(insertionMarkerX, insertionMarkerBottom);
+ int insertionMarkerFlags = 0;
+ if (isTopVisible || isBottomVisible) {
+ insertionMarkerFlags |= CursorAnchorInfo.FLAG_HAS_VISIBLE_REGION;
+ }
+ if (!isTopVisible || !isBottomVisible) {
+ insertionMarkerFlags |= CursorAnchorInfo.FLAG_HAS_INVISIBLE_REGION;
+ }
builder.setInsertionMarkerLocation(insertionMarkerX, insertionMarkerTop,
- insertionMarkerBaseline, insertionMarkerBottom, isClipped);
+ insertionMarkerBaseline, insertionMarkerBottom, insertionMarkerFlags);
}
imm.updateCursorAnchorInfo(mTextView, builder.build());
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 9b3a1e0..3e1b674 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -1861,6 +1861,10 @@
return getCompoundPaddingTop();
}
+ if (mLayout == null) {
+ assumeLayout();
+ }
+
if (mLayout.getLineCount() <= mMaximum) {
return getCompoundPaddingTop();
}
@@ -1894,6 +1898,10 @@
return getCompoundPaddingBottom();
}
+ if (mLayout == null) {
+ assumeLayout();
+ }
+
if (mLayout.getLineCount() <= mMaximum) {
return getCompoundPaddingBottom();
}
diff --git a/core/java/android/widget/Toolbar.java b/core/java/android/widget/Toolbar.java
index ece8aa4..3ba03b8 100644
--- a/core/java/android/widget/Toolbar.java
+++ b/core/java/android/widget/Toolbar.java
@@ -248,11 +248,12 @@
final Drawable navIcon = a.getDrawable(R.styleable.Toolbar_navigationIcon);
if (navIcon != null) {
setNavigationIcon(navIcon);
- final CharSequence navDesc = a.getText(
- R.styleable.Toolbar_navigationContentDescription);
- if (!TextUtils.isEmpty(navDesc)) {
- setNavigationContentDescription(navDesc);
- }
+ }
+
+ final CharSequence navDesc = a.getText(
+ R.styleable.Toolbar_navigationContentDescription);
+ if (!TextUtils.isEmpty(navDesc)) {
+ setNavigationContentDescription(navDesc);
}
a.recycle();
}
diff --git a/core/java/com/android/internal/app/ToolbarActionBar.java b/core/java/com/android/internal/app/ToolbarActionBar.java
index abe8a9f..6f1c7ec 100644
--- a/core/java/com/android/internal/app/ToolbarActionBar.java
+++ b/core/java/com/android/internal/app/ToolbarActionBar.java
@@ -22,6 +22,7 @@
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.drawable.Drawable;
+import android.text.TextUtils;
import android.view.ActionMode;
import android.view.KeyEvent;
import android.view.LayoutInflater;
@@ -32,6 +33,7 @@
import android.view.WindowCallbackWrapper;
import android.widget.SpinnerAdapter;
import android.widget.Toolbar;
+import com.android.internal.R;
import com.android.internal.view.menu.MenuBuilder;
import com.android.internal.widget.DecorToolbar;
import com.android.internal.widget.ToolbarWidgetWrapper;
@@ -44,6 +46,8 @@
private boolean mToolbarMenuPrepared;
private Window.Callback mWindowCallback;
+ private CharSequence mHomeDescription;
+
private boolean mLastMenuVisibility;
private ArrayList<OnMenuVisibilityListener> mMenuVisibilityListeners =
new ArrayList<OnMenuVisibilityListener>();
@@ -70,6 +74,8 @@
mDecorToolbar.setWindowCallback(mWindowCallback);
toolbar.setOnMenuItemClickListener(mMenuClicker);
mDecorToolbar.setWindowTitle(title);
+ mHomeDescription = mToolbar.getNavigationContentDescription();
+ updateNavDescription();
}
public Window.Callback getWrappedWindowCallback() {
@@ -161,6 +167,7 @@
@Override
public void setHomeActionContentDescription(CharSequence description) {
mToolbar.setNavigationContentDescription(description);
+ mHomeDescription = description;
}
@Override
@@ -171,6 +178,7 @@
@Override
public void setHomeActionContentDescription(int resId) {
mToolbar.setNavigationContentDescription(resId);
+ mHomeDescription = mToolbar.getNavigationContentDescription();
}
@Override
@@ -247,8 +255,22 @@
@Override
public void setDisplayOptions(@DisplayOptions int options, @DisplayOptions int mask) {
- mDecorToolbar.setDisplayOptions((options & mask) |
- mDecorToolbar.getDisplayOptions() & ~mask);
+ final int currentOptions = mDecorToolbar.getDisplayOptions();
+ final int changed = (options ^ currentOptions) & mask;
+ mDecorToolbar.setDisplayOptions(options & mask | currentOptions & ~mask);
+ if ((changed & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
+ updateNavDescription();
+ }
+ }
+
+ private void updateNavDescription() {
+ if ((mDecorToolbar.getDisplayOptions() & ActionBar.DISPLAY_HOME_AS_UP) != 0) {
+ if (TextUtils.isEmpty(mHomeDescription)) {
+ mToolbar.setNavigationContentDescription(R.string.action_bar_up_description);
+ } else {
+ mToolbar.setNavigationContentDescription(mHomeDescription);
+ }
+ }
}
@Override
diff --git a/core/jni/android/graphics/BitmapFactory.cpp b/core/jni/android/graphics/BitmapFactory.cpp
index 62ea351..8ea28ec 100644
--- a/core/jni/android/graphics/BitmapFactory.cpp
+++ b/core/jni/android/graphics/BitmapFactory.cpp
@@ -367,6 +367,9 @@
peeker.mOpticalInsets[0], peeker.mOpticalInsets[1], peeker.mOpticalInsets[2], peeker.mOpticalInsets[3],
peeker.mOutlineInsets[0], peeker.mOutlineInsets[1], peeker.mOutlineInsets[2], peeker.mOutlineInsets[3],
peeker.mOutlineRadius, peeker.mOutlineAlpha, scale);
+ if (ninePatchInsets == NULL) {
+ return nullObjectReturn("nine patch insets == null");
+ }
if (javaBitmap != NULL) {
env->SetObjectField(javaBitmap, gBitmap_ninePatchInsetsFieldID, ninePatchInsets);
}
diff --git a/core/jni/android/graphics/Graphics.cpp b/core/jni/android/graphics/Graphics.cpp
index 7c41c2e..d7b75db 100644
--- a/core/jni/android/graphics/Graphics.cpp
+++ b/core/jni/android/graphics/Graphics.cpp
@@ -419,6 +419,7 @@
{
SkASSERT(bitmap);
SkASSERT(bitmap->pixelRef());
+ SkASSERT(!env->ExceptionCheck());
bool isMutable = bitmapCreateFlags & kBitmapCreateFlag_Mutable;
bool isPremultiplied = bitmapCreateFlags & kBitmapCreateFlag_Premultiplied;
diff --git a/core/res/res/drawable-hdpi/pointer_arrow_icon.xml b/core/res/res/drawable-hdpi/pointer_arrow_icon.xml
deleted file mode 100644
index a4cce5c..0000000
--- a/core/res/res/drawable-hdpi/pointer_arrow_icon.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<pointer-icon xmlns:android="http://schemas.android.com/apk/res/android"
- android:bitmap="@drawable/pointer_arrow"
- android:hotSpotX="9"
- android:hotSpotY="9" />
diff --git a/core/res/res/drawable-hdpi/pointer_spot_anchor.png b/core/res/res/drawable-hdpi/pointer_spot_anchor.png
index d7aca36..bdb5311 100644
--- a/core/res/res/drawable-hdpi/pointer_spot_anchor.png
+++ b/core/res/res/drawable-hdpi/pointer_spot_anchor.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/pointer_spot_hover.png b/core/res/res/drawable-hdpi/pointer_spot_hover.png
index 5041aa3..e7f2a0c 100644
--- a/core/res/res/drawable-hdpi/pointer_spot_hover.png
+++ b/core/res/res/drawable-hdpi/pointer_spot_hover.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/pointer_spot_touch.png b/core/res/res/drawable-hdpi/pointer_spot_touch.png
index 64a42a1..0326f91 100644
--- a/core/res/res/drawable-hdpi/pointer_spot_touch.png
+++ b/core/res/res/drawable-hdpi/pointer_spot_touch.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_spot_anchor.png b/core/res/res/drawable-mdpi/pointer_spot_anchor.png
index d7aca36..4e282e7 100644
--- a/core/res/res/drawable-mdpi/pointer_spot_anchor.png
+++ b/core/res/res/drawable-mdpi/pointer_spot_anchor.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_spot_anchor_icon.xml b/core/res/res/drawable-mdpi/pointer_spot_anchor_icon.xml
deleted file mode 100644
index 2222b8e..0000000
--- a/core/res/res/drawable-mdpi/pointer_spot_anchor_icon.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<pointer-icon xmlns:android="http://schemas.android.com/apk/res/android"
- android:bitmap="@drawable/pointer_spot_anchor"
- android:hotSpotX="33"
- android:hotSpotY="33" />
diff --git a/core/res/res/drawable-mdpi/pointer_spot_hover.png b/core/res/res/drawable-mdpi/pointer_spot_hover.png
index 5041aa3..67d0b06 100644
--- a/core/res/res/drawable-mdpi/pointer_spot_hover.png
+++ b/core/res/res/drawable-mdpi/pointer_spot_hover.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_spot_hover_icon.xml b/core/res/res/drawable-mdpi/pointer_spot_hover_icon.xml
deleted file mode 100644
index dc62a69..0000000
--- a/core/res/res/drawable-mdpi/pointer_spot_hover_icon.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<pointer-icon xmlns:android="http://schemas.android.com/apk/res/android"
- android:bitmap="@drawable/pointer_spot_hover"
- android:hotSpotX="33"
- android:hotSpotY="33" />
diff --git a/core/res/res/drawable-mdpi/pointer_spot_touch.png b/core/res/res/drawable-mdpi/pointer_spot_touch.png
index 64a42a1..45dc5c08 100644
--- a/core/res/res/drawable-mdpi/pointer_spot_touch.png
+++ b/core/res/res/drawable-mdpi/pointer_spot_touch.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_spot_touch_icon.xml b/core/res/res/drawable-mdpi/pointer_spot_touch_icon.xml
deleted file mode 100644
index 4bffee6..0000000
--- a/core/res/res/drawable-mdpi/pointer_spot_touch_icon.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<pointer-icon xmlns:android="http://schemas.android.com/apk/res/android"
- android:bitmap="@drawable/pointer_spot_touch"
- android:hotSpotX="24"
- android:hotSpotY="24" />
diff --git a/core/res/res/drawable-xhdpi/pointer_arrow_icon.xml b/core/res/res/drawable-xhdpi/pointer_arrow_icon.xml
deleted file mode 100644
index 2fbe45a..0000000
--- a/core/res/res/drawable-xhdpi/pointer_arrow_icon.xml
+++ /dev/null
@@ -1,5 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<pointer-icon xmlns:android="http://schemas.android.com/apk/res/android"
- android:bitmap="@drawable/pointer_arrow"
- android:hotSpotX="12"
- android:hotSpotY="12" />
diff --git a/core/res/res/drawable-xhdpi/pointer_spot_anchor.png b/core/res/res/drawable-xhdpi/pointer_spot_anchor.png
index ad41c97..fa9226e 100644
--- a/core/res/res/drawable-xhdpi/pointer_spot_anchor.png
+++ b/core/res/res/drawable-xhdpi/pointer_spot_anchor.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_spot_hover.png b/core/res/res/drawable-xhdpi/pointer_spot_hover.png
index e9b98f6..f09a778 100644
--- a/core/res/res/drawable-xhdpi/pointer_spot_hover.png
+++ b/core/res/res/drawable-xhdpi/pointer_spot_hover.png
Binary files differ
diff --git a/core/res/res/drawable-xhdpi/pointer_spot_touch.png b/core/res/res/drawable-xhdpi/pointer_spot_touch.png
index e10d998..53d7a20 100644
--- a/core/res/res/drawable-xhdpi/pointer_spot_touch.png
+++ b/core/res/res/drawable-xhdpi/pointer_spot_touch.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/pointer_arrow_icon.xml b/core/res/res/drawable/pointer_arrow_icon.xml
similarity index 73%
rename from core/res/res/drawable-mdpi/pointer_arrow_icon.xml
rename to core/res/res/drawable/pointer_arrow_icon.xml
index 2f5676f..8f7d658 100644
--- a/core/res/res/drawable-mdpi/pointer_arrow_icon.xml
+++ b/core/res/res/drawable/pointer_arrow_icon.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<pointer-icon xmlns:android="http://schemas.android.com/apk/res/android"
android:bitmap="@drawable/pointer_arrow"
- android:hotSpotX="6"
- android:hotSpotY="6" />
+ android:hotSpotX="6dp"
+ android:hotSpotY="6dp" />
diff --git a/core/res/res/drawable-hdpi/pointer_spot_anchor_icon.xml b/core/res/res/drawable/pointer_spot_anchor_icon.xml
similarity index 73%
rename from core/res/res/drawable-hdpi/pointer_spot_anchor_icon.xml
rename to core/res/res/drawable/pointer_spot_anchor_icon.xml
index 2222b8e..73c0c11 100644
--- a/core/res/res/drawable-hdpi/pointer_spot_anchor_icon.xml
+++ b/core/res/res/drawable/pointer_spot_anchor_icon.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<pointer-icon xmlns:android="http://schemas.android.com/apk/res/android"
android:bitmap="@drawable/pointer_spot_anchor"
- android:hotSpotX="33"
- android:hotSpotY="33" />
+ android:hotSpotX="22dp"
+ android:hotSpotY="22dp" />
diff --git a/core/res/res/drawable-hdpi/pointer_spot_hover_icon.xml b/core/res/res/drawable/pointer_spot_hover_icon.xml
similarity index 73%
rename from core/res/res/drawable-hdpi/pointer_spot_hover_icon.xml
rename to core/res/res/drawable/pointer_spot_hover_icon.xml
index dc62a69..1d7440b 100644
--- a/core/res/res/drawable-hdpi/pointer_spot_hover_icon.xml
+++ b/core/res/res/drawable/pointer_spot_hover_icon.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<pointer-icon xmlns:android="http://schemas.android.com/apk/res/android"
android:bitmap="@drawable/pointer_spot_hover"
- android:hotSpotX="33"
- android:hotSpotY="33" />
+ android:hotSpotX="22dp"
+ android:hotSpotY="22dp" />
diff --git a/core/res/res/drawable-hdpi/pointer_spot_touch_icon.xml b/core/res/res/drawable/pointer_spot_touch_icon.xml
similarity index 73%
rename from core/res/res/drawable-hdpi/pointer_spot_touch_icon.xml
rename to core/res/res/drawable/pointer_spot_touch_icon.xml
index 4bffee6..f4f0639 100644
--- a/core/res/res/drawable-hdpi/pointer_spot_touch_icon.xml
+++ b/core/res/res/drawable/pointer_spot_touch_icon.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<pointer-icon xmlns:android="http://schemas.android.com/apk/res/android"
android:bitmap="@drawable/pointer_spot_touch"
- android:hotSpotX="24"
- android:hotSpotY="24" />
+ android:hotSpotX="16dp"
+ android:hotSpotY="16dp" />
diff --git a/core/res/res/layout/preference_material.xml b/core/res/res/layout/preference_material.xml
index 778e70a..a137149 100644
--- a/core/res/res/layout/preference_material.xml
+++ b/core/res/res/layout/preference_material.xml
@@ -24,7 +24,8 @@
android:gravity="center_vertical"
android:paddingStart="?attr/listPreferredItemPaddingStart"
android:paddingEnd="?attr/listPreferredItemPaddingEnd"
- android:background="?attr/activatedBackgroundIndicator">
+ android:background="?attr/activatedBackgroundIndicator"
+ android:clipToPadding="false">
<LinearLayout
android:id="@+id/icon_frame"
diff --git a/core/res/res/layout/screen_toolbar.xml b/core/res/res/layout/screen_toolbar.xml
index 039e89f..88c9cf6 100644
--- a/core/res/res/layout/screen_toolbar.xml
+++ b/core/res/res/layout/screen_toolbar.xml
@@ -41,6 +41,7 @@
android:id="@+id/action_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:navigationContentDescription="@string/action_bar_up_description"
style="?attr/toolbarStyle" />
<com.android.internal.widget.ActionBarContextView
android:id="@+id/action_context_bar"
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index a798d2e..ce2bc85 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -7112,9 +7112,9 @@
<!-- Drawable to use as the icon bitmap. -->
<attr name="bitmap" format="reference" />
<!-- X coordinate of the icon hot spot. -->
- <attr name="hotSpotX" format="float" />
+ <attr name="hotSpotX" format="dimension" />
<!-- Y coordinate of the icon hot spot. -->
- <attr name="hotSpotY" format="float" />
+ <attr name="hotSpotY" format="dimension" />
</declare-styleable>
<declare-styleable name="Storage">
diff --git a/core/res/res/values/styles_material.xml b/core/res/res/values/styles_material.xml
index 8b3cbaf..452ee11 100644
--- a/core/res/res/values/styles_material.xml
+++ b/core/res/res/values/styles_material.xml
@@ -1068,16 +1068,16 @@
<!-- Dialog styles -->
<style name="AlertDialog.Material" parent="AlertDialog">
- <item name="fullDark">@color/transparent</item>
- <item name="topDark">@color/transparent</item>
- <item name="centerDark">@color/transparent</item>
- <item name="bottomDark">@color/transparent</item>
- <item name="fullBright">@color/transparent</item>
- <item name="topBright">@color/transparent</item>
- <item name="centerBright">@color/transparent</item>
- <item name="bottomBright">@color/transparent</item>
- <item name="bottomMedium">@color/transparent</item>
- <item name="centerMedium">@color/transparent</item>
+ <item name="fullDark">@null</item>
+ <item name="topDark">@null</item>
+ <item name="centerDark">@null</item>
+ <item name="bottomDark">@null</item>
+ <item name="fullBright">@null</item>
+ <item name="topBright">@null</item>
+ <item name="centerBright">@null</item>
+ <item name="bottomBright">@null</item>
+ <item name="bottomMedium">@null</item>
+ <item name="centerMedium">@null</item>
<item name="layout">@layout/alert_dialog_material</item>
<item name="listLayout">@layout/select_dialog_material</item>
<item name="progressLayout">@layout/progress_dialog_material</item>
diff --git a/graphics/java/android/graphics/drawable/RippleBackground.java b/graphics/java/android/graphics/drawable/RippleBackground.java
index 40a5e18..ab43e01 100644
--- a/graphics/java/android/graphics/drawable/RippleBackground.java
+++ b/graphics/java/android/graphics/drawable/RippleBackground.java
@@ -107,9 +107,6 @@
/** Whether we have an explicit maximum radius. */
private boolean mHasMaxRadius;
- /** Whether we were canceled externally and should avoid self-removal. */
- private boolean mCanceled;
-
/**
* Creates a new ripple.
*/
@@ -406,6 +403,9 @@
mHardwareAnimating = true;
+ // Set up the software values to match the hardware end values.
+ mOuterOpacity = 0;
+
invalidateSelf();
}
@@ -414,10 +414,8 @@
* removing the ripple from the list of animating ripples.
*/
public void jump() {
- mCanceled = true;
endSoftwareAnimations();
endHardwareAnimations();
- mCanceled = false;
}
private void endSoftwareAnimations() {
@@ -446,7 +444,6 @@
// listener on a pending animation, we also need to remove ourselves.
if (!mPendingAnimations.isEmpty()) {
mPendingAnimations.clear();
- removeSelf();
}
mHardwareAnimating = false;
@@ -526,10 +523,8 @@
* the ripple from the list of animating ripples.
*/
public void cancel() {
- mCanceled = true;
cancelSoftwareAnimations();
cancelHardwareAnimations(true);
- mCanceled = false;
}
private void cancelSoftwareAnimations() {
@@ -555,7 +550,6 @@
for (int i = 0; i < N; i++) {
runningAnimations.get(i).cancel();
}
-
runningAnimations.clear();
if (cancelPending && !mPendingAnimations.isEmpty()) {
@@ -565,13 +559,6 @@
mHardwareAnimating = false;
}
- private void removeSelf() {
- // The owner will invalidate itself.
- if (!mCanceled) {
- mOwner.removeBackground(this);
- }
- }
-
private void invalidateSelf() {
mOwner.invalidateSelf();
}
@@ -579,7 +566,7 @@
private final AnimatorListenerAdapter mAnimationListener = new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
- removeSelf();
+ mHardwareAnimating = false;
}
};
diff --git a/graphics/java/android/graphics/drawable/RippleDrawable.java b/graphics/java/android/graphics/drawable/RippleDrawable.java
index b90fd81..e87a114 100644
--- a/graphics/java/android/graphics/drawable/RippleDrawable.java
+++ b/graphics/java/android/graphics/drawable/RippleDrawable.java
@@ -628,11 +628,10 @@
@Override
public void draw(@NonNull Canvas canvas) {
- final boolean isProjected = isProjected();
final boolean hasMask = mMask != null;
final boolean drawNonMaskContent = mLayerState.mNum > (hasMask ? 1 : 0);
final boolean drawMask = hasMask && mMask.getOpacity() != PixelFormat.OPAQUE;
- final Rect bounds = isProjected ? getDirtyBounds() : getBounds();
+ final Rect bounds = getDirtyBounds();
// If we have content, draw it into a layer first.
final int contentLayer = drawNonMaskContent ?
@@ -685,13 +684,6 @@
}
}
- void removeBackground(RippleBackground background) {
- if (mBackground == background) {
- mBackground = null;
- invalidateSelf();
- }
- }
-
private int getRippleIndex(Ripple ripple) {
final Ripple[] ripples = mExitingRipples;
final int count = mExitingRipplesCount;
diff --git a/graphics/java/android/graphics/pdf/PdfRenderer.java b/graphics/java/android/graphics/pdf/PdfRenderer.java
index b5d9729..1072b3c 100644
--- a/graphics/java/android/graphics/pdf/PdfRenderer.java
+++ b/graphics/java/android/graphics/pdf/PdfRenderer.java
@@ -195,6 +195,7 @@
public Page openPage(int index) {
throwIfClosed();
throwIfPageOpened();
+ throwIfPageNotInDocument(index);
mCurrentPage = new Page(index);
return mCurrentPage;
}
@@ -237,6 +238,12 @@
}
}
+ private void throwIfPageNotInDocument(int pageIndex) {
+ if (pageIndex >= mPageCount) {
+ throw new IllegalArgumentException("Invalid page index");
+ }
+ }
+
/**
* This class represents a PDF document page for rendering.
*/
diff --git a/libs/hwui/ProgramCache.cpp b/libs/hwui/ProgramCache.cpp
index c802b18..23fe1b9 100644
--- a/libs/hwui/ProgramCache.cpp
+++ b/libs/hwui/ProgramCache.cpp
@@ -88,7 +88,7 @@
"varying vec2 ditherTexCoords;\n",
};
const char* gVS_Header_Varyings_HasRoundRectClip =
- "varying vec2 roundRectPos;\n";
+ "varying highp vec2 roundRectPos;\n";
const char* gVS_Main =
"\nvoid main(void) {\n";
const char* gVS_Main_OutTexCoords =
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 491a295..0a17e132 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -110,8 +110,7 @@
}
void CanvasContext::pauseSurface(ANativeWindow* window) {
- // TODO: For now we just need a fence, in the future suspend any animations
- // and such to prevent from trying to render into this surface
+ stopDrawing();
}
void CanvasContext::setup(int width, int height, const Vector3& lightCenter, float lightRadius,
diff --git a/media/java/android/media/AudioService.java b/media/java/android/media/AudioService.java
index 10fa404..dd14c11 100644
--- a/media/java/android/media/AudioService.java
+++ b/media/java/android/media/AudioService.java
@@ -544,6 +544,9 @@
MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL] = SystemProperties.getInt(
"ro.config.vc_call_vol_steps",
MAX_STREAM_VOLUME[AudioSystem.STREAM_VOICE_CALL]);
+ MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC] = SystemProperties.getInt(
+ "ro.config.music_vol_steps",
+ MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC]);
sSoundEffectVolumeDb = context.getResources().getInteger(
com.android.internal.R.integer.config_soundEffectVolumeDb);
@@ -1564,6 +1567,9 @@
callingPackage) != AppOpsManager.MODE_ALLOWED) {
return;
}
+ if (!checkAudioSettingsPermission("setMicrophoneMute()")) {
+ return;
+ }
AudioSystem.muteMicrophone(on);
// Post a persist microphone msg.
diff --git a/media/java/android/media/session/MediaController.java b/media/java/android/media/session/MediaController.java
index 9641f83..4d4d646 100644
--- a/media/java/android/media/session/MediaController.java
+++ b/media/java/android/media/session/MediaController.java
@@ -47,8 +47,9 @@
* receive updates from the session, such as metadata and play state changes.
* <p>
* A MediaController can be created through {@link MediaSessionManager} if you
- * hold the "android.permission.MEDIA_CONTENT_CONTROL" permission or directly if
- * you have a {@link MediaSession.Token} from the session owner.
+ * hold the "android.permission.MEDIA_CONTENT_CONTROL" permission or are an
+ * enabled notification listener or by getting a {@link MediaSession.Token}
+ * directly from the session owner.
* <p>
* MediaController objects are thread-safe.
*/
@@ -612,14 +613,18 @@
/**
* Request that the player start playback for a specific search query.
+ * An empty or null query should be treated as a request to play any
+ * music.
*
* @param query The search query.
- * @param extras Optional extras that can include extra information about the query.
+ * @param extras Optional extras that can include extra information
+ * about the query.
*/
public void playFromSearch(String query, Bundle extras) {
- if (TextUtils.isEmpty(query)) {
- throw new IllegalArgumentException(
- "You must specify a non-empty search query for playFromSearch.");
+ if (query == null) {
+ // This is to remain compatible with
+ // INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH
+ query = "";
}
try {
mSessionBinder.playFromSearch(query, extras);
diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java
index ae8ce4b..095f885 100644
--- a/media/java/android/media/session/MediaSession.java
+++ b/media/java/android/media/session/MediaSession.java
@@ -771,7 +771,10 @@
}
/**
- * Override to handle requests to begin playback from a search query.
+ * Override to handle requests to begin playback from a search query. An
+ * empty query indicates that the app may play any music. The
+ * implementation should attempt to make a smart choice about what to
+ * play.
*/
public void onPlayFromSearch(String query, Bundle extras) {
}
diff --git a/packages/Keyguard/res/layout/keyguard_emergency_carrier_area_empty.xml b/packages/Keyguard/res/layout/keyguard_emergency_carrier_area_empty.xml
deleted file mode 100644
index 2f4adae..0000000
--- a/packages/Keyguard/res/layout/keyguard_emergency_carrier_area_empty.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-**
-** Copyright 2012, 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.
-*/
--->
-
-<!-- This is a blank layout to simplify implementation on landscape on phones
- it is referenced indirectly by keyguard_eca -->
-<LinearLayout
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="0dip"
- android:layout_height="0dip"
- android:orientation="vertical"
- android:gravity="center"
- android:layout_gravity="center_horizontal"
- android:layout_alignParentBottom="true">
-
-</LinearLayout>
diff --git a/packages/Keyguard/res/values-land/alias.xml b/packages/Keyguard/res/values-land/alias.xml
deleted file mode 100644
index 7aac5b4..0000000
--- a/packages/Keyguard/res/values-land/alias.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/common/assets/res/any/colors.xml
-**
-** Copyright 2012, 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.
-*/
--->
-<resources>
- <!-- Alias used to reference one of two possible layouts in keyguard. -->
- <item type="layout" name="keyguard_eca">@layout/keyguard_emergency_carrier_area_empty</item>
-</resources>
diff --git a/packages/Keyguard/res/values-port/alias.xml b/packages/Keyguard/res/values-port/alias.xml
deleted file mode 100644
index c3ecbb9..0000000
--- a/packages/Keyguard/res/values-port/alias.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/* //device/apps/common/assets/res/any/colors.xml
-**
-** Copyright 2012, 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.
-*/
--->
-<resources>
- <!-- Alias used to reference one of two possible layouts in keyguard. -->
- <item type="layout" name="keyguard_eca">@layout/keyguard_emergency_carrier_area</item>
-</resources>
diff --git a/packages/Keyguard/res/values/alias.xml b/packages/Keyguard/res/values/alias.xml
index e6657a1..09e9591 100644
--- a/packages/Keyguard/res/values/alias.xml
+++ b/packages/Keyguard/res/values/alias.xml
@@ -49,4 +49,6 @@
<!-- Alias used to reference framework activity duration. -->
<item type="integer" name="config_activityDefaultDur">@*android:integer/config_activityDefaultDur</item>
+ <!-- Alias used to reference one of two possible layouts in keyguard. -->
+ <item type="layout" name="keyguard_eca">@layout/keyguard_emergency_carrier_area</item>
</resources>
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
index a0fab42..8898f9e 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
@@ -128,16 +128,19 @@
getResources().getDimensionPixelSize(R.dimen.widget_label_font_size));
}
- protected void refresh() {
- AlarmManager.AlarmClockInfo nextAlarm = mLockPatternUtils.getNextAlarm();
- Patterns.update(mContext, nextAlarm != null);
-
+ public void refreshTime() {
mDateView.setFormat24Hour(Patterns.dateView);
mDateView.setFormat12Hour(Patterns.dateView);
mClockView.setFormat12Hour(Patterns.clockView12);
mClockView.setFormat24Hour(Patterns.clockView24);
+ }
+ private void refresh() {
+ AlarmManager.AlarmClockInfo nextAlarm = mLockPatternUtils.getNextAlarm();
+ Patterns.update(mContext, nextAlarm != null);
+
+ refreshTime();
refreshAlarmStatus(nextAlarm);
}
diff --git a/packages/PrintSpooler/Android.mk b/packages/PrintSpooler/Android.mk
index 3fbd4d8..4948a02 100644
--- a/packages/PrintSpooler/Android.mk
+++ b/packages/PrintSpooler/Android.mk
@@ -19,6 +19,7 @@
LOCAL_MODULE_TAGS := optional
LOCAL_SRC_FILES := $(call all-java-files-under, src)
+LOCAL_SRC_FILES += src/com/android/printspooler/renderer/IPdfRenderer.aidl
LOCAL_PACKAGE_NAME := PrintSpooler
diff --git a/packages/PrintSpooler/AndroidManifest.xml b/packages/PrintSpooler/AndroidManifest.xml
index 540a2f3..9efda2f 100644
--- a/packages/PrintSpooler/AndroidManifest.xml
+++ b/packages/PrintSpooler/AndroidManifest.xml
@@ -53,6 +53,11 @@
android:permission="android.permission.BIND_PRINT_SPOOLER_SERVICE">
</service>
+ <service
+ android:name=".renderer.PdfRendererService"
+ android:isolatedProcess="true">
+ </service>
+
<activity
android:name=".ui.PrintActivity"
android:configChanges="orientation|screenSize"
diff --git a/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java b/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java
index c3ddad9..cd2ccbd 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/model/PageContentRepository.java
@@ -17,24 +17,31 @@
package com.android.printspooler.model;
import android.app.ActivityManager;
+import android.content.ComponentName;
import android.content.Context;
-import android.content.res.Configuration;
+import android.content.Intent;
+import android.content.ServiceConnection;
import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
import android.graphics.Color;
-import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.drawable.BitmapDrawable;
-import android.graphics.pdf.PdfRenderer;
import android.os.AsyncTask;
+import android.os.IBinder;
import android.os.ParcelFileDescriptor;
-import android.print.PrintAttributes.MediaSize;
-import android.print.PrintAttributes.Margins;
+import android.os.RemoteException;
+import android.print.PrintAttributes;
import android.print.PrintDocumentInfo;
import android.util.ArrayMap;
import android.util.Log;
import android.view.View;
+import com.android.internal.annotations.GuardedBy;
+import com.android.printspooler.renderer.IPdfRenderer;
+import com.android.printspooler.renderer.PdfRendererService;
import dalvik.system.CloseGuard;
+import libcore.io.IoUtils;
+import java.io.FileDescriptor;
import java.io.IOException;
import java.util.Iterator;
import java.util.LinkedHashMap;
@@ -55,9 +62,6 @@
private static final int BYTES_PER_MEGABYTE = 1048576;
- private static final int MILS_PER_INCH = 1000;
- private static final int POINTS_IN_INCH = 72;
-
private final CloseGuard mCloseGuard = CloseGuard.get();
private final ArrayMap<Integer, PageContentProvider> mPageContentProviders =
@@ -115,7 +119,6 @@
if (DEBUG) {
Log.i(LOG_TAG, "STATE_DESTROYED");
}
- throwIfNotClosed();
doDestroy();
}
@@ -351,15 +354,13 @@
public static final class RenderSpec {
final int bitmapWidth;
final int bitmapHeight;
- final MediaSize mediaSize;
- final Margins minMargins;
+ final PrintAttributes printAttributes;
public RenderSpec(int bitmapWidth, int bitmapHeight,
- MediaSize mediaSize, Margins minMargins) {
+ PrintAttributes printAttributes) {
this.bitmapWidth = bitmapWidth;
this.bitmapHeight = bitmapHeight;
- this.mediaSize = mediaSize;
- this.minMargins = minMargins;
+ this.printAttributes = printAttributes;
}
@Override
@@ -380,18 +381,11 @@
if (bitmapWidth != other.bitmapWidth) {
return false;
}
- if (mediaSize != null) {
- if (!mediaSize.equals(other.mediaSize)) {
+ if (printAttributes != null) {
+ if (!printAttributes.equals(other.printAttributes)) {
return false;
}
- } else if (other.mediaSize != null) {
- return false;
- }
- if (minMargins != null) {
- if (!minMargins.equals(other.minMargins)) {
- return false;
- }
- } else if (other.minMargins != null) {
+ } else if (other.printAttributes != null) {
return false;
}
return true;
@@ -407,8 +401,7 @@
public int hashCode() {
int result = bitmapWidth;
result = 31 * result + bitmapHeight;
- result = 31 * result + (mediaSize != null ? mediaSize.hashCode() : 0);
- result = 31 * result + (minMargins != null ? minMargins.hashCode() : 0);
+ result = 31 * result + (printAttributes != null ? printAttributes.hashCode() : 0);
return result;
}
}
@@ -440,13 +433,11 @@
}
}
- private static int pointsFromMils(int mils) {
- return (int) (((float) mils / MILS_PER_INCH) * POINTS_IN_INCH);
- }
-
- private static class AsyncRenderer {
+ private static final class AsyncRenderer implements ServiceConnection {
private static final int MALFORMED_PDF_FILE_ERROR = -2;
+ private final Object mLock = new Object();
+
private final Context mContext;
private final PageContentLruCache mPageContentCache;
@@ -457,8 +448,8 @@
private int mPageCount = PrintDocumentInfo.PAGE_COUNT_UNKNOWN;
- // Accessed only by the executor thread.
- private PdfRenderer mRenderer;
+ @GuardedBy("mLock")
+ private IPdfRenderer mRenderer;
public AsyncRenderer(Context context, OnMalformedPdfFileListener malformedPdfFileListener) {
mContext = context;
@@ -470,6 +461,21 @@
mPageContentCache = new PageContentLruCache(cacheSizeInBytes);
}
+ @Override
+ public void onServiceConnected(ComponentName name, IBinder service) {
+ synchronized (mLock) {
+ mRenderer = IPdfRenderer.Stub.asInterface(service);
+ mLock.notifyAll();
+ }
+ }
+
+ @Override
+ public void onServiceDisconnected(ComponentName name) {
+ synchronized (mLock) {
+ mRenderer = null;
+ }
+ }
+
public void open(final ParcelFileDescriptor source, final Runnable callback) {
// Opening a new document invalidates the cache as it has pages
// from the last document. We keep the cache even when the document
@@ -479,13 +485,27 @@
new AsyncTask<Void, Void, Integer>() {
@Override
+ protected void onPreExecute() {
+ Intent intent = new Intent(mContext, PdfRendererService.class);
+ mContext.bindService(intent, AsyncRenderer.this, Context.BIND_AUTO_CREATE);
+ }
+
+ @Override
protected Integer doInBackground(Void... params) {
- try {
- mRenderer = new PdfRenderer(source);
- return mRenderer.getPageCount();
- } catch (IOException ioe) {
- Log.e(LOG_TAG, "Cannot open PDF document");
- return MALFORMED_PDF_FILE_ERROR;
+ synchronized (mLock) {
+ while (mRenderer == null) {
+ try {
+ mLock.wait();
+ } catch (InterruptedException ie) {
+ /* ignore */
+ }
+ }
+ try {
+ return mRenderer.openDocument(source);
+ } catch (RemoteException re) {
+ Log.e(LOG_TAG, "Cannot open PDF document");
+ return MALFORMED_PDF_FILE_ERROR;
+ }
}
}
@@ -510,7 +530,13 @@
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... params) {
- mRenderer.close();
+ synchronized (mLock) {
+ try {
+ mRenderer.closeDocument();
+ } catch (RemoteException re) {
+ /* ignore */
+ }
+ }
return null;
}
@@ -525,8 +551,19 @@
}
public void destroy() {
- mPageContentCache.invalidate();
- mPageContentCache.clear();
+ new AsyncTask<Void, Void, Void>() {
+ @Override
+ protected Void doInBackground(Void... params) {
+ return null;
+ }
+
+ @Override
+ public void onPostExecute(Void result) {
+ mContext.unbindService(AsyncRenderer.this);
+ mPageContentCache.invalidate();
+ mPageContentCache.clear();
+ }
+ }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, (Void[]) null);
}
public void startPreload(int firstShownPage, int lastShownPage, RenderSpec renderSpec) {
@@ -752,62 +789,30 @@
return mRenderedPage;
}
- PdfRenderer.Page page = mRenderer.openPage(mPageIndex);
-
- if (isCancelled()) {
- page.close();
- return mRenderedPage;
- }
-
Bitmap bitmap = mRenderedPage.content.getBitmap();
- final int srcWidthPts = page.getWidth();
- final int srcHeightPts = page.getHeight();
+ ParcelFileDescriptor[] pipe = null;
+ try {
+ pipe = ParcelFileDescriptor.createPipe();
+ ParcelFileDescriptor source = pipe[0];
+ ParcelFileDescriptor destination = pipe[1];
- final int dstWidthPts = pointsFromMils(mRenderSpec.mediaSize.getWidthMils());
- final int dstHeightPts = pointsFromMils(mRenderSpec.mediaSize.getHeightMils());
+ mRenderer.renderPage(mPageIndex, bitmap.getWidth(), bitmap.getHeight(),
+ mRenderSpec.printAttributes, destination);
- final boolean scaleContent = mRenderer.shouldScaleForPrinting();
- final boolean contentLandscape = !mRenderSpec.mediaSize.isPortrait();
+ // We passed the file descriptor to the other side which took
+ // ownership, so close our copy for the write to complete.
+ destination.close();
- final float displayScale;
- Matrix matrix = new Matrix();
-
- if (scaleContent) {
- displayScale = Math.min((float) bitmap.getWidth() / srcWidthPts,
- (float) bitmap.getHeight() / srcHeightPts);
- } else {
- if (contentLandscape) {
- displayScale = (float) bitmap.getHeight() / dstHeightPts;
- } else {
- displayScale = (float) bitmap.getWidth() / dstWidthPts;
- }
+ BitmapFactory.Options options = new BitmapFactory.Options();
+ options.inBitmap = bitmap;
+ BitmapFactory.decodeFileDescriptor(source.getFileDescriptor(), null, options);
+ } catch (IOException|RemoteException e) {
+ Log.e(LOG_TAG, "Error rendering page:" + mPageIndex, e);
+ } finally {
+ IoUtils.closeQuietly(pipe[0]);
+ IoUtils.closeQuietly(pipe[1]);
}
- matrix.postScale(displayScale, displayScale);
-
- Configuration configuration = mContext.getResources().getConfiguration();
- if (configuration.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
- matrix.postTranslate(bitmap.getWidth() - srcWidthPts * displayScale, 0);
- }
-
- final int paddingLeftPts = pointsFromMils(mRenderSpec.minMargins.getLeftMils());
- final int paddingTopPts = pointsFromMils(mRenderSpec.minMargins.getTopMils());
- final int paddingRightPts = pointsFromMils(mRenderSpec.minMargins.getRightMils());
- final int paddingBottomPts = pointsFromMils(mRenderSpec.minMargins.getBottomMils());
-
- Rect clip = new Rect();
- clip.left = (int) (paddingLeftPts * displayScale);
- clip.top = (int) (paddingTopPts * displayScale);
- clip.right = (int) (bitmap.getWidth() - paddingRightPts * displayScale);
- clip.bottom = (int) (bitmap.getHeight() - paddingBottomPts * displayScale);
-
- if (DEBUG) {
- Log.i(LOG_TAG, "Rendering page:" + mPageIndex + " of " + mPageCount);
- }
-
- page.render(bitmap, clip, matrix, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
-
- page.close();
return mRenderedPage;
}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/renderer/IPdfRenderer.aidl b/packages/PrintSpooler/src/com/android/printspooler/renderer/IPdfRenderer.aidl
new file mode 100644
index 0000000..1fba2b1
--- /dev/null
+++ b/packages/PrintSpooler/src/com/android/printspooler/renderer/IPdfRenderer.aidl
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.printspooler.renderer;
+
+import android.graphics.Rect;
+import android.os.ParcelFileDescriptor;
+import android.print.PageRange;
+import android.print.PrintAttributes;
+
+/**
+ * Interface for communication with a remote pdf renderer.
+ */
+interface IPdfRenderer {
+ int openDocument(in ParcelFileDescriptor source);
+ oneway void renderPage(int pageIndex, int bitmapWidth, int bitmapHeight,
+ in PrintAttributes attributes, in ParcelFileDescriptor destination);
+ oneway void closeDocument();
+ oneway void writePages(in PageRange[] pages);
+}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/renderer/PdfRendererService.java b/packages/PrintSpooler/src/com/android/printspooler/renderer/PdfRendererService.java
new file mode 100644
index 0000000..a4c6932
--- /dev/null
+++ b/packages/PrintSpooler/src/com/android/printspooler/renderer/PdfRendererService.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.printspooler.renderer;
+
+import android.app.Service;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.graphics.Bitmap;
+import android.graphics.Matrix;
+import android.graphics.Rect;
+import android.graphics.pdf.PdfRenderer;
+import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.print.PageRange;
+import android.print.PrintAttributes;
+import android.print.PrintAttributes.Margins;
+import android.util.Log;
+import android.view.View;
+import libcore.io.IoUtils;
+
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+/**
+ * Service for rendering PDF documents in an isolated process.
+ */
+public final class PdfRendererService extends Service {
+ private static final String LOG_TAG = "PdfRendererService";
+ private static final boolean DEBUG = false;
+
+ private static final int MILS_PER_INCH = 1000;
+ private static final int POINTS_IN_INCH = 72;
+
+ @Override
+ public IBinder onBind(Intent intent) {
+ return new PdfRendererImpl();
+ }
+
+ private final class PdfRendererImpl extends IPdfRenderer.Stub {
+ private final Object mLock = new Object();
+
+ private Bitmap mBitmap;
+ private PdfRenderer mRenderer;
+
+ @Override
+ public int openDocument(ParcelFileDescriptor source) throws RemoteException {
+ synchronized (mLock) {
+ throwIfOpened();
+ if (DEBUG) {
+ Log.i(LOG_TAG, "openDocument()");
+ }
+ try {
+ mRenderer = new PdfRenderer(source);
+ return mRenderer.getPageCount();
+ } catch (IOException ioe) {
+ throw new RemoteException("Cannot open file");
+ }
+ }
+ }
+
+ @Override
+ public void renderPage(int pageIndex, int bitmapWidth, int bitmapHeight,
+ PrintAttributes attributes, ParcelFileDescriptor destination) {
+ FileOutputStream out = null;
+ synchronized (mLock) {
+ try {
+ throwIfNotOpened();
+
+ PdfRenderer.Page page = mRenderer.openPage(pageIndex);
+
+ final int srcWidthPts = page.getWidth();
+ final int srcHeightPts = page.getHeight();
+
+ final int dstWidthPts = pointsFromMils(
+ attributes.getMediaSize().getWidthMils());
+ final int dstHeightPts = pointsFromMils(
+ attributes.getMediaSize().getHeightMils());
+
+ final boolean scaleContent = mRenderer.shouldScaleForPrinting();
+ final boolean contentLandscape = !attributes.getMediaSize().isPortrait();
+
+ final float displayScale;
+ Matrix matrix = new Matrix();
+
+ if (scaleContent) {
+ displayScale = Math.min((float) bitmapWidth / srcWidthPts,
+ (float) bitmapHeight / srcHeightPts);
+ } else {
+ if (contentLandscape) {
+ displayScale = (float) bitmapHeight / dstHeightPts;
+ } else {
+ displayScale = (float) bitmapWidth / dstWidthPts;
+ }
+ }
+ matrix.postScale(displayScale, displayScale);
+
+ Configuration configuration = PdfRendererService.this.getResources()
+ .getConfiguration();
+ if (configuration.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL) {
+ matrix.postTranslate(bitmapWidth - srcWidthPts * displayScale, 0);
+ }
+
+ Margins minMargins = attributes.getMinMargins();
+ final int paddingLeftPts = pointsFromMils(minMargins.getLeftMils());
+ final int paddingTopPts = pointsFromMils(minMargins.getTopMils());
+ final int paddingRightPts = pointsFromMils(minMargins.getRightMils());
+ final int paddingBottomPts = pointsFromMils(minMargins.getBottomMils());
+
+ Rect clip = new Rect();
+ clip.left = (int) (paddingLeftPts * displayScale);
+ clip.top = (int) (paddingTopPts * displayScale);
+ clip.right = (int) (bitmapWidth - paddingRightPts * displayScale);
+ clip.bottom = (int) (bitmapHeight - paddingBottomPts * displayScale);
+
+ if (DEBUG) {
+ Log.i(LOG_TAG, "Rendering page:" + pageIndex);
+ }
+
+ Bitmap bitmap = getBitmapForSize(bitmapWidth, bitmapHeight);
+ page.render(bitmap, clip, matrix, PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY);
+
+ page.close();
+
+ out = new FileOutputStream(destination.getFileDescriptor());
+ bitmap.compress(Bitmap.CompressFormat.PNG, 0, out);
+ } finally {
+ IoUtils.closeQuietly(out);
+ IoUtils.closeQuietly(destination);
+ }
+ }
+ }
+
+ @Override
+ public void closeDocument() {
+ synchronized (mLock) {
+ throwIfNotOpened();
+ if (DEBUG) {
+ Log.i(LOG_TAG, "openDocument()");
+ }
+ mRenderer.close();
+ mRenderer = null;
+ }
+ }
+
+ @Override
+ public void writePages(PageRange[] pages) {
+ synchronized (mLock) {
+ throwIfNotOpened();
+ if (DEBUG) {
+ Log.i(LOG_TAG, "writePages()");
+ }
+ // TODO: Implement dropping undesired pages.
+ }
+ }
+
+ private Bitmap getBitmapForSize(int width, int height) {
+ if (mBitmap != null) {
+ if (mBitmap.getWidth() == width && mBitmap.getHeight() == height) {
+ return mBitmap;
+ }
+ mBitmap.recycle();
+ }
+ mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+ return mBitmap;
+ }
+
+ private void throwIfOpened() {
+ if (mRenderer != null) {
+ throw new IllegalStateException("Already opened");
+ }
+ }
+
+ private void throwIfNotOpened() {
+ if (mRenderer == null) {
+ throw new IllegalStateException("Not opened");
+ }
+ }
+ }
+
+ private static int pointsFromMils(int mils) {
+ return (int) (((float) mils / MILS_PER_INCH) * POINTS_IN_INCH);
+ }
+}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
index 01c9746..022e0d04 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
@@ -319,6 +319,7 @@
mProgressMessageController.cancel();
mPrinterRegistry.setTrackedPrinter(null);
+ mPrintPreviewController.destroy();
mSpoolerProvider.destroy();
mPrintedDocument.finish();
mPrintedDocument.destroy();
@@ -2185,4 +2186,4 @@
updateOptionsUi();
}
}
-}
\ No newline at end of file
+}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintPreviewController.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintPreviewController.java
index 4a23ec4..ddf637e 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintPreviewController.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintPreviewController.java
@@ -191,6 +191,9 @@
}
public void destroy() {
+ if (mPageAdapter.isOpened()) {
+ mPageAdapter.close(null);
+ }
mPageAdapter.destroy();
}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/widget/PageContentView.java b/packages/PrintSpooler/src/com/android/printspooler/widget/PageContentView.java
index 8365373..76ff167 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/widget/PageContentView.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/widget/PageContentView.java
@@ -20,6 +20,7 @@
import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
+import android.print.PrintAttributes;
import android.print.PrintAttributes.MediaSize;
import android.print.PrintAttributes.Margins;
import android.util.AttributeSet;
@@ -38,13 +39,12 @@
public class PageContentView extends View
implements PageContentRepository.OnPageContentAvailableCallback {
+ private final PrintAttributes mAttributes = new PrintAttributes.Builder().build();
+
private final ColorDrawable mEmptyState;
private PageContentProvider mProvider;
- private MediaSize mMediaSize;
- private Margins mMinMargins;
-
private boolean mContentRequested;
public PageContentView(Context context, AttributeSet attrs) {
@@ -83,15 +83,17 @@
}
public void init(PageContentProvider provider, MediaSize mediaSize, Margins minMargins) {
- if (mProvider == provider
- && ((mMediaSize == null) ? mediaSize == null : mMediaSize.equals(mediaSize))
- && ((mMinMargins == null) ? minMargins == null : mMinMargins.equals(minMargins))) {
+ if (mProvider == null ? provider == null : mProvider.equals(provider)
+ && ((mAttributes.getMediaSize() == null)
+ ? mediaSize == null : mAttributes.getMediaSize().equals(mediaSize))
+ && ((mAttributes.getMinMargins() == null)
+ ? minMargins == null : mAttributes.getMinMargins().equals(minMargins))) {
return;
}
mProvider = provider;
- mMediaSize = mediaSize;
- mMinMargins = minMargins;
+ mAttributes.setMediaSize(mediaSize);
+ mAttributes.setMinMargins(minMargins);
mContentRequested = false;
// If there is no provider we want immediately to switch to
@@ -106,8 +108,7 @@
private void requestPageContentIfNeeded() {
if (getWidth() > 0 && getHeight() > 0 && !mContentRequested && mProvider != null) {
mContentRequested = true;
- mProvider.getPageContent(new RenderSpec(getWidth(), getHeight(), mMediaSize,
- mMinMargins), this);
+ mProvider.getPageContent(new RenderSpec(getWidth(), getHeight(), mAttributes), this);
}
}
}
diff --git a/packages/SystemUI/res/drawable/notification_material_bg_dim.xml b/packages/SystemUI/res/drawable/notification_material_bg_dim.xml
index b04394d..6581942 100644
--- a/packages/SystemUI/res/drawable/notification_material_bg_dim.xml
+++ b/packages/SystemUI/res/drawable/notification_material_bg_dim.xml
@@ -14,7 +14,11 @@
~ See the License for the specific language governing permissions and
~ limitations under the License
-->
-<shape xmlns:android="http://schemas.android.com/apk/res/android">
- <solid android:color="@color/notification_material_background_dimmed_color" />
- <corners android:radius="@dimen/notification_material_rounded_rect_radius" />
-</shape>
+<ripple xmlns:android="http://schemas.android.com/apk/res/android">
+ <item>
+ <shape>
+ <solid android:color="@color/notification_material_background_dimmed_color" />
+ <corners android:radius="@dimen/notification_material_rounded_rect_radius" />
+ </shape>
+ </item>
+</ripple>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index f3a62b8..6da811f 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -90,7 +90,10 @@
<color name="notification_material_background_media_default_color">#ff424242</color>
<!-- The color of the ripples on the untinted notifications -->
- <color name="notification_ripple_untinted_color">#20000000</color>
+ <color name="notification_ripple_untinted_color">#28000000</color>
+
+ <!-- The color of the ripples on the low priority notifications -->
+ <color name="notification_ripple_color_low_priority">#30000000</color>
<!-- The color of the ripples on the tinted notifications -->
<color name="notification_ripple_tinted_color">#30ffffff</color>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
index 500bf45..e6984b2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
@@ -88,6 +88,9 @@
= new PathInterpolator(0.6f, 0, 0.5f, 1);
private static final Interpolator ACTIVATE_INVERSE_ALPHA_INTERPOLATOR
= new PathInterpolator(0, 0, 0.5f, 1);
+ private final int mTintedRippleColor;
+ private final int mLowPriorityRippleColor;
+ private final int mNormalRippleColor;
private boolean mDimmed;
private boolean mDark;
@@ -153,6 +156,12 @@
mNormalColor = getResources().getColor(R.color.notification_material_background_color);
mLowPriorityColor = getResources().getColor(
R.color.notification_material_background_low_priority_color);
+ mTintedRippleColor = context.getResources().getColor(
+ R.color.notification_ripple_tinted_color);
+ mLowPriorityRippleColor = context.getResources().getColor(
+ R.color.notification_ripple_color_low_priority);
+ mNormalRippleColor = context.getResources().getColor(
+ R.color.notification_ripple_untinted_color);
}
@Override
@@ -191,6 +200,16 @@
}
}
+ @Override
+ protected void drawableStateChanged() {
+ super.drawableStateChanged();
+ if (mDimmed) {
+ mBackgroundDimmed.setState(getDrawableState());
+ } else {
+ mBackgroundNormal.setState(getDrawableState());
+ }
+ }
+
private boolean handleTouchEventDimmed(MotionEvent event) {
int action = event.getActionMasked();
switch (action) {
@@ -372,12 +391,15 @@
private void updateBackgroundTint() {
int color = getBackgroundColor();
+ int rippleColor = getRippleColor();
if (color == mNormalColor) {
// We don't need to tint a normal notification
color = 0;
}
mBackgroundDimmed.setTint(color);
mBackgroundNormal.setTint(color);
+ mBackgroundDimmed.setRippleColor(rippleColor);
+ mBackgroundNormal.setRippleColor(rippleColor);
}
private void fadeBackground() {
@@ -618,6 +640,18 @@
}
}
+ private int getRippleColor() {
+ if (mBgTint != 0) {
+ return mTintedRippleColor;
+ } else if (mShowingLegacyBackground) {
+ return mTintedRippleColor;
+ } else if (mIsBelowSpeedBump) {
+ return mLowPriorityRippleColor;
+ } else {
+ return mNormalRippleColor;
+ }
+ }
+
/**
* When we draw the appear animation, we render the view in a bitmap and render this bitmap
* as a shader of a rect. This call creates the Bitmap and switches the drawing mode,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBackgroundView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBackgroundView.java
index ad274b0..5db680a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBackgroundView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationBackgroundView.java
@@ -35,15 +35,9 @@
private Drawable mBackground;
private int mClipTopAmount;
private int mActualHeight;
- private final int mTintedRippleColor;
- private final int mNormalRippleColor;
public NotificationBackgroundView(Context context, AttributeSet attrs) {
super(context, attrs);
- mTintedRippleColor = context.getResources().getColor(
- R.color.notification_ripple_tinted_color);
- mNormalRippleColor = context.getResources().getColor(
- R.color.notification_ripple_untinted_color);
}
@Override
@@ -103,17 +97,10 @@
}
public void setTint(int tintColor) {
- int rippleColor;
if (tintColor != 0) {
mBackground.setColorFilter(tintColor, PorterDuff.Mode.SRC_ATOP);
- rippleColor = mTintedRippleColor;
} else {
mBackground.clearColorFilter();
- rippleColor = mNormalRippleColor;
- }
- if (mBackground instanceof RippleDrawable) {
- RippleDrawable ripple = (RippleDrawable) mBackground;
- ripple.setColor(ColorStateList.valueOf(rippleColor));
}
invalidate();
}
@@ -138,4 +125,15 @@
// Prevents this view from creating a layer when alpha is animating.
return false;
}
+
+ public void setState(int[] drawableState) {
+ mBackground.setState(drawableState);
+ }
+
+ public void setRippleColor(int color) {
+ if (mBackground instanceof RippleDrawable) {
+ RippleDrawable ripple = (RippleDrawable) mBackground;
+ ripple.setColor(ColorStateList.valueOf(color));
+ }
+ }
}
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 5a94395..91a8b22 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -35,6 +35,7 @@
import android.widget.FrameLayout;
import android.widget.TextView;
+import com.android.keyguard.KeyguardStatusView;
import com.android.systemui.R;
import com.android.systemui.qs.QSPanel;
import com.android.systemui.statusbar.ExpandableView;
@@ -65,7 +66,7 @@
private KeyguardStatusBarView mKeyguardStatusBar;
private View mQsContainer;
private QSPanel mQsPanel;
- private View mKeyguardStatusView;
+ private KeyguardStatusView mKeyguardStatusView;
private ObservableScrollView mScrollView;
private TextView mClockView;
private View mReserveNotificationSpace;
@@ -174,7 +175,7 @@
mHeader = (StatusBarHeaderView) findViewById(R.id.header);
mHeader.setOnClickListener(this);
mKeyguardStatusBar = (KeyguardStatusBarView) findViewById(R.id.keyguard_header);
- mKeyguardStatusView = findViewById(R.id.keyguard_status_view);
+ mKeyguardStatusView = (KeyguardStatusView) findViewById(R.id.keyguard_status_view);
mQsContainer = findViewById(R.id.quick_settings_container);
mQsPanel = (QSPanel) findViewById(R.id.quick_settings_panel);
mClockView = (TextView) findViewById(R.id.clock_view);
@@ -1749,4 +1750,8 @@
mHeader.updateEverything();
}
};
+
+ public void onScreenTurnedOn() {
+ mKeyguardStatusView.refreshTime();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ObservableScrollView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ObservableScrollView.java
index 53361dc..b842a6b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ObservableScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ObservableScrollView.java
@@ -87,7 +87,9 @@
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
- if (!mTouchEnabled) {
+ boolean isEndGuesture = (ev.getAction() == MotionEvent.ACTION_UP
+ || ev.getAction() == MotionEvent.ACTION_CANCEL);
+ if (!mTouchEnabled && !isEndGuesture) {
return false;
}
return super.dispatchTouchEvent(ev);
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 3b24bfd..ad775cb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -3817,6 +3817,7 @@
public void onScreenTurnedOn() {
mStackScroller.setAnimationsEnabled(true);
+ mNotificationPanel.onScreenTurnedOn();
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
index e1fd779..1811d8d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowView.java
@@ -42,6 +42,7 @@
private DragDownHelper mDragDownHelper;
private NotificationStackScrollLayout mStackScrollLayout;
private NotificationPanelView mNotificationPanel;
+ private View mBrightnessMirror;
PhoneStatusBar mService;
@@ -72,6 +73,7 @@
R.id.notification_stack_scroller);
mNotificationPanel = (NotificationPanelView) findViewById(R.id.notification_panel);
mDragDownHelper = new DragDownHelper(getContext(), this, mStackScrollLayout, mService);
+ mBrightnessMirror = findViewById(R.id.brightness_mirror);
// We really need to be able to animate while window animations are going on
// so that activities may be started asynchronously from panel animations
@@ -106,6 +108,19 @@
}
@Override
+ public boolean dispatchTouchEvent(MotionEvent ev) {
+ if (mBrightnessMirror != null && mBrightnessMirror.getVisibility() == VISIBLE) {
+ // Disallow new pointers while the brightness mirror is visible. This is so that you
+ // can't touch anything other than the brightness slider while the mirror is showing
+ // and the rest of the panel is transparent.
+ if (ev.getActionMasked() == MotionEvent.ACTION_POINTER_DOWN) {
+ return false;
+ }
+ }
+ return super.dispatchTouchEvent(ev);
+ }
+
+ @Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
boolean intercept = false;
if (mNotificationPanel.isFullyExpanded()
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 0919f77..ef0b155 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -967,6 +967,17 @@
}
@Override
+ public Network getNetworkForType(int networkType) {
+ enforceAccessPermission();
+ final int uid = Binder.getCallingUid();
+ if (isNetworkBlocked(networkType, uid)) {
+ return null;
+ }
+ NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
+ return (nai == null) ? null : nai.network;
+ }
+
+ @Override
public Network[] getAllNetworks() {
enforceAccessPermission();
final ArrayList<Network> result = new ArrayList();
@@ -1724,7 +1735,7 @@
pw.println();
synchronized (this) {
- pw.println("NetworkTranstionWakeLock is currently " +
+ pw.println("NetworkTransitionWakeLock is currently " +
(mNetTransitionWakeLock.isHeld() ? "" : "not ") + "held.");
pw.println("It was last requested for "+mNetTransitionWakeLockCausedBy);
}
diff --git a/services/core/java/com/android/server/MmsServiceBroker.java b/services/core/java/com/android/server/MmsServiceBroker.java
index df54c7f..2830b5e 100644
--- a/services/core/java/com/android/server/MmsServiceBroker.java
+++ b/services/core/java/com/android/server/MmsServiceBroker.java
@@ -29,10 +29,12 @@
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Binder;
+import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
+import android.os.ServiceManager;
import android.telephony.TelephonyManager;
import android.util.Slog;
@@ -228,21 +230,8 @@
}
@Override
- public boolean getCarrierConfigBoolean(long subId, String name, boolean defaultValue)
- throws RemoteException {
- return getServiceGuarded().getCarrierConfigBoolean(subId, name, defaultValue);
- }
-
- @Override
- public int getCarrierConfigInt(long subId, String name, int defaultValue)
- throws RemoteException {
- return getServiceGuarded().getCarrierConfigInt(subId, name, defaultValue);
- }
-
- @Override
- public String getCarrierConfigString(long subId, String name, String defaultValue)
- throws RemoteException {
- return getServiceGuarded().getCarrierConfigString(subId, name, defaultValue);
+ public Bundle getCarrierConfigValues(long subId) throws RemoteException {
+ return getServiceGuarded().getCarrierConfigValues(subId);
}
@Override
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index f9b65b8..1318f66 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -44,6 +44,7 @@
import android.net.InterfaceConfiguration;
import android.net.IpPrefix;
import android.net.LinkAddress;
+import android.net.Network;
import android.net.NetworkStats;
import android.net.NetworkUtils;
import android.net.RouteInfo;
@@ -1200,10 +1201,12 @@
}
@Override
- public void setDnsForwarders(String[] dns) {
+ public void setDnsForwarders(Network network, String[] dns) {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
- final Command cmd = new Command("tether", "dns", "set");
+ int netId = (network != null) ? network.netId : ConnectivityManager.NETID_UNSET;
+ final Command cmd = new Command("tether", "dns", "set", netId);
+
for (String s : dns) {
cmd.appendArg(NetworkUtils.numericToInetAddress(s).getHostAddress());
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 389369f..a3a5709 100755
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -2903,9 +2903,11 @@
boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
+ long startTime = SystemClock.elapsedRealtime();
ProcessRecord app;
if (!isolated) {
app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
+ checkTime(startTime, "startProcess: after getProcessRecord");
} else {
// If this is an isolated process, it can't re-use an existing process.
app = null;
@@ -2927,14 +2929,17 @@
if (DEBUG_PROCESSES) Slog.v(TAG, "App already running: " + app);
// If this is a new package in the process, add the package to the list
app.addPackage(info.packageName, info.versionCode, mProcessStats);
+ checkTime(startTime, "startProcess: done, added package to proc");
return app;
}
// An application record is attached to a previous process,
// clean it up now.
if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG, "App died: " + app);
+ checkTime(startTime, "startProcess: bad proc running, killing");
Process.killProcessGroup(app.info.uid, app.pid);
handleAppDiedLocked(app, true, true);
+ checkTime(startTime, "startProcess: done killing old proc");
}
String hostingNameStr = hostingName != null
@@ -2970,6 +2975,7 @@
}
if (app == null) {
+ checkTime(startTime, "startProcess: creating new process record");
app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
app.crashHandler = crashHandler;
if (app == null) {
@@ -2981,9 +2987,11 @@
if (isolated) {
mIsolatedProcesses.put(app.uid, app);
}
+ checkTime(startTime, "startProcess: done creating new process record");
} else {
// If this is a new package in the process, add the package to the list
app.addPackage(info.packageName, info.versionCode, mProcessStats);
+ checkTime(startTime, "startProcess: added package to existing proc");
}
// If the system is not ready yet, then hold off on starting this
@@ -2995,11 +3003,14 @@
mProcessesOnHold.add(app);
}
if (DEBUG_PROCESSES) Slog.v(TAG, "System not ready, putting on hold: " + app);
+ checkTime(startTime, "startProcess: returning with proc on hold");
return app;
}
+ checkTime(startTime, "startProcess: stepping in to startProcess");
startProcessLocked(
app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
+ checkTime(startTime, "startProcess: done starting proc!");
return (app.pid != 0) ? app : null;
}
@@ -3015,11 +3026,14 @@
private final void startProcessLocked(ProcessRecord app, String hostingType,
String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
+ long startTime = SystemClock.elapsedRealtime();
if (app.pid > 0 && app.pid != MY_PID) {
+ checkTime(startTime, "startProcess: removing from pids map");
synchronized (mPidsSelfLocked) {
mPidsSelfLocked.remove(app.pid);
mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
}
+ checkTime(startTime, "startProcess: done removing from pids map");
app.setPid(0);
}
@@ -3027,7 +3041,9 @@
"startProcessLocked removing on hold: " + app);
mProcessesOnHold.remove(app);
+ checkTime(startTime, "startProcess: starting to update cpu stats");
updateCpuStats();
+ checkTime(startTime, "startProcess: done updating cpu stats");
try {
int uid = app.uid;
@@ -3037,10 +3053,12 @@
if (!app.isolated) {
int[] permGids = null;
try {
+ checkTime(startTime, "startProcess: getting gids from package manager");
final PackageManager pm = mContext.getPackageManager();
permGids = pm.getPackageGids(app.info.packageName);
if (Environment.isExternalStorageEmulated()) {
+ checkTime(startTime, "startProcess: checking external storage perm");
if (pm.checkPermission(
android.Manifest.permission.ACCESS_ALL_EXTERNAL_STORAGE,
app.info.packageName) == PERMISSION_GRANTED) {
@@ -3066,6 +3084,7 @@
gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
}
+ checkTime(startTime, "startProcess: building args");
if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
&& mTopComponent != null
@@ -3109,14 +3128,17 @@
// the PID of the new process, or else throw a RuntimeException.
boolean isActivityProcess = (entryPoint == null);
if (entryPoint == null) entryPoint = "android.app.ActivityThread";
+ checkTime(startTime, "startProcess: asking zygote to start proc");
Process.ProcessStartResult startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
app.info.targetSdkVersion, app.info.seinfo, requiredAbi, entryPointArgs);
+ checkTime(startTime, "startProcess: returned from zygote!");
if (app.isolated) {
mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
}
mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
+ checkTime(startTime, "startProcess: done updating battery stats");
EventLog.writeEvent(EventLogTags.AM_PROC_START,
UserHandle.getUserId(uid), startResult.pid, uid,
@@ -3127,6 +3149,7 @@
Watchdog.getInstance().processStarted(app.processName, startResult.pid);
}
+ checkTime(startTime, "startProcess: building log message");
StringBuilder buf = mStringBuilder;
buf.setLength(0);
buf.append("Start proc ");
@@ -3164,6 +3187,7 @@
app.usingWrapper = startResult.usingWrapper;
app.removed = false;
app.killedByAm = false;
+ checkTime(startTime, "startProcess: starting to update pids map");
synchronized (mPidsSelfLocked) {
this.mPidsSelfLocked.put(startResult.pid, app);
if (isActivityProcess) {
@@ -3173,6 +3197,7 @@
? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
}
}
+ checkTime(startTime, "startProcess: done updating pids map");
} catch (RuntimeException e) {
// XXX do better error recovery.
app.setPid(0);
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 6545134..6bc1c9c 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -1729,16 +1729,19 @@
| (baseIntent.getFlags()&flagsOfInterest);
intent.setFlags(launchFlags);
inTask.setIntent(r);
+ addingToTask = true;
- // If the task is not empty, then we are going to add the new activity on top
- // of the task, so it can not be launching as a new task.
+ // If the task is not empty and the caller is asking to start it as the root
+ // of a new task, then we don't actually want to start this on the task. We
+ // will bring the task to the front, and possibly give it a new intent.
} else if ((launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
- ActivityOptions.abort(options);
- throw new IllegalStateException("Caller has inTask " + inTask
- + " but target is a new task");
+ addingToTask = false;
+
+ } else {
+ addingToTask = true;
}
+
reuseTask = inTask;
- addingToTask = true;
} else {
inTask = null;
}
@@ -1979,7 +1982,7 @@
sourceRecord.task : null;
// Should this be considered a new task?
- if (r.resultTo == null && !addingToTask
+ if (r.resultTo == null && inTask == null && !addingToTask
&& (launchFlags & Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
if (isLockTaskModeViolation(reuseTask)) {
Slog.e(TAG, "Attempted Lock Task Mode violation r=" + r);
@@ -2092,6 +2095,13 @@
}
}
+ if (!addingToTask) {
+ // We don't actually want to have this activity added to the task, so just
+ // stop here but still tell the caller that we consumed the intent.
+ ActivityOptions.abort(options);
+ return ActivityManager.START_TASK_TO_FRONT;
+ }
+
r.setTask(inTask, null);
if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
+ " in explicit task " + r.task);
diff --git a/services/core/java/com/android/server/connectivity/Tethering.java b/services/core/java/com/android/server/connectivity/Tethering.java
index 1fd114c..7c303ff 100644
--- a/services/core/java/com/android/server/connectivity/Tethering.java
+++ b/services/core/java/com/android/server/connectivity/Tethering.java
@@ -31,6 +31,7 @@
import android.net.InterfaceConfiguration;
import android.net.LinkAddress;
import android.net.LinkProperties;
+import android.net.Network;
import android.net.NetworkInfo;
import android.net.NetworkUtils;
import android.net.RouteInfo;
@@ -56,6 +57,7 @@
import java.net.InetAddress;
import java.net.Inet4Address;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
@@ -742,7 +744,7 @@
static final int CMD_IP_FORWARDING_ENABLE_ERROR = 7;
// notification from the master SM that it had trouble disabling IP Forwarding
static final int CMD_IP_FORWARDING_DISABLE_ERROR = 8;
- // notification from the master SM that it had trouble staring tethering
+ // notification from the master SM that it had trouble starting tethering
static final int CMD_START_TETHERING_ERROR = 9;
// notification from the master SM that it had trouble stopping tethering
static final int CMD_STOP_TETHERING_ERROR = 10;
@@ -1235,12 +1237,6 @@
return false;
}
}
- try {
- mNMService.setDnsForwarders(mDefaultDnsServers);
- } catch (Exception e) {
- transitionTo(mSetDnsForwardersErrorState);
- return false;
- }
return true;
}
protected boolean turnOffMasterTetherSettings() {
@@ -1348,8 +1344,17 @@
}
}
try {
- mNMService.setDnsForwarders(dnsServers);
+ Network network = getConnectivityManager().getNetworkForType(upType);
+ if (network == null) {
+ Log.e(TAG, "No Network for upstream type " + upType + "!");
+ }
+ if (VDBG) {
+ Log.d(TAG, "Setting DNS forwarders: Network=" + network +
+ ", dnsServers=" + Arrays.toString(dnsServers));
+ }
+ mNMService.setDnsForwarders(network, dnsServers);
} catch (Exception e) {
+ Log.e(TAG, "Setting DNS forwarders failed!");
transitionTo(mSetDnsForwardersErrorState);
}
}
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index 0da2cfa..b936130d 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -231,7 +231,7 @@
* @param direction The direction to adjust volume in.
*/
public void adjustVolume(int direction, int flags, String packageName, int uid) {
- if (isPlaybackActive(false)) {
+ if (isPlaybackActive(false) || hasFlag(MediaSession.FLAG_EXCLUSIVE_GLOBAL_PRIORITY)) {
flags &= ~AudioManager.FLAG_PLAY_SOUND;
}
if (direction > 1) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index 0a01247..08343d8 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -11398,7 +11398,8 @@
final WindowList windows = getDefaultWindowListLocked();
for (int winNdx = windows.size() - 1; winNdx >= 0; --winNdx) {
final WindowState win = windows.get(winNdx);
- if (win.mHasSurface && win.mAppToken != null) {
+ if (win.mHasSurface
+ && (win.mAppToken != null || mPolicy.isForceHiding(win.mAttrs))) {
win.mWinAnimator.mDrawState = WindowStateAnimator.DRAW_PENDING;
// Force add to mResizingWindows.
win.mLastContentInsets.set(-1, -1, -1, -1);
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 4b7dd08..3d4be12 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -524,6 +524,7 @@
private boolean mShown = false;
private int mLayerStack;
private boolean mIsOpaque;
+ private float mDsdx, mDtdx, mDsdy, mDtdy;
private final String mName;
public SurfaceTrace(SurfaceSession s,
@@ -619,6 +620,19 @@
}
@Override
+ public void setMatrix(float dsdx, float dtdx, float dsdy, float dtdy) {
+ if (dsdx != mDsdx || dtdx != mDtdx || dsdy != mDsdy || dtdy != mDtdy) {
+ Slog.v(SURFACE_TAG, "setMatrix(" + dsdx + "," + dtdx + "," + dsdy + "," + dtdy +
+ "): OLD:" + this + ". Called by " + Debug.getCallers(3));
+ mDsdx = dsdx;
+ mDtdx = dtdx;
+ mDsdy = dsdy;
+ mDtdy = dtdy;
+ }
+ super.setMatrix(dsdx, dtdx, dsdy, dtdy);
+ }
+
+ @Override
public void hide() {
if (mShown) {
Slog.v(SURFACE_TAG, "hide: OLD:" + this + ". Called by " + Debug.getCallers(3));
@@ -665,7 +679,8 @@
+ " alpha=" + mSurfaceTraceAlpha + " " + mPosition.x + "," + mPosition.y
+ " " + mSize.x + "x" + mSize.y
+ " crop=" + mWindowCrop.toShortString()
- + " opaque=" + mIsOpaque;
+ + " opaque=" + mIsOpaque
+ + " (" + mDsdx + "," + mDtdx + "," + mDsdy + "," + mDtdy + ")";
}
}
@@ -1068,6 +1083,14 @@
mShownAlpha *= appTransformation.getAlpha();
if (appTransformation.hasClipRect()) {
mClipRect.set(appTransformation.getClipRect());
+ if (mWin.mHScale > 0) {
+ mClipRect.left /= mWin.mHScale;
+ mClipRect.right /= mWin.mHScale;
+ }
+ if (mWin.mVScale > 0) {
+ mClipRect.top /= mWin.mVScale;
+ mClipRect.bottom /= mWin.mVScale;
+ }
mHasClipRect = true;
}
}
@@ -1418,10 +1441,10 @@
w.mLastVScale = w.mVScale;
if (WindowManagerService.SHOW_TRANSACTIONS) WindowManagerService.logSurface(w,
"alpha=" + mShownAlpha + " layer=" + mAnimLayer
- + " matrix=[" + (mDsDx*w.mHScale)
- + "," + (mDtDx*w.mVScale)
- + "][" + (mDsDy*w.mHScale)
- + "," + (mDtDy*w.mVScale) + "]", null);
+ + " matrix=[" + mDsDx + "*" + w.mHScale
+ + "," + mDtDx + "*" + w.mVScale
+ + "][" + mDsDy + "*" + w.mHScale
+ + "," + mDtDy + "*" + w.mVScale + "]", null);
if (mSurfaceControl != null) {
try {
mSurfaceAlpha = mShownAlpha;
diff --git a/telephony/java/com/android/internal/telephony/IMms.aidl b/telephony/java/com/android/internal/telephony/IMms.aidl
index cbcef25..2aeb42f 100644
--- a/telephony/java/com/android/internal/telephony/IMms.aidl
+++ b/telephony/java/com/android/internal/telephony/IMms.aidl
@@ -19,6 +19,7 @@
import android.app.PendingIntent;
import android.content.ContentValues;
import android.net.Uri;
+import android.os.Bundle;
/**
* Service interface to handle MMS API requests
@@ -78,33 +79,11 @@
void updateMmsDownloadStatus(int messageRef, in byte[] pdu);
/**
- * Get carrier-dependent configuration value as boolean. For example, if multipart SMS
- * is supported.
+ * Get carrier-dependent configuration values.
*
* @param subId the SIM id
- * @param name the configuration name
- * @param defaultValue the default value if fail to find the name
*/
- boolean getCarrierConfigBoolean(long subId, String name, boolean defaultValue);
-
- /**
- * Get carrier-dependent configuration value as int. For example, the MMS message size limit.
- *
- * @param subId the SIM id
- * @param name the configuration name
- * @param defaultValue the default value if fail to find the name
- */
- int getCarrierConfigInt(long subId, String name, int defaultValue);
-
- /**
- * Get carrier-dependent configuration value as String. For example, extra HTTP headers for
- * MMS request.
- *
- * @param subId the SIM id
- * @param name the configuration name
- * @param defaultValue the default value if fail to find the name
- */
- String getCarrierConfigString(long subId, String name, String defaultValue);
+ Bundle getCarrierConfigValues(long subId);
/**
* Import a text message into system's SMS store
diff --git a/wifi/java/android/net/wifi/IWifiManager.aidl b/wifi/java/android/net/wifi/IWifiManager.aidl
index 397d700..a752686 100644
--- a/wifi/java/android/net/wifi/IWifiManager.aidl
+++ b/wifi/java/android/net/wifi/IWifiManager.aidl
@@ -18,7 +18,6 @@
import android.net.wifi.BatchedScanResult;
import android.net.wifi.BatchedScanSettings;
-import android.net.wifi.WifiAdapter;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.ScanSettings;
@@ -40,9 +39,9 @@
*/
interface IWifiManager
{
- List<WifiAdapter> getAdaptors();
+ int getSupportedFeatures();
- WifiActivityEnergyInfo reportActivityInfo(in WifiAdapter adapter);
+ WifiActivityEnergyInfo reportActivityInfo();
List<WifiConfiguration> getConfiguredNetworks();
diff --git a/wifi/java/android/net/wifi/WifiAdapter.aidl b/wifi/java/android/net/wifi/WifiAdapter.aidl
deleted file mode 100644
index 0bb5dd7..0000000
--- a/wifi/java/android/net/wifi/WifiAdapter.aidl
+++ /dev/null
@@ -1,19 +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.wifi;
-
-parcelable WifiAdapter;
diff --git a/wifi/java/android/net/wifi/WifiAdapter.java b/wifi/java/android/net/wifi/WifiAdapter.java
deleted file mode 100644
index 0b12dea..0000000
--- a/wifi/java/android/net/wifi/WifiAdapter.java
+++ /dev/null
@@ -1,257 +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.wifi;
-
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.RemoteException;
-import android.util.Log;
-
-/**
- * Represents local wifi adapter. Different devices have different kinds of
- * wifi adapters; each with different capabilities. Use this class to find out
- * which capabilites are supported by the wifi adapter on the device.
- */
-public class WifiAdapter implements Parcelable {
- private static final String TAG = "WifiAdapter";
-
- /* Keep this list in sync with wifi_hal.h */
- /** @hide */
- public static final int WIFI_FEATURE_INFRA = 0x0001; // Basic infrastructure mode
- /** @hide */
- public static final int WIFI_FEATURE_INFRA_5G = 0x0002; // Support for 5 GHz Band
- /** @hide */
- public static final int WIFI_FEATURE_PASSPOINT = 0x0004; // Support for GAS/ANQP
- /** @hide */
- public static final int WIFI_FEATURE_P2P = 0x0008; // Wifi-Direct
- /** @hide */
- public static final int WIFI_FEATURE_MOBILE_HOTSPOT = 0x0010; // Soft AP
- /** @hide */
- public static final int WIFI_FEATURE_SCANNER = 0x0020; // WifiScanner APIs
- /** @hide */
- public static final int WIFI_FEATURE_NAN = 0x0040; // Neighbor Awareness Networking
- /** @hide */
- public static final int WIFI_FEATURE_D2D_RTT = 0x0080; // Device-to-device RTT
- /** @hide */
- public static final int WIFI_FEATURE_D2AP_RTT = 0x0100; // Device-to-AP RTT
- /** @hide */
- public static final int WIFI_FEATURE_BATCH_SCAN = 0x0200; // Batched Scan (deprecated)
- /** @hide */
- public static final int WIFI_FEATURE_PNO = 0x0400; // Preferred network offload
- /** @hide */
- public static final int WIFI_FEATURE_ADDITIONAL_STA = 0x0800; // Support for two STAs
- /** @hide */
- public static final int WIFI_FEATURE_TDLS = 0x1000; // Tunnel directed link setup
- /** @hide */
- public static final int WIFI_FEATURE_TDLS_OFFCHANNEL = 0x2000; // Support for TDLS off channel
- /** @hide */
- public static final int WIFI_FEATURE_EPR = 0x4000; // Enhanced power reporting
-
- private static final int CONTROLLER_ENERGY_UPDATE_TIMEOUT_MILLIS = 30;
- /** @hide */
- public static final int ACTIVITY_ENERGY_INFO_CACHED = 0;
- /** @hide */
- public static final int ACTIVITY_ENERGY_INFO_REFRESHED = 1;
-
- private String name;
- private int supportedFeatures;
-
- // Make the API consistent with BlueTooth Adaptor, allowing WifiService to be accessed
- // Directly from the adapter
- /** @hide */
- public IWifiManager mService = null;
-
- /** @hide */
- public WifiAdapter(String name, int supportedFeatures) {
- this.name = name;
- this.supportedFeatures = supportedFeatures;
- }
-
- /**
- * @return name of the adapter
- */
- public String getName() {
- return name;
- }
-
- private int getSupportedFeatures() {
- return supportedFeatures;
- }
-
- private boolean isFeatureSupported(int feature) {
- return (supportedFeatures & feature) == feature;
- }
-
- /**
- * @return true if this adapter supports 5 GHz band
- */
- public boolean is5GHzBandSupported() {
- return isFeatureSupported(WIFI_FEATURE_INFRA_5G);
- }
-
- /**
- * @return true if this adapter supports passpoint
- */
- public boolean isPasspointSupported() {
- return isFeatureSupported(WIFI_FEATURE_PASSPOINT);
- }
-
- /**
- * @return true if this adapter supports WifiP2pManager (Wi-Fi Direct)
- */
- public boolean isP2pSupported() {
- return isFeatureSupported(WIFI_FEATURE_P2P);
- }
-
- /**
- * @return true if this adapter supports portable Wi-Fi hotspot
- */
- public boolean isPortableHotspotSupported() {
- return isFeatureSupported(WIFI_FEATURE_MOBILE_HOTSPOT);
- }
-
- /**
- * @return true if this adapter supports WifiScanner APIs
- */
- public boolean isWifiScannerSupported() {
- return isFeatureSupported(WIFI_FEATURE_SCANNER);
- }
-
- /**
- * @return true if this adapter supports Neighbour Awareness Network APIs
- * @hide
- */
- public boolean isNanSupported() {
- return isFeatureSupported(WIFI_FEATURE_NAN);
- }
-
- /**
- * @return true if this adapter supports Device-to-device RTT
- */
- public boolean isDeviceToDeviceRttSupported() {
- return isFeatureSupported(WIFI_FEATURE_D2D_RTT);
- }
-
- /**
- * @return true if this adapter supports Device-to-AP RTT
- */
- public boolean isDeviceToApRttSupported() {
- return isFeatureSupported(WIFI_FEATURE_D2AP_RTT);
- }
-
- /**
- * @return true if this adapter supports offloaded connectivity scan
- */
- public boolean isPreferredNetworkOffloadSupported() {
- return isFeatureSupported(WIFI_FEATURE_PNO);
- }
-
- /**
- * @return true if this adapter supports multiple simultaneous connections
- * @hide
- */
- public boolean isAdditionalStaSupported() {
- return isFeatureSupported(WIFI_FEATURE_ADDITIONAL_STA);
- }
-
- /**
- * @return true if this adapter supports Tunnel Directed Link Setup
- */
- public boolean isTdlsSupported() {
- return isFeatureSupported(WIFI_FEATURE_TDLS);
- }
-
- /**
- * @return true if this adapter supports Off Channel Tunnel Directed Link Setup
- */
- public boolean isOffChannelTdlsSupported() {
- return isFeatureSupported(WIFI_FEATURE_TDLS_OFFCHANNEL);
- }
-
- /**
- * @return true if this adapter supports advanced power/performance counters
- */
- public boolean isEnhancedPowerReportingSupported() {
- return isFeatureSupported(WIFI_FEATURE_EPR);
- }
-
-
- /**
- * Return the record of {@link WifiActivityEnergyInfo} object that
- * has the activity and energy info. This can be used to ascertain what
- * the controller has been up to, since the last sample.
- * @param updateType Type of info, cached vs refreshed.
- *
- * @return a record with {@link WifiActivityEnergyInfo} or null if
- * report is unavailable or unsupported
- * @hide
- */
- public WifiActivityEnergyInfo getControllerActivityEnergyInfo(int updateType) {
- if (mService == null) return null;
- try {
- WifiActivityEnergyInfo record;
- if (!isEnhancedPowerReportingSupported()) {
- return null;
- }
- synchronized(this) {
- record = mService.reportActivityInfo(this);
- if (record.isValid()) {
- return record;
- } else {
- return null;
- }
- }
- } catch (RemoteException e) {
- Log.e(TAG, "getControllerActivityEnergyInfo: " + e);
- }
- return null;
- }
-
- /* Parcelable implementation */
- /**
- * Implement the Parcelable interface
- * {@hide}
- */
- public int describeContents() {
- return 0;
- }
-
- /**
- * Implement the Parcelable interface
- * {@hide}
- */
- public void writeToParcel(Parcel dest, int flags) {
- dest.writeString(name);
- dest.writeInt(supportedFeatures);
- }
-
- /**
- * Implement the Parcelable interface
- * {@hide}
- */
- public static final Creator<WifiAdapter> CREATOR =
- new Creator<WifiAdapter>() {
- public WifiAdapter createFromParcel(Parcel in) {
- WifiAdapter adaptor = new WifiAdapter(in.readString(), in.readInt());
- return adaptor;
- }
-
- public WifiAdapter[] newArray(int size) {
- return new WifiAdapter[size];
- }
- };
-}
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index 4a4da22..74f2f65 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -576,22 +576,6 @@
}
/**
- * Retrieve all wifi adapters available on this device
- * @return list of adapters
- */
- public List<WifiAdapter> getAdapters() {
- try {
- List<WifiAdapter> adapterList = mService.getAdaptors();
- for (WifiAdapter a : adapterList) {
- a.mService = mService;
- }
- return adapterList;
- } catch (RemoteException e) {
- return null;
- }
- }
-
- /**
* Return a list of all the networks configured in the supplicant.
* Not all fields of WifiConfiguration are returned. Only the following
* fields are filled in:
@@ -824,6 +808,182 @@
}
}
+ /* Keep this list in sync with wifi_hal.h */
+ /** @hide */
+ public static final int WIFI_FEATURE_INFRA = 0x0001; // Basic infrastructure mode
+ /** @hide */
+ public static final int WIFI_FEATURE_INFRA_5G = 0x0002; // Support for 5 GHz Band
+ /** @hide */
+ public static final int WIFI_FEATURE_PASSPOINT = 0x0004; // Support for GAS/ANQP
+ /** @hide */
+ public static final int WIFI_FEATURE_P2P = 0x0008; // Wifi-Direct
+ /** @hide */
+ public static final int WIFI_FEATURE_MOBILE_HOTSPOT = 0x0010; // Soft AP
+ /** @hide */
+ public static final int WIFI_FEATURE_SCANNER = 0x0020; // WifiScanner APIs
+ /** @hide */
+ public static final int WIFI_FEATURE_NAN = 0x0040; // Neighbor Awareness Networking
+ /** @hide */
+ public static final int WIFI_FEATURE_D2D_RTT = 0x0080; // Device-to-device RTT
+ /** @hide */
+ public static final int WIFI_FEATURE_D2AP_RTT = 0x0100; // Device-to-AP RTT
+ /** @hide */
+ public static final int WIFI_FEATURE_BATCH_SCAN = 0x0200; // Batched Scan (deprecated)
+ /** @hide */
+ public static final int WIFI_FEATURE_PNO = 0x0400; // Preferred network offload
+ /** @hide */
+ public static final int WIFI_FEATURE_ADDITIONAL_STA = 0x0800; // Support for two STAs
+ /** @hide */
+ public static final int WIFI_FEATURE_TDLS = 0x1000; // Tunnel directed link setup
+ /** @hide */
+ public static final int WIFI_FEATURE_TDLS_OFFCHANNEL = 0x2000; // Support for TDLS off channel
+ /** @hide */
+ public static final int WIFI_FEATURE_EPR = 0x4000; // Enhanced power reporting
+
+ private int getSupportedFeatures() {
+ try {
+ return mService.getSupportedFeatures();
+ } catch (RemoteException e) {
+ return 0;
+ }
+ }
+
+ private boolean isFeatureSupported(int feature) {
+ return (getSupportedFeatures() & feature) == feature;
+ }
+ /**
+ * @return true if this adapter supports 5 GHz band
+ */
+ public boolean is5GHzBandSupported() {
+ return isFeatureSupported(WIFI_FEATURE_INFRA_5G);
+ }
+
+ /**
+ * @return true if this adapter supports passpoint
+ * @hide
+ */
+ public boolean isPasspointSupported() {
+ return isFeatureSupported(WIFI_FEATURE_PASSPOINT);
+ }
+
+ /**
+ * @return true if this adapter supports WifiP2pManager (Wi-Fi Direct)
+ */
+ public boolean isP2pSupported() {
+ return isFeatureSupported(WIFI_FEATURE_P2P);
+ }
+
+ /**
+ * @return true if this adapter supports portable Wi-Fi hotspot
+ * @hide
+ */
+ @SystemApi
+ public boolean isPortableHotspotSupported() {
+ return isFeatureSupported(WIFI_FEATURE_MOBILE_HOTSPOT);
+ }
+
+ /**
+ * @return true if this adapter supports WifiScanner APIs
+ * @hide
+ */
+ @SystemApi
+ public boolean isWifiScannerSupported() {
+ return isFeatureSupported(WIFI_FEATURE_SCANNER);
+ }
+
+ /**
+ * @return true if this adapter supports Neighbour Awareness Network APIs
+ * @hide
+ */
+ public boolean isNanSupported() {
+ return isFeatureSupported(WIFI_FEATURE_NAN);
+ }
+
+ /**
+ * @return true if this adapter supports Device-to-device RTT
+ * @hide
+ */
+ @SystemApi
+ public boolean isDeviceToDeviceRttSupported() {
+ return isFeatureSupported(WIFI_FEATURE_D2D_RTT);
+ }
+
+ /**
+ * @return true if this adapter supports Device-to-AP RTT
+ */
+ @SystemApi
+ public boolean isDeviceToApRttSupported() {
+ return isFeatureSupported(WIFI_FEATURE_D2AP_RTT);
+ }
+
+ /**
+ * @return true if this adapter supports offloaded connectivity scan
+ */
+ public boolean isPreferredNetworkOffloadSupported() {
+ return isFeatureSupported(WIFI_FEATURE_PNO);
+ }
+
+ /**
+ * @return true if this adapter supports multiple simultaneous connections
+ * @hide
+ */
+ public boolean isAdditionalStaSupported() {
+ return isFeatureSupported(WIFI_FEATURE_ADDITIONAL_STA);
+ }
+
+ /**
+ * @return true if this adapter supports Tunnel Directed Link Setup
+ */
+ public boolean isTdlsSupported() {
+ return isFeatureSupported(WIFI_FEATURE_TDLS);
+ }
+
+ /**
+ * @return true if this adapter supports Off Channel Tunnel Directed Link Setup
+ * @hide
+ */
+ public boolean isOffChannelTdlsSupported() {
+ return isFeatureSupported(WIFI_FEATURE_TDLS_OFFCHANNEL);
+ }
+
+ /**
+ * @return true if this adapter supports advanced power/performance counters
+ */
+ public boolean isEnhancedPowerReportingSupported() {
+ return isFeatureSupported(WIFI_FEATURE_EPR);
+ }
+
+ /**
+ * Return the record of {@link WifiActivityEnergyInfo} object that
+ * has the activity and energy info. This can be used to ascertain what
+ * the controller has been up to, since the last sample.
+ * @param updateType Type of info, cached vs refreshed.
+ *
+ * @return a record with {@link WifiActivityEnergyInfo} or null if
+ * report is unavailable or unsupported
+ * @hide
+ */
+ public WifiActivityEnergyInfo getControllerActivityEnergyInfo(int updateType) {
+ if (mService == null) return null;
+ try {
+ WifiActivityEnergyInfo record;
+ if (!isEnhancedPowerReportingSupported()) {
+ return null;
+ }
+ synchronized(this) {
+ record = mService.reportActivityInfo();
+ if (record.isValid()) {
+ return record;
+ } else {
+ return null;
+ }
+ }
+ } catch (RemoteException e) {
+ Log.e(TAG, "getControllerActivityEnergyInfo: " + e);
+ }
+ return null;
+ }
+
/**
* Request a scan for access points. Returns immediately. The availability
* of the results is made known later by means of an asynchronous event sent
@@ -1457,12 +1617,14 @@
/**
* Passed with {@link ActionListener#onFailure}.
* Indicates that the operation failed due to an internal error.
+ * @hide
*/
public static final int ERROR = 0;
/**
* Passed with {@link ActionListener#onFailure}.
* Indicates that the operation is already in progress
+ * @hide
*/
public static final int IN_PROGRESS = 1;
@@ -1470,6 +1632,7 @@
* Passed with {@link ActionListener#onFailure}.
* Indicates that the operation failed because the framework is busy and
* unable to service the request
+ * @hide
*/
public static final int BUSY = 2;
@@ -1488,18 +1651,21 @@
/**
* Passed with {@link ActionListener#onFailure}.
* Indicates that the operation failed due to invalid inputs
+ * @hide
*/
public static final int INVALID_ARGS = 8;
/**
* Passed with {@link ActionListener#onFailure}.
* Indicates that the operation failed due to user permissions.
- *
* @hide
*/
public static final int NOT_AUTHORIZED = 9;
- /** Interface for callback invocation on an application action */
+ /**
+ * Interface for callback invocation on an application action
+ * @hide
+ */
public interface ActionListener {
/** The operation succeeded */
public void onSuccess();
@@ -1512,19 +1678,21 @@
}
/** Interface for callback invocation on a start WPS action */
- public interface WpsListener {
+ public static abstract class WpsCallback {
/** WPS start succeeded */
- public void onStartSuccess(String pin);
+ public abstract void onStarted(String pin);
/** WPS operation completed succesfully */
- public void onCompletion();
+ public abstract void onSucceeded();
/**
* WPS operation failed
* @param reason The reason for failure could be one of
- * {@link #IN_PROGRESS}, {@link #WPS_OVERLAP_ERROR},{@link #ERROR} or {@link #BUSY}
+ * {@link #WPS_TKIP_ONLY_PROHIBITED}, {@link #WPS_OVERLAP_ERROR},
+ * {@link #WPS_WEP_PROHIBITED}, {@link #WPS_TIMED_OUT} or {@link #WPS_AUTH_FAILURE}
+ * and some generic errors.
*/
- public void onFailure(int reason);
+ public abstract void onFailed(int reason);
}
/** Interface for callback invocation on a TX packet count poll action {@hide} */
@@ -1576,7 +1744,6 @@
case WifiManager.CONNECT_NETWORK_FAILED:
case WifiManager.FORGET_NETWORK_FAILED:
case WifiManager.SAVE_NETWORK_FAILED:
- case WifiManager.CANCEL_WPS_FAILED:
case WifiManager.DISABLE_NETWORK_FAILED:
if (listener != null) {
((ActionListener) listener).onFailure(message.arg1);
@@ -1586,7 +1753,6 @@
case WifiManager.CONNECT_NETWORK_SUCCEEDED:
case WifiManager.FORGET_NETWORK_SUCCEEDED:
case WifiManager.SAVE_NETWORK_SUCCEEDED:
- case WifiManager.CANCEL_WPS_SUCCEDED:
case WifiManager.DISABLE_NETWORK_SUCCEEDED:
if (listener != null) {
((ActionListener) listener).onSuccess();
@@ -1595,7 +1761,7 @@
case WifiManager.START_WPS_SUCCEEDED:
if (listener != null) {
WpsResult result = (WpsResult) message.obj;
- ((WpsListener) listener).onStartSuccess(result.pin);
+ ((WpsCallback) listener).onStarted(result.pin);
//Listener needs to stay until completion or failure
synchronized(sListenerMapLock) {
sListenerMap.put(message.arg2, listener);
@@ -1604,12 +1770,22 @@
break;
case WifiManager.WPS_COMPLETED:
if (listener != null) {
- ((WpsListener) listener).onCompletion();
+ ((WpsCallback) listener).onSucceeded();
}
break;
case WifiManager.WPS_FAILED:
if (listener != null) {
- ((WpsListener) listener).onFailure(message.arg1);
+ ((WpsCallback) listener).onFailed(message.arg1);
+ }
+ break;
+ case WifiManager.CANCEL_WPS_SUCCEDED:
+ if (listener != null) {
+ ((WpsCallback) listener).onSucceeded();
+ }
+ break;
+ case WifiManager.CANCEL_WPS_FAILED:
+ if (listener != null) {
+ ((WpsCallback) listener).onFailed(message.arg1);
}
break;
case WifiManager.RSSI_PKTCNT_FETCH_SUCCEEDED:
@@ -1794,7 +1970,7 @@
* @throws IllegalStateException if the WifiManager instance needs to be
* initialized again
*/
- public void startWps(WpsInfo config, WpsListener listener) {
+ public void startWps(WpsInfo config, WpsCallback listener) {
if (config == null) throw new IllegalArgumentException("config cannot be null");
validateChannel();
sAsyncChannel.sendMessage(START_WPS, 0, putListener(listener), config);
@@ -1807,7 +1983,7 @@
* @throws IllegalStateException if the WifiManager instance needs to be
* initialized again
*/
- public void cancelWps(ActionListener listener) {
+ public void cancelWps(WpsCallback listener) {
validateChannel();
sAsyncChannel.sendMessage(CANCEL_WPS, 0, putListener(listener));
}
@@ -2352,4 +2528,7 @@
return 0;
}
}
+
+
+
}