summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--api/current.txt2
-rw-r--r--api/system-current.txt2
-rw-r--r--api/test-current.txt2
-rw-r--r--core/java/android/app/Notification.java30
-rw-r--r--core/java/android/app/job/JobInfo.java37
-rw-r--r--core/java/android/content/pm/ActivityInfo.java2
-rw-r--r--core/java/android/content/pm/PackageParser.java30
-rw-r--r--core/java/android/hardware/location/ContextHubInfo.java5
-rw-r--r--core/java/android/net/ConnectivityManager.java21
-rw-r--r--core/java/android/net/IConnectivityManager.aidl6
-rw-r--r--core/java/android/net/INetworkPolicyManager.aidl3
-rw-r--r--core/java/android/os/BatteryStats.java16
-rw-r--r--core/java/android/os/INetworkManagementService.aidl5
-rwxr-xr-xcore/java/android/provider/Settings.java27
-rw-r--r--core/java/android/service/notification/NotificationListenerService.java4
-rw-r--r--core/java/android/view/ViewRootImpl.java11
-rw-r--r--core/java/com/android/internal/app/IBatteryStats.aidl3
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java139
-rw-r--r--core/jni/android_hardware_location_ContextHubService.cpp44
-rw-r--r--core/res/res/values/attrs_manifest.xml10
-rw-r--r--core/res/res/values/public.xml1
-rw-r--r--core/res/res/values/strings.xml44
-rw-r--r--core/res/res/values/themes_holo.xml3
-rw-r--r--docs/html/preview/behavior-changes.jd10
-rw-r--r--media/java/android/media/MediaCodecInfo.java3
-rw-r--r--packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java8
-rw-r--r--packages/SystemUI/res/layout/volume_dialog_row.xml1
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java19
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java5
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java1
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java26
-rw-r--r--services/backup/java/com/android/server/backup/BackupManagerService.java19
-rw-r--r--services/core/java/com/android/server/BatteryService.java2
-rw-r--r--services/core/java/com/android/server/ConnectivityService.java113
-rw-r--r--services/core/java/com/android/server/NetworkManagementService.java61
-rw-r--r--services/core/java/com/android/server/accounts/AccountManagerService.java81
-rw-r--r--services/core/java/com/android/server/am/ActivityStarter.java3
-rw-r--r--services/core/java/com/android/server/am/AppErrors.java247
-rw-r--r--services/core/java/com/android/server/am/BatteryStatsService.java8
-rw-r--r--services/core/java/com/android/server/job/JobStore.java5
-rw-r--r--services/core/java/com/android/server/job/controllers/ConnectivityController.java5
-rw-r--r--services/core/java/com/android/server/job/controllers/JobStatus.java23
-rw-r--r--services/core/java/com/android/server/net/NetworkPolicyManagerService.java108
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java60
-rw-r--r--services/core/java/com/android/server/wm/WindowStateAnimator.java12
-rwxr-xr-xtools/fonts/fontchain_lint.py16
-rw-r--r--tools/layoutlib/Android.mk2
-rw-r--r--tools/layoutlib/bridge/Android.mk1
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java19
-rw-r--r--tools/layoutlib/bridge/tests/Android.mk2
-rw-r--r--tools/layoutlib/create/Android.mk2
-rw-r--r--tools/layoutlib/create/tests/Android.mk2
58 files changed, 1011 insertions, 353 deletions
diff --git a/api/current.txt b/api/current.txt
index 5e4b2d4eb958..b7b65f1402c7 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5241,6 +5241,7 @@ package android.app {
method public boolean getContentIntentAvailableOffline();
method public int getCustomContentHeight();
method public int getCustomSizePreset();
+ method public java.lang.String getDismissalId();
method public android.app.PendingIntent getDisplayIntent();
method public int getGravity();
method public boolean getHintAmbientBigPicture();
@@ -5258,6 +5259,7 @@ package android.app {
method public android.app.Notification.WearableExtender setContentIntentAvailableOffline(boolean);
method public android.app.Notification.WearableExtender setCustomContentHeight(int);
method public android.app.Notification.WearableExtender setCustomSizePreset(int);
+ method public android.app.Notification.WearableExtender setDismissalId(java.lang.String);
method public android.app.Notification.WearableExtender setDisplayIntent(android.app.PendingIntent);
method public android.app.Notification.WearableExtender setGravity(int);
method public android.app.Notification.WearableExtender setHintAmbientBigPicture(boolean);
diff --git a/api/system-current.txt b/api/system-current.txt
index bde3a8cd7bb1..6b5f1e992d3d 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5386,6 +5386,7 @@ package android.app {
method public boolean getContentIntentAvailableOffline();
method public int getCustomContentHeight();
method public int getCustomSizePreset();
+ method public java.lang.String getDismissalId();
method public android.app.PendingIntent getDisplayIntent();
method public int getGravity();
method public boolean getHintAmbientBigPicture();
@@ -5403,6 +5404,7 @@ package android.app {
method public android.app.Notification.WearableExtender setContentIntentAvailableOffline(boolean);
method public android.app.Notification.WearableExtender setCustomContentHeight(int);
method public android.app.Notification.WearableExtender setCustomSizePreset(int);
+ method public android.app.Notification.WearableExtender setDismissalId(java.lang.String);
method public android.app.Notification.WearableExtender setDisplayIntent(android.app.PendingIntent);
method public android.app.Notification.WearableExtender setGravity(int);
method public android.app.Notification.WearableExtender setHintAmbientBigPicture(boolean);
diff --git a/api/test-current.txt b/api/test-current.txt
index 91415066a3df..ae58f3685f16 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -5241,6 +5241,7 @@ package android.app {
method public boolean getContentIntentAvailableOffline();
method public int getCustomContentHeight();
method public int getCustomSizePreset();
+ method public java.lang.String getDismissalId();
method public android.app.PendingIntent getDisplayIntent();
method public int getGravity();
method public boolean getHintAmbientBigPicture();
@@ -5258,6 +5259,7 @@ package android.app {
method public android.app.Notification.WearableExtender setContentIntentAvailableOffline(boolean);
method public android.app.Notification.WearableExtender setCustomContentHeight(int);
method public android.app.Notification.WearableExtender setCustomSizePreset(int);
+ method public android.app.Notification.WearableExtender setDismissalId(java.lang.String);
method public android.app.Notification.WearableExtender setDisplayIntent(android.app.PendingIntent);
method public android.app.Notification.WearableExtender setGravity(int);
method public android.app.Notification.WearableExtender setHintAmbientBigPicture(boolean);
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 20037ce30cdb..0c2e3c189aae 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -5486,6 +5486,7 @@ public class Notification implements Parcelable
private static final String KEY_CUSTOM_CONTENT_HEIGHT = "customContentHeight";
private static final String KEY_GRAVITY = "gravity";
private static final String KEY_HINT_SCREEN_TIMEOUT = "hintScreenTimeout";
+ private static final String KEY_DISMISSAL_ID = "dismissalId";
// Flags bitwise-ored to mFlags
private static final int FLAG_CONTENT_INTENT_AVAILABLE_OFFLINE = 0x1;
@@ -5514,6 +5515,7 @@ public class Notification implements Parcelable
private int mCustomContentHeight;
private int mGravity = DEFAULT_GRAVITY;
private int mHintScreenTimeout;
+ private String mDismissalId;
/**
* Create a {@link android.app.Notification.WearableExtender} with default
@@ -5550,6 +5552,7 @@ public class Notification implements Parcelable
mCustomContentHeight = wearableBundle.getInt(KEY_CUSTOM_CONTENT_HEIGHT);
mGravity = wearableBundle.getInt(KEY_GRAVITY, DEFAULT_GRAVITY);
mHintScreenTimeout = wearableBundle.getInt(KEY_HINT_SCREEN_TIMEOUT);
+ mDismissalId = wearableBundle.getString(KEY_DISMISSAL_ID);
}
}
@@ -5600,6 +5603,9 @@ public class Notification implements Parcelable
if (mHintScreenTimeout != 0) {
wearableBundle.putInt(KEY_HINT_SCREEN_TIMEOUT, mHintScreenTimeout);
}
+ if (mDismissalId != null) {
+ wearableBundle.putString(KEY_DISMISSAL_ID, mDismissalId);
+ }
builder.getExtras().putBundle(EXTRA_WEARABLE_EXTENSIONS, wearableBundle);
return builder;
@@ -5620,6 +5626,7 @@ public class Notification implements Parcelable
that.mCustomContentHeight = this.mCustomContentHeight;
that.mGravity = this.mGravity;
that.mHintScreenTimeout = this.mHintScreenTimeout;
+ that.mDismissalId = this.mDismissalId;
return that;
}
@@ -6107,6 +6114,29 @@ public class Notification implements Parcelable
return (mFlags & FLAG_HINT_CONTENT_INTENT_LAUNCHES_ACTIVITY) != 0;
}
+ /**
+ * When you post a notification, if you set the dismissal id field, then when that
+ * notification is canceled, notifications on other wearables and the paired Android phone
+ * having that same dismissal id will also be canceled. Note that this only works if you
+ * have notification bridge mode set to NO_BRIDGING in your Wear app manifest. See
+ * <a href="{@docRoot}wear/notifications/index.html">Adding Wearable Features to
+ * Notifications</a> for more information on how to use the bridge mode feature.
+ * @param dismissalId the dismissal id of the notification.
+ * @return this object for method chaining
+ */
+ public WearableExtender setDismissalId(String dismissalId) {
+ mDismissalId = dismissalId;
+ return this;
+ }
+
+ /**
+ * Returns the dismissal id of the notification.
+ * @return the dismissal id of the notification or null if it has not been set.
+ */
+ public String getDismissalId() {
+ return mDismissalId;
+ }
+
private void setFlag(int mask, boolean value) {
if (value) {
mFlags |= mask;
diff --git a/core/java/android/app/job/JobInfo.java b/core/java/android/app/job/JobInfo.java
index ecfc527cb7f3..c47557501b64 100644
--- a/core/java/android/app/job/JobInfo.java
+++ b/core/java/android/app/job/JobInfo.java
@@ -16,6 +16,8 @@
package android.app.job;
+import static android.util.TimeUtils.formatDuration;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.ComponentName;
@@ -24,7 +26,6 @@ import android.os.Parcel;
import android.os.Parcelable;
import android.os.PersistableBundle;
import android.util.Log;
-import static android.util.TimeUtils.formatDuration;
import java.util.ArrayList;
@@ -154,6 +155,20 @@ public class JobInfo implements Parcelable {
*/
public static final int PRIORITY_ADJ_ALWAYS_RUNNING = -80;
+ /**
+ * Indicates that the implementation of this job will be using
+ * {@link JobService#startForeground(int, android.app.Notification)} to run
+ * in the foreground.
+ * <p>
+ * When set, the internal scheduling of this job will ignore any background
+ * network restrictions for the requesting app. Note that this flag alone
+ * doesn't actually place your {@link JobService} in the foreground; you
+ * still need to post the notification yourself.
+ *
+ * @hide
+ */
+ public static final int FLAG_WILL_BE_FOREGROUND = 1 << 0;
+
private final int jobId;
private final PersistableBundle extras;
private final ComponentName service;
@@ -174,6 +189,7 @@ public class JobInfo implements Parcelable {
private final long initialBackoffMillis;
private final int backoffPolicy;
private final int priority;
+ private final int flags;
/**
* Unique job id associated with this class. This is assigned to your job by the scheduler.
@@ -201,6 +217,11 @@ public class JobInfo implements Parcelable {
return priority;
}
+ /** @hide */
+ public int getFlags() {
+ return flags;
+ }
+
/**
* Whether this job needs the device to be plugged in.
*/
@@ -356,6 +377,7 @@ public class JobInfo implements Parcelable {
hasEarlyConstraint = in.readInt() == 1;
hasLateConstraint = in.readInt() == 1;
priority = in.readInt();
+ flags = in.readInt();
}
private JobInfo(JobInfo.Builder b) {
@@ -381,6 +403,7 @@ public class JobInfo implements Parcelable {
hasEarlyConstraint = b.mHasEarlyConstraint;
hasLateConstraint = b.mHasLateConstraint;
priority = b.mPriority;
+ flags = b.mFlags;
}
@Override
@@ -410,6 +433,7 @@ public class JobInfo implements Parcelable {
out.writeInt(hasEarlyConstraint ? 1 : 0);
out.writeInt(hasLateConstraint ? 1 : 0);
out.writeInt(priority);
+ out.writeInt(this.flags);
}
public static final Creator<JobInfo> CREATOR = new Creator<JobInfo>() {
@@ -504,6 +528,7 @@ public class JobInfo implements Parcelable {
private PersistableBundle mExtras = PersistableBundle.EMPTY;
private ComponentName mJobService;
private int mPriority = PRIORITY_DEFAULT;
+ private int mFlags;
// Requirements.
private boolean mRequiresCharging;
private boolean mRequiresDeviceIdle;
@@ -539,14 +564,18 @@ public class JobInfo implements Parcelable {
mJobId = jobId;
}
- /**
- * @hide
- */
+ /** @hide */
public Builder setPriority(int priority) {
mPriority = priority;
return this;
}
+ /** @hide */
+ public Builder setFlags(int flags) {
+ mFlags = flags;
+ return this;
+ }
+
/**
* Set optional extras. This is persisted, so we only allow primitive types.
* @param extras Bundle containing extras you want the scheduler to hold on to for you.
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 167befc089dd..bdea1e009eb0 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -188,7 +188,7 @@ public class ActivityInfo extends ComponentInfo
* See {@link android.R.attr#resizeableActivity}.
* @hide
*/
- public int resizeMode;
+ public int resizeMode = RESIZE_MODE_RESIZEABLE;
/**
* Name of the VrListenerService component to run for this activity.
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 66c500063861..6534f5b32456 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -159,6 +159,7 @@ public class PackageParser {
private static final String TAG_SUPPORTS_INPUT = "supports-input";
private static final String TAG_EAT_COMMENT = "eat-comment";
private static final String TAG_PACKAGE = "package";
+ private static final String TAG_RESTRICT_UPDATE = "restrict-update";
// These are the tags supported by child packages
private static final Set<String> CHILD_PACKAGE_TAGS = new ArraySet<>();
@@ -1639,9 +1640,9 @@ public class PackageParser {
/**
* This is the common parsing routing for handling parent and child
* packages in a base APK. The difference between parent and child
- * parsing is that some targs are not supported by child packages as
+ * parsing is that some tags are not supported by child packages as
* well as some manifest attributes are ignored. The implementation
- * assumes the calling code already handled the manifest tag if needed
+ * assumes the calling code has already handled the manifest tag if needed
* (this applies to the parent only).
*
* @param pkg The package which to populate
@@ -2089,6 +2090,29 @@ public class PackageParser {
// If parsing a child failed the error is already set
return null;
}
+
+ } else if (tagName.equals(TAG_RESTRICT_UPDATE)) {
+ if ((flags & PARSE_IS_SYSTEM_DIR) != 0) {
+ sa = res.obtainAttributes(parser,
+ com.android.internal.R.styleable.AndroidManifestRestrictUpdate);
+ final String hash = sa.getNonConfigurationString(
+ com.android.internal.R.styleable.AndroidManifestRestrictUpdate_hash, 0);
+ sa.recycle();
+
+ pkg.restrictUpdateHash = null;
+ if (hash != null) {
+ final int hashLength = hash.length();
+ final byte[] hashBytes = new byte[hashLength / 2];
+ for (int i = 0; i < hashLength; i += 2){
+ hashBytes[i/2] = (byte) ((Character.digit(hash.charAt(i), 16) << 4)
+ + Character.digit(hash.charAt(i + 1), 16));
+ }
+ pkg.restrictUpdateHash = hashBytes;
+ }
+ }
+
+ XmlUtils.skipCurrentTag(parser);
+
} else if (RIGID_PARSER) {
outError[0] = "Bad element under <manifest>: "
+ parser.getName();
@@ -4822,6 +4846,8 @@ public class PackageParser {
*/
public boolean use32bitAbi;
+ public byte[] restrictUpdateHash;
+
public Package(String packageName) {
this.packageName = packageName;
applicationInfo.packageName = packageName;
diff --git a/core/java/android/hardware/location/ContextHubInfo.java b/core/java/android/hardware/location/ContextHubInfo.java
index 194b9ee58780..aaf6c57b9abe 100644
--- a/core/java/android/hardware/location/ContextHubInfo.java
+++ b/core/java/android/hardware/location/ContextHubInfo.java
@@ -357,6 +357,7 @@ public class ContextHubInfo {
retVal += "\n\tPeakMips : " + mPeakMips;
retVal += ", StoppedPowerDraw : " + mStoppedPowerDrawMw + " mW";
retVal += ", PeakPowerDraw : " + mPeakPowerDrawMw + " mW";
+ retVal += ", MaxPacketLength : " + mMaxPacketLengthBytes + " Bytes";
retVal += "\n\tSupported sensors : " + Arrays.toString(mSupportedSensors);
retVal += "\n\tMemory Regions : " + Arrays.toString(mMemoryRegions);
@@ -375,6 +376,7 @@ public class ContextHubInfo {
mStoppedPowerDrawMw = in.readFloat();
mSleepPowerDrawMw = in.readFloat();
mPeakPowerDrawMw = in.readFloat();
+ mMaxPacketLengthBytes = in.readInt();
int numSupportedSensors = in.readInt();
mSupportedSensors = new int[numSupportedSensors];
@@ -398,6 +400,7 @@ public class ContextHubInfo {
out.writeFloat(mStoppedPowerDrawMw);
out.writeFloat(mSleepPowerDrawMw);
out.writeFloat(mPeakPowerDrawMw);
+ out.writeInt(mMaxPacketLengthBytes);
out.writeInt(mSupportedSensors.length);
out.writeIntArray(mSupportedSensors);
@@ -414,4 +417,4 @@ public class ContextHubInfo {
return new ContextHubInfo[size];
}
};
-} \ No newline at end of file
+}
diff --git a/core/java/android/net/ConnectivityManager.java b/core/java/android/net/ConnectivityManager.java
index faf5c64e5a00..933dddf4a948 100644
--- a/core/java/android/net/ConnectivityManager.java
+++ b/core/java/android/net/ConnectivityManager.java
@@ -774,8 +774,13 @@ public class ConnectivityManager {
* @hide
*/
public Network getActiveNetworkForUid(int uid) {
+ return getActiveNetworkForUid(uid, false);
+ }
+
+ /** {@hide} */
+ public Network getActiveNetworkForUid(int uid, boolean ignoreBlocked) {
try {
- return mService.getActiveNetworkForUid(uid);
+ return mService.getActiveNetworkForUid(uid, ignoreBlocked);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -836,8 +841,13 @@ public class ConnectivityManager {
* {@hide}
*/
public NetworkInfo getActiveNetworkInfoForUid(int uid) {
+ return getActiveNetworkInfoForUid(uid, false);
+ }
+
+ /** {@hide} */
+ public NetworkInfo getActiveNetworkInfoForUid(int uid, boolean ignoreBlocked) {
try {
- return mService.getActiveNetworkInfoForUid(uid);
+ return mService.getActiveNetworkInfoForUid(uid, ignoreBlocked);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -880,8 +890,13 @@ public class ConnectivityManager {
* is not valid.
*/
public NetworkInfo getNetworkInfo(Network network) {
+ return getNetworkInfoForUid(network, Process.myUid(), false);
+ }
+
+ /** {@hide} */
+ public NetworkInfo getNetworkInfoForUid(Network network, int uid, boolean ignoreBlocked) {
try {
- return mService.getNetworkInfoForNetwork(network);
+ return mService.getNetworkInfoForUid(network, uid, ignoreBlocked);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/net/IConnectivityManager.aidl b/core/java/android/net/IConnectivityManager.aidl
index c897c4506c1f..aec6b3ec23fe 100644
--- a/core/java/android/net/IConnectivityManager.aidl
+++ b/core/java/android/net/IConnectivityManager.aidl
@@ -44,11 +44,11 @@ import com.android.internal.net.VpnProfile;
interface IConnectivityManager
{
Network getActiveNetwork();
- Network getActiveNetworkForUid(int uid);
+ Network getActiveNetworkForUid(int uid, boolean ignoreBlocked);
NetworkInfo getActiveNetworkInfo();
- NetworkInfo getActiveNetworkInfoForUid(int uid);
+ NetworkInfo getActiveNetworkInfoForUid(int uid, boolean ignoreBlocked);
NetworkInfo getNetworkInfo(int networkType);
- NetworkInfo getNetworkInfoForNetwork(in Network network);
+ NetworkInfo getNetworkInfoForUid(in Network network, int uid, boolean ignoreBlocked);
NetworkInfo[] getAllNetworkInfo();
Network getNetworkForType(int networkType);
Network[] getAllNetworks();
diff --git a/core/java/android/net/INetworkPolicyManager.aidl b/core/java/android/net/INetworkPolicyManager.aidl
index 2b8b28d91bd0..224ff5b395c7 100644
--- a/core/java/android/net/INetworkPolicyManager.aidl
+++ b/core/java/android/net/INetworkPolicyManager.aidl
@@ -38,6 +38,9 @@ interface INetworkPolicyManager {
boolean isUidForeground(int uid);
+ /** Higher priority listener before general event dispatch */
+ void setConnectivityListener(INetworkPolicyListener listener);
+
void registerListener(INetworkPolicyListener listener);
void unregisterListener(INetworkPolicyListener listener);
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 2c63be255c0b..959b30946c8a 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -1157,6 +1157,8 @@ public abstract class BatteryStats implements Parcelable {
public short batteryTemperature;
public char batteryVoltage;
+
+ public int batteryChargeCoulombs;
// Constants from SCREEN_BRIGHTNESS_*
public static final int STATE_BRIGHTNESS_SHIFT = 0;
@@ -1181,6 +1183,8 @@ public abstract class BatteryStats implements Parcelable {
public static final int STATE_WIFI_SCAN_FLAG = 1<<27;
public static final int STATE_WIFI_RADIO_ACTIVE_FLAG = 1<<26;
public static final int STATE_MOBILE_RADIO_ACTIVE_FLAG = 1<<25;
+ // Do not use, this is used for coulomb delta count.
+ private static final int STATE_RESERVED_0 = 1<<24;
// These are on the lower bits used for the command; if they change
// we need to write another int of data.
public static final int STATE_SENSOR_ON_FLAG = 1<<23;
@@ -1352,6 +1356,7 @@ public abstract class BatteryStats implements Parcelable {
bat = (((int)batteryTemperature)&0xffff)
| ((((int)batteryVoltage)<<16)&0xffff0000);
dest.writeInt(bat);
+ dest.writeInt(batteryChargeCoulombs);
dest.writeInt(states);
dest.writeInt(states2);
if (wakelockTag != null) {
@@ -1380,6 +1385,7 @@ public abstract class BatteryStats implements Parcelable {
int bat2 = src.readInt();
batteryTemperature = (short)(bat2&0xffff);
batteryVoltage = (char)((bat2>>16)&0xffff);
+ batteryChargeCoulombs = src.readInt();
states = src.readInt();
states2 = src.readInt();
if ((bat&0x10000000) != 0) {
@@ -1419,6 +1425,7 @@ public abstract class BatteryStats implements Parcelable {
batteryPlugType = 0;
batteryTemperature = 0;
batteryVoltage = 0;
+ batteryChargeCoulombs = 0;
states = 0;
states2 = 0;
wakelockTag = null;
@@ -1446,6 +1453,7 @@ public abstract class BatteryStats implements Parcelable {
batteryPlugType = o.batteryPlugType;
batteryTemperature = o.batteryTemperature;
batteryVoltage = o.batteryVoltage;
+ batteryChargeCoulombs = o.batteryChargeCoulombs;
states = o.states;
states2 = o.states2;
if (o.wakelockTag != null) {
@@ -1477,6 +1485,7 @@ public abstract class BatteryStats implements Parcelable {
&& batteryPlugType == o.batteryPlugType
&& batteryTemperature == o.batteryTemperature
&& batteryVoltage == o.batteryVoltage
+ && batteryChargeCoulombs == o.batteryChargeCoulombs
&& states == o.states
&& states2 == o.states2
&& currentTime == o.currentTime;
@@ -4527,6 +4536,7 @@ public abstract class BatteryStats implements Parcelable {
int oldPlug = -1;
int oldTemp = -1;
int oldVolt = -1;
+ int oldCharge = -1;
long lastTime = -1;
void reset() {
@@ -4537,6 +4547,7 @@ public abstract class BatteryStats implements Parcelable {
oldPlug = -1;
oldTemp = -1;
oldVolt = -1;
+ oldCharge = -1;
}
public void printNextItem(PrintWriter pw, HistoryItem rec, long baseTime, boolean checkin,
@@ -4698,6 +4709,11 @@ public abstract class BatteryStats implements Parcelable {
pw.print(checkin ? ",Bv=" : " volt=");
pw.print(oldVolt);
}
+ if (oldCharge != rec.batteryChargeCoulombs) {
+ oldCharge = rec.batteryChargeCoulombs;
+ pw.print(checkin ? ",Bcc=" : " charge=");
+ pw.print(oldCharge);
+ }
printBitDescriptions(pw, oldState, rec.states, rec.wakelockTag,
HISTORY_STATE_DESCRIPTIONS, !checkin);
printBitDescriptions(pw, oldState2, rec.states2, null,
diff --git a/core/java/android/os/INetworkManagementService.aidl b/core/java/android/os/INetworkManagementService.aidl
index 68b0a9fb2969..b546da021e18 100644
--- a/core/java/android/os/INetworkManagementService.aidl
+++ b/core/java/android/os/INetworkManagementService.aidl
@@ -324,6 +324,11 @@ interface INetworkManagementService
void removeIdleTimer(String iface);
/**
+ * Configure name servers, search paths, and resolver parameters for the given network.
+ */
+ void setDnsConfigurationForNetwork(int netId, in String[] servers, String domains);
+
+ /**
* Bind name servers to a network in the DNS resolver.
*/
void setDnsServersForNetwork(int netId, in String[] servers, String domains);
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index d98e2177058a..700c2d28b3dd 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -6974,6 +6974,33 @@ public final class Settings {
public static final String STORAGE_BENCHMARK_INTERVAL = "storage_benchmark_interval";
/**
+ * Sample validity in seconds to configure for the system DNS resolver.
+ * {@hide}
+ */
+ public static final String DNS_RESOLVER_SAMPLE_VALIDITY_SECONDS =
+ "dns_resolver_sample_validity_seconds";
+
+ /**
+ * Success threshold in percent for use with the system DNS resolver.
+ * {@hide}
+ */
+ public static final String DNS_RESOLVER_SUCCESS_THRESHOLD_PERCENT =
+ "dns_resolver_success_threshold_percent";
+
+ /**
+ * Minimum number of samples needed for statistics to be considered meaningful in the
+ * system DNS resolver.
+ * {@hide}
+ */
+ public static final String DNS_RESOLVER_MIN_SAMPLES = "dns_resolver_min_samples";
+
+ /**
+ * Maximum number taken into account for statistics purposes in the system DNS resolver.
+ * {@hide}
+ */
+ public static final String DNS_RESOLVER_MAX_SAMPLES = "dns_resolver_max_samples";
+
+ /**
* Whether to disable the automatic scheduling of system updates.
* 1 = system updates won't be automatically scheduled (will always
* present notification instead).
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index e708b0ad5aff..cf783d25251e 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -764,9 +764,9 @@ public abstract class NotificationListenerService extends Service {
}
mSystemContext = context;
INotificationManager noMan = getNotificationInterface();
- noMan.registerListener(mWrapper, componentName, currentUser);
- mCurrentUser = currentUser;
mHandler = new MyHandler(context.getMainLooper());
+ mCurrentUser = currentUser;
+ noMan.registerListener(mWrapper, componentName, currentUser);
}
/**
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index a0384f2601d3..edf05ba5fc33 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -389,6 +389,8 @@ public final class ViewRootImpl implements ViewParent,
/** Set to true once doDie() has been called. */
private boolean mRemoved;
+ private boolean mNeedsHwRendererSetup;
+
/**
* Consistency verifier for debugging purposes.
*/
@@ -915,6 +917,11 @@ public final class ViewRootImpl implements ViewParent,
mWindowAttributes.surfaceInsets.set(
oldInsetLeft, oldInsetTop, oldInsetRight, oldInsetBottom);
mWindowAttributes.hasManualSurfaceInsets = oldHasManualSurfaceInsets;
+ } else if (mWindowAttributes.surfaceInsets.left != oldInsetLeft
+ || mWindowAttributes.surfaceInsets.top != oldInsetTop
+ || mWindowAttributes.surfaceInsets.right != oldInsetRight
+ || mWindowAttributes.surfaceInsets.bottom != oldInsetBottom) {
+ mNeedsHwRendererSetup = true;
}
applyKeepScreenOnFlag(mWindowAttributes);
@@ -1959,9 +1966,11 @@ public final class ViewRootImpl implements ViewParent,
if (hardwareRenderer != null && hardwareRenderer.isEnabled()) {
if (hwInitialized
|| mWidth != hardwareRenderer.getWidth()
- || mHeight != hardwareRenderer.getHeight()) {
+ || mHeight != hardwareRenderer.getHeight()
+ || mNeedsHwRendererSetup) {
hardwareRenderer.setup(mWidth, mHeight, mAttachInfo,
mWindowAttributes.surfaceInsets);
+ mNeedsHwRendererSetup = false;
}
}
diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl
index a2a135b59a73..42b89d53c9b6 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -122,7 +122,8 @@ interface IBatteryStats {
void noteNetworkInterfaceType(String iface, int type);
void noteNetworkStatsEnabled();
void noteDeviceIdleMode(int mode, String activeReason, int activeUid);
- void setBatteryState(int status, int health, int plugType, int level, int temp, int volt);
+ void setBatteryState(int status, int health, int plugType, int level, int temp, int volt,
+ int chargeCount);
long getAwakeTimeBattery();
long getAwakeTimePlugged();
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 5358d78e1b02..654a4f19e0dc 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -108,7 +108,7 @@ public class BatteryStatsImpl extends BatteryStats {
private static final int MAGIC = 0xBA757475; // 'BATSTATS'
// Current on-disk Parcel version
- private static final int VERSION = 143 + (USE_OLD_HISTORY ? 1000 : 0);
+ private static final int VERSION = 144 + (USE_OLD_HISTORY ? 1000 : 0);
// Maximum number of items we will record in the history.
private static final int MAX_HISTORY_ITEMS = 2000;
@@ -2089,27 +2089,111 @@ public class BatteryStatsImpl extends BatteryStats {
tag.poolIdx = index;
}
+ /*
+ The history delta format uses flags to denote further data in subsequent ints in the parcel.
+
+ There is always the first token, which may contain the delta time, or an indicator of
+ the length of the time (int or long) following this token.
+
+ First token: always present,
+ 31 23 15 7 0
+ â–ˆM|L|K|J|I|H|G|Fâ–ˆE|D|C|B|A|T|T|Tâ–ˆT|T|T|T|T|T|T|Tâ–ˆT|T|T|T|T|T|T|Tâ–ˆ
+
+ T: the delta time if it is <= 0x7fffd. Otherwise 0x7fffe indicates an int immediately
+ follows containing the time, and 0x7ffff indicates a long immediately follows with the
+ delta time.
+ A: battery level changed and an int follows with battery data.
+ B: state changed and an int follows with state change data.
+ C: state2 has changed and an int follows with state2 change data.
+ D: wakelock/wakereason has changed and an wakelock/wakereason struct follows.
+ E: event data has changed and an event struct follows.
+ F: battery charge in coulombs has changed and an int with the charge follows.
+ G: state flag denoting that the mobile radio was active.
+ H: state flag denoting that the wifi radio was active.
+ I: state flag denoting that a wifi scan occurred.
+ J: state flag denoting that a wifi full lock was held.
+ K: state flag denoting that the gps was on.
+ L: state flag denoting that a wakelock was held.
+ M: state flag denoting that the cpu was running.
+
+ Time int/long: if T in the first token is 0x7ffff or 0x7fffe, then an int or long follows
+ with the time delta.
+
+ Battery level int: if A in the first token is set,
+ 31 23 15 7 0
+ â–ˆL|L|L|L|L|L|L|Tâ–ˆT|T|T|T|T|T|T|Tâ–ˆT|V|V|V|V|V|V|Vâ–ˆV|V|V|V|V|V|V|Dâ–ˆ
+
+ D: indicates that extra history details follow.
+ V: the battery voltage.
+ T: the battery temperature.
+ L: the battery level (out of 100).
+
+ State change int: if B in the first token is set,
+ 31 23 15 7 0
+ â–ˆS|S|S|H|H|H|P|Pâ–ˆF|E|D|C|B| | |Aâ–ˆ | | | | | | | â–ˆ | | | | | | | â–ˆ
+
+ A: wifi multicast was on.
+ B: battery was plugged in.
+ C: screen was on.
+ D: phone was scanning for signal.
+ E: audio was on.
+ F: a sensor was active.
+
+ State2 change int: if C in the first token is set,
+ 31 23 15 7 0
+ â–ˆM|L|K|J|I|H|H|Gâ–ˆF|E|D|C| | | | â–ˆ | | | | | | | â–ˆ |B|B|B|A|A|A|Aâ–ˆ
+
+ A: 4 bits indicating the wifi supplicant state: {@link BatteryStats#WIFI_SUPPL_STATE_NAMES}.
+ B: 3 bits indicating the wifi signal strength: 0, 1, 2, 3, 4.
+ C: a bluetooth scan was active.
+ D: the camera was active.
+ E: bluetooth was on.
+ F: a phone call was active.
+ G: the device was charging.
+ H: 2 bits indicating the device-idle (doze) state: off, light, full
+ I: the flashlight was on.
+ J: wifi was on.
+ K: wifi was running.
+ L: video was playing.
+ M: power save mode was on.
+
+ Wakelock/wakereason struct: if D in the first token is set,
+ TODO(adamlesinski): describe wakelock/wakereason struct.
+
+ Event struct: if E in the first token is set,
+ TODO(adamlesinski): describe the event struct.
+
+ History step details struct: if D in the battery level int is set,
+ TODO(adamlesinski): describe the history step details struct.
+
+ Battery charge int: if F in the first token is set, an int representing the battery charge
+ in coulombs follows.
+ */
+
// Part of initial delta int that specifies the time delta.
static final int DELTA_TIME_MASK = 0x7ffff;
static final int DELTA_TIME_LONG = 0x7ffff; // The delta is a following long
static final int DELTA_TIME_INT = 0x7fffe; // The delta is a following int
static final int DELTA_TIME_ABS = 0x7fffd; // Following is an entire abs update.
// Flag in delta int: a new battery level int follows.
- static final int DELTA_BATTERY_LEVEL_FLAG = 0x00080000;
+ static final int DELTA_BATTERY_LEVEL_FLAG = 0x00080000;
// Flag in delta int: a new full state and battery status int follows.
- static final int DELTA_STATE_FLAG = 0x00100000;
+ static final int DELTA_STATE_FLAG = 0x00100000;
// Flag in delta int: a new full state2 int follows.
- static final int DELTA_STATE2_FLAG = 0x00200000;
+ static final int DELTA_STATE2_FLAG = 0x00200000;
// Flag in delta int: contains a wakelock or wakeReason tag.
- static final int DELTA_WAKELOCK_FLAG = 0x00400000;
+ static final int DELTA_WAKELOCK_FLAG = 0x00400000;
// Flag in delta int: contains an event description.
- static final int DELTA_EVENT_FLAG = 0x00800000;
+ static final int DELTA_EVENT_FLAG = 0x00800000;
+ // Flag in delta int: contains a coulomb charge count.
+ static final int DELTA_BATTERY_CHARGE_COULOMBS_FLAG = 0x01000000;
// These upper bits are the frequently changing state bits.
- static final int DELTA_STATE_MASK = 0xff000000;
+ static final int DELTA_STATE_MASK = 0xfe000000;
// These are the pieces of battery state that are packed in to the upper bits of
// the state int that have been packed in to the first delta int. They must fit
- // in DELTA_STATE_MASK.
+ // in STATE_BATTERY_MASK.
+ static final int STATE_BATTERY_MASK = 0xff000000;
static final int STATE_BATTERY_STATUS_MASK = 0x00000007;
static final int STATE_BATTERY_STATUS_SHIFT = 29;
static final int STATE_BATTERY_HEALTH_MASK = 0x00000007;
@@ -2165,6 +2249,12 @@ public class BatteryStatsImpl extends BatteryStats {
if (cur.eventCode != HistoryItem.EVENT_NONE) {
firstToken |= DELTA_EVENT_FLAG;
}
+
+ final boolean batteryChargeCoulombsChanged = cur.batteryChargeCoulombs
+ != last.batteryChargeCoulombs;
+ if (batteryChargeCoulombsChanged) {
+ firstToken |= DELTA_BATTERY_CHARGE_COULOMBS_FLAG;
+ }
dest.writeInt(firstToken);
if (DEBUG) Slog.i(TAG, "WRITE DELTA: firstToken=0x" + Integer.toHexString(firstToken)
+ " deltaTime=" + deltaTime);
@@ -2247,6 +2337,12 @@ public class BatteryStatsImpl extends BatteryStats {
mLastHistoryStepDetails = null;
}
mLastHistoryStepLevel = cur.batteryLevel;
+
+ if (batteryChargeCoulombsChanged) {
+ if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryChargeCoulombs="
+ + cur.batteryChargeCoulombs);
+ dest.writeInt(cur.batteryChargeCoulombs);
+ }
}
private int buildBatteryLevelInt(HistoryItem h) {
@@ -2273,7 +2369,7 @@ public class BatteryStatsImpl extends BatteryStats {
return ((h.batteryStatus&STATE_BATTERY_STATUS_MASK)<<STATE_BATTERY_STATUS_SHIFT)
| ((h.batteryHealth&STATE_BATTERY_HEALTH_MASK)<<STATE_BATTERY_HEALTH_SHIFT)
| ((plugType&STATE_BATTERY_PLUG_MASK)<<STATE_BATTERY_PLUG_SHIFT)
- | (h.states&(~DELTA_STATE_MASK));
+ | (h.states&(~STATE_BATTERY_MASK));
}
private void computeHistoryStepDetails(final HistoryStepDetails out,
@@ -2412,7 +2508,7 @@ public class BatteryStatsImpl extends BatteryStats {
if ((firstToken&DELTA_STATE_FLAG) != 0) {
int stateInt = src.readInt();
- cur.states = (firstToken&DELTA_STATE_MASK) | (stateInt&(~DELTA_STATE_MASK));
+ cur.states = (firstToken&DELTA_STATE_MASK) | (stateInt&(~STATE_BATTERY_MASK));
cur.batteryStatus = (byte)((stateInt>>STATE_BATTERY_STATUS_SHIFT)
& STATE_BATTERY_STATUS_MASK);
cur.batteryHealth = (byte)((stateInt>>STATE_BATTERY_HEALTH_SHIFT)
@@ -2438,7 +2534,7 @@ public class BatteryStatsImpl extends BatteryStats {
+ " batteryPlugType=" + cur.batteryPlugType
+ " states=0x" + Integer.toHexString(cur.states));
} else {
- cur.states = (firstToken&DELTA_STATE_MASK) | (cur.states&(~DELTA_STATE_MASK));
+ cur.states = (firstToken&DELTA_STATE_MASK) | (cur.states&(~STATE_BATTERY_MASK));
}
if ((firstToken&DELTA_STATE2_FLAG) != 0) {
@@ -2493,6 +2589,10 @@ public class BatteryStatsImpl extends BatteryStats {
} else {
cur.stepDetails = null;
}
+
+ if ((firstToken&DELTA_BATTERY_CHARGE_COULOMBS_FLAG) != 0) {
+ cur.batteryChargeCoulombs = src.readInt();
+ }
}
@Override
@@ -5611,12 +5711,12 @@ public class BatteryStatsImpl extends BatteryStats {
mWifiControllerActivity.reset(false);
}
- if (mBsi.mBluetoothActivity != null) {
- mBsi.mBluetoothActivity.reset(false);
+ if (mBluetoothControllerActivity != null) {
+ mBluetoothControllerActivity.reset(false);
}
- if (mBsi.mModemActivity != null) {
- mBsi.mModemActivity.reset(false);
+ if (mModemControllerActivity != null) {
+ mModemControllerActivity.reset(false);
}
mUserCpuTime.reset(false);
@@ -9210,7 +9310,7 @@ public class BatteryStatsImpl extends BatteryStats {
public static final int BATTERY_PLUGGED_NONE = 0;
public void setBatteryStateLocked(int status, int health, int plugType, int level,
- int temp, int volt) {
+ int temp, int volt, int chargeCount) {
final boolean onBattery = plugType == BATTERY_PLUGGED_NONE;
final long uptime = mClocks.uptimeMillis();
final long elapsedRealtime = mClocks.elapsedRealtime();
@@ -9254,6 +9354,7 @@ public class BatteryStatsImpl extends BatteryStats {
if (mDischargePlugLevel < 0) {
mDischargePlugLevel = level;
}
+
if (onBattery != mOnBattery) {
mHistoryCur.batteryLevel = (byte)level;
mHistoryCur.batteryStatus = (byte)status;
@@ -9261,6 +9362,7 @@ public class BatteryStatsImpl extends BatteryStats {
mHistoryCur.batteryPlugType = (byte)plugType;
mHistoryCur.batteryTemperature = (short)temp;
mHistoryCur.batteryVoltage = (char)volt;
+ mHistoryCur.batteryChargeCoulombs = chargeCount;
setOnBatteryLocked(elapsedRealtime, uptime, onBattery, oldStatus, level);
} else {
boolean changed = false;
@@ -9294,6 +9396,11 @@ public class BatteryStatsImpl extends BatteryStats {
mHistoryCur.batteryVoltage = (char)volt;
changed = true;
}
+ if (chargeCount >= (mHistoryCur.batteryChargeCoulombs+10)
+ || chargeCount <= (mHistoryCur.batteryChargeCoulombs-10)) {
+ mHistoryCur.batteryChargeCoulombs = chargeCount;
+ changed = true;
+ }
long modeBits = (((long)mInitStepMode) << STEP_LEVEL_INITIAL_MODE_SHIFT)
| (((long)mModStepMode) << STEP_LEVEL_MODIFIED_MODE_SHIFT)
| (((long)(level&0xff)) << STEP_LEVEL_LEVEL_SHIFT);
diff --git a/core/jni/android_hardware_location_ContextHubService.cpp b/core/jni/android_hardware_location_ContextHubService.cpp
index 5c961d96cf56..98d6b247429c 100644
--- a/core/jni/android_hardware_location_ContextHubService.cpp
+++ b/core/jni/android_hardware_location_ContextHubService.cpp
@@ -44,7 +44,6 @@ static constexpr int HEADER_FIELD_MSG_TYPE=0;
static constexpr int HEADER_FIELD_HUB_HANDLE=2;
static constexpr int HEADER_FIELD_APP_INSTANCE=3;
-
namespace android {
namespace {
@@ -164,9 +163,20 @@ static int get_hub_id_for_app_instance(int id) {
return db.hubInfo.hubs[hubHandle].hub_id;
}
+static int get_app_instance_for_app_id(uint64_t app_id) {
+ auto end = db.appInstances.end();
+ for (auto current = db.appInstances.begin(); current != end; ++current) {
+ if (current->second.appInfo.app_name.id == app_id) {
+ return current->first;
+ }
+ }
+ ALOGD("Cannot find app for app instance %" PRIu64 ".", app_id);
+ return -1;
+}
+
static int set_dest_app(hub_message_t *msg, int id) {
if (!db.appInstances.count(id)) {
- ALOGD("%s: Cannod find app for app instance %d", __FUNCTION__, id);
+ ALOGD("%s: Cannot find app for app instance %d", __FUNCTION__, id);
return -1;
}
@@ -301,7 +311,7 @@ static void initContextHubService() {
}
}
-static int onMessageReceipt(int *header, int headerLen, char *msg, int msgLen) {
+static int onMessageReceipt(uint32_t *header, size_t headerLen, char *msg, size_t msgLen) {
JNIEnv *env;
if ((db.jniInfo.vm)->AttachCurrentThread(&env, nullptr) != JNI_OK) {
@@ -396,14 +406,9 @@ static bool sanity_check_cookie(void *cookie, uint32_t hub_id) {
int context_hub_callback(uint32_t hubId,
const struct hub_message_t *msg,
void *cookie) {
- int msgHeader[MSG_HEADER_SIZE];
-
if (!msg) {
return -1;
}
-
- msgHeader[HEADER_FIELD_MSG_TYPE] = msg->message_type;
-
if (!sanity_check_cookie(cookie, hubId)) {
ALOGW("Incorrect cookie %" PRId32 " for cookie %p! Bailing",
hubId, cookie);
@@ -411,17 +416,22 @@ int context_hub_callback(uint32_t hubId,
return -1;
}
- msgHeader[HEADER_FIELD_HUB_HANDLE] = *(uint32_t*)cookie;
+ uint32_t messageType = msg->message_type;
+ uint32_t hubHandle = *(uint32_t*) cookie;
- if (msgHeader[HEADER_FIELD_MSG_TYPE] < CONTEXT_HUB_TYPE_PRIVATE_MSG_BASE &&
- msgHeader[HEADER_FIELD_MSG_TYPE] != 0 ) {
- handle_os_message(msgHeader[HEADER_FIELD_MSG_TYPE],
- msgHeader[HEADER_FIELD_HUB_HANDLE],
- (char *)msg->message,
- msg->message_len);
+ if (messageType < CONTEXT_HUB_TYPE_PRIVATE_MSG_BASE) {
+ handle_os_message(messageType, hubHandle, (char*) msg->message, msg->message_len);
} else {
- onMessageReceipt(msgHeader, sizeof(msgHeader),
- (char *)msg->message, msg->message_len);
+ int appHandle = get_app_instance_for_app_id(msg->app_name.id);
+ if (appHandle < 0) {
+ ALOGE("Filtering out message due to invalid App Instance.");
+ } else {
+ uint32_t msgHeader[MSG_HEADER_SIZE] = {};
+ msgHeader[HEADER_FIELD_MSG_TYPE] = messageType;
+ msgHeader[HEADER_FIELD_HUB_HANDLE] = hubHandle;
+ msgHeader[HEADER_FIELD_APP_INSTANCE] = appHandle;
+ onMessageReceipt(msgHeader, MSG_HEADER_SIZE, (char*) msg->message, msg->message_len);
+ }
}
return 0;
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index 3fd75f70c089..191afe5fd521 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -2291,4 +2291,14 @@
<attr name="minimalHeight" format="dimension" />
</declare-styleable>
+ <!-- <code>restrict-update</code> tag restricts system apps from being updated unless the
+ SHA-512 hash equals the specified value.
+ @hide -->
+ <declare-styleable name="AndroidManifestRestrictUpdate" parent="AndroidManifest">
+ <!-- The SHA-512 hash of the only APK that can be used to update a package.
+ <p>NOTE: This is only applicable to system packages.
+ @hide -->
+ <attr name="hash" format="string" />
+ </declare-styleable>
+
</resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 11df8e5fa589..c91e09fd39d0 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2715,6 +2715,7 @@
<public type="attr" name="contentInsetEndWithActions" />
<public type="attr" name="numberPickerStyle" />
<public type="attr" name="enableVrMode" />
+ <public type="attr" name="hash" />
<public type="style" name="Theme.Material.Light.DialogWhenLarge.DarkActionBar" />
<public type="style" name="Widget.Material.SeekBar.Discrete" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index fb7a19f9487d..dffab2c9c59b 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -626,7 +626,7 @@
<!-- Title for the capability of an accessibility service to request touch exploration. -->
<string name="capability_title_canRequestTouchExploration">Turn on Explore by Touch</string>
<!-- Description for the capability of an accessibility service to request touch exploration. -->
- <string name="capability_desc_canRequestTouchExploration">Touched items will be spoken aloud
+ <string name="capability_desc_canRequestTouchExploration">Tapped items will be spoken aloud
and the screen can be explored using gestures.</string>
<!-- Title for the capability of an accessibility service to request enhanced web accessibility. -->
@@ -1708,7 +1708,7 @@
<string name="keyguard_password_enter_pin_prompt">New PIN code</string>
<!-- Displayed as hint in passwordEntry EditText on PasswordUnlockScreen [CHAR LIMIT=30]-->
- <string name="keyguard_password_entry_touch_hint"><font size="17">Touch to type password</font></string>
+ <string name="keyguard_password_entry_touch_hint"><font size="17">Tap to type password</font></string>
<!-- Instructions telling the user to enter their text password to unlock the keyguard.
Displayed in one line in a large font. -->
@@ -2577,7 +2577,7 @@
is running</string>
<!-- [CHAR LIMIT=NONE] Stub notification text for an app running a service that has provided
a bad bad notification for itself. -->
- <string name="app_running_notification_text">Touch for more information
+ <string name="app_running_notification_text">Tap for more information
or to stop the app.</string>
<!-- Preference framework strings. -->
@@ -2761,7 +2761,7 @@
<string name="heavy_weight_notification"><xliff:g id="app">%1$s</xliff:g> running</string>
<!-- Notification details to tell the user that a heavy-weight application is running. -->
- <string name="heavy_weight_notification_detail">Touch to switch to app</string>
+ <string name="heavy_weight_notification_detail">Tap to switch to app</string>
<!-- Title of dialog prompting whether user wants to switch between heavy-weight apps. -->
<string name="heavy_weight_switcher_title">Switch apps?</string>
@@ -2782,7 +2782,7 @@
<!-- Notification details to tell the user that a process has exceeded its memory limit. -->
<string name="dump_heap_notification_detail">Heap dump has been collected;
- touch to share</string>
+ tap to share</string>
<!-- Title of dialog prompting the user to share a heap dump. -->
<string name="dump_heap_title">Share heap dump?</string>
@@ -2865,7 +2865,7 @@
<string name="wifi_no_internet">Wi-Fi has no Internet access</string>
<!-- A notification is shown when the user connects to a Wi-Fi network and the system detects that that network has no Internet access. This is the notification's message. -->
- <string name="wifi_no_internet_detailed">Touch for options</string>
+ <string name="wifi_no_internet_detailed">Tap for options</string>
<!-- A notification is shown when a user's selected SSID is later disabled due to connectivity problems. This is the notification's title / ticker. -->
<string name="wifi_watchdog_network_disabled">Couldn\'t connect to Wi-Fi</string>
@@ -2887,7 +2887,7 @@
<string name="wifi_p2p_turnon_message">Start Wi-Fi Direct. This will turn off Wi-Fi client/hotspot.</string>
<string name="wifi_p2p_failed_message">Couldn\'t start Wi-Fi Direct.</string>
<string name="wifi_p2p_enabled_notification_title">Wi-Fi Direct is on</string>
- <string name="wifi_p2p_enabled_notification_message">Touch for settings</string>
+ <string name="wifi_p2p_enabled_notification_message">Tap for settings</string>
<string name="accept">Accept</string>
<string name="decline">Decline</string>
@@ -2995,12 +2995,12 @@
<!-- USB_PREFERENCES: Notification for when a USB accessory is attached. This is the title -->
<string name="usb_accessory_notification_title">Connected to a USB accessory</string>
<!-- See USB_PREFERENCES. This is the message. -->
- <string name="usb_notification_message">Touch for more options.</string>
+ <string name="usb_notification_message">Tap for more options.</string>
<!-- Title of notification shown when ADB is actively connected to the phone. -->
<string name="adb_active_notification_title">USB debugging connected</string>
<!-- Message of notification shown when ADB is actively connected to the phone. -->
- <string name="adb_active_notification_message">Touch to disable USB debugging.</string>
+ <string name="adb_active_notification_message">Tap to disable USB debugging.</string>
<!-- Title of notification shown to indicate that bug report is being collected. -->
<string name="taking_remote_bugreport_notification_title">Taking bug report\u2026</string>
@@ -3057,12 +3057,12 @@
<!-- Notification title when external media is unmountable (corrupt) [CHAR LIMIT=30] -->
<string name="ext_media_unmountable_notification_title">Corrupted <xliff:g id="name" example="SD card">%s</xliff:g></string>
<!-- Notification body when external media is unmountable (corrupt) [CHAR LIMIT=NONE] -->
- <string name="ext_media_unmountable_notification_message"><xliff:g id="name" example="SD card">%s</xliff:g> is corrupt. Touch to fix.</string>
+ <string name="ext_media_unmountable_notification_message"><xliff:g id="name" example="SD card">%s</xliff:g> is corrupt. Tap to fix.</string>
<!-- Notification title when external media is unsupported [CHAR LIMIT=30] -->
<string name="ext_media_unsupported_notification_title">Unsupported <xliff:g id="name" example="SD card">%s</xliff:g></string>
<!-- Notification body when external media is unsupported [CHAR LIMIT=NONE] -->
- <string name="ext_media_unsupported_notification_message">This device doesn\u2019t support this <xliff:g id="name" example="SD card">%s</xliff:g>. Touch to set up in a supported format.</string>
+ <string name="ext_media_unsupported_notification_message">This device doesn\u2019t support this <xliff:g id="name" example="SD card">%s</xliff:g>. Tap to set up in a supported format.</string>
<!-- Notification title when external media is unsafely removed [CHAR LIMIT=30] -->
<string name="ext_media_badremoval_notification_title"><xliff:g id="name" example="SD card">%s</xliff:g> unexpectedly removed</string>
@@ -3148,7 +3148,7 @@
<string name="permdesc_requestInstallPackages">Allows an application to request installation of packages.</string>
<!-- Shown in the tutorial for tap twice for zoom control. -->
- <string name="tutorial_double_tap_to_zoom_message_short">Touch twice for zoom control</string>
+ <string name="tutorial_double_tap_to_zoom_message_short">Tap twice for zoom control</string>
<!-- Shown in gadget hosts (e.g. the home screen) when there was an error inflating
@@ -3235,9 +3235,9 @@
<!-- The title of the notification when VPN is active with an application name. -->
<string name="vpn_title_long">VPN is activated by <xliff:g id="app" example="FooVPN client">%s</xliff:g></string>
<!-- The text of the notification when VPN is active. -->
- <string name="vpn_text">Touch to manage the network.</string>
+ <string name="vpn_text">Tap to manage the network.</string>
<!-- The text of the notification when VPN is active with a session name. -->
- <string name="vpn_text_long">Connected to <xliff:g id="session" example="office">%s</xliff:g>. Touch to manage the network.</string>
+ <string name="vpn_text_long">Connected to <xliff:g id="session" example="office">%s</xliff:g>. Tap to manage the network.</string>
<!-- Notification title when connecting to lockdown VPN. -->
<string name="vpn_lockdown_connecting">Always-on VPN connecting\u2026</string>
@@ -3246,7 +3246,7 @@
<!-- Notification title when error connecting to lockdown VPN. -->
<string name="vpn_lockdown_error">Always-on VPN error</string>
<!-- Notification body that indicates user can touch to configure lockdown VPN connection. -->
- <string name="vpn_lockdown_config">Touch to configure</string>
+ <string name="vpn_lockdown_config">Tap to configure</string>
<!-- Localized strings for WebView -->
<!-- Label for button in a WebView that will open a chooser to choose a file to upload -->
@@ -3261,12 +3261,12 @@
<!-- Strings for car mode notification -->
<!-- Shown when car mode is enabled -->
<string name="car_mode_disable_notification_title">Car mode enabled</string>
- <string name="car_mode_disable_notification_message">Touch to exit car mode.</string>
+ <string name="car_mode_disable_notification_message">Tap to exit car mode.</string>
<!-- Strings for tethered notification -->
<!-- Shown when the device is tethered -->
<string name="tethered_notification_title">Tethering or hotspot active</string>
- <string name="tethered_notification_message">Touch to set up.</string>
+ <string name="tethered_notification_message">Tap to set up.</string>
<!-- Strings for possible PreferenceActivity Back/Next buttons -->
<string name="back_button_label">Back</string>
@@ -3352,7 +3352,7 @@
<!-- Description of the button to decrease the NumberPicker value. [CHAR LIMIT=NONE] -->
<string name="number_picker_decrement_button">Decrease</string>
<!-- Description of the tap and hold action to get into scroll mode in NumberPicker. [CHAR LIMIT=NONE] -->
- <string name="number_picker_increment_scroll_mode"><xliff:g id="value" example="3">%s</xliff:g> touch and hold.</string>
+ <string name="number_picker_increment_scroll_mode"><xliff:g id="value" example="3">%s</xliff:g> touch &amp; hold.</string>
<!-- Description of the scrolling action in NumberPicker. [CHAR LIMIT=NONE] -->
<string name="number_picker_increment_scroll_action">Slide up to increase and down to decrease.</string>
@@ -3470,7 +3470,7 @@
<!-- Notification title when data usage has exceeded warning threshold. [CHAR LIMIT=32] -->
<string name="data_usage_warning_title">Data usage warning</string>
<!-- Notification body when data usage has exceeded warning threshold. [CHAR LIMIT=32] -->
- <string name="data_usage_warning_body">Touch to view usage and settings.</string>
+ <string name="data_usage_warning_body">Tap to view usage and settings.</string>
<!-- Notification title when 2G-3G data usage has exceeded limit threshold, and has been disabled. [CHAR LIMIT=32] -->
<string name="data_usage_3g_limit_title">2G-3G data limit reached</string>
@@ -3497,7 +3497,7 @@
<!-- Notification title when background data usage is limited. [CHAR LIMIT=32] -->
<string name="data_usage_restricted_title">Background data restricted</string>
<!-- Notification body when background data usage is limited. [CHAR LIMIT=32] -->
- <string name="data_usage_restricted_body">Touch to remove restriction.</string>
+ <string name="data_usage_restricted_body">Tap to remove restriction.</string>
<!-- SSL Certificate dialogs -->
<!-- Title for an SSL Certificate dialog -->
@@ -4080,9 +4080,9 @@
<string name="date_picker_day_typeface">sans-serif-medium</string>
<!-- Notify use that they are in Lock-to-app -->
- <string name="lock_to_app_toast">To unpin this screen, touch and hold Back.</string>
+ <string name="lock_to_app_toast">To unpin this screen, touch &amp; hold Back.</string>
<!-- Notify use that they are in Lock-to-app in accessibility mode -->
- <string name="lock_to_app_toast_accessible">To unpin this screen, touch and hold Overview.</string>
+ <string name="lock_to_app_toast_accessible">To unpin this screen, touch &amp; hold Overview.</string>
<!-- Notify user that they are locked in lock-to-app mode -->
<string name="lock_to_app_toast_locked">App is pinned: Unpinning isn\'t allowed on this device.</string>
<!-- Starting lock-to-app indication. -->
diff --git a/core/res/res/values/themes_holo.xml b/core/res/res/values/themes_holo.xml
index 34c89fc662ec..677051aa0dd5 100644
--- a/core/res/res/values/themes_holo.xml
+++ b/core/res/res/values/themes_holo.xml
@@ -466,6 +466,9 @@ please see themes_device_defaults.xml.
<item name="editTextColor">?attr/textColorPrimary</item>
<item name="editTextBackground">@drawable/edit_text_holo_light</item>
+ <item name="textEditSuggestionItemLayout">@layout/text_edit_suggestion_item</item>
+ <item name="textEditSuggestionContainerLayout">@layout/text_edit_suggestion_container</item>
+ <item name="textEditSuggestionHighlightStyle">@style/TextAppearance.Holo.SuggestionHighlight</item>
<item name="candidatesTextStyleSpans">@string/candidates_style</item>
diff --git a/docs/html/preview/behavior-changes.jd b/docs/html/preview/behavior-changes.jd
index 0cf5bc9de6f2..7c8bfe8ba29e 100644
--- a/docs/html/preview/behavior-changes.jd
+++ b/docs/html/preview/behavior-changes.jd
@@ -215,11 +215,17 @@ page.image=images/cards/card-n-changes_2x.png
<ul>
<li>
- Private files’ file permissions can no longer be relaxed by the owner, and
- an attempt to do so using
+ Private files’ file permissions should no longer be relaxed by the owner,
+ and an attempt to do so using
{@link android.content.Context#MODE_WORLD_READABLE} and/or
{@link android.content.Context#MODE_WORLD_WRITEABLE}, will trigger a
{@link java.lang.SecurityException}.
+ <p class="note">
+ <strong>Note:</strong> As of yet, this restriction is not fully enforced.
+ Apps may still modify permissions to their private directory using
+ native APIs or the {@link java.io.File File} API. However, we strongly
+ discourage relaxing the permissions to the private directory.
+ </p>
</li>
<li>
Passing <code>file://</code> URIs outside the package domain may leave the
diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java
index a8c26522f419..625723857a17 100644
--- a/media/java/android/media/MediaCodecInfo.java
+++ b/media/java/android/media/MediaCodecInfo.java
@@ -1247,7 +1247,8 @@ public final class MediaCodecInfo {
private Range<Double> estimateFrameRatesFor(int width, int height) {
Size size = findClosestSize(width, height);
Range<Long> range = mMeasuredFrameRates.get(size);
- Double ratio = (double)(size.getWidth() * size.getHeight()) / (width * height);
+ Double ratio = getBlockCount(size.getWidth(), size.getHeight())
+ / (double)Math.max(getBlockCount(width, height), 1);
return Range.create(range.getLower() * ratio, range.getUpper() * ratio);
}
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
index f72c7ac7c08f..74bd01689874 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/PrintActivity.java
@@ -288,12 +288,8 @@ public class PrintActivity extends Activity implements RemotePrintDocument.Updat
// the first batch of results which will be delivered
// after reading historical data. This should be pretty
// fast, so just wait before showing the UI.
- mPrinterRegistry = new PrinterRegistry(PrintActivity.this,
- new Runnable() {
- @Override
- public void run() {
- onPrinterRegistryReady(documentAdapter);
- }
+ mPrinterRegistry = new PrinterRegistry(PrintActivity.this, () -> {
+ (new Handler(getMainLooper())).post(() -> onPrinterRegistryReady(documentAdapter));
}, LOADER_ID_PRINT_REGISTRY, LOADER_ID_PRINT_REGISTRY_INT);
}
diff --git a/packages/SystemUI/res/layout/volume_dialog_row.xml b/packages/SystemUI/res/layout/volume_dialog_row.xml
index f0ae1c997efc..be05a3ac259c 100644
--- a/packages/SystemUI/res/layout/volume_dialog_row.xml
+++ b/packages/SystemUI/res/layout/volume_dialog_row.xml
@@ -18,6 +18,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipChildren="false"
+ android:clipToPadding="false"
android:id="@+id/volume_dialog_row"
android:paddingEnd="@dimen/volume_button_size" >
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
index 716185f343b5..b2aa966c7449 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/QSCustomizer.java
@@ -106,6 +106,7 @@ public class QSCustomizer extends LinearLayout implements OnMenuItemClickListene
public void setHost(QSTileHost host) {
mHost = host;
mPhoneStatusBar = host.getPhoneStatusBar();
+ mTileAdapter.setHost(host);
}
public void setContainer(NotificationsQuickSettingsContainer notificationsQsContainer) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
index 41b49d824a99..ec0eefb6e662 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileAdapter.java
@@ -81,6 +81,7 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta
private Holder mCurrentDrag;
private boolean mAccessibilityMoving;
private int mAccessibilityFromIndex;
+ private QSTileHost mHost;
public TileAdapter(Context context) {
mContext = context;
@@ -88,6 +89,10 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta
mItemTouchHelper = new ItemTouchHelper(mCallbacks);
}
+ public void setHost(QSTileHost host) {
+ mHost = host;
+ }
+
@Override
public long getItemId(int position) {
return mTiles.get(position) != null ? mAllTiles.indexOf(mTiles.get(position))
@@ -108,7 +113,7 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta
newSpecs.add(mTiles.get(i).spec);
}
host.changeTiles(mCurrentSpecs, newSpecs);
- setTileSpecs(newSpecs);
+ mCurrentSpecs = newSpecs;
}
public void setTileSpecs(List<String> currentSpecs) {
@@ -285,6 +290,7 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta
move(mAccessibilityFromIndex, position, v);
notifyItemChanged(mAccessibilityFromIndex);
notifyItemMoved(mAccessibilityFromIndex, position);
+ saveSpecs(mHost);
}
private void showAccessibilityDialog(final int position, final View v) {
@@ -373,6 +379,7 @@ public class TileAdapter extends RecyclerView.Adapter<Holder> implements TileSta
fromLabel, (to + 1));
}
v.announceForAccessibility(announcement);
+ saveSpecs(mHost);
return true;
}
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 f7ecd61e1568..6fc32de100e2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -409,6 +409,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
if (mKeyguardBottomArea != null) {
mKeyguardBottomArea.setUserSetupComplete(mUserSetup);
}
+ if (mNetworkController != null) {
+ mNetworkController.setUserSetupComplete(mUserSetup);
+ }
}
if (mIconPolicy != null) {
mIconPolicy.setCurrentUserSetup(mUserSetup);
@@ -838,6 +841,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}
});
mNetworkController = new NetworkControllerImpl(mContext, mHandlerThread.getLooper());
+ mNetworkController.setUserSetupComplete(mUserSetup);
mHotspotController = new HotspotControllerImpl(mContext);
mBluetoothController = new BluetoothControllerImpl(mContext, mHandlerThread.getLooper());
mSecurityController = new SecurityControllerImpl(mContext);
@@ -1437,7 +1441,11 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
public void removeNotification(String key, RankingMap ranking) {
boolean deferRemoval = false;
if (mHeadsUpManager.isHeadsUp(key)) {
- deferRemoval = !mHeadsUpManager.removeNotification(key);
+ // A cancel() in repsonse to a remote input shouldn't be delayed, as it makes the
+ // sending look longer than it takes.
+ boolean ignoreEarliestRemovalTime = mRemoteInputController.isSpinning(key)
+ && !FORCE_REMOTE_INPUT_HISTORY;
+ deferRemoval = !mHeadsUpManager.removeNotification(key, ignoreEarliestRemovalTime);
}
if (key.equals(mMediaNotificationKey)) {
clearCurrentMediaNotification();
@@ -2364,7 +2372,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
if (wasHeadsUp) {
if (!shouldPeek) {
// We don't want this to be interrupting anymore, lets remove it
- mHeadsUpManager.removeNotification(key);
+ mHeadsUpManager.removeNotification(key, false /* ignoreEarliestRemovalTime */);
} else {
mHeadsUpManager.updateNotification(entry, alertAgain);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
index 52fb47022275..d3ae54984e99 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManager.java
@@ -264,9 +264,9 @@ public class HeadsUpManager implements ViewTreeObserver.OnComputeInternalInsetsL
* @return true if the notification was removed and false if it still needs to be kept around
* for a bit since it wasn't shown long enough
*/
- public boolean removeNotification(String key) {
+ public boolean removeNotification(String key, boolean ignoreEarliestRemovalTime) {
if (DEBUG) Log.v(TAG, "remove");
- if (wasShownLongEnough(key)) {
+ if (wasShownLongEnough(key) || ignoreEarliestRemovalTime) {
releaseImmediately(key);
return true;
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index 80dcfb6dfe2c..83e25ebd7497 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -114,6 +114,11 @@ public class MobileSignalController extends SignalController<
notifyListenersIfNecessary();
}
+ public void setUserSetupComplete(boolean userSetup) {
+ mCurrentState.userSetup = userSetup;
+ notifyListenersIfNecessary();
+ }
+
@Override
public void updateConnectivity(BitSet connectedTransports, BitSet validatedTransports) {
boolean isValidated = validatedTransports.get(mTransportType);
@@ -204,11 +209,13 @@ public class MobileSignalController extends SignalController<
String contentDescription = getStringIfExists(getContentDescription());
String dataContentDescription = getStringIfExists(icons.mDataContentDescription);
+ final boolean dataDisabled = mCurrentState.iconGroup == TelephonyIcons.DATA_DISABLED
+ && mCurrentState.userSetup;
- // Show icon in QS when we are connected or need to show roaming.
+ // Show icon in QS when we are connected or need to show roaming or data is disabled.
boolean showDataIcon = mCurrentState.dataConnected
|| mCurrentState.iconGroup == TelephonyIcons.ROAMING
- || mCurrentState.iconGroup == TelephonyIcons.DATA_DISABLED;
+ || dataDisabled;
IconState statusIcon = new IconState(mCurrentState.enabled && !mCurrentState.airplaneMode,
getCurrentIconId(), contentDescription);
@@ -230,7 +237,7 @@ public class MobileSignalController extends SignalController<
&& mCurrentState.activityOut;
showDataIcon &= mCurrentState.isDefault
|| mCurrentState.iconGroup == TelephonyIcons.ROAMING
- || mCurrentState.iconGroup == TelephonyIcons.DATA_DISABLED;
+ || dataDisabled;
int typeIcon = showDataIcon ? icons.mDataType : 0;
callback.setMobileDataIndicators(statusIcon, qsIcon, typeIcon, qsTypeIcon,
activityIn, activityOut, dataContentDescription, description, icons.mIsWide,
@@ -511,6 +518,7 @@ public class MobileSignalController extends SignalController<
boolean airplaneMode;
boolean carrierNetworkChangeMode;
boolean isDefault;
+ boolean userSetup;
@Override
public void copyFrom(State s) {
@@ -524,6 +532,7 @@ public class MobileSignalController extends SignalController<
isEmergency = state.isEmergency;
airplaneMode = state.airplaneMode;
carrierNetworkChangeMode = state.carrierNetworkChangeMode;
+ userSetup = state.userSetup;
}
@Override
@@ -537,7 +546,9 @@ public class MobileSignalController extends SignalController<
builder.append("isDefault=").append(isDefault).append(',');
builder.append("isEmergency=").append(isEmergency).append(',');
builder.append("airplaneMode=").append(airplaneMode).append(',');
- builder.append("carrierNetworkChangeMode=").append(carrierNetworkChangeMode);
+ builder.append("carrierNetworkChangeMode=").append(carrierNetworkChangeMode)
+ .append(',');
+ builder.append("userSetup=").append(userSetup);
}
@Override
@@ -550,6 +561,7 @@ public class MobileSignalController extends SignalController<
&& ((MobileState) o).isEmergency == isEmergency
&& ((MobileState) o).airplaneMode == airplaneMode
&& ((MobileState) o).carrierNetworkChangeMode == carrierNetworkChangeMode
+ && ((MobileState) o).userSetup == userSetup
&& ((MobileState) o).isDefault == isDefault;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index 40dacd3b991d..a63324134512 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -130,6 +130,7 @@ public class NetworkControllerImpl extends BroadcastReceiver
@VisibleForTesting
ServiceState mLastServiceState;
+ private boolean mUserSetup;
/**
* Construct this controller object and register for updates.
@@ -490,6 +491,7 @@ public class NetworkControllerImpl extends BroadcastReceiver
MobileSignalController controller = new MobileSignalController(mContext, mConfig,
mHasMobileDataFeature, mPhone, mCallbackHandler,
this, subscriptions.get(i), mSubDefaults, mReceiverHandler.getLooper());
+ controller.setUserSetupComplete(mUserSetup);
mMobileSignalControllers.put(subId, controller);
if (subscriptions.get(i).getSimSlotIndex() == 0) {
mDefaultSignalController = controller;
@@ -516,6 +518,23 @@ public class NetworkControllerImpl extends BroadcastReceiver
updateAirplaneMode(true /* force */);
}
+ public void setUserSetupComplete(final boolean userSetup) {
+ mReceiverHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ handleSetUserSetupComplete(userSetup);
+ }
+ });
+ }
+
+ @VisibleForTesting
+ void handleSetUserSetupComplete(boolean userSetup) {
+ mUserSetup = userSetup;
+ for (MobileSignalController controller : mMobileSignalControllers.values()) {
+ controller.setUserSetupComplete(mUserSetup);
+ }
+ }
+
@VisibleForTesting
boolean hasCorrectMobileControllers(List<SubscriptionInfo> allSubscriptions) {
if (allSubscriptions.size() != mMobileSignalControllers.size()) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
index f3033cd89cf8..a855aed88694 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
@@ -91,8 +91,6 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
mEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
-
- // Check if this was the result of hitting the enter key
final boolean isSoftImeEvent = event == null
&& (actionId == EditorInfo.IME_ACTION_DONE
|| actionId == EditorInfo.IME_ACTION_NEXT
@@ -102,7 +100,10 @@ public class RemoteInputView extends LinearLayout implements View.OnClickListene
&& event.getAction() == KeyEvent.ACTION_DOWN;
if (isSoftImeEvent || isKeyboardEnterKey) {
- sendRemoteInput();
+ if (mEditText.length() > 0) {
+ sendRemoteInput();
+ }
+ // Consume action to prevent IME from closing.
return true;
}
return false;
diff --git a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
index 2c53e2962049..36dd72793428 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
@@ -654,8 +654,9 @@ public class StorageNotification extends SystemUI {
intent.putExtra(PackageManager.EXTRA_MOVE_ID, move.moveId);
final VolumeInfo vol = mStorageManager.findVolumeByQualifiedUuid(move.volumeUuid);
- intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, vol.getId());
-
+ if (vol != null) {
+ intent.putExtra(VolumeInfo.EXTRA_VOLUME_ID, vol.getId());
+ }
return PendingIntent.getActivityAsUser(mContext, move.moveId, intent,
PendingIntent.FLAG_CANCEL_CURRENT, null, UserHandle.CURRENT);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
index 60d33fa0f191..38cac1e74031 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerBaseTest.java
@@ -111,6 +111,7 @@ public class NetworkControllerBaseTest extends SysuiTestCase {
when(mMockTm.getDataEnabled(mSubId)).thenReturn(true);
setDefaultSubId(mSubId);
setSubscriptions(mSubId);
+ mNetworkController.handleSetUserSetupComplete(true);
mMobileSignalController = mNetworkController.mMobileSignalControllers.get(mSubId);
mPhoneStateListener = mMobileSignalController.mPhoneStateListener;
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
index d5eca95e2cbf..542c39021ee9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerDataTest.java
@@ -1,9 +1,9 @@
package com.android.systemui.statusbar.policy;
+import android.net.NetworkCapabilities;
import android.os.Looper;
import android.telephony.TelephonyManager;
import android.test.suitebuilder.annotation.SmallTest;
-
import com.android.settingslib.net.DataUsageController;
import org.mockito.Mockito;
@@ -99,6 +99,29 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
TelephonyIcons.QS_DATA_4G);
}
+ public void testDataDisabledIcon() {
+ setupNetworkController();
+ Mockito.when(mMockTm.getDataEnabled(mSubId)).thenReturn(false);
+ setupDefaultSignal();
+ updateDataConnectionState(TelephonyManager.DATA_DISCONNECTED, 0);
+ setConnectivity(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
+
+ verifyDataIndicators(TelephonyIcons.ICON_DATA_DISABLED,
+ TelephonyIcons.QS_ICON_DATA_DISABLED);
+ }
+
+ public void testDataDisabledIcon_UserNotSetup() {
+ setupNetworkController();
+ Mockito.when(mMockTm.getDataEnabled(mSubId)).thenReturn(false);
+ setupDefaultSignal();
+ updateDataConnectionState(TelephonyManager.DATA_DISCONNECTED, 0);
+ setConnectivity(NetworkCapabilities.TRANSPORT_CELLULAR, false, false);
+ mNetworkController.handleSetUserSetupComplete(false);
+
+ // Don't show the X until the device is setup.
+ verifyDataIndicators(0, 0);
+ }
+
public void test4gDataIconConfigChange() {
setupDefaultSignal();
updateDataConnectionState(TelephonyManager.DATA_CONNECTED,
@@ -145,7 +168,6 @@ public class NetworkControllerDataTest extends NetworkControllerBaseTest {
verifyLastMobileDataIndicators(true, DEFAULT_SIGNAL_STRENGTH, DEFAULT_ICON);
verifyLastQsMobileDataIndicators(true, DEFAULT_QS_SIGNAL_STRENGTH,
DEFAULT_QS_ICON, in, out);
-
}
private void verifyDataIndicators(int dataIcon, int qsDataIcon) {
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 95f9e2dc0935..1b63cd4958dc 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -3706,7 +3706,7 @@ public class BackupManagerService {
result = BackupTransport.TRANSPORT_OK;
}
} catch (IOException e) {
- Slog.e(TAG, "Error backing up " + mPkg.packageName, e);
+ Slog.e(TAG, "Error backing up " + mPkg.packageName + ": " + e.getMessage());
result = BackupTransport.AGENT_ERROR;
} finally {
try {
@@ -4466,7 +4466,6 @@ public class BackupManagerService {
}
}
-
// If we've lost our running criteria, tell the transport to cancel
// and roll back this (partial) backup payload; otherwise tell it
// that we've reached the clean finish state.
@@ -4484,14 +4483,16 @@ public class BackupManagerService {
}
}
- // TRANSPORT_ERROR here means that we've hit an error that the runner
- // doesn't know about, so it's still moving data but we're pulling the
+ // A transport-originated error here means that we've hit an error that the
+ // runner doesn't know about, so it's still moving data but we're pulling the
// rug out from under it. Don't ask for its result: we already know better
// and we'll hang if we block waiting for it, since it relies on us to
// read back the data it's writing into the engine. Just proceed with
// a graceful failure. The runner/engine mechanism will tear itself
- // down cleanly when we close the pipes from this end.
- if (backupPackageStatus != BackupTransport.TRANSPORT_ERROR) {
+ // down cleanly when we close the pipes from this end. Transport-level
+ // errors take precedence over agent/app-specific errors for purposes of
+ // determining our course of action.
+ if (backupPackageStatus == BackupTransport.TRANSPORT_OK) {
// We still could fail in backup runner thread, getting result from there.
int backupRunnerResult = backupRunner.getBackupResultBlocking();
if (backupRunnerResult != BackupTransport.TRANSPORT_OK) {
@@ -4499,10 +4500,14 @@ public class BackupManagerService {
// not TRANSPORT_ERROR here, overwrite it.
backupPackageStatus = backupRunnerResult;
}
+ } else {
+ if (MORE_DEBUG) {
+ Slog.i(TAG, "Transport-level failure; cancelling agent work");
+ }
}
if (MORE_DEBUG) {
- Slog.i(TAG, "Done trying to send backup data: result="
+ Slog.i(TAG, "Done delivering backup data: result="
+ backupPackageStatus);
}
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index 87539921be78..6b517210ef31 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -358,7 +358,7 @@ public final class BatteryService extends SystemService {
try {
mBatteryStats.setBatteryState(mBatteryProps.batteryStatus, mBatteryProps.batteryHealth,
mPlugType, mBatteryProps.batteryLevel, mBatteryProps.batteryTemperature,
- mBatteryProps.batteryVoltage);
+ mBatteryProps.batteryVoltage, mBatteryProps.batteryChargeCounter);
} catch (RemoteException e) {
// Should never happen.
}
diff --git a/services/core/java/com/android/server/ConnectivityService.java b/services/core/java/com/android/server/ConnectivityService.java
index d85827e99079..00dcdeae3a27 100644
--- a/services/core/java/com/android/server/ConnectivityService.java
+++ b/services/core/java/com/android/server/ConnectivityService.java
@@ -29,8 +29,12 @@ import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED;
import static android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED;
import static android.net.NetworkPolicyManager.RULE_ALLOW_ALL;
+import static android.net.NetworkPolicyManager.RULE_ALLOW_METERED;
import static android.net.NetworkPolicyManager.RULE_REJECT_ALL;
import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
+import static android.net.NetworkPolicyManager.RULE_TEMPORARY_ALLOW_METERED;
+import static android.net.NetworkPolicyManager.RULE_UNKNOWN;
+
import android.annotation.Nullable;
import android.app.BroadcastOptions;
import android.app.Notification;
@@ -96,8 +100,10 @@ import android.security.Credentials;
import android.security.KeyStore;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
+import android.util.ArraySet;
import android.util.LocalLog;
import android.util.LocalLog.ReadOnlyLocalLog;
+import android.util.Log;
import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
@@ -121,9 +127,9 @@ import com.android.internal.util.XmlUtils;
import com.android.server.am.BatteryStatsService;
import com.android.server.connectivity.DataConnectionStats;
import com.android.server.connectivity.KeepaliveTracker;
-import com.android.server.connectivity.NetworkDiagnostics;
import com.android.server.connectivity.Nat464Xlat;
import com.android.server.connectivity.NetworkAgentInfo;
+import com.android.server.connectivity.NetworkDiagnostics;
import com.android.server.connectivity.NetworkMonitor;
import com.android.server.connectivity.PacManager;
import com.android.server.connectivity.PermissionMonitor;
@@ -131,8 +137,8 @@ import com.android.server.connectivity.Tethering;
import com.android.server.connectivity.Vpn;
import com.android.server.net.BaseNetworkObserver;
import com.android.server.net.LockdownVpnTracker;
+
import com.google.android.collect.Lists;
-import com.google.android.collect.Sets;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -152,11 +158,11 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.SortedSet;
-import java.util.TreeSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.SortedSet;
+import java.util.TreeSet;
/**
* @hide
@@ -202,9 +208,14 @@ public class ConnectivityService extends IConnectivityManager.Stub
/** Lock around {@link #mUidRules} and {@link #mMeteredIfaces}. */
private Object mRulesLock = new Object();
/** Currently active network rules by UID. */
+ @GuardedBy("mRulesLock")
private SparseIntArray mUidRules = new SparseIntArray();
/** Set of ifaces that are costly. */
- private HashSet<String> mMeteredIfaces = Sets.newHashSet();
+ @GuardedBy("mRulesLock")
+ private ArraySet<String> mMeteredIfaces = new ArraySet<>();
+ /** Flag indicating if background data is restricted. */
+ @GuardedBy("mRulesLock")
+ private boolean mRestrictBackground;
final private Context mContext;
private int mNetworkPreference;
@@ -651,7 +662,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
try {
- mPolicyManager.registerListener(mPolicyListener);
+ mPolicyManager.setConnectivityListener(mPolicyListener);
+ mRestrictBackground = mPolicyManager.getRestrictBackground();
} catch (RemoteException e) {
// ouch, no rules updates means some processes may never get network
loge("unable to register INetworkPolicyListener" + e.toString());
@@ -819,7 +831,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
throw new IllegalStateException("No free netIds");
}
- private NetworkState getFilteredNetworkState(int networkType, int uid) {
+ private NetworkState getFilteredNetworkState(int networkType, int uid, boolean ignoreBlocked) {
if (mLegacyTypeTracker.isTypeSupported(networkType)) {
final NetworkAgentInfo nai = mLegacyTypeTracker.getNetworkForType(networkType);
final NetworkState state;
@@ -834,7 +846,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
state = new NetworkState(info, new LinkProperties(), new NetworkCapabilities(),
null, null, null);
}
- filterNetworkStateForUid(state, uid);
+ filterNetworkStateForUid(state, uid, ignoreBlocked);
return state;
} else {
return NetworkState.EMPTY;
@@ -890,22 +902,36 @@ public class ConnectivityService extends IConnectivityManager.Stub
/**
* Check if UID should be blocked from using the network with the given LinkProperties.
*/
- private boolean isNetworkWithLinkPropertiesBlocked(LinkProperties lp, int uid) {
- final boolean networkCostly;
+ private boolean isNetworkWithLinkPropertiesBlocked(LinkProperties lp, int uid,
+ boolean ignoreBlocked) {
+ // Networks aren't blocked when ignoring blocked status
+ if (ignoreBlocked) return false;
+ // Networks are never blocked for system services
+ if (uid < Process.FIRST_APPLICATION_UID) return false;
+
+ final boolean networkMetered;
final int uidRules;
final String iface = (lp == null ? "" : lp.getInterfaceName());
synchronized (mRulesLock) {
- networkCostly = mMeteredIfaces.contains(iface);
- uidRules = mUidRules.get(uid, RULE_ALLOW_ALL);
+ networkMetered = mMeteredIfaces.contains(iface);
+ uidRules = mUidRules.get(uid, RULE_UNKNOWN);
}
- if (uidRules == RULE_REJECT_ALL) {
- return true;
- } else if ((uidRules == RULE_REJECT_METERED) && networkCostly) {
- return true;
- } else {
- return false;
+ switch (uidRules) {
+ case RULE_ALLOW_ALL:
+ case RULE_ALLOW_METERED:
+ case RULE_TEMPORARY_ALLOW_METERED:
+ return false;
+ case RULE_REJECT_METERED:
+ return networkMetered;
+ case RULE_REJECT_ALL:
+ return true;
+ case RULE_UNKNOWN:
+ default:
+ // When background data is restricted device-wide, the default
+ // behavior for apps should be like RULE_REJECT_METERED
+ return mRestrictBackground ? networkMetered : false;
}
}
@@ -930,10 +956,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
* on {@link #isNetworkWithLinkPropertiesBlocked}, or
* {@link NetworkInfo#isMetered()} based on network policies.
*/
- private void filterNetworkStateForUid(NetworkState state, int uid) {
+ private void filterNetworkStateForUid(NetworkState state, int uid, boolean ignoreBlocked) {
if (state == null || state.networkInfo == null || state.linkProperties == null) return;
- if (isNetworkWithLinkPropertiesBlocked(state.linkProperties, uid)) {
+ if (isNetworkWithLinkPropertiesBlocked(state.linkProperties, uid, ignoreBlocked)) {
state.networkInfo.setDetailedState(DetailedState.BLOCKED, null, null);
}
if (mLockdownTracker != null) {
@@ -962,7 +988,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
enforceAccessPermission();
final int uid = Binder.getCallingUid();
final NetworkState state = getUnfilteredActiveNetworkState(uid);
- filterNetworkStateForUid(state, uid);
+ filterNetworkStateForUid(state, uid, false);
maybeLogBlockedNetworkInfo(state.networkInfo, uid);
return state.networkInfo;
}
@@ -970,16 +996,16 @@ public class ConnectivityService extends IConnectivityManager.Stub
@Override
public Network getActiveNetwork() {
enforceAccessPermission();
- return getActiveNetworkForUidInternal(Binder.getCallingUid());
+ return getActiveNetworkForUidInternal(Binder.getCallingUid(), false);
}
@Override
- public Network getActiveNetworkForUid(int uid) {
+ public Network getActiveNetworkForUid(int uid, boolean ignoreBlocked) {
enforceConnectivityInternalPermission();
- return getActiveNetworkForUidInternal(uid);
+ return getActiveNetworkForUidInternal(uid, ignoreBlocked);
}
- private Network getActiveNetworkForUidInternal(final int uid) {
+ private Network getActiveNetworkForUidInternal(final int uid, boolean ignoreBlocked) {
final int user = UserHandle.getUserId(uid);
int vpnNetId = NETID_UNSET;
synchronized (mVpns) {
@@ -994,7 +1020,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
if (nai != null) return nai.network;
}
nai = getDefaultNetwork();
- if (nai != null && isNetworkWithLinkPropertiesBlocked(nai.linkProperties, uid)) nai = null;
+ if (nai != null
+ && isNetworkWithLinkPropertiesBlocked(nai.linkProperties, uid, ignoreBlocked)) {
+ nai = null;
+ }
return nai != null ? nai.network : null;
}
@@ -1006,10 +1035,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
}
@Override
- public NetworkInfo getActiveNetworkInfoForUid(int uid) {
+ public NetworkInfo getActiveNetworkInfoForUid(int uid, boolean ignoreBlocked) {
enforceConnectivityInternalPermission();
final NetworkState state = getUnfilteredActiveNetworkState(uid);
- filterNetworkStateForUid(state, uid);
+ filterNetworkStateForUid(state, uid, ignoreBlocked);
return state.networkInfo;
}
@@ -1023,22 +1052,21 @@ public class ConnectivityService extends IConnectivityManager.Stub
// getUnfilteredActiveNetworkState.
final NetworkState state = getUnfilteredActiveNetworkState(uid);
if (state.networkInfo != null && state.networkInfo.getType() == networkType) {
- filterNetworkStateForUid(state, uid);
+ filterNetworkStateForUid(state, uid, false);
return state.networkInfo;
}
}
- final NetworkState state = getFilteredNetworkState(networkType, uid);
+ final NetworkState state = getFilteredNetworkState(networkType, uid, false);
return state.networkInfo;
}
@Override
- public NetworkInfo getNetworkInfoForNetwork(Network network) {
+ public NetworkInfo getNetworkInfoForUid(Network network, int uid, boolean ignoreBlocked) {
enforceAccessPermission();
- final int uid = Binder.getCallingUid();
final NetworkAgentInfo nai = getNetworkAgentInfoForNetwork(network);
if (nai != null) {
final NetworkState state = nai.getNetworkState();
- filterNetworkStateForUid(state, uid);
+ filterNetworkStateForUid(state, uid, ignoreBlocked);
return state.networkInfo;
} else {
return null;
@@ -1063,8 +1091,8 @@ public class ConnectivityService extends IConnectivityManager.Stub
public Network getNetworkForType(int networkType) {
enforceAccessPermission();
final int uid = Binder.getCallingUid();
- NetworkState state = getFilteredNetworkState(networkType, uid);
- if (!isNetworkWithLinkPropertiesBlocked(state.linkProperties, uid)) {
+ NetworkState state = getFilteredNetworkState(networkType, uid, false);
+ if (!isNetworkWithLinkPropertiesBlocked(state.linkProperties, uid, false)) {
return state.network;
}
return null;
@@ -1381,6 +1409,11 @@ public class ConnectivityService extends IConnectivityManager.Stub
if (LOGD_RULES) {
log("onRestrictBackgroundChanged(restrictBackground=" + restrictBackground + ")");
}
+
+ synchronized (mRulesLock) {
+ mRestrictBackground = restrictBackground;
+ }
+
if (restrictBackground) {
log("onRestrictBackgroundChanged(true): disabling tethering");
mTethering.untetherAll();
@@ -1824,6 +1857,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
pw.decreaseIndent();
pw.println();
+ pw.print("Restrict background: ");
+ pw.println(mRestrictBackground);
+ pw.println();
+
pw.println("Network Requests:");
pw.increaseIndent();
for (NetworkRequestInfo nri : mNetworkRequests.values()) {
@@ -2765,7 +2802,7 @@ public class ConnectivityService extends IConnectivityManager.Stub
// which isn't meant to work on uncreated networks.
if (!nai.created) return;
- if (isNetworkWithLinkPropertiesBlocked(nai.linkProperties, uid)) return;
+ if (isNetworkWithLinkPropertiesBlocked(nai.linkProperties, uid, false)) return;
nai.networkMonitor.sendMessage(NetworkMonitor.CMD_FORCE_REEVALUATION, uid);
}
@@ -4280,10 +4317,10 @@ public class ConnectivityService extends IConnectivityManager.Stub
Collection<InetAddress> dnses = newLp.getDnsServers();
if (DBG) log("Setting DNS servers for network " + netId + " to " + dnses);
try {
- mNetd.setDnsServersForNetwork(
+ mNetd.setDnsConfigurationForNetwork(
netId, NetworkUtils.makeStrings(dnses), newLp.getDomains());
} catch (Exception e) {
- loge("Exception in setDnsServersForNetwork: " + e);
+ loge("Exception in setDnsConfigurationForNetwork: " + e);
}
final NetworkAgentInfo defaultNai = getDefaultNetwork();
if (defaultNai != null && defaultNai.network.netId == netId) {
diff --git a/services/core/java/com/android/server/NetworkManagementService.java b/services/core/java/com/android/server/NetworkManagementService.java
index 9fc17a2a3a29..2418160255f8 100644
--- a/services/core/java/com/android/server/NetworkManagementService.java
+++ b/services/core/java/com/android/server/NetworkManagementService.java
@@ -47,6 +47,7 @@ import static com.android.server.NetworkManagementService.NetdResponseCode.TtyLi
import static com.android.server.NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED;
import android.annotation.NonNull;
import android.app.ActivityManagerNative;
+import android.content.ContentResolver;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.INetd;
@@ -76,6 +77,7 @@ import android.os.ServiceSpecificException;
import android.os.StrictMode;
import android.os.SystemClock;
import android.os.SystemProperties;
+import android.provider.Settings;
import android.telephony.DataConnectionRealTimeInfo;
import android.telephony.PhoneStateListener;
import android.telephony.SubscriptionManager;
@@ -175,6 +177,12 @@ public class NetworkManagementService extends INetworkManagementService.Stub
public static final int StrictCleartext = 617;
}
+ /* Defaults for resolver parameters. */
+ public static final int DNS_RESOLVER_DEFAULT_SAMPLE_VALIDITY_SECONDS = 1800;
+ public static final int DNS_RESOLVER_DEFAULT_SUCCESS_THRESHOLD_PERCENT = 25;
+ public static final int DNS_RESOLVER_DEFAULT_MIN_SAMPLES = 8;
+ public static final int DNS_RESOLVER_DEFAULT_MAX_SAMPLES = 64;
+
/**
* String indicating a softap command.
*/
@@ -1927,6 +1935,51 @@ public class NetworkManagementService extends INetworkManagementService.Stub
}
@Override
+ public void setDnsConfigurationForNetwork(int netId, String[] servers, String domains) {
+ mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+
+ ContentResolver resolver = mContext.getContentResolver();
+
+ int sampleValidity = Settings.Global.getInt(resolver,
+ Settings.Global.DNS_RESOLVER_SAMPLE_VALIDITY_SECONDS,
+ DNS_RESOLVER_DEFAULT_SAMPLE_VALIDITY_SECONDS);
+ if (sampleValidity < 0 || sampleValidity > 65535) {
+ Slog.w(TAG, "Invalid sampleValidity=" + sampleValidity + ", using default=" +
+ DNS_RESOLVER_DEFAULT_SAMPLE_VALIDITY_SECONDS);
+ sampleValidity = DNS_RESOLVER_DEFAULT_SAMPLE_VALIDITY_SECONDS;
+ }
+
+ int successThreshold = Settings.Global.getInt(resolver,
+ Settings.Global.DNS_RESOLVER_SUCCESS_THRESHOLD_PERCENT,
+ DNS_RESOLVER_DEFAULT_SUCCESS_THRESHOLD_PERCENT);
+ if (successThreshold < 0 || successThreshold > 100) {
+ Slog.w(TAG, "Invalid successThreshold=" + successThreshold + ", using default=" +
+ DNS_RESOLVER_DEFAULT_SUCCESS_THRESHOLD_PERCENT);
+ successThreshold = DNS_RESOLVER_DEFAULT_SUCCESS_THRESHOLD_PERCENT;
+ }
+
+ int minSamples = Settings.Global.getInt(resolver,
+ Settings.Global.DNS_RESOLVER_MIN_SAMPLES, DNS_RESOLVER_DEFAULT_MIN_SAMPLES);
+ int maxSamples = Settings.Global.getInt(resolver,
+ Settings.Global.DNS_RESOLVER_MAX_SAMPLES, DNS_RESOLVER_DEFAULT_MAX_SAMPLES);
+ if (minSamples < 0 || minSamples > maxSamples || maxSamples > 64) {
+ Slog.w(TAG, "Invalid sample count (min, max)=(" + minSamples + ", " + maxSamples +
+ "), using default=(" + DNS_RESOLVER_DEFAULT_MIN_SAMPLES + ", " +
+ DNS_RESOLVER_DEFAULT_MAX_SAMPLES + ")");
+ minSamples = DNS_RESOLVER_DEFAULT_MIN_SAMPLES;
+ maxSamples = DNS_RESOLVER_DEFAULT_MAX_SAMPLES;
+ }
+
+ final String[] domainStrs = domains == null ? new String[0] : domains.split(" ");
+ final int[] params = { sampleValidity, successThreshold, minSamples, maxSamples };
+ try {
+ mNetdService.setResolverConfiguration(netId, servers, domainStrs, params);
+ } catch (RemoteException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
public void setDnsServersForNetwork(int netId, String[] servers, String domains) {
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
@@ -2048,13 +2101,13 @@ public class NetworkManagementService extends INetworkManagementService.Stub
}
}
- private void closeSocketsForFirewallChain(int chain, String chainName) {
+ private void closeSocketsForFirewallChainLocked(int chain, String chainName) {
// UID ranges to close sockets on.
UidRange[] ranges;
// UID ranges whose sockets we won't touch.
int[] exemptUids;
- SparseIntArray rules = getUidFirewallRules(chain);
+ final SparseIntArray rules = getUidFirewallRules(chain);
int numUids = 0;
if (getFirewallType(chain) == FIREWALL_TYPE_WHITELIST) {
@@ -2119,7 +2172,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub
mFirewallChainStates.put(chain, enable);
final String operation = enable ? "enable_chain" : "disable_chain";
- String chainName;
+ final String chainName;
switch(chain) {
case FIREWALL_CHAIN_STANDBY:
chainName = FIREWALL_CHAIN_NAME_STANDBY;
@@ -2146,7 +2199,7 @@ public class NetworkManagementService extends INetworkManagementService.Stub
// whitelist and blacklist chains allow RSTs through.
if (enable) {
if (DBG) Slog.d(TAG, "Closing sockets after enabling chain " + chainName);
- closeSocketsForFirewallChain(chain, chainName);
+ closeSocketsForFirewallChainLocked(chain, chainName);
}
}
}
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 96214d6b1a08..98b3b088399a 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -409,7 +409,6 @@ public class AccountManagerService
*/
public void validateAccounts(int userId) {
final UserAccounts accounts = getUserAccounts(userId);
-
// Invalidate user-specific cache to make sure we catch any
// removed authenticators.
validateAccountsInternal(accounts, true /* invalidateAuthenticatorCache */);
@@ -426,15 +425,13 @@ public class AccountManagerService
+ " isCeDatabaseAttached=" + accounts.openHelper.isCeDatabaseAttached()
+ " userLocked=" + mLocalUnlockedUsers.get(accounts.userId));
}
+
if (invalidateAuthenticatorCache) {
mAuthenticatorCache.invalidateCache(accounts.userId);
}
- final HashMap<String, Integer> knownAuth = new HashMap<>();
- for (RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> service :
- mAuthenticatorCache.getAllServices(accounts.userId)) {
- knownAuth.put(service.type.type, service.uid);
- }
+ final HashMap<String, Integer> knownAuth = getAuthenticatorTypeAndUIDForUser(
+ mAuthenticatorCache, accounts.userId);
synchronized (accounts.cacheLock) {
final SQLiteDatabase db = accounts.openHelper.getWritableDatabase();
@@ -452,6 +449,7 @@ public class AccountManagerService
// Create a list of authenticator type whose previous uid no longer exists
HashSet<String> obsoleteAuthType = Sets.newHashSet();
try {
+ SparseBooleanArray knownUids = null;
while (metaCursor.moveToNext()) {
String type = TextUtils.split(metaCursor.getString(0), META_KEY_DELIMITER)[1];
String uid = metaCursor.getString(1);
@@ -466,23 +464,48 @@ public class AccountManagerService
// Remove it from the knownAuth list if it's unchanged.
knownAuth.remove(type);
} else {
- // Only add it to the list if it no longer exists or uid different
- obsoleteAuthType.add(type);
- // And delete it from the TABLE_META
- db.delete(
- TABLE_META,
- META_KEY + "=? AND " + META_VALUE + "=?",
- new String[] {
- META_KEY_FOR_AUTHENTICATOR_UID_FOR_TYPE_PREFIX + type,
- uid}
- );
+ /*
+ * The authenticator is presently not cached and should only be triggered
+ * when we think an authenticator has been removed (or is being updated).
+ * But we still want to check if any data with the associated uid is
+ * around. This is an (imperfect) signal that the package may be updating.
+ *
+ * A side effect of this is that an authenticator sharing a uid with
+ * multiple apps won't get its credentials wiped as long as some app with
+ * that uid is still on the device. But I suspect that this is a rare case.
+ * And it isn't clear to me how an attacker could really exploit that
+ * feature.
+ *
+ * The upshot is that we don't have to worry about accounts getting
+ * uninstalled while the authenticator's package is being updated.
+ *
+ */
+ if (knownUids == null) {
+ knownUids = getUidsOfInstalledOrUpdatedPackagesAsUser(accounts.userId);
+ }
+ if (!knownUids.get(Integer.parseInt(uid))) {
+ // The authenticator is not presently available to the cache. And the
+ // package no longer has a data directory (so we surmise it isn't updating).
+ // So purge its data from the account databases.
+ obsoleteAuthType.add(type);
+ // And delete it from the TABLE_META
+ db.delete(
+ TABLE_META,
+ META_KEY + "=? AND " + META_VALUE + "=?",
+ new String[] {
+ META_KEY_FOR_AUTHENTICATOR_UID_FOR_TYPE_PREFIX + type,
+ uid}
+ );
+ }
}
}
} finally {
metaCursor.close();
}
- // Add the newly registered authenticator to TABLE_META
+ // Add the newly registered authenticator to TABLE_META. If old authenticators have
+ // been renabled (after being updated for example), then we just overwrite the old
+ // values.
Iterator<Entry<String, Integer>> iterator = knownAuth.entrySet().iterator();
while (iterator.hasNext()) {
Entry<String, Integer> entry = iterator.next();
@@ -490,7 +513,7 @@ public class AccountManagerService
values.put(META_KEY,
META_KEY_FOR_AUTHENTICATOR_UID_FOR_TYPE_PREFIX + entry.getKey());
values.put(META_VALUE, entry.getValue());
- db.insert(TABLE_META, null, values);
+ db.insertWithOnConflict(TABLE_META, null, values, SQLiteDatabase.CONFLICT_REPLACE);
}
Cursor cursor = db.query(TABLE_ACCOUNTS,
@@ -544,10 +567,32 @@ public class AccountManagerService
}
}
+ private SparseBooleanArray getUidsOfInstalledOrUpdatedPackagesAsUser(int userId) {
+ // Get the UIDs of all apps that might have data on the device. We want
+ // to preserve user data if the app might otherwise be storing data.
+ List<PackageInfo> pkgsWithData =
+ mPackageManager.getInstalledPackagesAsUser(
+ PackageManager.MATCH_UNINSTALLED_PACKAGES, userId);
+ SparseBooleanArray knownUids = new SparseBooleanArray(pkgsWithData.size());
+ for (PackageInfo pkgInfo : pkgsWithData) {
+ if (pkgInfo.applicationInfo != null
+ && (pkgInfo.applicationInfo.flags & ApplicationInfo.FLAG_INSTALLED) != 0) {
+ knownUids.put(pkgInfo.applicationInfo.uid, true);
+ }
+ }
+ return knownUids;
+ }
+
private static HashMap<String, Integer> getAuthenticatorTypeAndUIDForUser(
Context context,
int userId) {
AccountAuthenticatorCache authCache = new AccountAuthenticatorCache(context);
+ return getAuthenticatorTypeAndUIDForUser(authCache, userId);
+ }
+
+ private static HashMap<String, Integer> getAuthenticatorTypeAndUIDForUser(
+ IAccountAuthenticatorCache authCache,
+ int userId) {
HashMap<String, Integer> knownAuth = new HashMap<>();
for (RegisteredServicesCache.ServiceInfo<AuthenticatorDescription> service : authCache
.getAllServices(userId)) {
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 33b87b656fa0..82ec80c6288c 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -1597,9 +1597,6 @@ class ActivityStarter {
private void setTaskFromReuseOrCreateNewTask(TaskRecord taskToAffiliate) {
mTargetStack = computeStackFocus(mStartActivity, true, mLaunchBounds, mLaunchFlags,
mOptions);
- if (mDoResume) {
- mTargetStack.moveToFront("startingNewTask");
- }
if (mReuseTask == null) {
final TaskRecord task = mTargetStack.createTaskRecord(
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index e9ed34b18baa..3ed996992e2e 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -304,6 +304,15 @@ class AppErrors {
* @param crashInfo describing the failure
*/
void crashApplication(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
+ final long origId = Binder.clearCallingIdentity();
+ try {
+ crashApplicationInner(r, crashInfo);
+ } finally {
+ Binder.restoreCallingIdentity(origId);
+ }
+ }
+
+ void crashApplicationInner(ProcessRecord r, ApplicationErrorReport.CrashInfo crashInfo) {
long timeMillis = System.currentTimeMillis();
String shortMsg = crashInfo.exceptionClassName;
String longMsg = crashInfo.exceptionMessage;
@@ -317,49 +326,20 @@ class AppErrors {
AppErrorResult result = new AppErrorResult();
TaskRecord task;
synchronized (mService) {
- if (mService.mController != null) {
- try {
- String name = r != null ? r.processName : null;
- int pid = r != null ? r.pid : Binder.getCallingPid();
- int uid = r != null ? r.info.uid : Binder.getCallingUid();
- if (!mService.mController.appCrashed(name, pid,
- shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
- if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
- && "Native crash".equals(crashInfo.exceptionClassName)) {
- Slog.w(TAG, "Skip killing native crashed app " + name
- + "(" + pid + ") during testing");
- } else {
- Slog.w(TAG, "Force-killing crashed app " + name
- + " at watcher's request");
- if (r != null) {
- r.kill("crash", true);
- } else {
- // Huh.
- Process.killProcess(pid);
- ActivityManagerService.killProcessGroup(uid, pid);
- }
- }
- return;
- }
- } catch (RemoteException e) {
- mService.mController = null;
- Watchdog.getInstance().setActivityController(null);
- }
+ /**
+ * If crash is handled by instance of {@link android.app.IActivityController},
+ * finish now and don't show the app error dialog.
+ */
+ if (handleAppCrashInActivityController(r, crashInfo, shortMsg, longMsg, stackTrace,
+ timeMillis)) {
+ return;
}
- final long origId = Binder.clearCallingIdentity();
-
- // If this process is running instrumentation, finish it.
+ /**
+ * If this process was running instrumentation, finish now - it will be handled in
+ * {@link ActivityManagerService#handleAppDiedLocked}.
+ */
if (r != null && r.instrumentationClass != null) {
- Slog.w(TAG, "Error in app " + r.processName
- + " running instrumentation " + r.instrumentationClass + ":");
- if (shortMsg != null) Slog.w(TAG, " " + shortMsg);
- if (longMsg != null) Slog.w(TAG, " " + longMsg);
- Bundle info = new Bundle();
- info.putString("shortMsg", shortMsg);
- info.putString("longMsg", longMsg);
- mService.finishInstrumentationLocked(r, Activity.RESULT_CANCELED, info);
- Binder.restoreCallingIdentity(origId);
return;
}
@@ -375,7 +355,6 @@ class AppErrors {
// If we can't identify the process or it's already exceeded its crash quota,
// quit right away without showing a crash dialog.
if (r == null || !makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace, data)) {
- Binder.restoreCallingIdentity(origId);
return;
}
@@ -385,97 +364,90 @@ class AppErrors {
task = data.task;
msg.obj = data;
mService.mUiHandler.sendMessage(msg);
-
- Binder.restoreCallingIdentity(origId);
}
int res = result.get();
Intent appErrorIntent = null;
- final long ident = Binder.clearCallingIdentity();
- try {
- MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_CRASH, res);
- if (res == AppErrorDialog.TIMEOUT) {
- res = AppErrorDialog.FORCE_QUIT;
- }
- if (res == AppErrorDialog.RESET) {
- String[] packageList = r.getPackageList();
- if (packageList != null) {
- PackageManager pm = mContext.getPackageManager();
- final Semaphore s = new Semaphore(0);
- for (int i = 0; i < packageList.length; i++) {
- if (i < packageList.length - 1) {
- pm.deleteApplicationCacheFiles(packageList[i], null);
- } else {
- pm.deleteApplicationCacheFiles(packageList[i],
- new IPackageDataObserver.Stub() {
- @Override
- public void onRemoveCompleted(String packageName,
- boolean succeeded) {
- s.release();
- }
- });
-
- // Wait until cache has been cleared before we restart.
- try {
- s.acquire();
- } catch (InterruptedException e) {
- }
- }
- }
- }
- // If there was nothing to reset, just restart;
- res = AppErrorDialog.RESTART;
- }
- synchronized (mService) {
- if (res == AppErrorDialog.MUTE) {
- stopReportingCrashesLocked(r);
- }
- if (res == AppErrorDialog.RESTART) {
- mService.removeProcessLocked(r, false, true, "crash");
- if (task != null) {
+ MetricsLogger.action(mContext, MetricsProto.MetricsEvent.ACTION_APP_CRASH, res);
+ if (res == AppErrorDialog.TIMEOUT) {
+ res = AppErrorDialog.FORCE_QUIT;
+ }
+ if (res == AppErrorDialog.RESET) {
+ String[] packageList = r.getPackageList();
+ if (packageList != null) {
+ PackageManager pm = mContext.getPackageManager();
+ final Semaphore s = new Semaphore(0);
+ for (int i = 0; i < packageList.length; i++) {
+ if (i < packageList.length - 1) {
+ pm.deleteApplicationCacheFiles(packageList[i], null);
+ } else {
+ pm.deleteApplicationCacheFiles(packageList[i],
+ new IPackageDataObserver.Stub() {
+ @Override
+ public void onRemoveCompleted(String packageName,
+ boolean succeeded) {
+ s.release();
+ }
+ });
+
+ // Wait until cache has been cleared before we restart.
try {
- mService.startActivityFromRecents(task.taskId,
- ActivityOptions.makeBasic().toBundle());
- } catch (IllegalArgumentException e) {
- // Hmm, that didn't work, app might have crashed before creating a
- // recents entry. Let's see if we have a safe-to-restart intent.
- if (task.intent.getCategories().contains(
- Intent.CATEGORY_LAUNCHER)) {
- mService.startActivityInPackage(task.mCallingUid,
- task.mCallingPackage, task.intent,
- null, null, null, 0, 0,
- ActivityOptions.makeBasic().toBundle(),
- task.userId, null, null);
- }
+ s.acquire();
+ } catch (InterruptedException e) {
}
}
}
- if (res == AppErrorDialog.FORCE_QUIT) {
- long orig = Binder.clearCallingIdentity();
+ }
+ // If there was nothing to reset, just restart;
+ res = AppErrorDialog.RESTART;
+ }
+ synchronized (mService) {
+ if (res == AppErrorDialog.MUTE) {
+ stopReportingCrashesLocked(r);
+ }
+ if (res == AppErrorDialog.RESTART) {
+ mService.removeProcessLocked(r, false, true, "crash");
+ if (task != null) {
try {
- // Kill it with fire!
- mService.mStackSupervisor.handleAppCrashLocked(r);
- if (!r.persistent) {
- mService.removeProcessLocked(r, false, false, "crash");
- mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ mService.startActivityFromRecents(task.taskId,
+ ActivityOptions.makeBasic().toBundle());
+ } catch (IllegalArgumentException e) {
+ // Hmm, that didn't work, app might have crashed before creating a
+ // recents entry. Let's see if we have a safe-to-restart intent.
+ if (task.intent.getCategories().contains(
+ Intent.CATEGORY_LAUNCHER)) {
+ mService.startActivityInPackage(task.mCallingUid,
+ task.mCallingPackage, task.intent,
+ null, null, null, 0, 0,
+ ActivityOptions.makeBasic().toBundle(),
+ task.userId, null, null);
}
- } finally {
- Binder.restoreCallingIdentity(orig);
}
}
- if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
- appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
- }
- if (r != null && !r.isolated && res != AppErrorDialog.RESTART) {
- // XXX Can't keep track of crash time for isolated processes,
- // since they don't have a persistent identity.
- mProcessCrashTimes.put(r.info.processName, r.uid,
- SystemClock.uptimeMillis());
+ }
+ if (res == AppErrorDialog.FORCE_QUIT) {
+ long orig = Binder.clearCallingIdentity();
+ try {
+ // Kill it with fire!
+ mService.mStackSupervisor.handleAppCrashLocked(r);
+ if (!r.persistent) {
+ mService.removeProcessLocked(r, false, false, "crash");
+ mService.mStackSupervisor.resumeFocusedStackTopActivityLocked();
+ }
+ } finally {
+ Binder.restoreCallingIdentity(orig);
}
}
- } finally {
- Binder.restoreCallingIdentity(ident);
+ if (res == AppErrorDialog.FORCE_QUIT_AND_REPORT) {
+ appErrorIntent = createAppErrorIntentLocked(r, timeMillis, crashInfo);
+ }
+ if (r != null && !r.isolated && res != AppErrorDialog.RESTART) {
+ // XXX Can't keep track of crash time for isolated processes,
+ // since they don't have a persistent identity.
+ mProcessCrashTimes.put(r.info.processName, r.uid,
+ SystemClock.uptimeMillis());
+ }
}
if (appErrorIntent != null) {
@@ -487,6 +459,47 @@ class AppErrors {
}
}
+ private boolean handleAppCrashInActivityController(ProcessRecord r,
+ ApplicationErrorReport.CrashInfo crashInfo,
+ String shortMsg, String longMsg,
+ String stackTrace, long timeMillis) {
+ if (mService.mController == null) {
+ return false;
+ }
+
+ try {
+ String name = r != null ? r.processName : null;
+ int pid = r != null ? r.pid : Binder.getCallingPid();
+ int uid = r != null ? r.info.uid : Binder.getCallingUid();
+ if (!mService.mController.appCrashed(name, pid,
+ shortMsg, longMsg, timeMillis, crashInfo.stackTrace)) {
+ if ("1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"))
+ && "Native crash".equals(crashInfo.exceptionClassName)) {
+ Slog.w(TAG, "Skip killing native crashed app " + name
+ + "(" + pid + ") during testing");
+ } else {
+ Slog.w(TAG, "Force-killing crashed app " + name
+ + " at watcher's request");
+ if (r != null) {
+ if (!makeAppCrashingLocked(r, shortMsg, longMsg, stackTrace, null))
+ {
+ r.kill("crash", true);
+ }
+ } else {
+ // Huh.
+ Process.killProcess(pid);
+ ActivityManagerService.killProcessGroup(uid, pid);
+ }
+ }
+ return true;
+ }
+ } catch (RemoteException e) {
+ mService.mController = null;
+ Watchdog.getInstance().setActivityController(null);
+ }
+ return false;
+ }
+
private boolean makeAppCrashingLocked(ProcessRecord app,
String shortMsg, String longMsg, String stackTrace, AppErrorDialog.Data data) {
app.crashing = true;
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index c6786defd3f9..d34ec868dc1c 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -974,7 +974,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub
@Override
public void setBatteryState(final int status, final int health, final int plugType,
- final int level, final int temp, final int volt) {
+ final int level, final int temp, final int volt, final int chargeCount) {
enforceCallingPermission();
// BatteryService calls us here and we may update external state. It would be wrong
@@ -987,7 +987,8 @@ public final class BatteryStatsService extends IBatteryStats.Stub
if (mStats.isOnBattery() == onBattery) {
// The battery state has not changed, so we don't need to sync external
// stats immediately.
- mStats.setBatteryStateLocked(status, health, plugType, level, temp, volt);
+ mStats.setBatteryStateLocked(status, health, plugType, level, temp, volt,
+ chargeCount);
return;
}
}
@@ -996,7 +997,8 @@ public final class BatteryStatsService extends IBatteryStats.Stub
// immediately here, we may not collect the relevant data later.
updateExternalStatsSync("battery-state", BatteryStatsImpl.ExternalStatsSync.UPDATE_ALL);
synchronized (mStats) {
- mStats.setBatteryStateLocked(status, health, plugType, level, temp, volt);
+ mStats.setBatteryStateLocked(status, health, plugType, level, temp, volt,
+ chargeCount);
}
}
});
diff --git a/services/core/java/com/android/server/job/JobStore.java b/services/core/java/com/android/server/job/JobStore.java
index 5ad988a42792..1f7d3128d655 100644
--- a/services/core/java/com/android/server/job/JobStore.java
+++ b/services/core/java/com/android/server/job/JobStore.java
@@ -333,6 +333,7 @@ public class JobStore {
out.attribute(null, "sourceUserId", String.valueOf(jobStatus.getSourceUserId()));
out.attribute(null, "uid", Integer.toString(jobStatus.getUid()));
out.attribute(null, "priority", String.valueOf(jobStatus.getPriority()));
+ out.attribute(null, "flags", String.valueOf(jobStatus.getFlags()));
}
private void writeBundleToXml(PersistableBundle extras, XmlSerializer out)
@@ -543,6 +544,10 @@ public class JobStore {
if (val != null) {
jobBuilder.setPriority(Integer.parseInt(val));
}
+ val = parser.getAttributeValue(null, "flags");
+ if (val != null) {
+ jobBuilder.setFlags(Integer.parseInt(val));
+ }
val = parser.getAttributeValue(null, "sourceUserId");
sourceUserId = val == null ? -1 : Integer.parseInt(val);
} catch (NumberFormatException e) {
diff --git a/services/core/java/com/android/server/job/controllers/ConnectivityController.java b/services/core/java/com/android/server/job/controllers/ConnectivityController.java
index 88cf322ed913..f5aac087f9b0 100644
--- a/services/core/java/com/android/server/job/controllers/ConnectivityController.java
+++ b/services/core/java/com/android/server/job/controllers/ConnectivityController.java
@@ -16,6 +16,7 @@
package com.android.server.job.controllers;
+import android.app.job.JobInfo;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -97,7 +98,9 @@ public class ConnectivityController extends StateController implements
}
private boolean updateConstraintsSatisfied(JobStatus jobStatus) {
- final NetworkInfo info = mConnManager.getActiveNetworkInfoForUid(jobStatus.getSourceUid());
+ final boolean ignoreBlocked = (jobStatus.getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) != 0;
+ final NetworkInfo info = mConnManager.getActiveNetworkInfoForUid(jobStatus.getSourceUid(),
+ ignoreBlocked);
final boolean connected = (info != null) && info.isConnected();
final boolean unmetered = connected && !info.isMetered();
final boolean notRoaming = connected && !info.isRoaming();
diff --git a/services/core/java/com/android/server/job/controllers/JobStatus.java b/services/core/java/com/android/server/job/controllers/JobStatus.java
index 590d075446cf..19bede97c503 100644
--- a/services/core/java/com/android/server/job/controllers/JobStatus.java
+++ b/services/core/java/com/android/server/job/controllers/JobStatus.java
@@ -297,6 +297,10 @@ public final class JobStatus {
return job.getPriority();
}
+ public int getFlags() {
+ return job.getFlags();
+ }
+
public boolean hasConnectivityConstraint() {
return (requiredConstraints&CONSTRAINT_CONNECTIVITY) != 0;
}
@@ -416,12 +420,12 @@ public final class JobStatus {
// satisfied).
// AppNotIdle implicit constraint must be satisfied
// DeviceNotDozing implicit constraint must be satisfied
- return (isConstraintsSatisfied()
- || (!job.isPeriodic()
- && hasDeadlineConstraint() && (satisfiedConstraints&CONSTRAINT_DEADLINE) != 0)
- )
- && (satisfiedConstraints & CONSTRAINT_APP_NOT_IDLE) != 0
- && (satisfiedConstraints & CONSTRAINT_DEVICE_NOT_DOZING) != 0;
+ final boolean deadlineSatisfied = (!job.isPeriodic() && hasDeadlineConstraint()
+ && (satisfiedConstraints & CONSTRAINT_DEADLINE) != 0);
+ final boolean notIdle = (satisfiedConstraints & CONSTRAINT_APP_NOT_IDLE) != 0;
+ final boolean notDozing = (satisfiedConstraints & CONSTRAINT_DEVICE_NOT_DOZING) != 0
+ || (job.getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) != 0;
+ return (isConstraintsSatisfied() || deadlineSatisfied) && notIdle && notDozing;
}
static final int CONSTRAINTS_OF_INTEREST =
@@ -561,6 +565,10 @@ public final class JobStatus {
if (job.getPriority() != 0) {
pw.print(prefix); pw.print(" Priority: "); pw.println(job.getPriority());
}
+ if (job.getFlags() != 0) {
+ pw.print(prefix); pw.print(" Flags: ");
+ pw.println(Integer.toHexString(job.getFlags()));
+ }
pw.print(prefix); pw.print(" Requires: charging=");
pw.print(job.isRequireCharging()); pw.print(" deviceIdle=");
pw.println(job.isRequireDeviceIdle());
@@ -613,6 +621,9 @@ public final class JobStatus {
pw.print(prefix); pw.print("Satisfied constraints:");
dumpConstraints(pw, satisfiedConstraints);
pw.println();
+ pw.print(prefix); pw.print("Unsatisfied constraints:");
+ dumpConstraints(pw, (requiredConstraints & ~satisfiedConstraints));
+ pw.println();
}
if (changedAuthorities != null) {
pw.print(prefix); pw.println("Changed authorities:");
diff --git a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
index 30aab8cc5897..50d936853fed 100644
--- a/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
+++ b/services/core/java/com/android/server/net/NetworkPolicyManagerService.java
@@ -48,7 +48,6 @@ import static android.net.NetworkPolicyManager.FIREWALL_RULE_DEFAULT;
import static android.net.NetworkPolicyManager.FIREWALL_RULE_DENY;
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_ALLOW_METERED;
import static android.net.NetworkPolicyManager.RULE_REJECT_METERED;
import static android.net.NetworkPolicyManager.RULE_TEMPORARY_ALLOW_METERED;
@@ -349,6 +348,9 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
/** Foreground at UID granularity. */
final SparseIntArray mUidState = new SparseIntArray();
+ /** Higher priority listener before general event dispatch */
+ private INetworkPolicyListener mConnectivityListener;
+
private final RemoteCallbackList<INetworkPolicyListener>
mListeners = new RemoteCallbackList<>();
@@ -1391,6 +1393,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
final String tag = in.getName();
if (type == START_TAG) {
if (TAG_POLICY_LIST.equals(tag)) {
+ final boolean oldValue = mRestrictBackground;
version = readIntAttribute(in, ATTR_VERSION);
if (version >= VERSION_ADDED_RESTRICT_BACKGROUND) {
mRestrictBackground = readBooleanAttribute(
@@ -1398,6 +1401,12 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
} else {
mRestrictBackground = false;
}
+ if (mRestrictBackground != oldValue) {
+ // Some early services may have read the default value,
+ // so notify them that it's changed
+ mHandler.obtainMessage(MSG_RESTRICT_BACKGROUND_CHANGED,
+ mRestrictBackground ? 1 : 0, 0).sendToTarget();
+ }
} else if (TAG_NETWORK_POLICY.equals(tag)) {
final int networkTemplate = readIntAttribute(in, ATTR_NETWORK_TEMPLATE);
@@ -1766,20 +1775,25 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
}
@Override
+ public void setConnectivityListener(INetworkPolicyListener listener) {
+ mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
+ if (mConnectivityListener != null) {
+ throw new IllegalStateException("Connectivity listener already registered");
+ }
+ mConnectivityListener = listener;
+ }
+
+ @Override
public void registerListener(INetworkPolicyListener listener) {
// TODO: create permission for observing network policy
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
-
mListeners.register(listener);
-
- // TODO: consider dispatching existing rules to new listeners
}
@Override
public void unregisterListener(INetworkPolicyListener listener) {
// TODO: create permission for observing network policy
mContext.enforceCallingOrSelfPermission(CONNECTIVITY_INTERNAL, TAG);
-
mListeners.unregister(listener);
}
@@ -2754,8 +2768,8 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
final boolean isBlacklisted = (uidPolicy & POLICY_REJECT_METERED_BACKGROUND) != 0;
final boolean isWhitelisted = mRestrictBackgroundWhitelistUids.get(uid);
- int newRule = RULE_ALLOW_ALL;
- final int oldRule = mUidRules.get(uid);
+ int newRule = RULE_UNKNOWN;
+ final int oldRule = mUidRules.get(uid, RULE_UNKNOWN);
// First step: define the new rule based on user restrictions and foreground state.
if (isForeground) {
@@ -2777,8 +2791,7 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
+ ", oldRule: " + ruleToString(oldRule));
}
-
- if (newRule == RULE_ALLOW_ALL) {
+ if (newRule == RULE_UNKNOWN) {
mUidRules.delete(uid);
} else {
mUidRules.put(uid, newRule);
@@ -2858,6 +2871,45 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
}
}
+ private void dispatchUidRulesChanged(INetworkPolicyListener listener, int uid, int uidRules) {
+ if (listener != null) {
+ try {
+ listener.onUidRulesChanged(uid, uidRules);
+ } catch (RemoteException ignored) {
+ }
+ }
+ }
+
+ private void dispatchMeteredIfacesChanged(INetworkPolicyListener listener,
+ String[] meteredIfaces) {
+ if (listener != null) {
+ try {
+ listener.onMeteredIfacesChanged(meteredIfaces);
+ } catch (RemoteException ignored) {
+ }
+ }
+ }
+
+ private void dispatchRestrictBackgroundChanged(INetworkPolicyListener listener,
+ boolean restrictBackground) {
+ if (listener != null) {
+ try {
+ listener.onRestrictBackgroundChanged(restrictBackground);
+ } catch (RemoteException ignored) {
+ }
+ }
+ }
+
+ private void dispatchRestrictBackgroundWhitelistChanged(INetworkPolicyListener listener,
+ int uid, boolean whitelisted) {
+ if (listener != null) {
+ try {
+ listener.onRestrictBackgroundWhitelistChanged(uid, whitelisted);
+ } catch (RemoteException ignored) {
+ }
+ }
+ }
+
private Handler.Callback mHandlerCallback = new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
@@ -2865,30 +2917,22 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
case MSG_RULES_CHANGED: {
final int uid = msg.arg1;
final int uidRules = msg.arg2;
+ dispatchUidRulesChanged(mConnectivityListener, uid, uidRules);
final int length = mListeners.beginBroadcast();
for (int i = 0; i < length; i++) {
final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
- if (listener != null) {
- try {
- listener.onUidRulesChanged(uid, uidRules);
- } catch (RemoteException e) {
- }
- }
+ dispatchUidRulesChanged(listener, uid, uidRules);
}
mListeners.finishBroadcast();
return true;
}
case MSG_METERED_IFACES_CHANGED: {
final String[] meteredIfaces = (String[]) msg.obj;
+ dispatchMeteredIfacesChanged(mConnectivityListener, meteredIfaces);
final int length = mListeners.beginBroadcast();
for (int i = 0; i < length; i++) {
final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
- if (listener != null) {
- try {
- listener.onMeteredIfacesChanged(meteredIfaces);
- } catch (RemoteException e) {
- }
- }
+ dispatchMeteredIfacesChanged(listener, meteredIfaces);
}
mListeners.finishBroadcast();
return true;
@@ -2915,15 +2959,11 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
}
case MSG_RESTRICT_BACKGROUND_CHANGED: {
final boolean restrictBackground = msg.arg1 != 0;
+ dispatchRestrictBackgroundChanged(mConnectivityListener, restrictBackground);
final int length = mListeners.beginBroadcast();
for (int i = 0; i < length; i++) {
final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
- if (listener != null) {
- try {
- listener.onRestrictBackgroundChanged(restrictBackground);
- } catch (RemoteException e) {
- }
- }
+ dispatchRestrictBackgroundChanged(listener, restrictBackground);
}
mListeners.finishBroadcast();
final Intent intent =
@@ -2947,18 +2987,16 @@ public class NetworkPolicyManagerService extends INetworkPolicyManager.Stub {
final boolean changed = msg.arg2 == 1;
final Boolean whitelisted = (Boolean) msg.obj;
+ // First notify internal listeners...
if (whitelisted != null) {
+ final boolean whitelistedBool = whitelisted.booleanValue();
+ dispatchRestrictBackgroundWhitelistChanged(mConnectivityListener, uid,
+ whitelistedBool);
final int length = mListeners.beginBroadcast();
for (int i = 0; i < length; i++) {
- // First notify internal listeners...
final INetworkPolicyListener listener = mListeners.getBroadcastItem(i);
- if (listener != null) {
- try {
- listener.onRestrictBackgroundWhitelistChanged(uid,
- whitelisted.booleanValue());
- } catch (RemoteException e) {
- }
- }
+ dispatchRestrictBackgroundWhitelistChanged(listener, uid,
+ whitelistedBool);
}
mListeners.finishBroadcast();
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index ba651fce1ec9..61e36d964188 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -266,6 +266,7 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileDescriptor;
+import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
@@ -274,6 +275,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
+import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
@@ -437,6 +439,8 @@ public class PackageManagerService extends IPackageManager.Stub {
*/
private static final int DEFAULT_VERIFICATION_RESPONSE = PackageManager.VERIFICATION_ALLOW;
+ static final String PLATFORM_PACKAGE_NAME = "android";
+
static final String DEFAULT_CONTAINER_PACKAGE = "com.android.defcontainer";
static final ComponentName DEFAULT_CONTAINER_COMPONENT = new ComponentName(
@@ -9725,7 +9729,9 @@ public class PackageManagerService extends IPackageManager.Stub {
switch (grant) {
case GRANT_INSTALL: {
// Revoke this as runtime permission to handle the case of
- // a runtime permission being downgraded to an install one. Also in permission review mode we keep dangerous permissions for legacy apps
+ // a runtime permission being downgraded to an install one.
+ // Also in permission review mode we keep dangerous permissions
+ // for legacy apps
for (int userId : UserManagerService.getInstance().getUserIds()) {
if (origPermissions.getRuntimePermissionState(
bp.name, userId) != null) {
@@ -9773,10 +9779,21 @@ public class PackageManagerService extends IPackageManager.Stub {
&& !appSupportsRuntimePermissions) {
// For legacy apps that need a permission review, every new
// runtime permission is granted but it is pending a review.
- if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
- permissionsState.grantRuntimePermission(bp, userId);
- flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
- // We changed the permission and flags, hence have to write.
+ // We also need to review only platform defined runtime
+ // permissions as these are the only ones the platform knows
+ // how to disable the API to simulate revocation as legacy
+ // apps don't expect to run with revoked permissions.
+ if (PLATFORM_PACKAGE_NAME.equals(bp.sourcePackage)) {
+ if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
+ flags |= FLAG_PERMISSION_REVIEW_REQUIRED;
+ // We changed the flags, hence have to write.
+ changedRuntimePermissionUserIds = ArrayUtils.appendInt(
+ changedRuntimePermissionUserIds, userId);
+ }
+ }
+ if (permissionsState.grantRuntimePermission(bp, userId)
+ != PermissionsState.PERMISSION_OPERATION_FAILURE) {
+ // We changed the permission, hence have to write.
changedRuntimePermissionUserIds = ArrayUtils.appendInt(
changedRuntimePermissionUserIds, userId);
}
@@ -13817,6 +13834,13 @@ public class PackageManagerService extends IPackageManager.Stub {
return false;
}
+ private static void updateDigest(MessageDigest digest, File file) throws IOException {
+ try (DigestInputStream digestStream =
+ new DigestInputStream(new FileInputStream(file), digest)) {
+ while (digestStream.read() != -1) {} // nothing to do; just plow through the file
+ }
+ }
+
private void replacePackageLIF(PackageParser.Package pkg, final int policyFlags, int scanFlags,
UserHandle user, String installerPackageName, PackageInstalledInfo res) {
final boolean isEphemeral = (policyFlags & PackageParser.PARSE_IS_EPHEMERAL) != 0;
@@ -13871,6 +13895,32 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
+ // don't allow a system upgrade unless the upgrade hash matches
+ if (oldPackage.restrictUpdateHash != null && oldPackage.isSystemApp()) {
+ byte[] digestBytes = null;
+ try {
+ final MessageDigest digest = MessageDigest.getInstance("SHA-512");
+ updateDigest(digest, new File(pkg.baseCodePath));
+ if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
+ for (String path : pkg.splitCodePaths) {
+ updateDigest(digest, new File(path));
+ }
+ }
+ digestBytes = digest.digest();
+ } catch (NoSuchAlgorithmException | IOException e) {
+ res.setError(INSTALL_FAILED_INVALID_APK,
+ "Could not compute hash: " + pkgName);
+ return;
+ }
+ if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) {
+ res.setError(INSTALL_FAILED_INVALID_APK,
+ "New package fails restrict-update check: " + pkgName);
+ return;
+ }
+ // retain upgrade restriction
+ pkg.restrictUpdateHash = oldPackage.restrictUpdateHash;
+ }
+
// Check for shared user id changes
String invalidPackageName =
getParentOrChildPackageChangedSharedUser(oldPackage, pkg);
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 1493bc73a17f..e3194074f792 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -1441,6 +1441,18 @@ class WindowStateAnimator {
return;
}
+ // Do not change surface properties of opening apps if we are waiting for the
+ // transition to be ready. transitionGoodToGo could be not ready even after all
+ // opening apps are drawn. It's only waiting on isFetchingAppTransitionsSpecs()
+ // to get the animation spec. (For example, go into Recents and immediately open
+ // the same app again before the app's surface is destroyed or saved, the surface
+ // is always ready in the whole process.) If we go ahead here, the opening app
+ // will be shown with the full size before the correct animation spec arrives.
+ if (mService.mAppTransition.isReady() && isDummyAnimation() &&
+ mService.mOpeningApps.contains(w.mAppToken)) {
+ return;
+ }
+
boolean displayed = false;
computeShownFrameLocked();
diff --git a/tools/fonts/fontchain_lint.py b/tools/fonts/fontchain_lint.py
index 81ab3ccf3ec5..fe7c3b9b400f 100755
--- a/tools/fonts/fontchain_lint.py
+++ b/tools/fonts/fontchain_lint.py
@@ -330,7 +330,7 @@ def check_emoji_defaults(default_emoji):
0x2764, # HEAVY BLACK HEART
}
assert missing_text_chars == set(), (
- 'Text style version of some emoji characters are missing.')
+ 'Text style version of some emoji characters are missing: ' + repr(missing_text_chars))
# Setting reverse to true returns a dictionary that maps the values to sets of
@@ -411,6 +411,20 @@ def parse_ucd(ucd_path):
_emoji_zwj_sequences = parse_unicode_datafile(
path.join(ucd_path, 'emoji-zwj-sequences.txt'))
+ # filter modern pentathlon, as it seems likely to be removed from final spec
+ def is_excluded(n):
+ return n == 0x1f93b
+
+ def contains_excluded(t):
+ if type(t) == int:
+ return is_excluded(t)
+ return any(is_excluded(cp) for cp in t)
+
+ # filter modern pentathlon, as it seems likely to be removed from final spec
+ _emoji_properties['Emoji'] = set(
+ t for t in _emoji_properties['Emoji'] if not contains_excluded(t))
+ _emoji_sequences = dict(
+ (t, v) for (t, v) in _emoji_sequences.items() if not contains_excluded(t))
def flag_sequence(territory_code):
return tuple(0x1F1E6 + ord(ch) - ord('A') for ch in territory_code)
diff --git a/tools/layoutlib/Android.mk b/tools/layoutlib/Android.mk
index 663e1e25e603..f87f6c53c8dc 100644
--- a/tools/layoutlib/Android.mk
+++ b/tools/layoutlib/Android.mk
@@ -16,8 +16,6 @@
LOCAL_PATH := $(my-dir)
include $(CLEAR_VARS)
-LOCAL_JAVA_LANGUAGE_VERSION := 1.8
-
#
# Define rules to build temp_layoutlib.jar, which contains a subset of
# the classes in framework.jar. The layoutlib_create tool is used to
diff --git a/tools/layoutlib/bridge/Android.mk b/tools/layoutlib/bridge/Android.mk
index 16e5913ab81d..3dd8002bcff5 100644
--- a/tools/layoutlib/bridge/Android.mk
+++ b/tools/layoutlib/bridge/Android.mk
@@ -18,7 +18,6 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(call all-java-files-under,src)
LOCAL_JAVA_RESOURCE_DIRS := resources
-LOCAL_JAVA_LANGUAGE_VERSION := 1.8
LOCAL_JAVA_LIBRARIES := \
layoutlib_api-prebuilt \
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index 80e230cd8b86..f87269b7c9f7 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -861,7 +861,9 @@ public final class BridgeContext extends Context {
resValue = mRenderResources.resolveResValue(resValue);
if (defaultPropMap != null) {
- defaultPropMap.put(attrName,
+ defaultPropMap.put(
+ frameworkAttr ? SdkConstants.PREFIX_ANDROID + attrName :
+ attrName,
new Property(preResolve, resValue.getValue()));
}
@@ -932,7 +934,8 @@ public final class BridgeContext extends Context {
@Nullable StyleResourceValue style, int[] attrs) throws Resources.NotFoundException {
List<Pair<String, Boolean>> attributes = searchAttrs(attrs);
- BridgeTypedArray ta = Resources_Delegate.newTypeArray(mSystemResources, attrs.length, false);
+ BridgeTypedArray ta =
+ Resources_Delegate.newTypeArray(mSystemResources, attrs.length, false);
PropertiesMap defaultPropMap = new PropertiesMap();
// for each attribute, get its name so that we can search it in the style
@@ -943,11 +946,11 @@ public final class BridgeContext extends Context {
// look for the value in the given style
ResourceValue resValue;
String attrName = attribute.getFirst();
+ boolean frameworkAttr = attribute.getSecond();
if (style != null) {
- resValue = mRenderResources.findItemInStyle(style, attrName,
- attribute.getSecond());
+ resValue = mRenderResources.findItemInStyle(style, attrName, frameworkAttr);
} else {
- resValue = mRenderResources.findItemInTheme(attrName, attribute.getSecond());
+ resValue = mRenderResources.findItemInTheme(attrName, frameworkAttr);
}
if (resValue != null) {
@@ -955,8 +958,10 @@ public final class BridgeContext extends Context {
String preResolve = resValue.getValue();
// resolve it to make sure there are no references left.
resValue = mRenderResources.resolveResValue(resValue);
- ta.bridgeSetValue(i, attrName, attribute.getSecond(), resValue);
- defaultPropMap.put(attrName, new Property(preResolve, resValue.getValue()));
+ ta.bridgeSetValue(i, attrName, frameworkAttr, resValue);
+ defaultPropMap.put(
+ frameworkAttr ? SdkConstants.ANDROID_PREFIX + attrName : attrName,
+ new Property(preResolve, resValue.getValue()));
}
}
}
diff --git a/tools/layoutlib/bridge/tests/Android.mk b/tools/layoutlib/bridge/tests/Android.mk
index 5c062d0c7042..8a81d0b684db 100644
--- a/tools/layoutlib/bridge/tests/Android.mk
+++ b/tools/layoutlib/bridge/tests/Android.mk
@@ -16,8 +16,6 @@ LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
-LOCAL_JAVA_LANGUAGE_VERSION := 1.8
-
# Only compile source java files in this lib.
LOCAL_SRC_FILES := $(call all-java-files-under, src)
LOCAL_JAVA_RESOURCE_DIRS := res
diff --git a/tools/layoutlib/create/Android.mk b/tools/layoutlib/create/Android.mk
index 47377ae42d01..c7f2c4137687 100644
--- a/tools/layoutlib/create/Android.mk
+++ b/tools/layoutlib/create/Android.mk
@@ -16,8 +16,6 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
-LOCAL_JAVA_LANGUAGE_VERSION := 1.8
-
LOCAL_SRC_FILES := $(call all-java-files-under,src)
LOCAL_JAR_MANIFEST := manifest.txt
diff --git a/tools/layoutlib/create/tests/Android.mk b/tools/layoutlib/create/tests/Android.mk
index c59528e81ef2..dafb9c6f9402 100644
--- a/tools/layoutlib/create/tests/Android.mk
+++ b/tools/layoutlib/create/tests/Android.mk
@@ -15,8 +15,6 @@
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
-LOCAL_JAVA_LANGUAGE_VERSION := 1.8
-
# Only compile source java files in this lib.
LOCAL_SRC_FILES := $(call all-java-files-under, com)