summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/ApplicationPackageManager.java3
-rw-r--r--core/java/android/net/DhcpResults.java9
-rw-r--r--core/java/android/net/NetworkPolicyManager.java28
-rw-r--r--packages/SystemUI/res/values-ca/strings.xml4
-rw-r--r--packages/SystemUI/res/values-ro/strings.xml2
-rw-r--r--services/core/java/com/android/server/ConnectivityService.java12
-rw-r--r--services/core/java/com/android/server/net/NetworkPolicyManagerService.java98
-rw-r--r--services/core/java/com/android/server/wm/WindowManagerService.java9
-rw-r--r--services/net/java/android/net/dhcp/DhcpAckPacket.java4
-rw-r--r--services/net/java/android/net/dhcp/DhcpClient.java43
-rw-r--r--services/net/java/android/net/dhcp/DhcpOfferPacket.java4
-rw-r--r--services/net/java/android/net/dhcp/DhcpPacket.java97
-rw-r--r--services/tests/servicestests/src/android/net/dhcp/DhcpPacketTest.java90
-rw-r--r--services/usage/java/com/android/server/usage/UsageStatsService.java5
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java2
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java16
16 files changed, 286 insertions, 140 deletions
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 0adce5d..7cae745 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -1619,7 +1619,8 @@ final class ApplicationPackageManager extends PackageManager {
// System apps and apps demanding internal storage can't be moved
// anywhere else
if (app.isSystemApp()
- || app.installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
+ || app.installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY
+ || app.installLocation == PackageInfo.INSTALL_LOCATION_UNSPECIFIED) {
return false;
}
diff --git a/core/java/android/net/DhcpResults.java b/core/java/android/net/DhcpResults.java
index 87c063f..97bd5d2 100644
--- a/core/java/android/net/DhcpResults.java
+++ b/core/java/android/net/DhcpResults.java
@@ -21,7 +21,6 @@ import android.os.Parcel;
import android.text.TextUtils;
import android.util.Log;
-import java.net.InetAddress;
import java.net.Inet4Address;
import java.util.Objects;
@@ -34,7 +33,7 @@ import java.util.Objects;
public class DhcpResults extends StaticIpConfiguration {
private static final String TAG = "DhcpResults";
- public InetAddress serverAddress;
+ public Inet4Address serverAddress;
/** Vendor specific information (from RFC 2132). */
public String vendorInfo;
@@ -142,7 +141,7 @@ public class DhcpResults extends StaticIpConfiguration {
private static void readFromParcel(DhcpResults dhcpResults, Parcel in) {
StaticIpConfiguration.readFromParcel(dhcpResults, in);
dhcpResults.leaseDuration = in.readInt();
- dhcpResults.serverAddress = NetworkUtils.unparcelInetAddress(in);
+ dhcpResults.serverAddress = (Inet4Address) NetworkUtils.unparcelInetAddress(in);
dhcpResults.vendorInfo = in.readString();
}
@@ -183,8 +182,8 @@ public class DhcpResults extends StaticIpConfiguration {
public boolean setServerAddress(String addrString) {
try {
- serverAddress = NetworkUtils.numericToInetAddress(addrString);
- } catch (IllegalArgumentException e) {
+ serverAddress = (Inet4Address) NetworkUtils.numericToInetAddress(addrString);
+ } catch (IllegalArgumentException|ClassCastException e) {
Log.e(TAG, "setServerAddress failed with addrString " + addrString);
return true;
}
diff --git a/core/java/android/net/NetworkPolicyManager.java b/core/java/android/net/NetworkPolicyManager.java
index 3f40484..a83e722 100644
--- a/core/java/android/net/NetworkPolicyManager.java
+++ b/core/java/android/net/NetworkPolicyManager.java
@@ -50,12 +50,13 @@ public class NetworkPolicyManager {
public static final int POLICY_ALLOW_BACKGROUND_BATTERY_SAVE = 0x2;
/* RULE_* are not masks and they must be exclusive */
+ public static final int RULE_UNKNOWN = -1;
/** All network traffic should be allowed. */
- public static final int RULE_ALLOW_ALL = 0x0;
+ public static final int RULE_ALLOW_ALL = 0;
/** Reject traffic on metered networks. */
- public static final int RULE_REJECT_METERED = 0x1;
+ public static final int RULE_REJECT_METERED = 1;
/** Reject traffic on all networks. */
- public static final int RULE_REJECT_ALL = 0x2;
+ public static final int RULE_REJECT_ALL = 2;
public static final int FIREWALL_RULE_DEFAULT = 0;
public static final int FIREWALL_RULE_ALLOW = 1;
@@ -326,25 +327,4 @@ public class NetworkPolicyManager {
// nothing found above; we can apply policy to UID
return true;
}
-
- /** {@hide} */
- public static void dumpPolicy(PrintWriter fout, int policy) {
- fout.write("[");
- if ((policy & POLICY_REJECT_METERED_BACKGROUND) != 0) {
- fout.write("REJECT_METERED_BACKGROUND");
- }
- fout.write("]");
- }
-
- /** {@hide} */
- public static void dumpRules(PrintWriter fout, int rules) {
- fout.write("[");
- if ((rules & RULE_REJECT_METERED) != 0) {
- fout.write("REJECT_METERED");
- } else if ((rules & RULE_REJECT_ALL) != 0) {
- fout.write("REJECT_ALL");
- }
- fout.write("]");
- }
-
}
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index e3ada5a..0b1f95a 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -170,7 +170,7 @@
<string name="accessibility_recents_task_header" msgid="1437183540924535457">"<xliff:g id="APP">%1$s</xliff:g> <xliff:g id="ACTIVITY_LABEL">%2$s</xliff:g>"</string>
<string name="accessibility_notification_dismissed" msgid="854211387186306927">"Notificació omesa."</string>
<string name="accessibility_desc_notification_shade" msgid="4690274844447504208">"Àrea de notificacions"</string>
- <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Configuració ràpida."</string>
+ <string name="accessibility_desc_quick_settings" msgid="6186378411582437046">"Configuració ràpida"</string>
<string name="accessibility_desc_lock_screen" msgid="5625143713611759164">"Pantalla de bloqueig"</string>
<string name="accessibility_desc_settings" msgid="3417884241751434521">"Configuració"</string>
<string name="accessibility_desc_recent_apps" msgid="4876900986661819788">"Visió general"</string>
@@ -337,7 +337,7 @@
<string name="user_new_user_name" msgid="426540612051178753">"Usuari nou"</string>
<string name="guest_nickname" msgid="8059989128963789678">"Convidat"</string>
<string name="guest_new_guest" msgid="600537543078847803">"Afegeix un convidat"</string>
- <string name="guest_exit_guest" msgid="7187359342030096885">"Suprimeix l\'usuari"</string>
+ <string name="guest_exit_guest" msgid="7187359342030096885">"Suprimeix el convidat"</string>
<string name="guest_exit_guest_dialog_title" msgid="8480693520521766688">"Vols suprimir el convidat?"</string>
<string name="guest_exit_guest_dialog_message" msgid="4155503224769676625">"Totes les aplicacions i les dades d\'aquesta sessió se suprimiran."</string>
<string name="guest_exit_guest_dialog_remove" msgid="7402231963862520531">"Suprimeix"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index a78e571..9cf669e 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -159,7 +159,7 @@
<string name="accessibility_gps_acquiring" msgid="8959333351058967158">"Se obţine GPS."</string>
<string name="accessibility_tty_enabled" msgid="4613200365379426561">"TeleTypewriter activat."</string>
<string name="accessibility_ringer_vibrate" msgid="666585363364155055">"Vibrare sonerie."</string>
- <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Sonerie silenţioasă."</string>
+ <string name="accessibility_ringer_silent" msgid="9061243307939135383">"Sonerie silențioasă."</string>
<!-- no translation found for accessibility_casting (6887382141726543668) -->
<skip />
<string name="accessibility_recents_item_will_be_dismissed" msgid="395770242498031481">"Închideți <xliff:g id="APP">%s</xliff:g>."</string>
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index 6190a5a..77837b7 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -946,13 +946,13 @@ public class ConnectivityService extends IConnectivityManager.Stub
uidRules = mUidRules.get(uid, RULE_ALLOW_ALL);
}
- if ((uidRules & RULE_REJECT_ALL) != 0
- || (networkCostly && (uidRules & RULE_REJECT_METERED) != 0)) {
+ if (uidRules == RULE_REJECT_ALL) {
return true;
+ } else if ((uidRules == RULE_REJECT_METERED) && networkCostly) {
+ return true;
+ } else {
+ return false;
}
-
- // no restrictive rules; network is visible
- return false;
}
/**
@@ -3724,7 +3724,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
synchronized(mRulesLock) {
uidRules = mUidRules.get(uid, RULE_ALLOW_ALL);
}
- if ((uidRules & (RULE_REJECT_METERED | RULE_REJECT_ALL)) != 0) {
+ if (uidRules != RULE_ALLOW_ALL) {
// we could silently fail or we can filter the available nets to only give
// them those they have access to. Chose the more useful
networkCapabilities.addCapability(NET_CAPABILITY_NOT_METERED);
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 5c1878e..88e86e7 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -39,17 +39,17 @@ import static android.net.NetworkPolicy.WARNING_DISABLED;
import static android.net.NetworkPolicyManager.EXTRA_NETWORK_TEMPLATE;
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_DOZABLE;
import static android.net.NetworkPolicyManager.FIREWALL_CHAIN_STANDBY;
-import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
import static android.net.NetworkPolicyManager.FIREWALL_RULE_ALLOW;
+import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
import static android.net.NetworkPolicyManager.FIREWALL_RULE_DENY;
import static android.net.NetworkPolicyManager.POLICY_ALLOW_BACKGROUND_BATTERY_SAVE;
import static android.net.NetworkPolicyManager.POLICY_NONE;
import static android.net.NetworkPolicyManager.POLICY_REJECT_METERED_BACKGROUND;
import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL;
+import static android.net.NetworkPolicyManager.RULE_REJECT_ALL;
import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
+import static android.net.NetworkPolicyManager.RULE_UNKNOWN;
import static android.net.NetworkPolicyManager.computeLastCycleBoundary;
-import static android.net.NetworkPolicyManager.dumpPolicy;
-import static android.net.NetworkPolicyManager.dumpRules;
import static android.net.NetworkTemplate.MATCH_MOBILE_3G_LOWER;
import static android.net.NetworkTemplate.MATCH_MOBILE_4G;
import static android.net.NetworkTemplate.MATCH_MOBILE_ALL;
@@ -108,6 +108,7 @@ import android.net.LinkProperties;
import android.net.NetworkIdentity;
import android.net.NetworkInfo;
import android.net.NetworkPolicy;
+import android.net.NetworkPolicyManager;
import android.net.NetworkQuotaInfo;
import android.net.NetworkState;
import android.net.NetworkTemplate;
@@ -138,6 +139,7 @@ import android.text.format.Time;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.AtomicFile;
+import android.util.DebugUtils;
import android.util.Log;
import android.util.NtpTrustedTime;
import android.util.Pair;
@@ -147,8 +149,6 @@ import android.util.SparseIntArray;
import android.util.TrustedTime;
import android.util.Xml;
-import com.android.server.DeviceIdleController;
-import com.android.server.EventLogTags;
import libcore.io.IoUtils;
import com.android.internal.R;
@@ -156,6 +156,8 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.IndentingPrintWriter;
+import com.android.server.DeviceIdleController;
+import com.android.server.EventLogTags;
import com.android.server.LocalServices;
import com.google.android.collect.Lists;
@@ -279,6 +281,10 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
final SparseIntArray mUidPolicy = new SparseIntArray();
/** Currently derived rules for each UID. */
final SparseIntArray mUidRules = new SparseIntArray();
+
+ final SparseIntArray mUidFirewallStandbyRules = new SparseIntArray();
+ final SparseIntArray mUidFirewallDozableRules = new SparseIntArray();
+
/** Set of states for the child firewall chains. True if the chain is active. */
final SparseBooleanArray mFirewallChainStates = new SparseBooleanArray();
@@ -446,14 +452,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
// read policy from disk
readPolicyLocked();
- if (mRestrictBackground || mRestrictPower || mDeviceIdleMode) {
- updateRulesForGlobalChangeLocked(false);
- updateNotificationsLocked();
- } else {
- // If we are not in any special mode, we just need to make sure the current
- // app idle state is updated.
- updateRulesForAppIdleLocked();
- }
+ updateRulesForGlobalChangeLocked(false);
+ updateNotificationsLocked();
}
updateScreenOn();
@@ -1800,7 +1800,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
if (mDeviceIdleMode != enabled) {
mDeviceIdleMode = enabled;
if (mSystemReady) {
- updateRulesForDeviceIdleLocked();
+ // Device idle change means we need to rebuild rules for all
+ // known apps, so do a global refresh.
+ updateRulesForGlobalChangeLocked(false);
}
if (enabled) {
EventLogTags.writeDeviceIdleOnPhase("net");
@@ -1938,7 +1940,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
fout.print("UID=");
fout.print(uid);
fout.print(" policy=");
- dumpPolicy(fout, policy);
+ fout.print(DebugUtils.flagsToString(NetworkPolicyManager.class, "POLICY_", policy));
fout.println();
}
fout.decreaseIndent();
@@ -1983,18 +1985,14 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
fout.print("UID=");
fout.print(uid);
- int state = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
+ final int state = mUidState.get(uid, ActivityManager.PROCESS_STATE_CACHED_EMPTY);
fout.print(" state=");
fout.print(state);
fout.print(state <= ActivityManager.PROCESS_STATE_TOP ? " (fg)" : " (bg)");
- fout.print(" rules=");
- final int rulesIndex = mUidRules.indexOfKey(uid);
- if (rulesIndex < 0) {
- fout.print("UNKNOWN");
- } else {
- dumpRules(fout, mUidRules.valueAt(rulesIndex));
- }
+ final int rule = mUidRules.get(uid, RULE_UNKNOWN);
+ fout.print(" rule=");
+ fout.print(DebugUtils.valueToString(NetworkPolicyManager.class, "RULE_", rule));
fout.println();
}
@@ -2029,7 +2027,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
updateRulesForUidStateChangeLocked(uid, oldUidState, uidState);
if (mDeviceIdleMode && isProcStateAllowedWhileIdle(oldUidState)
!= isProcStateAllowedWhileIdle(uidState)) {
- updateRulesForDeviceIdleLocked();
+ updateRuleForDeviceIdleLocked(uid);
}
}
}
@@ -2043,7 +2041,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
updateRulesForUidStateChangeLocked(uid, oldUidState,
ActivityManager.PROCESS_STATE_CACHED_EMPTY);
if (mDeviceIdleMode) {
- updateRulesForDeviceIdleLocked();
+ updateRuleForDeviceIdleLocked(uid);
}
}
}
@@ -2090,7 +2088,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
if (mDeviceIdleMode) {
// sync the whitelists before enable dozable chain. We don't care about the rules if
// we are disabling the chain.
- SparseIntArray uidRules = new SparseIntArray();
+ final SparseIntArray uidRules = mUidFirewallDozableRules;
+ uidRules.clear();
final List<UserInfo> users = mUserManager.getUsers();
for (int ui = users.size() - 1; ui >= 0; ui--) {
UserInfo user = users.get(ui);
@@ -2114,6 +2113,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
}
setUidFirewallRules(FIREWALL_CHAIN_DOZABLE, uidRules);
}
+
enableFirewallChainLocked(FIREWALL_CHAIN_DOZABLE, mDeviceIdleMode);
}
@@ -2127,11 +2127,15 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
setUidFirewallRule(FIREWALL_CHAIN_DOZABLE, uid, FIREWALL_RULE_DEFAULT);
}
}
+
+ updateRulesForUidLocked(uid);
}
void updateRulesForAppIdleLocked() {
+ final SparseIntArray uidRules = mUidFirewallStandbyRules;
+ uidRules.clear();
+
// Fully update the app idle firewall chain.
- SparseIntArray uidRules = new SparseIntArray();
final List<UserInfo> users = mUserManager.getUsers();
for (int ui = users.size() - 1; ui >= 0; ui--) {
UserInfo user = users.get(ui);
@@ -2142,6 +2146,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
}
}
}
+
setUidFirewallRules(FIREWALL_CHAIN_STANDBY, uidRules);
}
@@ -2154,11 +2159,14 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
} else {
setUidFirewallRule(FIREWALL_CHAIN_STANDBY, uid, FIREWALL_RULE_DEFAULT);
}
+
+ updateRulesForUidLocked(uid);
}
void updateRulesForAppIdleParoleLocked() {
boolean enableChain = !mUsageStats.isAppIdleParoleOn();
enableFirewallChainLocked(FIREWALL_CHAIN_STANDBY, enableChain);
+ updateRulesForUidsLocked(mUidFirewallStandbyRules);
}
/**
@@ -2228,6 +2236,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
return true;
}
+ void updateRulesForUidsLocked(SparseIntArray uids) {
+ for (int i = 0; i < uids.size(); i++) {
+ updateRulesForUidLocked(uids.keyAt(i));
+ }
+ }
+
/**
* Applies network rules to bandwidth and firewall controllers based on uid policy.
* @param uid The uid for which to apply the latest policy
@@ -2249,8 +2263,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
final int uidPolicy = mUidPolicy.get(uid, POLICY_NONE);
final boolean uidForeground = isUidForegroundLocked(uid);
- // derive active rules based on policy and active state
-
+ // Derive active rules based on policy and active state
int appId = UserHandle.getAppId(uid);
int uidRules = RULE_ALLOW_ALL;
if (!uidForeground && (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0) {
@@ -2273,20 +2286,27 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
}
}
- final int oldRules = mUidRules.get(uid);
+ // Check dozable state, which is whitelist
+ if (mFirewallChainStates.get(FIREWALL_CHAIN_DOZABLE)
+ && mUidFirewallDozableRules.get(uid, FIREWALL_RULE_DEFAULT) != FIREWALL_RULE_ALLOW) {
+ uidRules = RULE_REJECT_ALL;
+ }
+
+ // Check standby state, which is blacklist
+ if (mFirewallChainStates.get(FIREWALL_CHAIN_STANDBY)
+ && mUidFirewallStandbyRules.get(uid, FIREWALL_RULE_DEFAULT) == FIREWALL_RULE_DENY) {
+ uidRules = RULE_REJECT_ALL;
+ }
+ final int oldRules = mUidRules.get(uid);
if (uidRules == RULE_ALLOW_ALL) {
mUidRules.delete(uid);
} else {
mUidRules.put(uid, uidRules);
}
- // Update bandwidth rules if necessary
- final boolean oldRejectMetered = (oldRules & RULE_REJECT_METERED) != 0;
- final boolean rejectMetered = (uidRules & RULE_REJECT_METERED) != 0;
- if (oldRejectMetered != rejectMetered) {
- setUidNetworkRules(uid, rejectMetered);
- }
+ final boolean rejectMetered = (uidRules == RULE_REJECT_METERED);
+ setUidNetworkRules(uid, rejectMetered);
// dispatch changed rule to existing listeners
if (oldRules != uidRules) {
@@ -2472,6 +2492,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
* Add or remove a uid to the firewall blacklist for all network ifaces.
*/
private void setUidFirewallRule(int chain, int uid, int rule) {
+ if (chain == FIREWALL_CHAIN_DOZABLE) {
+ mUidFirewallDozableRules.put(uid, rule);
+ } else if (chain == FIREWALL_CHAIN_STANDBY) {
+ mUidFirewallStandbyRules.put(uid, rule);
+ }
+
try {
mNetworkManager.setFirewallUidRule(chain, uid, rule);
} catch (IllegalStateException e) {
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index e903e4f..71bbdb6 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -642,6 +642,7 @@ public class WindowManagerService extends IWindowManager.Stub
final InputManagerService mInputManager;
final DisplayManagerInternal mDisplayManagerInternal;
final DisplayManager mDisplayManager;
+ final Display[] mDisplays;
// Who is holding the screen on.
Session mHoldingScreenOn;
@@ -915,8 +916,8 @@ public class WindowManagerService extends IWindowManager.Stub
mFxSession = new SurfaceSession();
mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
- Display[] displays = mDisplayManager.getDisplays();
- for (Display display : displays) {
+ mDisplays = mDisplayManager.getDisplays();
+ for (Display display : mDisplays) {
createDisplayContentLocked(display);
}
@@ -7641,7 +7642,9 @@ public class WindowManagerService extends IWindowManager.Stub
}
public void displayReady() {
- displayReady(Display.DEFAULT_DISPLAY);
+ for (Display display : mDisplays) {
+ displayReady(display.getDisplayId());
+ }
synchronized(mWindowMap) {
final DisplayContent displayContent = getDefaultDisplayContentLocked();
diff --git a/services/net/java/android/net/dhcp/DhcpAckPacket.java b/services/net/java/android/net/dhcp/DhcpAckPacket.java
index 334f708..df44b11 100644
--- a/services/net/java/android/net/dhcp/DhcpAckPacket.java
+++ b/services/net/java/android/net/dhcp/DhcpAckPacket.java
@@ -46,7 +46,7 @@ class DhcpAckPacket extends DhcpPacket {
return s + " ACK: your new IP " + mYourIp +
", netmask " + mSubnetMask +
- ", gateway " + mGateway + dnsServers +
+ ", gateways " + mGateways + dnsServers +
", lease time " + mLeaseTime;
}
@@ -79,7 +79,7 @@ class DhcpAckPacket extends DhcpPacket {
}
addTlv(buffer, DHCP_SUBNET_MASK, mSubnetMask);
- addTlv(buffer, DHCP_ROUTER, mGateway);
+ addTlv(buffer, DHCP_ROUTER, mGateways);
addTlv(buffer, DHCP_DOMAIN_NAME, mDomainName);
addTlv(buffer, DHCP_BROADCAST_ADDRESS, mBroadcastAddress);
addTlv(buffer, DHCP_DNS_SERVER, mDnsServers);
diff --git a/services/net/java/android/net/dhcp/DhcpClient.java b/services/net/java/android/net/dhcp/DhcpClient.java
index e0d2ac1..28cb114 100644
--- a/services/net/java/android/net/dhcp/DhcpClient.java
+++ b/services/net/java/android/net/dhcp/DhcpClient.java
@@ -299,6 +299,7 @@ public class DhcpClient extends BaseDhcpStateMachine {
Os.setsockoptInt(mUdpSock, SOL_SOCKET, SO_REUSEADDR, 1);
Os.setsockoptIfreq(mUdpSock, SOL_SOCKET, SO_BINDTODEVICE, mIfaceName);
Os.setsockoptInt(mUdpSock, SOL_SOCKET, SO_BROADCAST, 1);
+ Os.setsockoptInt(mUdpSock, SOL_SOCKET, SO_RCVBUF, 0);
Os.bind(mUdpSock, Inet4Address.ANY, DhcpPacket.DHCP_CLIENT);
NetworkUtils.protectFromVpn(mUdpSock);
} catch(SocketException|ErrnoException e) {
@@ -308,6 +309,16 @@ public class DhcpClient extends BaseDhcpStateMachine {
return true;
}
+ private boolean connectUdpSock(Inet4Address to) {
+ try {
+ Os.connect(mUdpSock, to, DhcpPacket.DHCP_SERVER);
+ return true;
+ } catch (SocketException|ErrnoException e) {
+ Log.e(TAG, "Error connecting UDP socket", e);
+ return false;
+ }
+ }
+
private static void closeQuietly(FileDescriptor fd) {
try {
IoBridge.closeAndSignalBlockedThreads(fd);
@@ -325,7 +336,7 @@ public class DhcpClient extends BaseDhcpStateMachine {
try {
mNMService.setInterfaceConfig(mIfaceName, ifcg);
} catch (RemoteException|IllegalStateException e) {
- Log.e(TAG, "Error configuring IP address : " + e);
+ Log.e(TAG, "Error configuring IP address " + address + ": ", e);
return false;
}
return true;
@@ -345,21 +356,22 @@ public class DhcpClient extends BaseDhcpStateMachine {
public void run() {
maybeLog("Receive thread started");
while (!stopped) {
+ int length = 0; // Or compiler can't tell it's initialized if a parse error occurs.
try {
- int length = Os.read(mPacketSock, mPacket, 0, mPacket.length);
+ length = Os.read(mPacketSock, mPacket, 0, mPacket.length);
DhcpPacket packet = null;
packet = DhcpPacket.decodeFullPacket(mPacket, length, DhcpPacket.ENCAP_L2);
- if (packet != null) {
- maybeLog("Received packet: " + packet);
- sendMessage(CMD_RECEIVED_PACKET, packet);
- } else if (PACKET_DBG) {
- Log.d(TAG,
- "Can't parse packet" + HexDump.dumpHexString(mPacket, 0, length));
- }
+ maybeLog("Received packet: " + packet);
+ sendMessage(CMD_RECEIVED_PACKET, packet);
} catch (IOException|ErrnoException e) {
if (!stopped) {
Log.e(TAG, "Read error", e);
}
+ } catch (DhcpPacket.ParseException e) {
+ Log.e(TAG, "Can't parse packet: " + e.getMessage());
+ if (PACKET_DBG) {
+ Log.d(TAG, HexDump.dumpHexString(mPacket, 0, length));
+ }
}
}
maybeLog("Receive thread stopped");
@@ -376,8 +388,10 @@ public class DhcpClient extends BaseDhcpStateMachine {
maybeLog("Broadcasting " + description);
Os.sendto(mPacketSock, buf.array(), 0, buf.limit(), 0, mInterfaceBroadcastAddr);
} else {
- maybeLog("Unicasting " + description + " to " + to.getHostAddress());
- Os.sendto(mUdpSock, buf, 0, to, DhcpPacket.DHCP_SERVER);
+ // It's safe to call getpeername here, because we only send unicast packets if we
+ // have an IP address, and we connect the UDP socket in DhcpHaveAddressState#enter.
+ maybeLog("Unicasting " + description + " to " + Os.getpeername(mUdpSock));
+ Os.write(mUdpSock, buf);
}
} catch(ErrnoException|IOException e) {
Log.e(TAG, "Can't send packet: ", e);
@@ -789,6 +803,7 @@ public class DhcpClient extends BaseDhcpStateMachine {
transitionTo(mDhcpBoundState);
}
} else if (packet instanceof DhcpNakPacket) {
+ // TODO: Wait a while before returning into INIT state.
Log.d(TAG, "Received NAK, returning to INIT");
mOffer = null;
transitionTo(mDhcpInitState);
@@ -806,10 +821,8 @@ public class DhcpClient extends BaseDhcpStateMachine {
@Override
public void enter() {
super.enter();
- if (setIpAddress(mDhcpLease.ipAddress)) {
- maybeLog("Configured IP address " + mDhcpLease.ipAddress);
- } else {
- Log.e(TAG, "Failed to configure IP address " + mDhcpLease.ipAddress);
+ if (!setIpAddress(mDhcpLease.ipAddress) ||
+ !connectUdpSock((mDhcpLease.serverAddress))) {
notifyFailure();
// There's likely no point in going into DhcpInitState here, we'll probably just
// repeat the transaction, get the same IP address as before, and fail.
diff --git a/services/net/java/android/net/dhcp/DhcpOfferPacket.java b/services/net/java/android/net/dhcp/DhcpOfferPacket.java
index 7ca7100..99154ef 100644
--- a/services/net/java/android/net/dhcp/DhcpOfferPacket.java
+++ b/services/net/java/android/net/dhcp/DhcpOfferPacket.java
@@ -48,7 +48,7 @@ class DhcpOfferPacket extends DhcpPacket {
}
return s + " OFFER, ip " + mYourIp + ", mask " + mSubnetMask +
- dnsServers + ", gateway " + mGateway +
+ dnsServers + ", gateways " + mGateways +
" lease time " + mLeaseTime + ", domain " + mDomainName;
}
@@ -81,7 +81,7 @@ class DhcpOfferPacket extends DhcpPacket {
}
addTlv(buffer, DHCP_SUBNET_MASK, mSubnetMask);
- addTlv(buffer, DHCP_ROUTER, mGateway);
+ addTlv(buffer, DHCP_ROUTER, mGateways);
addTlv(buffer, DHCP_DOMAIN_NAME, mDomainName);
addTlv(buffer, DHCP_BROADCAST_ADDRESS, mBroadcastAddress);
addTlv(buffer, DHCP_DNS_SERVER, mDnsServers);
diff --git a/services/net/java/android/net/dhcp/DhcpPacket.java b/services/net/java/android/net/dhcp/DhcpPacket.java
index cbf8fc2..8927bfa 100644
--- a/services/net/java/android/net/dhcp/DhcpPacket.java
+++ b/services/net/java/android/net/dhcp/DhcpPacket.java
@@ -114,6 +114,11 @@ abstract class DhcpPacket {
protected static final int MAX_LENGTH = 1500;
/**
+ * The magic cookie that identifies this as a DHCP packet instead of BOOTP.
+ */
+ private static final int DHCP_MAGIC_COOKIE = 0x63825363;
+
+ /**
* DHCP Optional Type: DHCP Subnet Mask
*/
protected static final byte DHCP_SUBNET_MASK = 1;
@@ -123,7 +128,7 @@ abstract class DhcpPacket {
* DHCP Optional Type: DHCP Router
*/
protected static final byte DHCP_ROUTER = 3;
- protected Inet4Address mGateway;
+ protected List <Inet4Address> mGateways;
/**
* DHCP Optional Type: DHCP DNS Server
@@ -403,7 +408,7 @@ abstract class DhcpPacket {
(HWADDR_LEN - mClientMac.length) // pad addr to 16 bytes
+ 64 // empty server host name (64 bytes)
+ 128); // empty boot file name (128 bytes)
- buf.putInt(0x63825363); // magic number
+ buf.putInt(DHCP_MAGIC_COOKIE); // magic number
finishPacket(buf);
// round up to an even number of octets
@@ -668,6 +673,20 @@ abstract class DhcpPacket {
return new String(bytes, 0, length, StandardCharsets.US_ASCII);
}
+ private static boolean isPacketToOrFromClient(short udpSrcPort, short udpDstPort) {
+ return (udpSrcPort == DHCP_CLIENT) || (udpDstPort == DHCP_CLIENT);
+ }
+
+ private static boolean isPacketServerToServer(short udpSrcPort, short udpDstPort) {
+ return (udpSrcPort == DHCP_SERVER) && (udpDstPort == DHCP_SERVER);
+ }
+
+ public static class ParseException extends Exception {
+ public ParseException(String msg, Object... args) {
+ super(String.format(msg, args));
+ }
+ }
+
/**
* Creates a concrete DhcpPacket from the supplied ByteBuffer. The
* buffer may have an L2 encapsulation (which is the full EthernetII
@@ -677,7 +696,7 @@ abstract class DhcpPacket {
* A subset of the optional parameters are parsed and are stored
* in object fields.
*/
- public static DhcpPacket decodeFullPacket(ByteBuffer packet, int pktType)
+ public static DhcpPacket decodeFullPacket(ByteBuffer packet, int pktType) throws ParseException
{
// bootp parameters
int transactionId;
@@ -687,8 +706,8 @@ abstract class DhcpPacket {
Inet4Address nextIp;
Inet4Address relayIp;
byte[] clientMac;
- List<Inet4Address> dnsServers = new ArrayList<Inet4Address>();
- Inet4Address gateway = null; // aka router
+ List<Inet4Address> dnsServers = new ArrayList<>();
+ List<Inet4Address> gateways = new ArrayList<>(); // aka router
Inet4Address serverIdentifier = null;
Inet4Address netMask = null;
String message = null;
@@ -720,7 +739,8 @@ abstract class DhcpPacket {
// check to see if we need to parse L2, IP, and UDP encaps
if (pktType == ENCAP_L2) {
if (packet.remaining() < MIN_PACKET_LENGTH_L2) {
- return null;
+ throw new ParseException("L2 packet too short, %d < %d",
+ packet.remaining(), MIN_PACKET_LENGTH_L2);
}
byte[] l2dst = new byte[6];
@@ -732,18 +752,20 @@ abstract class DhcpPacket {
short l2type = packet.getShort();
if (l2type != OsConstants.ETH_P_IP)
- return null;
+ throw new ParseException("Unexpected L2 type 0x%04x, expected 0x%04x",
+ l2type, OsConstants.ETH_P_IP);
}
if (pktType <= ENCAP_L3) {
if (packet.remaining() < MIN_PACKET_LENGTH_L3) {
- return null;
+ throw new ParseException("L3 packet too short, %d < %d",
+ packet.remaining(), MIN_PACKET_LENGTH_L3);
}
byte ipTypeAndLength = packet.get();
int ipVersion = (ipTypeAndLength & 0xf0) >> 4;
if (ipVersion != 4) {
- return null;
+ throw new ParseException("Invalid IP version %d", ipVersion);
}
// System.out.println("ipType is " + ipType);
@@ -759,8 +781,9 @@ abstract class DhcpPacket {
ipSrc = readIpAddress(packet);
ipDst = readIpAddress(packet);
- if (ipProto != IP_TYPE_UDP) // UDP
- return null;
+ if (ipProto != IP_TYPE_UDP) {
+ throw new ParseException("Protocol not UDP: %d", ipProto);
+ }
// Skip options. This cannot cause us to read beyond the end of the buffer because the
// IPv4 header cannot be more than (0x0f * 4) = 60 bytes long, and that is less than
@@ -776,13 +799,19 @@ abstract class DhcpPacket {
short udpLen = packet.getShort();
short udpChkSum = packet.getShort();
- if ((udpSrcPort != DHCP_SERVER) && (udpSrcPort != DHCP_CLIENT))
+ // Only accept packets to or from the well-known client port (expressly permitting
+ // packets from ports other than the well-known server port; http://b/24687559), and
+ // server-to-server packets, e.g. for relays.
+ if (!isPacketToOrFromClient(udpSrcPort, udpDstPort) &&
+ !isPacketServerToServer(udpSrcPort, udpDstPort)) {
return null;
+ }
}
// We need to check the length even for ENCAP_L3 because the IPv4 header is variable-length.
if (pktType > ENCAP_BOOTP || packet.remaining() < MIN_PACKET_LENGTH_BOOTP) {
- return null;
+ throw new ParseException("Invalid type or BOOTP packet too short, %d < %d",
+ packet.remaining(), MIN_PACKET_LENGTH_BOOTP);
}
byte type = packet.get();
@@ -805,7 +834,7 @@ abstract class DhcpPacket {
packet.get(ipv4addr);
relayIp = (Inet4Address) Inet4Address.getByAddress(ipv4addr);
} catch (UnknownHostException ex) {
- return null;
+ throw new ParseException("Invalid IPv4 address: %s", Arrays.toString(ipv4addr));
}
// Some DHCP servers have been known to announce invalid client hardware address values such
@@ -828,8 +857,10 @@ abstract class DhcpPacket {
int dhcpMagicCookie = packet.getInt();
- if (dhcpMagicCookie != 0x63825363)
- return null;
+ if (dhcpMagicCookie != DHCP_MAGIC_COOKIE) {
+ throw new ParseException("Bad magic cookie 0x%08x, should be 0x%08x", dhcpMagicCookie,
+ DHCP_MAGIC_COOKIE);
+ }
// parse options
boolean notFinishedOptions = true;
@@ -852,8 +883,9 @@ abstract class DhcpPacket {
expectedLen = 4;
break;
case DHCP_ROUTER:
- gateway = readIpAddress(packet);
- expectedLen = 4;
+ for (expectedLen = 0; expectedLen < optionLen; expectedLen += 4) {
+ gateways.add(readIpAddress(packet));
+ }
break;
case DHCP_DNS_SERVER:
for (expectedLen = 0; expectedLen < optionLen; expectedLen += 4) {
@@ -937,18 +969,20 @@ abstract class DhcpPacket {
}
if (expectedLen != optionLen) {
- return null;
+ throw new ParseException("Invalid length %d for option %d, expected %d",
+ optionLen, optionType, expectedLen);
}
}
} catch (BufferUnderflowException e) {
- return null;
+ throw new ParseException("BufferUnderflowException");
}
}
DhcpPacket newPacket;
switch(dhcpType) {
- case -1: return null;
+ case (byte) 0xFF:
+ throw new ParseException("No DHCP message type option");
case DHCP_MESSAGE_TYPE_DISCOVER:
newPacket = new DhcpDiscoverPacket(
transactionId, secs, clientMac, broadcast);
@@ -981,14 +1015,13 @@ abstract class DhcpPacket {
clientMac);
break;
default:
- System.out.println("Unimplemented type: " + dhcpType);
- return null;
+ throw new ParseException("Unimplemented DHCP type %d", dhcpType);
}
newPacket.mBroadcastAddress = bcAddr;
newPacket.mDnsServers = dnsServers;
newPacket.mDomainName = domainName;
- newPacket.mGateway = gateway;
+ newPacket.mGateways = gateways;
newPacket.mHostName = hostName;
newPacket.mLeaseTime = leaseTime;
newPacket.mMessage = message;
@@ -1009,7 +1042,7 @@ abstract class DhcpPacket {
* Parse a packet from an array of bytes, stopping at the given length.
*/
public static DhcpPacket decodeFullPacket(byte[] packet, int length, int pktType)
- {
+ throws ParseException {
ByteBuffer buffer = ByteBuffer.wrap(packet, 0, length).order(ByteOrder.BIG_ENDIAN);
return decodeFullPacket(buffer, pktType);
}
@@ -1044,7 +1077,11 @@ abstract class DhcpPacket {
} catch (IllegalArgumentException e) {
return null;
}
- results.gateway = mGateway;
+
+ if (mGateways.size() > 0) {
+ results.gateway = mGateways.get(0);
+ }
+
results.dnsServers.addAll(mDnsServers);
results.domains = mDomainName;
results.serverAddress = mServerIdentifier;
@@ -1086,11 +1123,11 @@ abstract class DhcpPacket {
public static ByteBuffer buildOfferPacket(int encap, int transactionId,
boolean broadcast, Inet4Address serverIpAddr, Inet4Address clientIpAddr,
byte[] mac, Integer timeout, Inet4Address netMask, Inet4Address bcAddr,
- Inet4Address gateway, List<Inet4Address> dnsServers,
+ List<Inet4Address> gateways, List<Inet4Address> dnsServers,
Inet4Address dhcpServerIdentifier, String domainName) {
DhcpPacket pkt = new DhcpOfferPacket(
transactionId, (short) 0, broadcast, serverIpAddr, INADDR_ANY, clientIpAddr, mac);
- pkt.mGateway = gateway;
+ pkt.mGateways = gateways;
pkt.mDnsServers = dnsServers;
pkt.mLeaseTime = timeout;
pkt.mDomainName = domainName;
@@ -1106,11 +1143,11 @@ abstract class DhcpPacket {
public static ByteBuffer buildAckPacket(int encap, int transactionId,
boolean broadcast, Inet4Address serverIpAddr, Inet4Address clientIpAddr,
byte[] mac, Integer timeout, Inet4Address netMask, Inet4Address bcAddr,
- Inet4Address gateway, List<Inet4Address> dnsServers,
+ List<Inet4Address> gateways, List<Inet4Address> dnsServers,
Inet4Address dhcpServerIdentifier, String domainName) {
DhcpPacket pkt = new DhcpAckPacket(
transactionId, (short) 0, broadcast, serverIpAddr, INADDR_ANY, clientIpAddr, mac);
- pkt.mGateway = gateway;
+ pkt.mGateways = gateways;
pkt.mDnsServers = dnsServers;
pkt.mLeaseTime = timeout;
pkt.mDomainName = domainName;
diff --git a/services/tests/servicestests/src/android/net/dhcp/DhcpPacketTest.java b/services/tests/servicestests/src/android/net/dhcp/DhcpPacketTest.java
index cd3b8bb..7e60bf1 100644
--- a/services/tests/servicestests/src/android/net/dhcp/DhcpPacketTest.java
+++ b/services/tests/servicestests/src/android/net/dhcp/DhcpPacketTest.java
@@ -117,7 +117,7 @@ public class DhcpPacketTest extends TestCase {
private void assertDomainAndVendorInfoParses(
String expectedDomain, byte[] domainBytes,
- String expectedVendorInfo, byte[] vendorInfoBytes) {
+ String expectedVendorInfo, byte[] vendorInfoBytes) throws Exception {
ByteBuffer packet = new TestDhcpPacket(DHCP_MESSAGE_TYPE_OFFER)
.setDomainBytes(domainBytes)
.setVendorInfoBytes(vendorInfoBytes)
@@ -158,17 +158,25 @@ public class DhcpPacketTest extends TestCase {
}
private void assertLeaseTimeParses(boolean expectValid, Integer rawLeaseTime,
- long leaseTimeMillis, byte[] leaseTimeBytes) {
+ long leaseTimeMillis, byte[] leaseTimeBytes) throws Exception {
TestDhcpPacket testPacket = new TestDhcpPacket(DHCP_MESSAGE_TYPE_OFFER);
if (leaseTimeBytes != null) {
testPacket.setLeaseTimeBytes(leaseTimeBytes);
}
ByteBuffer packet = testPacket.build();
- DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_BOOTP);
+ DhcpPacket offerPacket = null;
+
if (!expectValid) {
- assertNull(offerPacket);
+ try {
+ offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_BOOTP);
+ fail("Invalid packet parsed successfully: " + offerPacket);
+ } catch (ParseException expected) {
+ }
return;
}
+
+ offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_BOOTP);
+ assertNotNull(offerPacket);
assertEquals(rawLeaseTime, offerPacket.mLeaseTime);
DhcpResults dhcpResults = offerPacket.toDhcpResults(); // Just check this doesn't crash.
assertEquals(leaseTimeMillis, offerPacket.getLeaseTimeMillis());
@@ -200,14 +208,14 @@ public class DhcpPacketTest extends TestCase {
}
private void checkIpAddress(String expected, Inet4Address clientIp, Inet4Address yourIp,
- byte[] netmaskBytes) {
+ byte[] netmaskBytes) throws Exception {
checkIpAddress(expected, DHCP_MESSAGE_TYPE_OFFER, clientIp, yourIp, netmaskBytes);
checkIpAddress(expected, DHCP_MESSAGE_TYPE_ACK, clientIp, yourIp, netmaskBytes);
}
private void checkIpAddress(String expected, byte type,
Inet4Address clientIp, Inet4Address yourIp,
- byte[] netmaskBytes) {
+ byte[] netmaskBytes) throws Exception {
ByteBuffer packet = new TestDhcpPacket(type, clientIp, yourIp)
.setNetmaskBytes(netmaskBytes)
.build();
@@ -506,4 +514,74 @@ public class DhcpPacketTest extends TestCase {
assertDhcpResults("10.32.158.205/20", "10.32.144.1", "148.88.65.52,148.88.65.53",
"lancs.ac.uk", "10.32.255.128", null, 7200, false, dhcpResults);
}
+
+ @SmallTest
+ public void testUdpServerAnySourcePort() throws Exception {
+ final ByteBuffer packet = ByteBuffer.wrap(HexEncoding.decode((
+ // Ethernet header.
+ "9cd917000000001c2e0000000800" +
+ // IP header.
+ "45a00148000040003d115087d18194fb0a0f7af2" +
+ // UDP header. TODO: fix invalid checksum (due to MAC address obfuscation).
+ // NOTE: The server source port is not the canonical port 67.
+ "C29F004401341268" +
+ // BOOTP header.
+ "02010600d628ba8200000000000000000a0f7af2000000000a0fc818" +
+ // MAC address.
+ "9cd91700000000000000000000000000" +
+ // Server name.
+ "0000000000000000000000000000000000000000000000000000000000000000" +
+ "0000000000000000000000000000000000000000000000000000000000000000" +
+ // File.
+ "0000000000000000000000000000000000000000000000000000000000000000" +
+ "0000000000000000000000000000000000000000000000000000000000000000" +
+ "0000000000000000000000000000000000000000000000000000000000000000" +
+ "0000000000000000000000000000000000000000000000000000000000000000" +
+ // Options.
+ "6382536335010236040a0169fc3304000151800104ffff000003040a0fc817060cd1818003d1819403" +
+ "d18180060f0777766d2e6564751c040a0fffffff000000"
+ ).toCharArray(), false));
+
+ DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L2);
+ assertTrue(offerPacket instanceof DhcpOfferPacket);
+ assertEquals("9CD917000000", HexDump.toHexString(offerPacket.getClientMac()));
+ DhcpResults dhcpResults = offerPacket.toDhcpResults();
+ assertDhcpResults("10.15.122.242/16", "10.15.200.23",
+ "209.129.128.3,209.129.148.3,209.129.128.6",
+ "wvm.edu", "10.1.105.252", null, 86400, false, dhcpResults);
+ }
+
+ @SmallTest
+ public void testMultipleRouters() throws Exception {
+ final ByteBuffer packet = ByteBuffer.wrap(HexEncoding.decode((
+ // Ethernet header.
+ "fc3d93000000" + "081735000000" + "0800" +
+ // IP header.
+ "45000148c2370000ff117ac2c0a8bd02ffffffff" +
+ // UDP header. TODO: fix invalid checksum (due to MAC address obfuscation).
+ "0043004401343beb" +
+ // BOOTP header.
+ "0201060027f518e20000800000000000c0a8bd310000000000000000" +
+ // MAC address.
+ "fc3d9300000000000000000000000000" +
+ // Server name.
+ "0000000000000000000000000000000000000000000000000000000000000000" +
+ "0000000000000000000000000000000000000000000000000000000000000000" +
+ // File.
+ "0000000000000000000000000000000000000000000000000000000000000000" +
+ "0000000000000000000000000000000000000000000000000000000000000000" +
+ "0000000000000000000000000000000000000000000000000000000000000000" +
+ "0000000000000000000000000000000000000000000000000000000000000000" +
+ // Options.
+ "638253633501023604c0abbd023304000070803a04000038403b04000062700104ffffff00" +
+ "0308c0a8bd01ffffff0006080808080808080404ff000000000000"
+ ).toCharArray(), false));
+
+ DhcpPacket offerPacket = DhcpPacket.decodeFullPacket(packet, ENCAP_L2);
+ assertTrue(offerPacket instanceof DhcpOfferPacket);
+ assertEquals("FC3D93000000", HexDump.toHexString(offerPacket.getClientMac()));
+ DhcpResults dhcpResults = offerPacket.toDhcpResults();
+ assertDhcpResults("192.168.189.49/24", "192.168.189.1", "8.8.8.8,8.8.4.4",
+ null, "192.171.189.2", null, 28800, false, dhcpResults);
+ }
}
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 4146c1c..5ad796f 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -314,6 +314,8 @@ public class UsageStatsService extends SystemService implements
mAppIdleParoled = paroled;
if (DEBUG) Slog.d(TAG, "Changing paroled to " + mAppIdleParoled);
if (paroled) {
+ postParoleEndTimeout();
+ } else {
mLastAppIdleParoledTime = checkAndGetTimeLocked();
postNextParoleTimeout();
}
@@ -404,8 +406,6 @@ public class UsageStatsService extends SystemService implements
if (timeSinceLastParole > mAppIdleParoleIntervalMillis) {
if (DEBUG) Slog.d(TAG, "Crossed default parole interval");
setAppIdleParoled(true);
- // Make sure it ends at some point
- postParoleEndTimeout();
} else {
if (DEBUG) Slog.d(TAG, "Not long enough to go to parole");
postNextParoleTimeout();
@@ -492,7 +492,6 @@ public class UsageStatsService extends SystemService implements
if (!deviceIdle
&& timeSinceLastParole >= mAppIdleParoleIntervalMillis) {
if (DEBUG) Slog.i(TAG, "Bringing idle apps out of inactive state due to deviceIdleMode=false");
- postNextParoleTimeout();
setAppIdleParoled(true);
} else if (deviceIdle) {
if (DEBUG) Slog.i(TAG, "Device idle, back to prison");
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index a8874d0..a96c164 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -925,7 +925,7 @@ public class VoiceInteractionManagerService extends SystemService {
return;
}
synchronized (this) {
- pw.println("VOICE INTERACTION MANAGER (dumpsys voiceinteraction)\n");
+ pw.println("VOICE INTERACTION MANAGER (dumpsys voiceinteraction)");
pw.println(" mEnableService: " + mEnableService);
if (mImpl == null) {
pw.println(" (No active implementation)");
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index 28520be..30296e1 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -36,6 +36,7 @@ import android.service.voice.IVoiceInteractionService;
import android.service.voice.IVoiceInteractionSession;
import android.service.voice.VoiceInteractionService;
import android.service.voice.VoiceInteractionServiceInfo;
+import android.util.PrintWriterPrinter;
import android.util.Slog;
import android.view.IWindowManager;
@@ -114,9 +115,9 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne
mAm = ActivityManagerNative.getDefault();
VoiceInteractionServiceInfo info;
try {
- info = new VoiceInteractionServiceInfo(context.getPackageManager(), service);
- } catch (PackageManager.NameNotFoundException e) {
- Slog.w(TAG, "Voice interaction service not found: " + service);
+ info = new VoiceInteractionServiceInfo(context.getPackageManager(), service, mUser);
+ } catch (RemoteException|PackageManager.NameNotFoundException e) {
+ Slog.w(TAG, "Voice interaction service not found: " + service, e);
mInfo = null;
mSessionComponentName = null;
mIWindowManager = null;
@@ -260,9 +261,18 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne
}
return;
}
+ pw.print(" mUser="); pw.println(mUser);
pw.print(" mComponent="); pw.println(mComponent.flattenToShortString());
pw.print(" Session service="); pw.println(mInfo.getSessionService());
+ pw.println(" Service info:");
+ mInfo.getServiceInfo().dump(new PrintWriterPrinter(pw), " ");
+ pw.println(" Application info:");
+ mInfo.getServiceInfo().applicationInfo.dump(new PrintWriterPrinter(pw), " ");
+ pw.print(" Recognition service="); pw.println(mInfo.getRecognitionService());
pw.print(" Settings activity="); pw.println(mInfo.getSettingsActivity());
+ pw.print(" Supports assist="); pw.println(mInfo.getSupportsAssist());
+ pw.print(" Supports launch from keyguard=");
+ pw.println(mInfo.getSupportsLaunchFromKeyguard());
if (mDisabledShowContext != 0) {
pw.print(" mDisabledShowContext=");
pw.println(Integer.toHexString(mDisabledShowContext));