Merge "Add more data (fg services, associations) to procstats."
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 3f19b8f..2247e43 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -246,6 +246,7 @@
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/statsdprotolite_intermediates)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/framework/com.android.mediadrm.signer.jar)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/framework/com.android.location.provider.jar)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/framework/com.android.future.usb.accessory.jar)
# ******************************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST ABOVE THIS BANNER
# ******************************************************************
diff --git a/api/current.txt b/api/current.txt
index 20e62c0..8892b24 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -32811,6 +32811,7 @@
method public void readMap(java.util.Map, java.lang.ClassLoader);
method public <T extends android.os.Parcelable> T readParcelable(java.lang.ClassLoader);
method public android.os.Parcelable[] readParcelableArray(java.lang.ClassLoader);
+ method public <T extends android.os.Parcelable> java.util.List<T> readParcelableList(java.util.List<T>, java.lang.ClassLoader);
method public android.os.PersistableBundle readPersistableBundle();
method public android.os.PersistableBundle readPersistableBundle(java.lang.ClassLoader);
method public java.io.Serializable readSerializable();
@@ -32857,6 +32858,7 @@
method public void writeNoException();
method public void writeParcelable(android.os.Parcelable, int);
method public <T extends android.os.Parcelable> void writeParcelableArray(T[], int);
+ method public <T extends android.os.Parcelable> void writeParcelableList(java.util.List<T>, int);
method public void writePersistableBundle(android.os.PersistableBundle);
method public void writeSerializable(java.io.Serializable);
method public void writeSize(android.util.Size);
@@ -33208,6 +33210,7 @@
method public android.os.StrictMode.VmPolicy.Builder detectAll();
method public android.os.StrictMode.VmPolicy.Builder detectCleartextNetwork();
method public android.os.StrictMode.VmPolicy.Builder detectContentUriWithoutPermission();
+ method public android.os.StrictMode.VmPolicy.Builder detectCredentialProtectedWhileLocked();
method public android.os.StrictMode.VmPolicy.Builder detectFileUriExposure();
method public android.os.StrictMode.VmPolicy.Builder detectImplicitDirectBoot();
method public android.os.StrictMode.VmPolicy.Builder detectLeakedClosableObjects();
@@ -33611,6 +33614,9 @@
public final class ContentUriWithoutPermissionViolation extends android.os.strictmode.Violation {
}
+ public final class CredentialProtectedWhileLockedViolation extends android.os.strictmode.Violation {
+ }
+
public final class CustomViolation extends android.os.strictmode.Violation {
}
@@ -41805,6 +41811,7 @@
field public static final java.lang.String KEY_SMS_REQUIRES_DESTINATION_NUMBER_CONVERSION_BOOL = "sms_requires_destination_number_conversion_bool";
field public static final java.lang.String KEY_SUPPORT_3GPP_CALL_FORWARDING_WHILE_ROAMING_BOOL = "support_3gpp_call_forwarding_while_roaming_bool";
field public static final java.lang.String KEY_SUPPORT_CONFERENCE_CALL_BOOL = "support_conference_call_bool";
+ field public static final java.lang.String KEY_SUPPORT_EMERGENCY_SMS_OVER_IMS_BOOL = "support_emergency_sms_over_ims_bool";
field public static final java.lang.String KEY_SUPPORT_PAUSE_IMS_VIDEO_CALLS_BOOL = "support_pause_ims_video_calls_bool";
field public static final java.lang.String KEY_SUPPORT_SWAP_AFTER_MERGE_BOOL = "support_swap_after_merge_bool";
field public static final java.lang.String KEY_TREAT_DOWNGRADED_VIDEO_CALLS_AS_VIDEO_CALLS_BOOL = "treat_downgraded_video_calls_as_video_calls_bool";
diff --git a/api/test-current.txt b/api/test-current.txt
index b08ae0e..e052578 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -130,6 +130,12 @@
method public android.content.ComponentName getEffectsSuppressor();
}
+ public final class PictureInPictureParams implements android.os.Parcelable {
+ method public java.util.List<android.app.RemoteAction> getActions();
+ method public float getAspectRatio();
+ method public android.graphics.Rect getSourceRectHint();
+ }
+
public class TimePickerDialog extends android.app.AlertDialog implements android.content.DialogInterface.OnClickListener android.widget.TimePicker.OnTimeChangedListener {
method public android.widget.TimePicker getTimePicker();
}
@@ -251,6 +257,8 @@
public class ApplicationInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
method public boolean isPrivilegedApp();
method public boolean isSystemApp();
+ field public static final int PRIVATE_FLAG_PRIVILEGED = 8; // 0x8
+ field public int privateFlags;
}
public class LauncherApps {
@@ -271,6 +279,8 @@
field public static final java.lang.String FEATURE_FILE_BASED_ENCRYPTION = "android.software.file_based_encryption";
field public static final int MATCH_FACTORY_ONLY = 2097152; // 0x200000
field public static final int MATCH_KNOWN_PACKAGES = 4202496; // 0x402000
+ field public static final java.lang.String SYSTEM_SHARED_LIBRARY_SERVICES = "android.ext.services";
+ field public static final java.lang.String SYSTEM_SHARED_LIBRARY_SHARED = "android.ext.shared";
}
public class PermissionInfo extends android.content.pm.PackageItemInfo implements android.os.Parcelable {
@@ -626,6 +636,10 @@
package android.os {
+ public class Build {
+ method public static boolean is64BitAbi(java.lang.String);
+ }
+
public static class Build.VERSION {
field public static final int FIRST_SDK_INT;
field public static final int RESOURCES_SDK_INT;
@@ -638,6 +652,7 @@
public class Environment {
method public static java.io.File buildPath(java.io.File, java.lang.String...);
+ method public static java.io.File getStorageDirectory();
}
public class IncidentManager {
@@ -660,8 +675,9 @@
field public static final android.os.Parcelable.Creator<android.os.IncidentReportArgs> CREATOR;
}
- public final class PowerManager {
- method public void nap(long);
+ public final class MessageQueue {
+ method public int postSyncBarrier();
+ method public void removeSyncBarrier(int);
}
public class Process {
@@ -682,9 +698,14 @@
}
public final class StrictMode {
+ method public static void conditionallyCheckInstanceCounts();
method public static void setViolationLogger(android.os.StrictMode.ViolationLogger);
}
+ public static final class StrictMode.ThreadPolicy.Builder {
+ method public android.os.StrictMode.ThreadPolicy.Builder detectExplicitGc();
+ }
+
public static final class StrictMode.ViolationInfo implements android.os.Parcelable {
ctor public StrictMode.ViolationInfo(android.os.Parcel);
ctor public StrictMode.ViolationInfo(android.os.Parcel, boolean);
@@ -709,6 +730,7 @@
}
public class SystemProperties {
+ method public static java.lang.String get(java.lang.String);
method public static java.lang.String get(java.lang.String, java.lang.String);
}
@@ -728,7 +750,17 @@
method public static android.os.VibrationEffect get(int);
method public static android.os.VibrationEffect get(int, boolean);
method public static android.os.VibrationEffect get(android.net.Uri, android.content.Context);
+ method public abstract long getDuration();
method protected static int scale(int, float, int);
+ field public static final int EFFECT_CLICK = 0; // 0x0
+ field public static final int EFFECT_DOUBLE_CLICK = 1; // 0x1
+ field public static final int EFFECT_HEAVY_CLICK = 5; // 0x5
+ field public static final int EFFECT_POP = 4; // 0x4
+ field public static final int EFFECT_STRENGTH_LIGHT = 0; // 0x0
+ field public static final int EFFECT_STRENGTH_MEDIUM = 1; // 0x1
+ field public static final int EFFECT_STRENGTH_STRONG = 2; // 0x2
+ field public static final int EFFECT_THUD = 3; // 0x3
+ field public static final int EFFECT_TICK = 2; // 0x2
field public static final int[] RINGTONES;
}
@@ -769,6 +801,86 @@
field public static final android.os.Parcelable.Creator<android.os.VibrationEffect.Waveform> CREATOR;
}
+ public class WorkSource implements android.os.Parcelable {
+ ctor public WorkSource(int);
+ method public boolean add(int);
+ method public boolean add(int, java.lang.String);
+ method public deprecated android.os.WorkSource addReturningNewbs(android.os.WorkSource);
+ method public int get(int);
+ method public java.lang.String getName(int);
+ method public deprecated android.os.WorkSource[] setReturningDiffs(android.os.WorkSource);
+ method public int size();
+ }
+
+}
+
+package android.os.health {
+
+ public class HealthKeys {
+ ctor public HealthKeys();
+ field public static final int BASE_PACKAGE = 40000; // 0x9c40
+ field public static final int BASE_PID = 20000; // 0x4e20
+ field public static final int BASE_PROCESS = 30000; // 0x7530
+ field public static final int BASE_SERVICE = 50000; // 0xc350
+ field public static final int BASE_UID = 10000; // 0x2710
+ field public static final int TYPE_COUNT = 5; // 0x5
+ field public static final int TYPE_MEASUREMENT = 1; // 0x1
+ field public static final int TYPE_MEASUREMENTS = 4; // 0x4
+ field public static final int TYPE_STATS = 2; // 0x2
+ field public static final int TYPE_TIMER = 0; // 0x0
+ field public static final int TYPE_TIMERS = 3; // 0x3
+ field public static final int UNKNOWN_KEY = 0; // 0x0
+ }
+
+ public static abstract class HealthKeys.Constant implements java.lang.annotation.Annotation {
+ }
+
+ public static class HealthKeys.Constants {
+ ctor public HealthKeys.Constants(java.lang.Class);
+ method public java.lang.String getDataType();
+ method public int getIndex(int, int);
+ method public int[] getKeys(int);
+ method public int getSize(int);
+ }
+
+ public class HealthStats {
+ ctor public HealthStats(android.os.Parcel);
+ }
+
+ public class HealthStatsParceler implements android.os.Parcelable {
+ ctor public HealthStatsParceler(android.os.health.HealthStatsWriter);
+ ctor public HealthStatsParceler(android.os.Parcel);
+ method public int describeContents();
+ method public android.os.health.HealthStats getHealthStats();
+ method public void writeToParcel(android.os.Parcel, int);
+ field public static final android.os.Parcelable.Creator<android.os.health.HealthStatsParceler> CREATOR;
+ }
+
+ public class HealthStatsWriter {
+ ctor public HealthStatsWriter(android.os.health.HealthKeys.Constants);
+ method public void addMeasurement(int, long);
+ method public void addMeasurements(int, java.lang.String, long);
+ method public void addStats(int, java.lang.String, android.os.health.HealthStatsWriter);
+ method public void addTimer(int, int, long);
+ method public void addTimers(int, java.lang.String, android.os.health.TimerStat);
+ method public void flattenToParcel(android.os.Parcel);
+ }
+
+}
+
+package android.os.storage {
+
+ public final class StorageVolume implements android.os.Parcelable {
+ method public java.lang.String getPath();
+ }
+
+}
+
+package android.os.strictmode {
+
+ public final class ExplicitGcViolation extends android.os.strictmode.Violation {
+ }
+
}
package android.print {
diff --git a/config/hiddenapi-light-greylist.txt b/config/hiddenapi-light-greylist.txt
index 0941d39..99c3723 100644
--- a/config/hiddenapi-light-greylist.txt
+++ b/config/hiddenapi-light-greylist.txt
@@ -857,9 +857,6 @@
Landroid/app/PictureInPictureArgs;-><init>()V
Landroid/app/PictureInPictureArgs;->setActions(Ljava/util/List;)V
Landroid/app/PictureInPictureArgs;->setAspectRatio(F)V
-Landroid/app/PictureInPictureParams;->getActions()Ljava/util/List;
-Landroid/app/PictureInPictureParams;->getAspectRatio()F
-Landroid/app/PictureInPictureParams;->getSourceRectHint()Landroid/graphics/Rect;
Landroid/app/Presentation;->createPresentationContext(Landroid/content/Context;Landroid/view/Display;I)Landroid/content/Context;
Landroid/app/ProgressDialog;->mMessageView:Landroid/widget/TextView;
Landroid/app/ProgressDialog;->mProgress:Landroid/widget/ProgressBar;
@@ -1447,8 +1444,6 @@
Landroid/content/pm/ApplicationInfo;->isPackageUnavailable(Landroid/content/pm/PackageManager;)Z
Landroid/content/pm/ApplicationInfo;->nativeLibraryRootDir:Ljava/lang/String;
Landroid/content/pm/ApplicationInfo;->primaryCpuAbi:Ljava/lang/String;
-Landroid/content/pm/ApplicationInfo;->privateFlags:I
-Landroid/content/pm/ApplicationInfo;->PRIVATE_FLAG_PRIVILEGED:I
Landroid/content/pm/ApplicationInfo;->resourceDirs:[Ljava/lang/String;
Landroid/content/pm/ApplicationInfo;->scanPublicSourceDir:Ljava/lang/String;
Landroid/content/pm/ApplicationInfo;->scanSourceDir:Ljava/lang/String;
@@ -3928,7 +3923,6 @@
Landroid/os/Environment;->getDataSystemDirectory()Ljava/io/File;
Landroid/os/Environment;->getLegacyExternalStorageObbDirectory()Ljava/io/File;
Landroid/os/Environment;->getOemDirectory()Ljava/io/File;
-Landroid/os/Environment;->getStorageDirectory()Ljava/io/File;
Landroid/os/Environment;->getVendorDirectory()Ljava/io/File;
Landroid/os/Environment;->initForCurrentUser()V
Landroid/os/Environment;->maybeTranslateEmulatedPathToInternal(Ljava/io/File;)Ljava/io/File;
@@ -3955,18 +3949,6 @@
Landroid/os/Handler;->mCallback:Landroid/os/Handler$Callback;
Landroid/os/Handler;->mLooper:Landroid/os/Looper;
Landroid/os/Handler;->mMessenger:Landroid/os/IMessenger;
-Landroid/os/health/HealthKeys$Constants;-><init>(Ljava/lang/Class;)V
-Landroid/os/health/HealthStats;-><init>(Landroid/os/Parcel;)V
-Landroid/os/health/HealthStatsParceler;-><init>(Landroid/os/health/HealthStatsWriter;)V
-Landroid/os/health/HealthStatsParceler;-><init>(Landroid/os/Parcel;)V
-Landroid/os/health/HealthStatsParceler;->getHealthStats()Landroid/os/health/HealthStats;
-Landroid/os/health/HealthStatsWriter;-><init>(Landroid/os/health/HealthKeys$Constants;)V
-Landroid/os/health/HealthStatsWriter;->addMeasurement(IJ)V
-Landroid/os/health/HealthStatsWriter;->addMeasurements(ILjava/lang/String;J)V
-Landroid/os/health/HealthStatsWriter;->addStats(ILjava/lang/String;Landroid/os/health/HealthStatsWriter;)V
-Landroid/os/health/HealthStatsWriter;->addTimer(IIJ)V
-Landroid/os/health/HealthStatsWriter;->addTimers(ILjava/lang/String;Landroid/os/health/TimerStat;)V
-Landroid/os/health/HealthStatsWriter;->flattenToParcel(Landroid/os/Parcel;)V
Landroid/os/health/SystemHealthManager;-><init>()V
Landroid/os/health/SystemHealthManager;->from(Landroid/content/Context;)Landroid/os/health/SystemHealthManager;
Landroid/os/HwParcel;-><init>(Z)V
@@ -4042,8 +4024,6 @@
Landroid/os/MessageQueue;->mQuitAllowed:Z
Landroid/os/MessageQueue;->nativePollOnce(JI)V
Landroid/os/MessageQueue;->next()Landroid/os/Message;
-Landroid/os/MessageQueue;->postSyncBarrier()I
-Landroid/os/MessageQueue;->removeSyncBarrier(I)V
Landroid/os/Parcel$ReadWriteHelper;-><init>()V
Landroid/os/Parcel;->getGlobalAllocCount()J
Landroid/os/Parcel;->getGlobalAllocSize()J
@@ -4055,13 +4035,11 @@
Landroid/os/Parcel;->readCreator(Landroid/os/Parcelable$Creator;Ljava/lang/ClassLoader;)Landroid/os/Parcelable;
Landroid/os/Parcel;->readExceptionCode()I
Landroid/os/Parcel;->readParcelableCreator(Ljava/lang/ClassLoader;)Landroid/os/Parcelable$Creator;
-Landroid/os/Parcel;->readParcelableList(Ljava/util/List;Ljava/lang/ClassLoader;)Ljava/util/List;
Landroid/os/Parcel;->readRawFileDescriptor()Ljava/io/FileDescriptor;
Landroid/os/Parcel;->writeArrayMap(Landroid/util/ArrayMap;)V
Landroid/os/Parcel;->writeArraySet(Landroid/util/ArraySet;)V
Landroid/os/Parcel;->writeCharSequence(Ljava/lang/CharSequence;)V
Landroid/os/Parcel;->writeParcelableCreator(Landroid/os/Parcelable;)V
-Landroid/os/Parcel;->writeParcelableList(Ljava/util/List;I)V
Landroid/os/ParcelableParcel;-><init>(Ljava/lang/ClassLoader;)V
Landroid/os/ParcelableParcel;->CREATOR:Landroid/os/Parcelable$ClassLoaderCreator;
Landroid/os/ParcelableParcel;->getClassLoader()Ljava/lang/ClassLoader;
@@ -4209,7 +4187,6 @@
Landroid/os/storage/StorageVolume;->getFatVolumeId()I
Landroid/os/storage/StorageVolume;->getMaxFileSize()J
Landroid/os/storage/StorageVolume;->getOwner()Landroid/os/UserHandle;
-Landroid/os/storage/StorageVolume;->getPath()Ljava/lang/String;
Landroid/os/storage/StorageVolume;->getPathFile()Ljava/io/File;
Landroid/os/storage/StorageVolume;->getUserLabel()Ljava/lang/String;
Landroid/os/storage/StorageVolume;->mDescription:Ljava/lang/String;
@@ -4255,7 +4232,6 @@
Landroid/os/StrictMode$ThreadPolicy;->mask:I
Landroid/os/StrictMode$VmPolicy$Builder;->mMask:I
Landroid/os/StrictMode$VmPolicy;->mask:I
-Landroid/os/StrictMode;->conditionallyCheckInstanceCounts()V
Landroid/os/StrictMode;->disableDeathOnFileUriExposure()V
Landroid/os/StrictMode;->enableDeathOnFileUriExposure()V
Landroid/os/StrictMode;->enterCriticalSpan(Ljava/lang/String;)Landroid/os/StrictMode$Span;
@@ -4371,19 +4347,11 @@
Landroid/os/VintfRuntimeInfo;->getOsName()Ljava/lang/String;
Landroid/os/VintfRuntimeInfo;->getOsRelease()Ljava/lang/String;
Landroid/os/VintfRuntimeInfo;->getOsVersion()Ljava/lang/String;
-Landroid/os/WorkSource;-><init>(I)V
Landroid/os/WorkSource;-><init>(Landroid/os/Parcel;)V
-Landroid/os/WorkSource;->add(I)Z
-Landroid/os/WorkSource;->add(ILjava/lang/String;)Z
-Landroid/os/WorkSource;->addReturningNewbs(Landroid/os/WorkSource;)Landroid/os/WorkSource;
-Landroid/os/WorkSource;->get(I)I
-Landroid/os/WorkSource;->getName(I)Ljava/lang/String;
Landroid/os/WorkSource;->mNames:[Ljava/lang/String;
Landroid/os/WorkSource;->mNum:I
Landroid/os/WorkSource;->mUids:[I
-Landroid/os/WorkSource;->setReturningDiffs(Landroid/os/WorkSource;)[Landroid/os/WorkSource;
Landroid/os/WorkSource;->sGoneWork:Landroid/os/WorkSource;
-Landroid/os/WorkSource;->size()I
Landroid/os/WorkSource;->sNewbWork:Landroid/os/WorkSource;
Landroid/os/WorkSource;->sTmpWorkSource:Landroid/os/WorkSource;
Landroid/os/WorkSource;->updateLocked(Landroid/os/WorkSource;ZZ)Z
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index e5cfe84..ed06f2a 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -213,4 +213,7 @@
* Returns {@code true} if {@code uid} is running an activity from {@code packageName}.
*/
public abstract boolean hasRunningActivity(int uid, @Nullable String packageName);
+
+ public abstract void updateOomAdj();
+ public abstract void sendForegroundProfileChanged(int userId);
}
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 82088dc..2eafb32 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -80,6 +80,8 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.Preconditions;
+import dalvik.system.BlockGuard;
+
import libcore.io.Memory;
import java.io.File;
@@ -2521,7 +2523,11 @@
private File makeFilename(File base, String name) {
if (name.indexOf(File.separatorChar) < 0) {
- return new File(base, name);
+ final File res = new File(base, name);
+ // We report as filesystem access here to give us the best shot at
+ // detecting apps that will pass the path down to native code.
+ BlockGuard.getVmPolicy().onPathAccess(res.getPath());
+ return res;
}
throw new IllegalArgumentException(
"File " + name + " contains a path separator");
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 49d3fff..76244ea 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -393,7 +393,6 @@
void setDumpHeapDebugLimit(in String processName, int uid, long maxMemSize,
in String reportPackage);
void dumpHeapFinished(in String path);
- void setVoiceKeepAwake(in IVoiceInteractionSession session, boolean keepAwake);
void updateLockTaskPackages(int userId, in String[] packages);
void noteAlarmStart(in IIntentSender sender, in WorkSource workSource, int sourceUid, in String tag);
void noteAlarmFinish(in IIntentSender sender, in WorkSource workSource, int sourceUid, in String tag);
diff --git a/core/java/android/app/IActivityTaskManager.aidl b/core/java/android/app/IActivityTaskManager.aidl
index 1eb187e..cba7003 100644
--- a/core/java/android/app/IActivityTaskManager.aidl
+++ b/core/java/android/app/IActivityTaskManager.aidl
@@ -421,4 +421,5 @@
void stopAppSwitches();
void resumeAppSwitches();
void setActivityController(in IActivityController watcher, boolean imAMonkey);
+ void setVoiceKeepAwake(in IVoiceInteractionSession session, boolean keepAwake);
}
diff --git a/core/java/android/app/PictureInPictureParams.java b/core/java/android/app/PictureInPictureParams.java
index 7313b0d..edaae75 100644
--- a/core/java/android/app/PictureInPictureParams.java
+++ b/core/java/android/app/PictureInPictureParams.java
@@ -17,6 +17,7 @@
package android.app;
import android.annotation.Nullable;
+import android.annotation.TestApi;
import android.graphics.Rect;
import android.os.Parcel;
import android.os.Parcelable;
@@ -181,6 +182,7 @@
* @return the aspect ratio. If none is set, return 0.
* @hide
*/
+ @TestApi
public float getAspectRatio() {
if (mAspectRatio != null) {
return mAspectRatio.floatValue();
@@ -205,6 +207,7 @@
* @return the set of user actions.
* @hide
*/
+ @TestApi
public List<RemoteAction> getActions() {
return mUserActions;
}
@@ -231,6 +234,7 @@
* @return the source rect hint
* @hide
*/
+ @TestApi
public Rect getSourceRectHint() {
return mSourceRectHint;
}
diff --git a/core/java/android/app/backup/BackupAgent.java b/core/java/android/app/backup/BackupAgent.java
index 9657922..ec2cf0c 100644
--- a/core/java/android/app/backup/BackupAgent.java
+++ b/core/java/android/app/backup/BackupAgent.java
@@ -43,7 +43,6 @@
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
-import java.util.Collection;
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;
@@ -833,7 +832,7 @@
}
if (excludes != null &&
- isFileSpecifiedInPathList(destination, excludes)) {
+ BackupUtils.isFileSpecifiedInPathList(destination, excludes)) {
if (Log.isLoggable(FullBackup.TAG_XML_PARSER, Log.VERBOSE)) {
Log.v(FullBackup.TAG_XML_PARSER,
"onRestoreFile: \"" + destinationCanonicalPath + "\": listed in"
@@ -847,7 +846,8 @@
// it's a small list), we'll go through and look for it.
boolean explicitlyIncluded = false;
for (Set<PathWithRequiredFlags> domainIncludes : includes.values()) {
- explicitlyIncluded |= isFileSpecifiedInPathList(destination, domainIncludes);
+ explicitlyIncluded |=
+ BackupUtils.isFileSpecifiedInPathList(destination, domainIncludes);
if (explicitlyIncluded) {
break;
}
@@ -866,33 +866,6 @@
}
/**
- * @return True if the provided file is either directly in the provided list, or the provided
- * file is within a directory in the list.
- */
- private boolean isFileSpecifiedInPathList(File file,
- Collection<PathWithRequiredFlags> canonicalPathList) throws IOException {
- for (PathWithRequiredFlags canonical : canonicalPathList) {
- String canonicalPath = canonical.getPath();
- File fileFromList = new File(canonicalPath);
- if (fileFromList.isDirectory()) {
- if (file.isDirectory()) {
- // If they are both directories check exact equals.
- return file.equals(fileFromList);
- } else {
- // O/w we have to check if the file is within the directory from the list.
- return file.getCanonicalPath().startsWith(canonicalPath);
- }
- } else {
- if (file.equals(fileFromList)) {
- // Need to check the explicit "equals" so we don't end up with substrings.
- return true;
- }
- }
- }
- return false;
- }
-
- /**
* Only specialized platform agents should overload this entry point to support
* restores to crazy non-app locations.
* @hide
diff --git a/core/java/android/app/backup/BackupUtils.java b/core/java/android/app/backup/BackupUtils.java
new file mode 100644
index 0000000..8cf8a84
--- /dev/null
+++ b/core/java/android/app/backup/BackupUtils.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.app.backup;
+
+import android.app.backup.FullBackup.BackupScheme.PathWithRequiredFlags;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+
+/** @hide */
+public class BackupUtils {
+
+ private BackupUtils() {}
+
+ /**
+ * Returns {@code true} if {@code file} is either directly in {@code canonicalPathList} or is a
+ * file contained in a directory in the list.
+ */
+ public static boolean isFileSpecifiedInPathList(
+ File file, Collection<PathWithRequiredFlags> canonicalPathList) throws IOException {
+ for (PathWithRequiredFlags canonical : canonicalPathList) {
+ String canonicalPath = canonical.getPath();
+ File fileFromList = new File(canonicalPath);
+ if (fileFromList.isDirectory()) {
+ if (file.isDirectory()) {
+ // If they are both directories check exact equals.
+ if (file.equals(fileFromList)) {
+ return true;
+ }
+ } else {
+ // O/w we have to check if the file is within the directory from the list.
+ if (file.toPath().startsWith(canonicalPath)) {
+ return true;
+ }
+ }
+ } else if (file.equals(fileFromList)) {
+ // Need to check the explicit "equals" so we don't end up with substrings.
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 3120421..13b67fd 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -477,6 +477,7 @@
*
* {@hide}
*/
+ @TestApi
public static final int PRIVATE_FLAG_PRIVILEGED = 1<<3;
/**
@@ -649,6 +650,7 @@
* Private/hidden flags. See {@code PRIVATE_FLAG_...} constants.
* @hide
*/
+ @TestApi
public @ApplicationInfoPrivateFlags int privateFlags;
/**
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 721063a..a622af8 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -2937,6 +2937,7 @@
*
* @hide
*/
+ @TestApi
public static final String SYSTEM_SHARED_LIBRARY_SERVICES = "android.ext.services";
/**
@@ -2948,6 +2949,7 @@
*
* @hide
*/
+ @TestApi
public static final String SYSTEM_SHARED_LIBRARY_SHARED = "android.ext.shared";
/**
diff --git a/core/java/android/hardware/face/FaceManager.java b/core/java/android/hardware/face/FaceManager.java
index 3ed6228..0a66e91 100644
--- a/core/java/android/hardware/face/FaceManager.java
+++ b/core/java/android/hardware/face/FaceManager.java
@@ -869,7 +869,7 @@
*
* @param face The face template that was removed.
*/
- public void onRemovalSucceeded(Face face) {
+ public void onRemovalSucceeded(Face face, int remaining) {
}
}
@@ -937,13 +937,13 @@
msg.arg2 /* vendorCode */);
break;
case MSG_REMOVED:
- sendRemovedResult((Face) msg.obj);
+ sendRemovedResult((Face) msg.obj, msg.arg1 /* remaining */);
break;
}
}
};
- private void sendRemovedResult(Face face) {
+ private void sendRemovedResult(Face face, int remaining) {
if (mRemovalCallback == null) {
return;
}
@@ -953,7 +953,7 @@
}
- mRemovalCallback.onRemovalSucceeded(face);
+ mRemovalCallback.onRemovalSucceeded(face, remaining);
}
private void sendErrorResult(long deviceId, int errMsgId, int vendorCode) {
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 80c534c..e71f4e9 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -165,6 +165,11 @@
public static final String[] SUPPORTED_64_BIT_ABIS =
getStringList("ro.product.cpu.abilist64", ",");
+ /** {@hide} */
+ @TestApi
+ public static boolean is64BitAbi(String abi) {
+ return VMRuntime.is64BitAbi(abi);
+ }
static {
/*
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index 213260f..e32ed9d 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -33,6 +33,8 @@
public class Environment {
private static final String TAG = "Environment";
+ // NOTE: keep credential-protected paths in sync with StrictMode.java
+
private static final String ENV_EXTERNAL_STORAGE = "EXTERNAL_STORAGE";
private static final String ENV_ANDROID_ROOT = "ANDROID_ROOT";
private static final String ENV_ANDROID_DATA = "ANDROID_DATA";
@@ -149,6 +151,7 @@
}
/** {@hide} */
+ @TestApi
public static File getStorageDirectory() {
return DIR_ANDROID_STORAGE;
}
diff --git a/core/java/android/os/MessageQueue.java b/core/java/android/os/MessageQueue.java
index b1c33c2..7c2ecc5 100644
--- a/core/java/android/os/MessageQueue.java
+++ b/core/java/android/os/MessageQueue.java
@@ -18,6 +18,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
+import android.annotation.TestApi;
import android.os.MessageQueueProto;
import android.util.Log;
import android.util.Printer;
@@ -458,6 +459,7 @@
*
* @hide
*/
+ @TestApi
public int postSyncBarrier() {
return postSyncBarrier(SystemClock.uptimeMillis());
}
@@ -501,6 +503,7 @@
*
* @hide
*/
+ @TestApi
public void removeSyncBarrier(int token) {
// Remove a sync barrier token from the queue.
// If the queue is no longer stalled by a barrier then wake it.
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index 3d4ce61..8878260 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -1465,7 +1465,6 @@
* {@link #readParcelableList(List, ClassLoader)} if required.
*
* @see #readParcelableList(List, ClassLoader)
- * @hide
*/
public final <T extends Parcelable> void writeParcelableList(@Nullable List<T> val, int flags) {
if (val == null) {
@@ -2570,7 +2569,6 @@
* list was {@code null}, {@code list} is cleared.
*
* @see #writeParcelableList(List, int)
- * @hide
*/
@NonNull
public final <T extends Parcelable> List<T> readParcelableList(@NonNull List<T> list,
diff --git a/core/java/android/os/PowerManager.java b/core/java/android/os/PowerManager.java
index 9c25848..463a6aa 100644
--- a/core/java/android/os/PowerManager.java
+++ b/core/java/android/os/PowerManager.java
@@ -961,7 +961,6 @@
*
* @hide Requires signature permission.
*/
- @TestApi
public void nap(long time) {
try {
mService.nap(time);
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index ea76c9a3..5ff6e55 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -31,8 +31,10 @@
import android.content.pm.PackageManager;
import android.net.TrafficStats;
import android.net.Uri;
+import android.os.storage.IStorageManager;
import android.os.strictmode.CleartextNetworkViolation;
import android.os.strictmode.ContentUriWithoutPermissionViolation;
+import android.os.strictmode.CredentialProtectedWhileLockedViolation;
import android.os.strictmode.CustomViolation;
import android.os.strictmode.DiskReadViolation;
import android.os.strictmode.DiskWriteViolation;
@@ -284,6 +286,8 @@
private static final int DETECT_VM_NON_SDK_API_USAGE = 1 << 9;
/** @hide */
private static final int DETECT_VM_IMPLICIT_DIRECT_BOOT = 1 << 10;
+ /** @hide */
+ private static final int DETECT_VM_CREDENTIAL_PROTECTED_WHILE_LOCKED = 1 << 11;
/** @hide */
private static final int DETECT_VM_ALL = 0x0000ffff;
@@ -577,6 +581,7 @@
*
* @hide
*/
+ @TestApi
public Builder detectExplicitGc() {
// TODO(b/3400644): Un-hide this for next API update
// TODO(b/3400644): Un-hide ExplicitGcViolation for next API update
@@ -859,6 +864,9 @@
detectContentUriWithoutPermission();
detectUntaggedSockets();
}
+ if (targetSdk >= Build.VERSION_CODES.Q) {
+ detectCredentialProtectedWhileLocked();
+ }
// TODO: Decide whether to detect non SDK API usage beyond a certain API level.
// TODO: enable detectImplicitDirectBoot() once system is less noisy
@@ -994,6 +1002,28 @@
}
/**
+ * Detect access to filesystem paths stored in credential protected
+ * storage areas while the user is locked.
+ * <p>
+ * When a user is locked, credential protected storage is
+ * unavailable, and files stored in these locations appear to not
+ * exist, which can result in subtle app bugs if they assume default
+ * behaviors or empty states. Instead, apps should store data needed
+ * while a user is locked under device protected storage areas.
+ *
+ * @see Context#createCredentialProtectedStorageContext()
+ * @see Context#createDeviceProtectedStorageContext()
+ */
+ public Builder detectCredentialProtectedWhileLocked() {
+ return enable(DETECT_VM_CREDENTIAL_PROTECTED_WHILE_LOCKED);
+ }
+
+ /** @hide */
+ public Builder permitCredentialProtectedWhileLocked() {
+ return disable(DETECT_VM_CREDENTIAL_PROTECTED_WHILE_LOCKED);
+ }
+
+ /**
* Crashes the whole process on violation. This penalty runs at the end of all enabled
* penalties so you'll still get your logging or other violations before the process
* dies.
@@ -1154,6 +1184,16 @@
androidPolicy.setThreadPolicyMask(threadPolicyMask);
}
+ private static void setBlockGuardVmPolicy(@VmPolicyMask int vmPolicyMask) {
+ // We only need to install BlockGuard for a small subset of VM policies
+ vmPolicyMask &= DETECT_VM_CREDENTIAL_PROTECTED_WHILE_LOCKED;
+ if (vmPolicyMask != 0) {
+ BlockGuard.setVmPolicy(VM_ANDROID_POLICY);
+ } else {
+ BlockGuard.setVmPolicy(BlockGuard.LAX_VM_POLICY);
+ }
+ }
+
// Sets up CloseGuard in Dalvik/libcore
private static void setCloseGuardEnabled(boolean enabled) {
if (!(CloseGuard.getReporter() instanceof AndroidCloseGuardReporter)) {
@@ -1741,6 +1781,34 @@
}
}
+ private static final BlockGuard.VmPolicy VM_ANDROID_POLICY = new BlockGuard.VmPolicy() {
+ @Override
+ public void onPathAccess(String path) {
+ if (path == null) return;
+
+ // NOTE: keep credential-protected paths in sync with Environment.java
+ if (path.startsWith("/data/user/")
+ || path.startsWith("/data/media/")
+ || path.startsWith("/data/system_ce/")
+ || path.startsWith("/data/misc_ce/")
+ || path.startsWith("/data/vendor_ce/")
+ || path.startsWith("/storage/emulated/")) {
+ final int second = path.indexOf('/', 1);
+ final int third = path.indexOf('/', second + 1);
+ final int fourth = path.indexOf('/', third + 1);
+ if (fourth == -1) return;
+
+ try {
+ final int userId = Integer.parseInt(path.substring(third + 1, fourth));
+ onCredentialProtectedPathAccess(path, userId);
+ } catch (NumberFormatException ignored) {
+ }
+ } else if (path.startsWith("/data/data/")) {
+ onCredentialProtectedPathAccess(path, UserHandle.USER_SYSTEM);
+ }
+ }
+ };
+
/**
* In the common case, as set by conditionallyEnableDebugLogging, we're just dropboxing any
* violations but not showing a dialog, not loggging, and not killing the process. In these
@@ -1814,6 +1882,7 @@
}
/** @hide */
+ @TestApi
public static void conditionallyCheckInstanceCounts() {
VmPolicy policy = getVmPolicy();
int policySize = policy.classInstanceLimit.size();
@@ -1907,6 +1976,8 @@
VMRuntime.setNonSdkApiUsageConsumer(null);
VMRuntime.setDedupeHiddenApiWarnings(true);
}
+
+ setBlockGuardVmPolicy(sVmPolicy.mask);
}
}
@@ -1970,6 +2041,11 @@
}
/** @hide */
+ public static boolean vmCredentialProtectedWhileLockedEnabled() {
+ return (sVmPolicy.mask & DETECT_VM_CREDENTIAL_PROTECTED_WHILE_LOCKED) != 0;
+ }
+
+ /** @hide */
public static void onSqliteObjectLeaked(String message, Throwable originStack) {
onVmPolicyViolation(new SqliteObjectLeakedViolation(message, originStack));
}
@@ -2005,10 +2081,6 @@
}
/** @hide */
- public static final String CLEARTEXT_DETECTED_MSG =
- "Detected cleartext network traffic from UID ";
-
- /** @hide */
public static void onCleartextNetworkDetected(byte[] firstPacket) {
byte[] rawAddr = null;
if (firstPacket != null) {
@@ -2024,7 +2096,7 @@
}
final int uid = android.os.Process.myUid();
- String msg = CLEARTEXT_DETECTED_MSG + uid;
+ String msg = "Detected cleartext network traffic from UID " + uid;
if (rawAddr != null) {
try {
msg += " to " + InetAddress.getByAddress(rawAddr);
@@ -2046,6 +2118,42 @@
onVmPolicyViolation(new ImplicitDirectBootViolation());
}
+ /** Assume locked until we hear otherwise */
+ private static volatile boolean sUserKeyUnlocked = false;
+
+ private static boolean isUserKeyUnlocked(int userId) {
+ final IStorageManager storage = IStorageManager.Stub
+ .asInterface(ServiceManager.getService("mount"));
+ if (storage != null) {
+ try {
+ return storage.isUserKeyUnlocked(userId);
+ } catch (RemoteException ignored) {
+ }
+ }
+ return false;
+ }
+
+ /** @hide */
+ private static void onCredentialProtectedPathAccess(String path, int userId) {
+ // We can cache the unlocked state for the userId we're running as,
+ // since any relocking of that user will always result in our
+ // process being killed to release any CE FDs we're holding onto.
+ if (userId == UserHandle.myUserId()) {
+ if (sUserKeyUnlocked) {
+ return;
+ } else if (isUserKeyUnlocked(userId)) {
+ sUserKeyUnlocked = true;
+ return;
+ }
+ } else if (isUserKeyUnlocked(userId)) {
+ return;
+ }
+
+ onVmPolicyViolation(new CredentialProtectedWhileLockedViolation(
+ "Accessed credential protected path " + path + " while user " + userId
+ + " was locked"));
+ }
+
// Map from VM violation fingerprint to uptime millis.
private static final HashMap<Integer, Long> sLastVmViolationTime = new HashMap<>();
diff --git a/core/java/android/os/SystemProperties.java b/core/java/android/os/SystemProperties.java
index 7d3ba6a..fb34a52 100644
--- a/core/java/android/os/SystemProperties.java
+++ b/core/java/android/os/SystemProperties.java
@@ -96,6 +96,7 @@
*/
@NonNull
@SystemApi
+ @TestApi
public static String get(@NonNull String key) {
if (TRACK_KEY_ACCESS) onKeyAccess(key);
return native_get(key);
diff --git a/core/java/android/os/VibrationEffect.java b/core/java/android/os/VibrationEffect.java
index 91c69fb..01d85c6 100644
--- a/core/java/android/os/VibrationEffect.java
+++ b/core/java/android/os/VibrationEffect.java
@@ -54,6 +54,7 @@
* @see #get(int)
* @hide
*/
+ @TestApi
public static final int EFFECT_CLICK = Effect.CLICK;
/**
@@ -62,6 +63,7 @@
* @see #get(int)
* @hide
*/
+ @TestApi
public static final int EFFECT_DOUBLE_CLICK = Effect.DOUBLE_CLICK;
/**
@@ -69,6 +71,7 @@
* @see #get(int)
* @hide
*/
+ @TestApi
public static final int EFFECT_TICK = Effect.TICK;
/**
@@ -76,6 +79,7 @@
* @see #get(int)
* @hide
*/
+ @TestApi
public static final int EFFECT_THUD = Effect.THUD;
/**
@@ -83,6 +87,7 @@
* @see #get(int)
* @hide
*/
+ @TestApi
public static final int EFFECT_POP = Effect.POP;
/**
@@ -90,8 +95,20 @@
* @see #get(int)
* @hide
*/
+ @TestApi
public static final int EFFECT_HEAVY_CLICK = Effect.HEAVY_CLICK;
+ /** {@hide} */
+ @TestApi
+ public static final int EFFECT_STRENGTH_LIGHT = EffectStrength.LIGHT;
+
+ /** {@hide} */
+ @TestApi
+ public static final int EFFECT_STRENGTH_MEDIUM = EffectStrength.MEDIUM;
+
+ /** {@hide} */
+ @TestApi
+ public static final int EFFECT_STRENGTH_STRONG = EffectStrength.STRONG;
/**
* Ringtone patterns. They may correspond with the device's ringtone audio, or may just be a
@@ -307,6 +324,7 @@
*
* @hide
*/
+ @TestApi
public abstract long getDuration();
/**
diff --git a/core/java/android/os/WorkSource.java b/core/java/android/os/WorkSource.java
index 3270719..2299ab2 100644
--- a/core/java/android/os/WorkSource.java
+++ b/core/java/android/os/WorkSource.java
@@ -2,6 +2,7 @@
import android.annotation.Nullable;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.content.Context;
import android.os.WorkSourceProto;
import android.provider.Settings;
@@ -83,6 +84,7 @@
}
/** @hide */
+ @TestApi
public WorkSource(int uid) {
mNum = 1;
mUids = new int[] { uid, 0 };
@@ -127,16 +129,19 @@
}
/** @hide */
+ @TestApi
public int size() {
return mNum;
}
/** @hide */
+ @TestApi
public int get(int index) {
return mUids[index];
}
/** @hide */
+ @TestApi
public String getName(int index) {
return mNames != null ? mNames[index] : null;
}
@@ -328,6 +333,7 @@
* to be aware of internal differences.
*/
@Deprecated
+ @TestApi
public WorkSource[] setReturningDiffs(WorkSource other) {
synchronized (sTmpWorkSource) {
sNewbWork = null;
@@ -379,6 +385,7 @@
* @deprecated meant for unit testing use only. Will be removed in a future API revision.
*/
@Deprecated
+ @TestApi
public WorkSource addReturningNewbs(WorkSource other) {
synchronized (sTmpWorkSource) {
sNewbWork = null;
@@ -388,6 +395,7 @@
}
/** @hide */
+ @TestApi
public boolean add(int uid) {
if (mNum <= 0) {
mNames = null;
@@ -407,6 +415,7 @@
}
/** @hide */
+ @TestApi
public boolean add(int uid, String name) {
if (mNum <= 0) {
insert(0, uid, name);
diff --git a/core/java/android/os/health/HealthKeys.java b/core/java/android/os/health/HealthKeys.java
index 842def3..5d60411 100644
--- a/core/java/android/os/health/HealthKeys.java
+++ b/core/java/android/os/health/HealthKeys.java
@@ -16,10 +16,8 @@
package android.os.health;
-import android.os.Parcel;
-import android.os.Parcelable;
+import android.annotation.TestApi;
-import java.lang.annotation.Annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -32,6 +30,7 @@
*
* @hide
*/
+@TestApi
public class HealthKeys {
/**
@@ -81,6 +80,7 @@
*
* @hide
*/
+ @TestApi
public static class Constants {
private final String mDataType;
private final int[][] mKeys = new int[TYPE_COUNT][];
diff --git a/core/java/android/os/health/HealthStats.java b/core/java/android/os/health/HealthStats.java
index 90d89c5..74ce515 100644
--- a/core/java/android/os/health/HealthStats.java
+++ b/core/java/android/os/health/HealthStats.java
@@ -16,6 +16,7 @@
package android.os.health;
+import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.ArrayMap;
@@ -126,6 +127,7 @@
*
* @hide
*/
+ @TestApi
public HealthStats(Parcel in) {
int count;
diff --git a/core/java/android/os/health/HealthStatsParceler.java b/core/java/android/os/health/HealthStatsParceler.java
index 28b3694..d358a2e 100644
--- a/core/java/android/os/health/HealthStatsParceler.java
+++ b/core/java/android/os/health/HealthStatsParceler.java
@@ -16,6 +16,7 @@
package android.os.health;
+import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.ArrayMap;
@@ -35,6 +36,7 @@
* reuse them.
* @hide
*/
+@TestApi
public class HealthStatsParceler implements Parcelable {
private HealthStatsWriter mWriter;
private HealthStats mHealthStats;
diff --git a/core/java/android/os/health/HealthStatsWriter.java b/core/java/android/os/health/HealthStatsWriter.java
index 351836b..d4d10b0 100644
--- a/core/java/android/os/health/HealthStatsWriter.java
+++ b/core/java/android/os/health/HealthStatsWriter.java
@@ -16,6 +16,7 @@
package android.os.health;
+import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.ArrayMap;
@@ -31,6 +32,7 @@
*
* @hide
*/
+@TestApi
public class HealthStatsWriter {
private final HealthKeys.Constants mConstants;
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index aeced951..8b8ae1c 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -71,6 +71,8 @@
import com.android.internal.os.SomeArgs;
import com.android.internal.util.Preconditions;
+import dalvik.system.BlockGuard;
+
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileNotFoundException;
@@ -1131,6 +1133,7 @@
/** {@hide} */
public void mkdirs(File file) {
+ BlockGuard.getVmPolicy().onPathAccess(file.getAbsolutePath());
try {
mStorageManager.mkdirs(mContext.getOpPackageName(), file.getAbsolutePath());
} catch (RemoteException e) {
diff --git a/core/java/android/os/storage/StorageVolume.java b/core/java/android/os/storage/StorageVolume.java
index fd5a22a..9880142 100644
--- a/core/java/android/os/storage/StorageVolume.java
+++ b/core/java/android/os/storage/StorageVolume.java
@@ -17,6 +17,7 @@
package android.os.storage;
import android.annotation.Nullable;
+import android.annotation.TestApi;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
@@ -162,6 +163,7 @@
* @return the mount path
* @hide
*/
+ @TestApi
public String getPath() {
return mPath.toString();
}
diff --git a/core/java/android/os/strictmode/CredentialProtectedWhileLockedViolation.java b/core/java/android/os/strictmode/CredentialProtectedWhileLockedViolation.java
new file mode 100644
index 0000000..12503f6
--- /dev/null
+++ b/core/java/android/os/strictmode/CredentialProtectedWhileLockedViolation.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os.strictmode;
+
+import android.content.Context;
+
+/**
+ * Subclass of {@code Violation} that is used when a process accesses filesystem
+ * paths stored in credential protected storage areas while the user is locked.
+ * <p>
+ * When a user is locked, credential protected storage is unavailable, and files
+ * stored in these locations appear to not exist, which can result in subtle app
+ * bugs if they assume default behaviors or empty states. Instead, apps should
+ * store data needed while a user is locked under device protected storage
+ * areas.
+ *
+ * @see Context#createCredentialProtectedStorageContext()
+ * @see Context#createDeviceProtectedStorageContext()
+ */
+public final class CredentialProtectedWhileLockedViolation extends Violation {
+ /** @hide */
+ public CredentialProtectedWhileLockedViolation(String message) {
+ super(message);
+ }
+}
diff --git a/core/java/android/os/strictmode/ExplicitGcViolation.java b/core/java/android/os/strictmode/ExplicitGcViolation.java
index c7480f9..583ed1a 100644
--- a/core/java/android/os/strictmode/ExplicitGcViolation.java
+++ b/core/java/android/os/strictmode/ExplicitGcViolation.java
@@ -15,11 +15,14 @@
*/
package android.os.strictmode;
+import android.annotation.TestApi;
+
/**
* See #{@link android.os.StrictMode.ThreadPolicy.Builder#detectExplicitGc()}.
*
* @hide
*/
+@TestApi
public final class ExplicitGcViolation extends Violation {
/** @hide */
public ExplicitGcViolation() {
diff --git a/core/java/android/os/strictmode/ImplicitDirectBootViolation.java b/core/java/android/os/strictmode/ImplicitDirectBootViolation.java
index d7877ca..e52e212 100644
--- a/core/java/android/os/strictmode/ImplicitDirectBootViolation.java
+++ b/core/java/android/os/strictmode/ImplicitDirectBootViolation.java
@@ -26,12 +26,8 @@
*/
public final class ImplicitDirectBootViolation extends Violation {
/** @hide */
- public static final String MESSAGE =
- "Implicitly relying on automatic Direct Boot filtering; request explicit"
- + " filtering with PackageManager.MATCH_DIRECT_BOOT flags";
-
- /** @hide */
public ImplicitDirectBootViolation() {
- super(MESSAGE);
+ super("Implicitly relying on automatic Direct Boot filtering; request explicit"
+ + " filtering with PackageManager.MATCH_DIRECT_BOOT flags");
}
}
diff --git a/core/java/android/os/strictmode/UntaggedSocketViolation.java b/core/java/android/os/strictmode/UntaggedSocketViolation.java
index 836a8b9..3b1ef25 100644
--- a/core/java/android/os/strictmode/UntaggedSocketViolation.java
+++ b/core/java/android/os/strictmode/UntaggedSocketViolation.java
@@ -17,12 +17,8 @@
public final class UntaggedSocketViolation extends Violation {
/** @hide */
- public static final String MESSAGE =
- "Untagged socket detected; use"
- + " TrafficStats.setThreadSocketTag() to track all network usage";
-
- /** @hide */
public UntaggedSocketViolation() {
- super(MESSAGE);
+ super("Untagged socket detected; use TrafficStats.setThreadSocketTag() to "
+ + "track all network usage");
}
}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index a7fcaff..13d4d08 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -6029,6 +6029,15 @@
NON_NEGATIVE_INTEGER_VALIDATOR;
/**
+ * Whether the in call notification is enabled to play sound during calls. The value is
+ * boolean (1 or 0).
+ * @hide
+ */
+ public static final String IN_CALL_NOTIFICATION_ENABLED = "in_call_notification_enabled";
+
+ private static final Validator IN_CALL_NOTIFICATION_ENABLED_VALIDATOR = BOOLEAN_VALIDATOR;
+
+ /**
* Uri of the slice that's presented on the keyguard.
* Defaults to a slice with the date and next alarm.
*
@@ -8048,6 +8057,7 @@
VOLUME_HUSH_GESTURE,
MANUAL_RINGER_TOGGLE_COUNT,
HUSH_GESTURE_USED,
+ IN_CALL_NOTIFICATION_ENABLED,
};
/**
@@ -8193,6 +8203,7 @@
ENABLED_NOTIFICATION_POLICY_ACCESS_PACKAGES_VALIDATOR); //legacy restore setting
VALIDATORS.put(HUSH_GESTURE_USED, HUSH_GESTURE_USED_VALIDATOR);
VALIDATORS.put(MANUAL_RINGER_TOGGLE_COUNT, MANUAL_RINGER_TOGGLE_COUNT_VALIDATOR);
+ VALIDATORS.put(IN_CALL_NOTIFICATION_ENABLED, IN_CALL_NOTIFICATION_ENABLED_VALIDATOR);
}
/**
diff --git a/core/java/android/view/RoundScrollbarRenderer.java b/core/java/android/view/RoundScrollbarRenderer.java
index 1348510..df9e23e 100644
--- a/core/java/android/view/RoundScrollbarRenderer.java
+++ b/core/java/android/view/RoundScrollbarRenderer.java
@@ -31,13 +31,14 @@
private static final int MAX_SCROLLBAR_ANGLE_SWIPE = 16;
private static final int MIN_SCROLLBAR_ANGLE_SWIPE = 6;
private static final float WIDTH_PERCENTAGE = 0.02f;
- private static final int DEFAULT_THUMB_COLOR = 0x4CFFFFFF;
- private static final int DEFAULT_TRACK_COLOR = 0x26FFFFFF;
+ private static final int DEFAULT_THUMB_COLOR = 0xFFE8EAED;
+ private static final int DEFAULT_TRACK_COLOR = 0x4CFFFFFF;
private final Paint mThumbPaint = new Paint();
private final Paint mTrackPaint = new Paint();
private final RectF mRect = new RectF();
private final View mParent;
+ private final int mMaskThickness;
public RoundScrollbarRenderer(View parent) {
// Paints for the round scrollbar.
@@ -52,6 +53,12 @@
mTrackPaint.setStyle(Paint.Style.STROKE);
mParent = parent;
+
+ // Fetch the resource indicating the thickness of CircularDisplayMask, rounding in the same
+ // way WindowManagerService.showCircularMask does. The scroll bar is inset by this amount so
+ // that it doesn't get clipped.
+ mMaskThickness = parent.getContext().getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.circular_display_mask_thickness);
}
public void drawRoundScrollbars(Canvas canvas, float alpha, Rect bounds) {
@@ -82,13 +89,13 @@
startAngle = clamp(startAngle, -SCROLLBAR_ANGLE_RANGE / 2,
SCROLLBAR_ANGLE_RANGE / 2 - sweepAngle);
- // Draw the track and the scroll bar.
+ // Draw the track and the thumb.
+ float inset = thumbWidth / 2 + mMaskThickness;
mRect.set(
- bounds.left - thumbWidth / 2,
- bounds.top,
- bounds.right - thumbWidth / 2,
- bounds.bottom);
-
+ bounds.left + inset,
+ bounds.top + inset,
+ bounds.right - inset,
+ bounds.bottom - inset);
canvas.drawArc(mRect, -SCROLLBAR_ANGLE_RANGE / 2, SCROLLBAR_ANGLE_RANGE, false,
mTrackPaint);
canvas.drawArc(mRect, startAngle, sweepAngle, false, mThumbPaint);
diff --git a/core/java/android/view/SurfaceSession.java b/core/java/android/view/SurfaceSession.java
index b5912bc..ee08bf7 100644
--- a/core/java/android/view/SurfaceSession.java
+++ b/core/java/android/view/SurfaceSession.java
@@ -37,7 +37,12 @@
}
public SurfaceSession(Surface root) {
- mNativeClient = nativeCreateScoped(root.mNativeObject);
+ synchronized (root.mLock) {
+ if (root.mNativeObject == 0) {
+ throw new IllegalStateException("Surface is not initialized or has been released");
+ }
+ mNativeClient = nativeCreateScoped(root.mNativeObject);
+ }
}
/* no user serviceable parts here ... */
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 964ee5e..546ea87 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -6119,14 +6119,18 @@
}
x += getScrollX();
y += getScrollY();
- if (isVerticalScrollBarEnabled() && !isVerticalScrollBarHidden()) {
+ final boolean canScrollVertically =
+ computeVerticalScrollRange() > computeVerticalScrollExtent();
+ if (isVerticalScrollBarEnabled() && !isVerticalScrollBarHidden() && canScrollVertically) {
final Rect touchBounds = mScrollCache.mScrollBarTouchBounds;
getVerticalScrollBarBounds(null, touchBounds);
if (touchBounds.contains((int) x, (int) y)) {
return true;
}
}
- if (isHorizontalScrollBarEnabled()) {
+ final boolean canScrollHorizontally =
+ computeHorizontalScrollRange() > computeHorizontalScrollExtent();
+ if (isHorizontalScrollBarEnabled() && canScrollHorizontally) {
final Rect touchBounds = mScrollCache.mScrollBarTouchBounds;
getHorizontalScrollBarBounds(null, touchBounds);
if (touchBounds.contains((int) x, (int) y)) {
@@ -6141,18 +6145,18 @@
}
private boolean isOnVerticalScrollbarThumb(float x, float y) {
- if (mScrollCache == null) {
+ if (mScrollCache == null || !isVerticalScrollBarEnabled() || isVerticalScrollBarHidden()) {
return false;
}
- if (isVerticalScrollBarEnabled() && !isVerticalScrollBarHidden()) {
+ final int range = computeVerticalScrollRange();
+ final int extent = computeVerticalScrollExtent();
+ if (range > extent) {
x += getScrollX();
y += getScrollY();
final Rect bounds = mScrollCache.mScrollBarBounds;
final Rect touchBounds = mScrollCache.mScrollBarTouchBounds;
getVerticalScrollBarBounds(bounds, touchBounds);
- final int range = computeVerticalScrollRange();
final int offset = computeVerticalScrollOffset();
- final int extent = computeVerticalScrollExtent();
final int thumbLength = ScrollBarUtils.getThumbLength(bounds.height(), bounds.width(),
extent, range);
final int thumbOffset = ScrollBarUtils.getThumbOffset(bounds.height(), thumbLength,
@@ -6168,18 +6172,19 @@
}
private boolean isOnHorizontalScrollbarThumb(float x, float y) {
- if (mScrollCache == null) {
+ if (mScrollCache == null || !isHorizontalScrollBarEnabled()) {
return false;
}
- if (isHorizontalScrollBarEnabled()) {
+ final int range = computeHorizontalScrollRange();
+ final int extent = computeHorizontalScrollExtent();
+ if (range > extent) {
x += getScrollX();
y += getScrollY();
final Rect bounds = mScrollCache.mScrollBarBounds;
final Rect touchBounds = mScrollCache.mScrollBarTouchBounds;
getHorizontalScrollBarBounds(bounds, touchBounds);
- final int range = computeHorizontalScrollRange();
final int offset = computeHorizontalScrollOffset();
- final int extent = computeHorizontalScrollExtent();
+
final int thumbLength = ScrollBarUtils.getThumbLength(bounds.width(), bounds.height(),
extent, range);
final int thumbOffset = ScrollBarUtils.getThumbOffset(bounds.width(), thumbLength,
@@ -23993,6 +23998,10 @@
Log.w(VIEW_LOG_TAG, "startDragAndDrop called on a detached view.");
return false;
}
+ if (!mAttachInfo.mViewRootImpl.mSurface.isValid()) {
+ Log.w(VIEW_LOG_TAG, "startDragAndDrop called with an invalid surface.");
+ return false;
+ }
if (data != null) {
data.prepareToLeaveProcess((flags & View.DRAG_FLAG_GLOBAL) != 0);
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index cba11a8..a085395 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -987,7 +987,9 @@
* {@link PluginState#OFF}.
*
* @param state a PluginState value
- * @deprecated Plugins will not be supported in future, and should not be used.
+ * @deprecated Plugins are not supported in API level
+ * {@link android.os.Build.VERSION_CODES#KITKAT} or later;
+ * enabling plugins is a no-op.
*/
@Deprecated
public abstract void setPluginState(PluginState state);
@@ -1182,7 +1184,9 @@
*
* @return the plugin state as a {@link PluginState} value
* @see #setPluginState
- * @deprecated Plugins will not be supported in future, and should not be used.
+ * @deprecated Plugins are not supported in API level
+ * {@link android.os.Build.VERSION_CODES#KITKAT} or later;
+ * enabling plugins is a no-op.
*/
@Deprecated
public abstract PluginState getPluginState();
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 9a60065..2e7ef8b 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -3451,7 +3451,7 @@
ColorStateList mTextColor = null;
ColorStateList mTextColorHint = null;
ColorStateList mTextColorLink = null;
- int mTextSize = 0;
+ int mTextSize = -1;
String mFontFamily = null;
Typeface mFontTypeface = null;
boolean mFontFamilyExplicit = false;
@@ -3662,7 +3662,7 @@
setHighlightColor(attributes.mTextColorHighlight);
}
- if (attributes.mTextSize != 0) {
+ if (attributes.mTextSize != -1) {
setRawTextSize(attributes.mTextSize, true /* shouldRequestLayout */);
}
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index d7db2e2..79d2570 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -107,6 +107,7 @@
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
+import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
@@ -1068,7 +1069,7 @@
// methods are protected not private to be VisibleForTesting
public static class TimeBase {
- protected final ArrayList<TimeBaseObs> mObservers = new ArrayList<>();
+ protected final ArrayList<WeakReference<TimeBaseObs>> mObservers = new ArrayList<>();
protected long mUptime;
protected long mRealtime;
@@ -1112,17 +1113,24 @@
}
public void add(TimeBaseObs observer) {
- mObservers.add(observer);
+ mObservers.add(new WeakReference<TimeBaseObs>(observer));
}
public void remove(TimeBaseObs observer) {
- if (!mObservers.remove(observer)) {
- Slog.wtf(TAG, "Removed unknown observer: " + observer);
- }
+ if (!mObservers.removeIf(ref -> ref.get() == observer)) {
+ Slog.wtf(TAG, "Removed unknown observer: " + observer);
+ }
}
public boolean hasObserver(TimeBaseObs observer) {
- return mObservers.contains(observer);
+ Iterator<WeakReference<TimeBaseObs>> i = mObservers.iterator();
+ while (i.hasNext()) {
+ TimeBaseObs obs = i.next().get();
+ if (obs == observer) {
+ return true;
+ }
+ }
+ return false;
}
public void init(long uptime, long realtime) {
@@ -1211,9 +1219,11 @@
mRealtimeStart = realtime;
long batteryUptime = mUnpluggedUptime = getUptime(uptime);
long batteryRealtime = mUnpluggedRealtime = getRealtime(realtime);
-
- for (int i = mObservers.size() - 1; i >= 0; i--) {
- mObservers.get(i).onTimeStarted(realtime, batteryUptime, batteryRealtime);
+ for (WeakReference<TimeBaseObs> ref : mObservers) {
+ TimeBaseObs obs = ref.get();
+ if (obs != null) {
+ obs.onTimeStarted(realtime, batteryUptime, batteryRealtime);
+ }
}
} else {
mPastUptime += uptime - mUptimeStart;
@@ -1221,11 +1231,14 @@
long batteryUptime = getUptime(uptime);
long batteryRealtime = getRealtime(realtime);
-
- for (int i = mObservers.size() - 1; i >= 0; i--) {
- mObservers.get(i).onTimeStopped(realtime, batteryUptime, batteryRealtime);
+ for (WeakReference<TimeBaseObs> ref : mObservers) {
+ TimeBaseObs obs = ref.get();
+ if (obs != null) {
+ obs.onTimeStopped(realtime, batteryUptime, batteryRealtime);
+ }
}
}
+ mObservers.removeIf(ref -> ref.get() == null);
return true;
}
return false;
@@ -4021,7 +4034,9 @@
try {
IBatteryPropertiesRegistrar registrar = IBatteryPropertiesRegistrar.Stub.asInterface(
ServiceManager.getService("batteryproperties"));
- registrar.scheduleUpdate();
+ if (registrar != null) {
+ registrar.scheduleUpdate();
+ }
} catch (RemoteException e) {
// Ignore.
}
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 381758f..aef48fa 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -2914,7 +2914,7 @@
<string name="config_keyguardComponent" translatable="false">com.android.systemui/com.android.systemui.keyguard.KeyguardService</string>
<!-- Limit for the number of face templates per user -->
- <integer name="config_face_MaxTemplatesPerUser">1</integer>
+ <integer name="config_faceMaxTemplatesPerUser">1</integer>
<!-- For performance and storage reasons, limit the number of fingerprints per user -->
<integer name="config_fingerprintMaxTemplatesPerUser">5</integer>
@@ -3374,6 +3374,9 @@
<!-- URI for in call notification sound -->
<string translatable="false" name="config_inCallNotificationSound">/system/media/audio/ui/InCallNotification.ogg</string>
+ <!-- Default number of notifications from the same app before they are automatically grouped by the OS -->
+ <integer translatable="false" name="config_autoGroupAtCount">4</integer>
+
<!-- The OEM specified sensor type for the lift trigger to launch the camera app. -->
<integer name="config_cameraLiftTriggerSensorType">-1</integer>
<!-- The OEM specified sensor string type for the gesture to launch camera app, this value
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 99d0dba..6054180 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2446,7 +2446,7 @@
<java-symbol type="string" name="face_name_template" />
<!-- Face config -->
- <java-symbol type="integer" name="config_face_MaxTemplatesPerUser" />
+ <java-symbol type="integer" name="config_faceMaxTemplatesPerUser" />
<!-- From various Material changes -->
<java-symbol type="attr" name="titleTextAppearance" />
@@ -3266,6 +3266,7 @@
<java-symbol type="bool" name="config_handleVolumeKeysInWindowManager" />
<java-symbol type="dimen" name="config_inCallNotificationVolume" />
<java-symbol type="string" name="config_inCallNotificationSound" />
+ <java-symbol type="integer" name="config_autoGroupAtCount" />
<java-symbol type="bool" name="config_dozeAlwaysOnDisplayAvailable" />
<java-symbol type="bool" name="config_dozeAlwaysOnEnabled" />
<java-symbol type="bool" name="config_displayBlanksAfterDoze" />
diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp
index d284269..0338a3a 100644
--- a/libs/hwui/Properties.cpp
+++ b/libs/hwui/Properties.cpp
@@ -17,6 +17,7 @@
#include "Properties.h"
#include "Debug.h"
#include "DeviceInfo.h"
+#include "SkTraceEventCommon.h"
#include <algorithm>
#include <cstdlib>
@@ -140,6 +141,9 @@
skpCaptureEnabled = debuggingEnabled && property_get_bool(PROPERTY_CAPTURE_SKP_ENABLED, false);
+ SkAndroidFrameworkTraceUtil::setEnableTracing(
+ property_get_bool(PROPERTY_SKIA_ATRACE_ENABLED, false));
+
runningInEmulator = property_get_bool(PROPERTY_QEMU_KERNEL, false);
return (prevDebugLayersUpdates != debugLayersUpdates) || (prevDebugOverdraw != debugOverdraw) ||
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index 657f9aa..d640c74 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -171,6 +171,11 @@
#define PROPERTY_CAPTURE_SKP_ENABLED "debug.hwui.capture_skp_enabled"
/**
+ * Allows to record Skia drawing commands with systrace.
+ */
+#define PROPERTY_SKIA_ATRACE_ENABLED "debug.hwui.skia_atrace_enabled"
+
+/**
* Defines how many frames in a sequence to capture.
*/
#define PROPERTY_CAPTURE_SKP_FRAMES "debug.hwui.capture_skp_frames"
diff --git a/libs/usb/Android.bp b/libs/usb/Android.bp
index b8f2904..027a748 100644
--- a/libs/usb/Android.bp
+++ b/libs/usb/Android.bp
@@ -1 +1,23 @@
+//
+// Copyright (C) 2018 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+java_sdk_library {
+ name: "com.android.future.usb.accessory",
+ srcs: ["src/**/*.java"],
+ api_packages: ["com.android.future.usb"],
+}
+
subdirs = ["tests/*"]
diff --git a/libs/usb/Android.mk b/libs/usb/Android.mk
deleted file mode 100644
index 129828f..0000000
--- a/libs/usb/Android.mk
+++ /dev/null
@@ -1,27 +0,0 @@
-#
-# Copyright (C) 2011 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-java-files-under,src)
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_MODULE:= com.android.future.usb.accessory
-
-include $(BUILD_JAVA_LIBRARY)
diff --git a/libs/usb/api/current.txt b/libs/usb/api/current.txt
new file mode 100644
index 0000000..8488db5
--- /dev/null
+++ b/libs/usb/api/current.txt
@@ -0,0 +1,25 @@
+package com.android.future.usb {
+
+ public class UsbAccessory {
+ method public java.lang.String getDescription();
+ method public java.lang.String getManufacturer();
+ method public java.lang.String getModel();
+ method public java.lang.String getSerial();
+ method public java.lang.String getUri();
+ method public java.lang.String getVersion();
+ }
+
+ public class UsbManager {
+ method public static com.android.future.usb.UsbAccessory getAccessory(android.content.Intent);
+ method public com.android.future.usb.UsbAccessory[] getAccessoryList();
+ method public static com.android.future.usb.UsbManager getInstance(android.content.Context);
+ method public boolean hasPermission(com.android.future.usb.UsbAccessory);
+ method public android.os.ParcelFileDescriptor openAccessory(com.android.future.usb.UsbAccessory);
+ method public void requestPermission(com.android.future.usb.UsbAccessory, android.app.PendingIntent);
+ field public static final java.lang.String ACTION_USB_ACCESSORY_ATTACHED = "android.hardware.usb.action.USB_ACCESSORY_ATTACHED";
+ field public static final java.lang.String ACTION_USB_ACCESSORY_DETACHED = "android.hardware.usb.action.USB_ACCESSORY_DETACHED";
+ field public static final java.lang.String EXTRA_PERMISSION_GRANTED = "permission";
+ }
+
+}
+
diff --git a/libs/usb/api/removed.txt b/libs/usb/api/removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libs/usb/api/removed.txt
diff --git a/libs/usb/api/system-current.txt b/libs/usb/api/system-current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libs/usb/api/system-current.txt
diff --git a/libs/usb/api/system-removed.txt b/libs/usb/api/system-removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libs/usb/api/system-removed.txt
diff --git a/libs/usb/api/test-current.txt b/libs/usb/api/test-current.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libs/usb/api/test-current.txt
diff --git a/libs/usb/api/test-removed.txt b/libs/usb/api/test-removed.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/libs/usb/api/test-removed.txt
diff --git a/libs/usb/tests/AccessoryChat/Android.mk b/libs/usb/tests/AccessoryChat/Android.mk
index ecb455a..cfe2da1 100644
--- a/libs/usb/tests/AccessoryChat/Android.mk
+++ b/libs/usb/tests/AccessoryChat/Android.mk
@@ -23,4 +23,6 @@
LOCAL_PACKAGE_NAME := AccessoryChat
+LOCAL_PRIVATE_PLATFORM_APIS := true
+
include $(BUILD_PACKAGE)
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
index d5d96fe..6da143c 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java
@@ -199,6 +199,9 @@
mClockView.setElegantTextHeight(false);
}
+ /**
+ * Moves clock and separator, adjusting margins when slice content changes.
+ */
private void onSliceContentChanged() {
boolean smallClock = mKeyguardSlice.hasHeader() || mPulsing;
float clockScale = smallClock ? mSmallClockScale : 1;
@@ -221,7 +224,7 @@
@Override
public void onLayoutChange(View view, int left, int top, int right, int bottom,
int oldLeft, int oldTop, int oldRight, int oldBottom) {
- int heightOffset = mPulsing ? 0 : getHeight() - mLastLayoutHeight;
+ int heightOffset = mPulsing || mWasPulsing ? 0 : getHeight() - mLastLayoutHeight;
boolean hasHeader = mKeyguardSlice.hasHeader();
boolean smallClock = hasHeader || mPulsing;
long duration = KeyguardSliceView.DEFAULT_ANIM_DURATION;
@@ -457,6 +460,11 @@
mWasPulsing = true;
}
mPulsing = pulsing;
+ // Animation can look really weird when the slice has a header, let's hide the views
+ // immediately instead of fading them away.
+ if (mKeyguardSlice.hasHeader()) {
+ animate = false;
+ }
mKeyguardSlice.setPulsing(pulsing, animate);
updateDozeVisibleViews();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index 83db6aa..9393d5b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -124,12 +124,12 @@
private final NotificationInflater mNotificationInflater;
private int mIconTransformContentShift;
private int mIconTransformContentShiftNoIcon;
- private int mNotificationMinHeightLegacy;
- private int mNotificationMinHeightBeforeP;
- private int mMaxHeadsUpHeightLegacy;
+ private int mMaxHeadsUpHeightBeforeN;
private int mMaxHeadsUpHeightBeforeP;
private int mMaxHeadsUpHeight;
private int mMaxHeadsUpHeightIncreased;
+ private int mNotificationMinHeightBeforeN;
+ private int mNotificationMinHeightBeforeP;
private int mNotificationMinHeight;
private int mNotificationMinHeightLarge;
private int mNotificationMaxHeight;
@@ -546,7 +546,7 @@
boolean beforeP = mEntry.targetSdk < Build.VERSION_CODES.P;
int minHeight;
if (customView && beforeP && !mIsSummaryWithChildren) {
- minHeight = beforeN ? mNotificationMinHeightLegacy : mNotificationMinHeightBeforeP;
+ minHeight = beforeN ? mNotificationMinHeightBeforeN : mNotificationMinHeightBeforeP;
} else if (mUseIncreasedCollapsedHeight && layout == mPrivateLayout) {
minHeight = mNotificationMinHeightLarge;
} else {
@@ -555,20 +555,20 @@
boolean headsUpCustom = layout.getHeadsUpChild() != null &&
layout.getHeadsUpChild().getId()
!= com.android.internal.R.id.status_bar_latest_event_content;
- int headsUpheight;
+ int headsUpHeight;
if (headsUpCustom && beforeP) {
- headsUpheight = beforeN ? mMaxHeadsUpHeightLegacy : mMaxHeadsUpHeightBeforeP;
+ headsUpHeight = beforeN ? mMaxHeadsUpHeightBeforeN : mMaxHeadsUpHeightBeforeP;
} else if (mUseIncreasedHeadsUpHeight && layout == mPrivateLayout) {
- headsUpheight = mMaxHeadsUpHeightIncreased;
+ headsUpHeight = mMaxHeadsUpHeightIncreased;
} else {
- headsUpheight = mMaxHeadsUpHeight;
+ headsUpHeight = mMaxHeadsUpHeight;
}
NotificationViewWrapper headsUpWrapper = layout.getVisibleWrapper(
NotificationContentView.VISIBLE_TYPE_HEADSUP);
if (headsUpWrapper != null) {
- headsUpheight = Math.max(headsUpheight, headsUpWrapper.getMinLayoutHeight());
+ headsUpHeight = Math.max(headsUpHeight, headsUpWrapper.getMinLayoutHeight());
}
- layout.setHeights(minHeight, headsUpheight, mNotificationMaxHeight,
+ layout.setHeights(minHeight, headsUpHeight, mNotificationMaxHeight,
mNotificationAmbientHeight);
}
@@ -1487,7 +1487,7 @@
}
private void initDimens() {
- mNotificationMinHeightLegacy = NotificationUtils.getFontScaledHeight(mContext,
+ mNotificationMinHeightBeforeN = NotificationUtils.getFontScaledHeight(mContext,
R.dimen.notification_min_height_legacy);
mNotificationMinHeightBeforeP = NotificationUtils.getFontScaledHeight(mContext,
R.dimen.notification_min_height_before_p);
@@ -1499,7 +1499,7 @@
R.dimen.notification_max_height);
mNotificationAmbientHeight = NotificationUtils.getFontScaledHeight(mContext,
R.dimen.notification_ambient_height);
- mMaxHeadsUpHeightLegacy = NotificationUtils.getFontScaledHeight(mContext,
+ mMaxHeadsUpHeightBeforeN = NotificationUtils.getFontScaledHeight(mContext,
R.dimen.notification_max_heads_up_height_legacy);
mMaxHeadsUpHeightBeforeP = NotificationUtils.getFontScaledHeight(mContext,
R.dimen.notification_max_heads_up_height_before_p);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadowKeyDrawable.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadowKeyDrawable.java
index 8311dfd..2471e34 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadowKeyDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ShadowKeyDrawable.java
@@ -82,7 +82,12 @@
if (bounds.isEmpty()) {
return;
}
- if (mState.mLastDrawnBitmap == null) {
+
+ // If no cache or previous cached bitmap is hardware/software acceleration does not match
+ // the current canvas on draw then regenerate
+ if (mState.mLastDrawnBitmap == null
+ || mState.mIsHardwareBitmap != canvas.isHardwareAccelerated()) {
+ mState.mIsHardwareBitmap = canvas.isHardwareAccelerated();
regenerateBitmapCache();
}
canvas.drawBitmap(mState.mLastDrawnBitmap, null, bounds, mPaint);
@@ -171,7 +176,10 @@
d.draw(canvas);
}
- bitmap = bitmap.copy(Bitmap.Config.HARDWARE, false);
+ if (mState.mIsHardwareBitmap) {
+ bitmap = bitmap.copy(Bitmap.Config.HARDWARE, false);
+ }
+
mState.mLastDrawnBitmap = bitmap;
canvas.restore();
}
@@ -186,6 +194,7 @@
int mShadowSize;
int mShadowColor;
+ boolean mIsHardwareBitmap;
Bitmap mLastDrawnBitmap;
ConstantState mChildState;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 4264adad..a4e184b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -3169,7 +3169,7 @@
private void startAnimationToState() {
if (mNeedsAnimation) {
- generateChildHierarchyEvents();
+ generateAllAnimationEvents();
mNeedsAnimation = false;
}
if (!mAnimationEvents.isEmpty() || isCurrentlyAnimating()) {
@@ -3186,7 +3186,7 @@
mGoToFullShadeDelay = 0;
}
- private void generateChildHierarchyEvents() {
+ private void generateAllAnimationEvents() {
generateHeadsUpAnimationEvents();
generateChildRemovalEvents();
generateChildAdditionEvents();
@@ -3203,7 +3203,6 @@
generateGroupExpansionEvent();
generateAnimateEverythingEvent();
generatePulsingAnimationEvent();
- mNeedsAnimation = false;
}
private void generateHeadsUpAnimationEvents() {
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index 73eb37f..dc6d16b 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -6145,6 +6145,21 @@
// CATEGORY: SETTINGS
// OS: Q
ACTION_FACE_ENROLL = 1505;
+
+ // OPEN: Face Enroll introduction
+ // CATEGORY: SETTINGS
+ // OS: Q
+ FACE_ENROLL_INTRO = 1506;
+
+ // OPEN: Face Enroll introduction
+ // CATEGORY: SETTINGS
+ // OS: Q
+ FACE_ENROLL_ENROLLING = 1507;
+
+ // OPEN: Face Enroll introduction
+ // CATEGORY: SETTINGS
+ // OS: Q
+ FACE_ENROLL_FINISHED = 1508;
// ---- End Q Constants, all Q constants go above this line ----
// Add new aosp constants above this line.
diff --git a/services/core/java/com/android/server/AlarmManagerService.java b/services/core/java/com/android/server/AlarmManagerService.java
index 3261209..cc5acdf 100644
--- a/services/core/java/com/android/server/AlarmManagerService.java
+++ b/services/core/java/com/android/server/AlarmManagerService.java
@@ -2685,19 +2685,23 @@
private void validateLastAlarmExpiredLocked(long nowElapsed) {
final StringBuilder errorMsg = new StringBuilder();
boolean stuck = false;
- if (mNextNonWakeup < nowElapsed && mLastWakeup < (mNextNonWakeup - 30_000)) {
+ if (mNextNonWakeup < (nowElapsed - 10_000) && mLastWakeup < mNextNonWakeup) {
stuck = true;
errorMsg.append("[mNextNonWakeup=");
TimeUtils.formatDuration(mNextNonWakeup - nowElapsed, errorMsg);
+ errorMsg.append(" set at ");
+ TimeUtils.formatDuration(mNextNonWakeUpSetAt, errorMsg);
errorMsg.append(", mLastWakeup=");
TimeUtils.formatDuration(mLastWakeup - nowElapsed, errorMsg);
errorMsg.append(", timerfd_gettime=" + getNextAlarm(mNativeData, ELAPSED_REALTIME));
errorMsg.append("];");
}
- if (mNextWakeup < nowElapsed && mLastWakeup < (mNextWakeup - 30_000)) {
+ if (mNextWakeup < (nowElapsed - 10_000) && mLastWakeup < mNextWakeup) {
stuck = true;
errorMsg.append("[mNextWakeup=");
TimeUtils.formatDuration(mNextWakeup - nowElapsed, errorMsg);
+ errorMsg.append(" set at ");
+ TimeUtils.formatDuration(mNextWakeUpSetAt, errorMsg);
errorMsg.append(", mLastWakeup=");
TimeUtils.formatDuration(mLastWakeup - nowElapsed, errorMsg);
errorMsg.append(", timerfd_gettime="
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 1d8a77c..9c55de7 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -2138,7 +2138,7 @@
private final boolean scheduleServiceRestartLocked(ServiceRecord r, boolean allowCancel) {
boolean canceled = false;
- if (mAm.isShuttingDownLocked()) {
+ if (mAm.mAtmInternal.isShuttingDown()) {
Slog.w(TAG, "Not scheduling restart of crashed service " + r.shortName
+ " - system is shutting down");
return false;
diff --git a/services/core/java/com/android/server/am/ActivityDisplay.java b/services/core/java/com/android/server/am/ActivityDisplay.java
index 9f9fe4c..562dfd6 100644
--- a/services/core/java/com/android/server/am/ActivityDisplay.java
+++ b/services/core/java/com/android/server/am/ActivityDisplay.java
@@ -141,7 +141,7 @@
+ " to displayId=" + mDisplayId + " position=" + position);
addStackReferenceIfNeeded(stack);
positionChildAt(stack, position);
- mSupervisor.mService.mAm.updateSleepIfNeededLocked();
+ mSupervisor.mService.updateSleepIfNeededLocked();
}
void removeChild(ActivityStack stack) {
@@ -149,7 +149,7 @@
+ " from displayId=" + mDisplayId);
mStacks.remove(stack);
removeStackReferenceIfNeeded(stack);
- mSupervisor.mService.mAm.updateSleepIfNeededLocked();
+ mSupervisor.mService.updateSleepIfNeededLocked();
onStackOrderChanged();
}
@@ -715,7 +715,7 @@
boolean shouldSleep() {
return (mStacks.isEmpty() || !mAllSleepTokens.isEmpty())
- && (mSupervisor.mService.mAm.mRunningVoice == null);
+ && (mSupervisor.mService.mRunningVoice == null);
}
/**
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 9798fa9..cc3d73f 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -89,12 +89,9 @@
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
import static android.provider.Settings.Global.DEBUG_APP;
-import static android.provider.Settings.Global.HIDE_ERROR_DIALOGS;
import static android.provider.Settings.Global.NETWORK_ACCESS_TIMEOUT_MS;
import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
-import static android.provider.Settings.System.FONT_SCALE;
import static android.text.format.DateUtils.DAY_IN_MILLIS;
-import static android.view.Display.DEFAULT_DISPLAY;
import static com.android.internal.util.XmlUtils.readBooleanAttribute;
import static com.android.internal.util.XmlUtils.readIntAttribute;
import static com.android.internal.util.XmlUtils.readLongAttribute;
@@ -581,11 +578,6 @@
public final IntentFirewall mIntentFirewall;
- // Whether we should show our dialogs (ANR, crash, etc) or just perform their
- // default action automatically. Important for devices without direct input
- // devices.
- private boolean mShowDialogs = true;
-
// Whether we should use SCHED_FIFO for UI and RenderThreads.
private boolean mUseFifoUiScheduling = false;
@@ -609,25 +601,6 @@
}
/**
- * The last resumed activity. This is identical to the current resumed activity most
- * of the time but could be different when we're pausing one activity before we resume
- * another activity.
- */
- ActivityRecord mLastResumedActivity;
-
- /**
- * The activity that is currently being traced as the active resumed activity.
- *
- * @see #updateResumedAppTrace
- */
- private @Nullable ActivityRecord mTracedResumedActivity;
-
- /**
- * If non-null, we are tracking the time the user spends in the currently focused app.
- */
- private AppTimeTracker mCurAppTimeTracker;
-
- /**
* The package name of the DeviceOwner. This package is not permitted to have its data cleared.
*/
String mDeviceOwnerName;
@@ -680,15 +653,6 @@
}
};
- public boolean canShowErrorDialogs() {
- return mShowDialogs && !mSleeping && !mShuttingDown
- && !mActivityTaskManager.mKeyguardController.isKeyguardOrAodShowing(DEFAULT_DISPLAY)
- && !mUserController.hasUserRestriction(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
- mUserController.getCurrentUserId())
- && !(UserManager.isDeviceInDemoMode(mContext)
- && mUserController.getCurrentUser().isDemo());
- }
-
private static ThreadPriorityBooster sThreadPriorityBooster = new ThreadPriorityBooster(
THREAD_PRIORITY_FOREGROUND, LockGuard.INDEX_ACTIVITY);
@@ -1096,32 +1060,6 @@
CoreSettingsObserver mCoreSettingsObserver;
- FontScaleSettingObserver mFontScaleSettingObserver;
-
- private final class FontScaleSettingObserver extends ContentObserver {
- private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
- private final Uri mHideErrorDialogsUri = Settings.Global.getUriFor(HIDE_ERROR_DIALOGS);
-
- public FontScaleSettingObserver() {
- super(mHandler);
- ContentResolver resolver = mContext.getContentResolver();
- resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
- resolver.registerContentObserver(mHideErrorDialogsUri, false, this,
- UserHandle.USER_ALL);
- }
-
- @Override
- public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
- if (mFontScaleUri.equals(uri)) {
- updateFontScaleIfNeeded(userId);
- } else if (mHideErrorDialogsUri.equals(uri)) {
- synchronized (ActivityManagerService.this) {
- updateShouldShowDialogsLocked(getGlobalConfiguration());
- }
- }
- }
- }
-
DevelopmentSettingsObserver mDevelopmentSettingsObserver;
private final class DevelopmentSettingsObserver extends ContentObserver {
@@ -1281,55 +1219,16 @@
long mLastPowerCheckUptime;
/**
- * Set while we are wanting to sleep, to prevent any
- * activities from being started/resumed.
- *
- * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
- *
- * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
- * while in the sleep state until there is a pending transition out of sleep, in which case
- * mSleeping is set to false, and remains false while awake.
- *
- * Whether mSleeping can quickly toggled between true/false without the device actually
- * display changing states is undefined.
- */
- private boolean mSleeping = false;
-
- /**
- * The process state used for processes that are running the top activities.
- * This changes between TOP and TOP_SLEEPING to following mSleeping.
- */
- int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
-
- /**
- * Set while we are running a voice interaction. This overrides
- * sleeping while it is active.
- */
- IVoiceInteractionSession mRunningVoice;
-
- /**
* For some direct access we need to power manager.
*/
PowerManagerInternal mLocalPowerManager;
/**
- * We want to hold a wake lock while running a voice interaction session, since
- * this may happen with the screen off and we need to keep the CPU running to
- * be able to continue to interact with the user.
- */
- PowerManager.WakeLock mVoiceWakeLock;
-
- /**
* State of external calls telling us if the device is awake or asleep.
*/
private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
/**
- * Set if we are shutting down the system, similar to sleeping.
- */
- boolean mShuttingDown = false;
-
- /**
* Current sequence id for oom_adj computation traversal.
*/
int mAdjSeq = 0;
@@ -1639,8 +1538,6 @@
static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
static final int SERVICE_TIMEOUT_MSG = 12;
static final int UPDATE_TIME_ZONE = 13;
- static final int SHOW_UID_ERROR_UI_MSG = 14;
- static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
static final int PROC_START_TIMEOUT_MSG = 20;
static final int KILL_APPLICATION_MSG = 22;
static final int FINALIZE_PENDING_INTENT_MSG = 23;
@@ -1658,12 +1555,10 @@
static final int UPDATE_TIME_PREFERENCE_MSG = 41;
static final int FINISH_BOOTING_MSG = 45;
static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
- static final int DISMISS_DIALOG_UI_MSG = 48;
static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 49;
static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 50;
static final int DELETE_DUMPHEAP_MSG = 51;
static final int DISPATCH_UIDS_CHANGED_UI_MSG = 53;
- static final int REPORT_TIME_TRACKER_MSG = 54;
static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 56;
static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 57;
static final int IDLE_UIDS_MSG = 58;
@@ -1778,7 +1673,7 @@
return;
}
AppErrorResult res = (AppErrorResult) data.get("result");
- if (mShowDialogs && !mSleeping && !mShuttingDown) {
+ if (mAtmInternal.showStrictModeViolationDialog()) {
Dialog d = new StrictModeViolationDialog(mUiContext,
ActivityManagerService.this, res, proc);
d.show();
@@ -1817,30 +1712,6 @@
}
}
} break;
- case SHOW_UID_ERROR_UI_MSG: {
- if (mShowDialogs) {
- AlertDialog d = new BaseErrorDialog(mUiContext);
- d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
- d.setCancelable(false);
- d.setTitle(mUiContext.getText(R.string.android_system_label));
- d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
- d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
- obtainMessage(DISMISS_DIALOG_UI_MSG, d));
- d.show();
- }
- } break;
- case SHOW_FINGERPRINT_ERROR_UI_MSG: {
- if (mShowDialogs) {
- AlertDialog d = new BaseErrorDialog(mUiContext);
- d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
- d.setCancelable(false);
- d.setTitle(mUiContext.getText(R.string.android_system_label));
- d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
- d.setButton(DialogInterface.BUTTON_POSITIVE, mUiContext.getText(R.string.ok),
- obtainMessage(DISMISS_DIALOG_UI_MSG, d));
- d.show();
- }
- } break;
case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
synchronized (ActivityManagerService.this) {
ActivityRecord ar = (ActivityRecord) msg.obj;
@@ -1869,11 +1740,6 @@
}
break;
}
- case DISMISS_DIALOG_UI_MSG: {
- final Dialog d = (Dialog) msg.obj;
- d.dismiss();
- break;
- }
case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
dispatchProcessesChanged();
break;
@@ -2128,7 +1994,7 @@
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
if (msg.arg2 != 0) {
- enableScreenAfterBoot();
+ mAtmInternal.enableScreenAfterBoot(mBooted);
}
break;
}
@@ -2248,10 +2114,6 @@
mMemWatchDumpUid = -1;
}
} break;
- case REPORT_TIME_TRACKER_MSG: {
- AppTimeTracker tracker = (AppTimeTracker)msg.obj;
- tracker.deliverResult(mContext);
- } break;
case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
try {
@@ -2890,12 +2752,9 @@
}
public void initPowerManagement() {
- mStackSupervisor.initPowerManagement();
+ mActivityTaskManager.onInitPowerManagement();
mBatteryStatsService.initPowerManagement();
mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
- PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
- mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
- mVoiceWakeLock.setReferenceCounted(false);
}
private ArraySet<String> getBackgroundLaunchBroadcasts() {
@@ -3146,96 +3005,6 @@
}
}
- /**
- * Update AMS states when an activity is resumed. This should only be called by
- * {@link ActivityStack#onActivityStateChanged(ActivityRecord, ActivityState, String)} when an
- * activity is resumed.
- */
- @GuardedBy("this")
- void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
- final TaskRecord task = r.getTask();
- if (task.isActivityTypeStandard()) {
- if (mCurAppTimeTracker != r.appTimeTracker) {
- // We are switching app tracking. Complete the current one.
- if (mCurAppTimeTracker != null) {
- mCurAppTimeTracker.stop();
- mHandler.obtainMessage(
- REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
- mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
- mCurAppTimeTracker = null;
- }
- if (r.appTimeTracker != null) {
- mCurAppTimeTracker = r.appTimeTracker;
- startTimeTrackingFocusedActivityLocked();
- }
- } else {
- startTimeTrackingFocusedActivityLocked();
- }
- } else {
- r.appTimeTracker = null;
- }
- // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
- // TODO: Probably not, because we don't want to resume voice on switching
- // back to this activity
- if (task.voiceInteractor != null) {
- startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
- } else {
- finishRunningVoiceLocked();
-
- if (mLastResumedActivity != null) {
- final IVoiceInteractionSession session;
-
- final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
- if (lastResumedActivityTask != null
- && lastResumedActivityTask.voiceSession != null) {
- session = lastResumedActivityTask.voiceSession;
- } else {
- session = mLastResumedActivity.voiceSession;
- }
-
- if (session != null) {
- // We had been in a voice interaction session, but now focused has
- // move to something different. Just finish the session, we can't
- // return to it and retain the proper state and synchronization with
- // the voice interaction service.
- mActivityTaskManager.finishVoiceTask(session);
- }
- }
- }
-
- if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
- mUserController.sendForegroundProfileChanged(r.userId);
- }
- updateResumedAppTrace(r);
- mLastResumedActivity = r;
-
- mWindowManager.setFocusedApp(r.appToken, true);
-
- mActivityTaskManager.applyUpdateLockStateLocked(r);
- mActivityTaskManager.applyUpdateVrModeLocked(r);
-
- EventLogTags.writeAmSetResumedActivity(
- r == null ? -1 : r.userId,
- r == null ? "NULL" : r.shortComponentName,
- reason);
- }
-
- private void updateResumedAppTrace(@Nullable ActivityRecord resumed) {
- if (mTracedResumedActivity != null) {
- Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER,
- constructResumedTraceName(mTracedResumedActivity.packageName), 0);
- }
- if (resumed != null) {
- Trace.asyncTraceBegin(TRACE_TAG_ACTIVITY_MANAGER,
- constructResumedTraceName(resumed.packageName), 0);
- }
- mTracedResumedActivity = resumed;
- }
-
- private String constructResumedTraceName(String packageName) {
- return "focused app: " + packageName;
- }
-
@Override
public void setFocusedStack(int stackId) {
mActivityTaskManager.setFocusedStack(stackId);
@@ -4655,44 +4424,6 @@
mActivityTaskManager.cancelRecentsAnimation(restoreHomeStackPosition);
}
- @GuardedBy("this")
- void onLocalVoiceInteractionStartedLocked(IBinder activity,
- IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
- ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
- if (activityToCallback == null) return;
- activityToCallback.setVoiceSessionLocked(voiceSession);
-
- // Inform the activity
- try {
- activityToCallback.app.getThread().scheduleLocalVoiceInteractionStarted(activity,
- voiceInteractor);
- long token = Binder.clearCallingIdentity();
- try {
- startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- // TODO: VI Should we cache the activity so that it's easier to find later
- // rather than scan through all the stacks and activities?
- } catch (RemoteException re) {
- activityToCallback.clearVoiceSessionLocked();
- // TODO: VI Should this terminate the voice session?
- }
- }
-
- @Override
- public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
- synchronized (this) {
- if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
- if (keepAwake) {
- mVoiceWakeLock.acquire();
- } else {
- mVoiceWakeLock.release();
- }
- }
- }
- }
-
/**
* This is the internal entry point for handling Activity.finish().
*
@@ -6604,16 +6335,6 @@
finishBooting ? 1 : 0, enableScreen ? 1 : 0));
}
- void enableScreenAfterBoot() {
- EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
- SystemClock.uptimeMillis());
- mWindowManager.enableScreenAfterBoot();
-
- synchronized (this) {
- updateEventDispatchingLocked();
- }
- }
-
@Override
public void showBootMessage(final CharSequence msg, final boolean always) {
if (Binder.getCallingUid() != myUid()) {
@@ -6761,7 +6482,7 @@
}
if (enableScreen) {
- enableScreenAfterBoot();
+ mAtmInternal.enableScreenAfterBoot(mBooted);
}
}
@@ -10160,7 +9881,7 @@
mConstants.start(mContext.getContentResolver());
mCoreSettingsObserver = new CoreSettingsObserver(this);
- mFontScaleSettingObserver = new FontScaleSettingObserver();
+ mActivityTaskManager.installSystemProviders();
mDevelopmentSettingsObserver = new DevelopmentSettingsObserver();
GlobalSettingsToPropertiesMapper.start(mContext.getContentResolver());
@@ -10506,20 +10227,6 @@
return pfd;
}
- // Actually is sleeping or shutting down or whatever else in the future
- // is an inactive state.
- boolean isSleepingOrShuttingDownLocked() {
- return isSleepingLocked() || mShuttingDown;
- }
-
- boolean isShuttingDownLocked() {
- return mShuttingDown;
- }
-
- boolean isSleepingLocked() {
- return mSleeping;
- }
-
void reportGlobalUsageEventLocked(int event) {
mUsageStatsService.reportEvent("android", mUserController.getCurrentUserId(), event);
int[] profiles = mUserController.getCurrentProfileIds();
@@ -10552,53 +10259,6 @@
}
}
- @GuardedBy("this")
- void finishRunningVoiceLocked() {
- if (mRunningVoice != null) {
- mRunningVoice = null;
- mVoiceWakeLock.release();
- updateSleepIfNeededLocked();
- }
- }
-
- void startTimeTrackingFocusedActivityLocked() {
- final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
- if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
- mCurAppTimeTracker.start(resumedActivity.packageName);
- }
- }
-
- @GuardedBy("this")
- void updateSleepIfNeededLocked() {
- final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
- final boolean wasSleeping = mSleeping;
-
- if (!shouldSleep) {
- // If wasSleeping is true, we need to wake up activity manager state from when
- // we started sleeping. In either case, we need to apply the sleep tokens, which
- // will wake up stacks or put them to sleep as appropriate.
- if (wasSleeping) {
- mSleeping = false;
- startTimeTrackingFocusedActivityLocked();
- mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
- mStackSupervisor.comeOutOfSleepIfNeededLocked();
- }
- mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
- if (wasSleeping) {
- updateOomAdjLocked();
- }
- } else if (!mSleeping && shouldSleep) {
- mSleeping = true;
- if (mCurAppTimeTracker != null) {
- mCurAppTimeTracker.stop();
- }
- mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
- mStackSupervisor.goingToSleepLocked();
- updateResumedAppTrace(null /* resumed */);
- updateOomAdjLocked();
- }
- }
-
@Override
public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
@@ -10612,14 +10272,7 @@
+ android.Manifest.permission.SHUTDOWN);
}
- boolean timedout = false;
-
- synchronized(this) {
- mShuttingDown = true;
- mStackSupervisor.prepareForShutdownLocked();
- updateEventDispatchingLocked();
- timedout = mStackSupervisor.shutdownLocked(timeout);
- }
+ final boolean timedout = mAtmInternal.shuttingDown(mBooted, timeout);
mAppOpsService.shutdown();
if (mUsageStatsService != null) {
@@ -10634,24 +10287,6 @@
return timedout;
}
- @GuardedBy("this")
- void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
- Slog.d(TAG, "<<< startRunningVoiceLocked()");
- mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
- if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
- boolean wasRunningVoice = mRunningVoice != null;
- mRunningVoice = session;
- if (!wasRunningVoice) {
- mVoiceWakeLock.acquire();
- updateSleepIfNeededLocked();
- }
- }
- }
-
- private void updateEventDispatchingLocked() {
- mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
- }
-
@Override
public void setLockScreenShown(boolean keyguardShowing, boolean aodShowing,
int secondaryDisplayShowing) {
@@ -11703,7 +11338,7 @@
proc.notCachedSinceIdle = true;
proc.initialIdlePss = 0;
proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, null,
- mTestPssMode, isSleepingLocked(), now);
+ mTestPssMode, mAtmInternal.isSleeping(), now);
}
}
}
@@ -11903,19 +11538,7 @@
}
startHomeActivityLocked(currentUserId, "systemReady");
- try {
- if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
- Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
- + " data partition or your device will be unstable.");
- mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
- }
- } catch (RemoteException e) {
- }
-
- if (!Build.isBuildConsistent()) {
- Slog.e(TAG, "Build fingerprint is not consistent, warning user");
- mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
- }
+ mAtmInternal.showSystemReadyErrorDialogsIfNeeded();
long ident = Binder.clearCallingIdentity();
try {
@@ -12643,14 +12266,6 @@
this, in, out, err, args, callback, resultReceiver);
}
- SleepToken acquireSleepToken(String tag, int displayId) {
- synchronized (this) {
- final SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
- updateSleepIfNeededLocked();
- return token;
- }
- }
-
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
PriorityDump.dump(mPriorityDumper, fd, pw, args);
@@ -13152,12 +12767,13 @@
final File[] files = new File(ANR_TRACE_DIR).listFiles();
if (ArrayUtils.isEmpty(files)) {
+ pw.println(" <no ANR has occurred since boot>");
return;
}
// Find the latest file.
File latest = null;
for (File f : files) {
- if (latest == null || latest.getName().compareTo(f.getName()) < 0) {
+ if ((latest == null) || (latest.lastModified() < f.lastModified())) {
latest = f;
}
}
@@ -13674,14 +13290,7 @@
if (dumpPackage == null) {
pw.println(" mWakefulness="
+ PowerManagerInternal.wakefulnessToString(mWakefulness));
- pw.println(" mSleepTokens=" + mStackSupervisor.mSleepTokens);
- pw.println(" mSleeping=" + mSleeping);
- pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
- if (mRunningVoice != null) {
- pw.println(" mRunningVoice=" + mRunningVoice);
- pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
- }
- mActivityTaskManager.dumpVrControllerLocked(pw);
+ mActivityTaskManager.dumpSleepStates(pw, mTestPssMode);
}
if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
|| mOrigWaitForDebugger) {
@@ -13696,8 +13305,8 @@
+ " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
}
}
- if (mCurAppTimeTracker != null) {
- mCurAppTimeTracker.dumpWithHeader(pw, " ", true);
+ if (mActivityTaskManager.mCurAppTimeTracker != null) {
+ mActivityTaskManager.mCurAppTimeTracker.dumpWithHeader(pw, " ", true);
}
if (mMemWatchProcesses.getMap().size() > 0) {
pw.println(" Mem watch processes:");
@@ -14034,23 +13643,10 @@
final long sleepToken = proto.start(ActivityManagerServiceDumpProcessesProto.SLEEP_STATUS);
proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.WAKEFULNESS,
PowerManagerInternal.wakefulnessToProtoEnum(mWakefulness));
- for (SleepToken st : mStackSupervisor.mSleepTokens) {
- proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEP_TOKENS, st.toString());
- }
- proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEPING, mSleeping);
- proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SHUTTING_DOWN, mShuttingDown);
proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.TEST_PSS_MODE, mTestPssMode);
proto.end(sleepToken);
- if (mRunningVoice != null) {
- final long vrToken = proto.start(ActivityManagerServiceDumpProcessesProto.RUNNING_VOICE);
- proto.write(ActivityManagerServiceDumpProcessesProto.Voice.SESSION, mRunningVoice.toString());
- mVoiceWakeLock.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.Voice.WAKELOCK);
- proto.end(vrToken);
- }
-
- mActivityTaskManager.writeVrControllerToProto(
- proto, ActivityManagerServiceDumpProcessesProto.VR_CONTROLLER);
+ mActivityTaskManager.writeSleepStateToProto(proto);
}
if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
@@ -14066,8 +13662,9 @@
}
}
- if (mCurAppTimeTracker != null) {
- mCurAppTimeTracker.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.CURRENT_TRACKER, true);
+ if (mActivityTaskManager.mCurAppTimeTracker != null) {
+ mActivityTaskManager.mCurAppTimeTracker.writeToProto(
+ proto, ActivityManagerServiceDumpProcessesProto.CURRENT_TRACKER, true);
}
if (mMemWatchProcesses.getMap().size() > 0) {
@@ -18971,13 +18568,9 @@
return mActivityTaskManager.getFocusedStackInfo();
}
+ @Override
public Configuration getConfiguration() {
- Configuration ci;
- synchronized(this) {
- ci = new Configuration(getGlobalConfiguration());
- ci.userSetLocale = false;
- }
- return ci;
+ return mActivityTaskManager.getConfiguration();
}
@Override
@@ -18998,22 +18591,6 @@
mActivityTaskManager.updatePersistentConfiguration(values, userId);
}
- private void updateFontScaleIfNeeded(@UserIdInt int userId) {
- final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
- FONT_SCALE, 1.0f, userId);
-
- synchronized (this) {
- if (getGlobalConfiguration().fontScale == scaleFactor) {
- return;
- }
-
- final Configuration configuration
- = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
- configuration.fontScale = scaleFactor;
- mActivityTaskManager.updatePersistentConfiguration(configuration, userId);
- }
- }
-
private void enforceWriteSettingsPermission(String func) {
int uid = Binder.getCallingUid();
if (uid == ROOT_UID) {
@@ -19038,29 +18615,6 @@
return mActivityTaskManager.updateConfiguration(values);
}
- /**
- * Decide based on the configuration whether we should show the ANR,
- * crash, etc dialogs. The idea is that if there is no affordance to
- * press the on-screen buttons, or the user experience would be more
- * greatly impacted than the crash itself, we shouldn't show the dialog.
- *
- * A thought: SystemUI might also want to get told about this, the Power
- * dialog / global actions also might want different behaviors.
- */
- void updateShouldShowDialogsLocked(Configuration config) {
- final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
- && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
- && config.navigation == Configuration.NAVIGATION_NONAV);
- int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
- final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
- && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
- && modeType != Configuration.UI_MODE_TYPE_TELEVISION
- && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
- final boolean hideDialogsSet = Settings.Global.getInt(mContext.getContentResolver(),
- HIDE_ERROR_DIALOGS, 0) != 0;
- mShowDialogs = inputMethodExists && uiModeSupportsDialogs && !hideDialogsSet;
- }
-
@Override
public int getLaunchedFromUid(IBinder activityToken) {
return mActivityTaskManager.getLaunchedFromUid(activityToken);
@@ -19279,7 +18833,7 @@
app.systemNoUi = false;
- final int PROCESS_STATE_CUR_TOP = mTopProcessState;
+ final int PROCESS_STATE_CUR_TOP = mAtmInternal.getTopProcessState();
// Determine the importance of the process, starting with most
// important to least, and assign an appropriate OOM adjustment.
@@ -20329,7 +19883,7 @@
app.pssStatType = always ? ProcessStats.ADD_PSS_INTERNAL_ALL_POLL
: ProcessStats.ADD_PSS_INTERNAL_ALL_MEM;
app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState,
- app.procStateMemTracker, mTestPssMode, isSleepingLocked(), now);
+ app.procStateMemTracker, mTestPssMode, mAtmInternal.isSleeping(), now);
mPendingPssProcesses.add(app);
}
}
@@ -20379,7 +19933,7 @@
}
}
return !processingBroadcasts
- && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
+ && (mAtmInternal.isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
}
/**
@@ -20713,7 +20267,7 @@
}
app.lastStateTime = now;
app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState,
- app.procStateMemTracker, mTestPssMode, isSleepingLocked(), now);
+ app.procStateMemTracker, mTestPssMode, mAtmInternal.isSleeping(), now);
if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
+ ProcessList.makeProcStateString(app.setProcState) + " to "
+ ProcessList.makeProcStateString(app.curProcState) + " next pss in "
@@ -20724,7 +20278,7 @@
mTestPssMode)))) {
if (requestPssLocked(app, app.setProcState)) {
app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState,
- app.procStateMemTracker, mTestPssMode, isSleepingLocked(), now);
+ app.procStateMemTracker, mTestPssMode, mAtmInternal.isSleeping(), now);
}
} else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
"Not requesting pss of " + app + ": next=" + (app.nextPssTime-now));
@@ -21365,7 +20919,8 @@
}
mLastMemoryLevel = memFactor;
mLastNumProcesses = mLruProcesses.size();
- boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
+ boolean allChanged = mProcessStats.setMemFactorLocked(
+ memFactor, mAtmInternal != null ? !mAtmInternal.isSleeping() : true, now);
final int trackerMemFactor = mProcessStats.getMemFactorLocked();
if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
if (mLowRamStartTime == 0) {
@@ -22814,6 +22369,18 @@
}
return false;
}
+
+ @Override
+ public void updateOomAdj() {
+ synchronized (ActivityManagerService.this) {
+ ActivityManagerService.this.updateOomAdjLocked();
+ }
+ }
+
+ @Override
+ public void sendForegroundProfileChanged(int userId) {
+ mUserController.sendForegroundProfileChanged(userId);
+ }
}
/**
diff --git a/services/core/java/com/android/server/am/ActivityMetricsLogger.java b/services/core/java/com/android/server/am/ActivityMetricsLogger.java
index 9b08823..62f8c72 100644
--- a/services/core/java/com/android/server/am/ActivityMetricsLogger.java
+++ b/services/core/java/com/android/server/am/ActivityMetricsLogger.java
@@ -133,7 +133,7 @@
private final class WindowingModeTransitionInfoSnapshot {
final private ApplicationInfo applicationInfo;
- final private ProcessRecord processRecord;
+ final private WindowProcessController processRecord;
final private String packageName;
final private String launchedActivityName;
final private String launchedActivityLaunchedFromPackage;
@@ -238,7 +238,7 @@
* @param launchedActivity the activity that is being launched
*/
void notifyActivityLaunched(int resultCode, ActivityRecord launchedActivity) {
- final ProcessRecord processRecord = findProcessForActivity(launchedActivity);
+ final WindowProcessController processRecord = findProcessForActivity(launchedActivity);
final boolean processRunning = processRecord != null;
// We consider this a "process switch" if the process of the activity that gets launched
@@ -246,7 +246,7 @@
// of caches might be purged so the time until it produces the first frame is very
// interesting.
final boolean processSwitch = processRecord == null
- || !processRecord.getWindowProcessController().hasStartedActivity(launchedActivity);
+ || !processRecord.hasStartedActivity(launchedActivity);
notifyActivityLaunched(resultCode, launchedActivity, processRunning, processSwitch);
}
@@ -631,7 +631,7 @@
return;
}
- final int pid = info.processRecord.pid;
+ final int pid = info.processRecord.getPid();
final int uid = info.applicationInfo.uid;
final MemoryStat memoryStat = readMemoryStatFromFilesystem(uid, pid);
if (memoryStat == null) {
@@ -651,9 +651,9 @@
memoryStat.swapInBytes);
}
- private ProcessRecord findProcessForActivity(ActivityRecord launchedActivity) {
+ private WindowProcessController findProcessForActivity(ActivityRecord launchedActivity) {
return launchedActivity != null
- ? mSupervisor.mService.mAm.mProcessNames.get(
+ ? mSupervisor.mService.mProcessNames.get(
launchedActivity.processName, launchedActivity.appInfo.uid)
: null;
}
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index d40b9b4..b44ce9a 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -641,7 +641,7 @@
}
private void scheduleConfigurationChanged(Configuration config) {
- if (attachedToProcess()) {
+ if (!attachedToProcess()) {
if (DEBUG_CONFIGURATION) Slog.w(TAG,
"Can't report activity configuration update - client not running"
+ ", activityRecord=" + this);
@@ -1343,13 +1343,8 @@
* @return Whether AppOps allows this package to enter picture-in-picture.
*/
private boolean checkEnterPictureInPictureAppOpsState() {
- try {
- return service.mAm.getAppOpsService().checkOperation(
- OP_PICTURE_IN_PICTURE, appInfo.uid, packageName) == MODE_ALLOWED;
- } catch (RemoteException e) {
- // Local call
- }
- return false;
+ return service.getAppOpsService().checkOperation(
+ OP_PICTURE_IN_PICTURE, appInfo.uid, packageName) == MODE_ALLOWED;
}
boolean isAlwaysFocusable() {
@@ -1424,7 +1419,7 @@
final boolean isSleeping() {
final ActivityStack stack = getStack();
- return stack != null ? stack.shouldSleepActivities() : service.mAm.isSleepingLocked();
+ return stack != null ? stack.shouldSleepActivities() : service.isSleepingLocked();
}
/**
@@ -2015,7 +2010,7 @@
EventLog.writeEvent(AM_ACTIVITY_FULLY_DRAWN_TIME,
userId, System.identityHashCode(this), shortComponentName,
thisTime, totalTime);
- StringBuilder sb = service.mAm.mStringBuilder;
+ StringBuilder sb = service.mStringBuilder;
sb.setLength(0);
sb.append("Fully drawn ");
sb.append(shortComponentName);
@@ -2052,7 +2047,7 @@
EventLog.writeEvent(AM_ACTIVITY_LAUNCH_TIME,
userId, System.identityHashCode(this), shortComponentName,
thisTime, totalTime);
- StringBuilder sb = service.mAm.mStringBuilder;
+ StringBuilder sb = service.mStringBuilder;
sb.setLength(0);
sb.append("Displayed ");
sb.append(shortComponentName);
@@ -2570,8 +2565,7 @@
// Update last reported values.
final Configuration newMergedOverrideConfig = getMergedOverrideConfiguration();
- setLastReportedConfiguration(service.mAm.getGlobalConfiguration(),
- newMergedOverrideConfig);
+ setLastReportedConfiguration(service.getGlobalConfiguration(), newMergedOverrideConfig);
if (mState == INITIALIZING) {
// No need to relaunch or schedule new config for activity that hasn't been launched
@@ -2773,7 +2767,7 @@
mStackSupervisor.activityRelaunchingLocked(this);
final ClientTransactionItem callbackItem = ActivityRelaunchItem.obtain(pendingResults,
pendingNewIntents, configChangeFlags,
- new MergedConfiguration(service.mAm.getGlobalConfiguration(),
+ new MergedConfiguration(service.getGlobalConfiguration(),
getMergedOverrideConfiguration()),
preserveWindow);
final ActivityLifecycleItem lifecycleItem;
@@ -2947,7 +2941,7 @@
}
final ActivityRecord r = new ActivityRecord(service, null /* caller */,
0 /* launchedFromPid */, launchedFromUid, launchedFromPackage, intent, resolvedType,
- aInfo, service.mAm.getConfiguration(), null /* resultTo */, null /* resultWho */,
+ aInfo, service.getConfiguration(), null /* resultTo */, null /* resultWho */,
0 /* reqCode */, componentSpecified, false /* rootVoiceInteraction */,
stackSupervisor, null /* options */, null /* sourceRecord */);
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index dae145d..c76df8b 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -495,7 +495,7 @@
if (DEBUG_STACK) Slog.v(TAG_STACK, "set resumed activity to:" + record + " reason:"
+ reason);
setResumedActivity(record, reason + " - onActivityStateChanged");
- mService.mAm.setResumedActivityUncheckLocked(record, reason);
+ mService.setResumedActivityUncheckLocked(record, reason);
mStackSupervisor.mRecentTasks.add(record.getTask());
}
}
@@ -1478,7 +1478,7 @@
// If we are not going to sleep, we want to ensure the device is
// awake until the next activity is started.
- if (!uiSleeping && !mService.mAm.isSleepingOrShuttingDownLocked()) {
+ if (!uiSleeping && !mService.isSleepingOrShuttingDownLocked()) {
mStackSupervisor.acquireLaunchWakelock();
}
@@ -2702,8 +2702,7 @@
next.sleeping = false;
mService.mAm.getAppWarningsLocked().onResumeActivity(next);
mService.mAm.showAskCompatModeDialogLocked(next);
- next.app.setPendingUiCleanAndForceProcessStateUpTo(
- mService.mAm.mTopProcessState);
+ next.app.setPendingUiCleanAndForceProcessStateUpTo(mService.mTopProcessState);
next.clearOptionsLocked();
transaction.setLifecycleStateRequest(
ResumeActivityItem.obtain(next.app.getReportedProcState(),
@@ -3546,7 +3545,7 @@
}
}
}
- mService.mAm.updateOomAdjLocked();
+ mService.updateOomAdj();
}
/**
@@ -3626,7 +3625,7 @@
} catch (RemoteException re) {
// Ok
}
- mService.mAm.finishRunningVoiceLocked();
+ mService.finishRunningVoiceLocked();
break;
}
}
@@ -3634,7 +3633,7 @@
}
if (didOne) {
- mService.mAm.updateOomAdjLocked();
+ mService.updateOomAdj();
}
}
@@ -3823,7 +3822,7 @@
"Moving to STOPPING: "+ r + " (finish requested)");
r.setState(STOPPING, "finishCurrentActivityLocked");
if (oomAdj) {
- mService.mAm.updateOomAdjLocked();
+ mService.updateOomAdj();
}
return r;
}
@@ -5362,11 +5361,11 @@
return false;
}
- return display != null ? display.isSleeping() : mService.mAm.isSleepingLocked();
+ return display != null ? display.isSleeping() : mService.isSleepingLocked();
}
boolean shouldSleepOrShutDownActivities() {
- return shouldSleepActivities() || mService.mAm.isShuttingDownLocked();
+ return shouldSleepActivities() || mService.mShuttingDown;
}
public void writeToProto(ProtoOutputStream proto, long fieldId) {
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 1cb6be6..7f749b3 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -624,7 +624,7 @@
mInitialized = true;
mRunningTasks = createRunningTasks();
mActivityMetricsLogger = new ActivityMetricsLogger(this, mService.mContext, mHandler.getLooper());
- mKeyguardController = new KeyguardController(mService.mAm, this);
+ mKeyguardController = new KeyguardController(mService, this);
mLaunchParamsController = new LaunchParamsController(mService);
mLaunchParamsController.registerDefaultModifiers(this);
@@ -912,7 +912,7 @@
// result to an activity belonging to userId. Example case: a document
// picker for personal files, opened by a work app, should still get locked.
if (taskTopActivityIsUser(task, userId)) {
- mService.mAm.mActivityTaskManager.getTaskChangeNotificationController().notifyTaskProfileLocked(
+ mService.getTaskChangeNotificationController().notifyTaskProfileLocked(
task.taskId, userId);
}
}
@@ -1167,7 +1167,7 @@
}
}
if (changed) {
- mService.mAm.notifyAll();
+ mService.mGlobalLock.notifyAll();
}
}
@@ -1197,7 +1197,7 @@
}
if (changed) {
- mService.mAm.notifyAll();
+ mService.mGlobalLock.notifyAll();
}
}
@@ -1218,7 +1218,7 @@
}
}
if (changed) {
- mService.mAm.notifyAll();
+ mService.mGlobalLock.notifyAll();
}
}
@@ -1512,13 +1512,13 @@
app.hasShownUi = true;
app.pendingUiClean = true;
- app.forceProcessStateUpTo(mService.mAm.mTopProcessState);
+ app.forceProcessStateUpTo(mService.mTopProcessState);
// Because we could be starting an Activity in the system process this may not go
// across a Binder interface which would create a new Configuration. Consequently
// we have to always create a new Configuration here.
final MergedConfiguration mergedConfiguration = new MergedConfiguration(
- mService.mAm.getGlobalConfiguration(), r.getMergedOverrideConfiguration());
+ mService.getGlobalConfiguration(), r.getMergedOverrideConfiguration());
r.setLastReportedConfiguration(mergedConfiguration);
logIfTransactionTooLarge(r.intent, r.icicle);
@@ -1752,7 +1752,7 @@
ProcessRecord callerApp, ActivityRecord resultRecord, ActivityStack resultStack) {
final boolean isCallerRecents = mService.getRecentTasks() != null
&& mService.getRecentTasks().isCallerRecents(callingUid);
- final int startAnyPerm = mService.mAm.checkPermission(START_ANY_ACTIVITY, callingPid,
+ final int startAnyPerm = mService.checkPermission(START_ANY_ACTIVITY, callingPid,
callingUid);
if (startAnyPerm == PERMISSION_GRANTED || (isCallerRecents && launchingInTask)) {
// If the caller has START_ANY_ACTIVITY, ignore all checks below. In addition, if the
@@ -1831,7 +1831,7 @@
// Check if the caller has enough privileges to embed activities and launch to private
// displays.
- final int startAnyPerm = mService.mAm.checkPermission(INTERNAL_SYSTEM_WINDOW, callingPid,
+ final int startAnyPerm = mService.checkPermission(INTERNAL_SYSTEM_WINDOW, callingPid,
callingUid);
if (startAnyPerm == PERMISSION_GRANTED) {
if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:"
@@ -1853,7 +1853,7 @@
return false;
}
// Check if the caller is allowed to embed activities from other apps.
- if (mService.mAm.checkPermission(ACTIVITY_EMBEDDING, callingPid, callingUid)
+ if (mService.checkPermission(ACTIVITY_EMBEDDING, callingPid, callingUid)
== PERMISSION_DENIED && !uidPresentOnDisplay) {
if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:"
+ " disallow activity embedding without permission.");
@@ -1926,8 +1926,8 @@
return ACTIVITY_RESTRICTION_NONE;
}
- if (mService.mAm.mAppOpsService.noteOperation(opCode, callingUid,
- callingPackage) != AppOpsManager.MODE_ALLOWED) {
+ if (mService.getAppOpsService().noteOperation(opCode, callingUid, callingPackage)
+ != AppOpsManager.MODE_ALLOWED) {
if (!ignoreTargetSecurity) {
return ACTIVITY_RESTRICTION_APPOP;
}
@@ -1960,7 +1960,7 @@
return ACTIVITY_RESTRICTION_NONE;
}
- if (mService.mAm.checkPermission(permission, callingPid, callingUid) == PERMISSION_DENIED) {
+ if (mService.checkPermission(permission, callingPid, callingUid) == PERMISSION_DENIED) {
return ACTIVITY_RESTRICTION_PERMISSION;
}
@@ -1969,8 +1969,8 @@
return ACTIVITY_RESTRICTION_NONE;
}
- if (mService.mAm.mAppOpsService.noteOperation(opCode, callingUid,
- callingPackage) != AppOpsManager.MODE_ALLOWED) {
+ if (mService.getAppOpsService().noteOperation(opCode, callingUid, callingPackage)
+ != AppOpsManager.MODE_ALLOWED) {
return ACTIVITY_RESTRICTION_APPOP;
}
@@ -3517,7 +3517,7 @@
long timeRemaining = endTime - System.currentTimeMillis();
if (timeRemaining > 0) {
try {
- mService.mAm.wait(timeRemaining);
+ mService.mGlobalLock.wait(timeRemaining);
} catch (InterruptedException e) {
}
} else {
@@ -3599,7 +3599,7 @@
}
void checkReadyForSleepLocked(boolean allowDelay) {
- if (!mService.mAm.isSleepingOrShuttingDownLocked()) {
+ if (!mService.isSleepingOrShuttingDownLocked()) {
// Do not care.
return;
}
@@ -3616,8 +3616,8 @@
if (mGoingToSleep.isHeld()) {
mGoingToSleep.release();
}
- if (mService.mAm.mShuttingDown) {
- mService.mAm.notifyAll();
+ if (mService.mShuttingDown) {
+ mService.mGlobalLock.notifyAll();
}
}
@@ -3884,7 +3884,7 @@
final ActivityStack stack = s.getStack();
final boolean shouldSleepOrShutDown = stack != null
? stack.shouldSleepOrShutDownActivities()
- : mService.mAm.isSleepingOrShuttingDownLocked();
+ : mService.isSleepingOrShuttingDownLocked();
if (!waitingVisible || shouldSleepOrShutDown) {
if (!processPausingActivities && s.isState(PAUSING)) {
// Defer processing pausing activities in this iteration and reschedule
@@ -4329,7 +4329,7 @@
int displayState = activityDisplay.mDisplay.getState();
if (displayState == Display.STATE_OFF && activityDisplay.mOffToken == null) {
activityDisplay.mOffToken =
- mService.mAm.acquireSleepToken("Display-off", displayId);
+ mService.acquireSleepToken("Display-off", displayId);
} else if (displayState == Display.STATE_ON
&& activityDisplay.mOffToken != null) {
activityDisplay.mOffToken.release();
@@ -4362,7 +4362,7 @@
if (display != null) {
display.mAllSleepTokens.remove(token);
if (display.mAllSleepTokens.isEmpty()) {
- mService.mAm.updateSleepIfNeededLocked();
+ mService.updateSleepIfNeededLocked();
}
}
}
@@ -4376,7 +4376,7 @@
}
display.mAllSleepTokens.clear();
- mService.mAm.updateSleepIfNeededLocked();
+ mService.updateSleepIfNeededLocked();
}
private StackInfo getStackInfo(ActivityStack stack) {
@@ -4673,7 +4673,7 @@
} break;
case SLEEP_TIMEOUT_MSG: {
synchronized (mService.mGlobalLock) {
- if (mService.mAm.isSleepingOrShuttingDownLocked()) {
+ if (mService.isSleepingOrShuttingDownLocked()) {
Slog.w(TAG, "Sleep timeout! Sleeping now.");
checkReadyForSleepLocked(false /* allowDelay */);
}
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index dac7715..d59a651 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -826,7 +826,7 @@
ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid,
callingUid,
- callingPackage, intent, resolvedType, aInfo, mService.mAm.getGlobalConfiguration(),
+ callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(),
resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null,
mSupervisor, checkedOptions, sourceRecord);
if (outActivity != null) {
@@ -1015,7 +1015,7 @@
synchronized (mService.mGlobalLock) {
final ActivityStack stack = mSupervisor.mFocusedStack;
stack.mConfigWillChange = globalConfig != null
- && mService.mAm.getGlobalConfiguration().diff(globalConfig) != 0;
+ && mService.getGlobalConfiguration().diff(globalConfig) != 0;
if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
"Starting activity when config will change = " + stack.mConfigWillChange);
diff --git a/services/core/java/com/android/server/am/ActivityTaskManagerService.java b/services/core/java/com/android/server/am/ActivityTaskManagerService.java
index d47fb44..50d0212 100644
--- a/services/core/java/com/android/server/am/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityTaskManagerService.java
@@ -26,7 +26,12 @@
import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
import static android.Manifest.permission.STOP_APP_SWITCHES;
import static android.app.ActivityManager.LOCK_TASK_MODE_NONE;
+import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
+import static android.provider.Settings.Global.HIDE_ERROR_DIALOGS;
+import static android.provider.Settings.System.FONT_SCALE;
import static com.android.server.am.ActivityManagerService.dumpStackTraces;
+import static com.android.server.am.ActivityTaskManagerService.H.REPORT_TIME_TRACKER_MSG;
+import static com.android.server.am.ActivityTaskManagerService.UiHandler.DISMISS_DIALOG_UI_MSG;
import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_CONTENT;
import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_DATA;
import static com.android.server.wm.ActivityTaskManagerInternal.ASSIST_KEY_RECEIVER_EXTRAS;
@@ -113,6 +118,23 @@
import android.app.ActivityManagerInternal;
import android.app.ActivityOptions;
import android.app.ActivityTaskManager;
+import android.app.ActivityThread;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.DialogInterface;
+import android.database.ContentObserver;
+import android.os.IUserManager;
+import android.os.PowerManager;
+import android.os.ServiceManager;
+import android.os.Trace;
+import android.os.UserManager;
+import android.os.WorkSource;
+import android.view.WindowManager;
+import com.android.internal.R;
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.app.IAppOpsService;
+import com.android.server.AppOpsService;
+import com.android.server.pm.UserManagerService;
import com.android.server.wm.ActivityTaskManagerInternal;
import android.app.AppGlobals;
import android.app.IActivityController;
@@ -228,6 +250,11 @@
private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
Context mContext;
+ /**
+ * This Context is themable and meant for UI display (AlertDialogs, etc.). The theme can
+ * change at runtime. Use mContext for non-UI purposes.
+ */
+ final Context mUiContext;
H mH;
UiHandler mUiHandler;
ActivityManagerService mAm;
@@ -236,6 +263,8 @@
Object mGlobalLock;
ActivityStackSupervisor mStackSupervisor;
WindowManagerService mWindowManager;
+ private UserManagerService mUserManager;
+ private AppOpsService mAppOpsService;
/** All processes currently running that might have a window organized by name. */
final ProcessMap<WindowProcessController> mProcessNames = new ProcessMap<>();
/** This is the process holding what we currently consider to be the "home" activity. */
@@ -314,6 +343,9 @@
*/
private Configuration mTempConfig = new Configuration();
+ /** Temporary to avoid allocations. */
+ final StringBuilder mStringBuilder = new StringBuilder(256);
+
// Amount of time after a call to stopAppSwitches() during which we will
// prevent further untrusted switches from happening.
private static final long APP_SWITCH_DELAY_TIME = 5 * 1000;
@@ -322,12 +354,12 @@
* The time at which we will allow normal application switches again,
* after a call to {@link #stopAppSwitches()}.
*/
- long mAppSwitchesAllowedTime;
+ private long mAppSwitchesAllowedTime;
/**
* This is set to true after the first switch after mAppSwitchesAllowedTime
* is set; any switches after that will clear the time.
*/
- boolean mDidAppSwitch;
+ private boolean mDidAppSwitch;
IActivityController mController = null;
boolean mControllerIsAMonkey = false;
@@ -336,7 +368,7 @@
* Used to retain an update lock when the foreground activity is in
* immersive mode.
*/
- final UpdateLock mUpdateLock = new UpdateLock("immersive");
+ private final UpdateLock mUpdateLock = new UpdateLock("immersive");
/**
* Packages that are being allowed to perform unrestricted app switches. Mapping is
@@ -345,9 +377,9 @@
final SparseArray<ArrayMap<String, Integer>> mAllowAppSwitchUids = new SparseArray<>();
/** The dimensions of the thumbnails in the Recents UI. */
- int mThumbnailWidth;
- int mThumbnailHeight;
- float mFullscreenThumbnailScale;
+ private int mThumbnailWidth;
+ private int mThumbnailHeight;
+ private float mFullscreenThumbnailScale;
/**
* Flag that indicates if multi-window is enabled.
@@ -375,8 +407,92 @@
// VR Vr2d Display Id.
int mVr2dDisplayId = INVALID_DISPLAY;
+ /**
+ * Set while we are wanting to sleep, to prevent any
+ * activities from being started/resumed.
+ *
+ * TODO(b/33594039): Clarify the actual state transitions represented by mSleeping.
+ *
+ * Currently mSleeping is set to true when transitioning into the sleep state, and remains true
+ * while in the sleep state until there is a pending transition out of sleep, in which case
+ * mSleeping is set to false, and remains false while awake.
+ *
+ * Whether mSleeping can quickly toggled between true/false without the device actually
+ * display changing states is undefined.
+ */
+ private boolean mSleeping = false;
+
+ /**
+ * The process state used for processes that are running the top activities.
+ * This changes between TOP and TOP_SLEEPING to following mSleeping.
+ */
+ int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
+
+ // Whether we should show our dialogs (ANR, crash, etc) or just perform their default action
+ // automatically. Important for devices without direct input devices.
+ private boolean mShowDialogs = true;
+
+ /** Set if we are shutting down the system, similar to sleeping. */
+ boolean mShuttingDown = false;
+
+ /**
+ * We want to hold a wake lock while running a voice interaction session, since
+ * this may happen with the screen off and we need to keep the CPU running to
+ * be able to continue to interact with the user.
+ */
+ PowerManager.WakeLock mVoiceWakeLock;
+
+ /**
+ * Set while we are running a voice interaction. This overrides sleeping while it is active.
+ */
+ IVoiceInteractionSession mRunningVoice;
+
+ /**
+ * The last resumed activity. This is identical to the current resumed activity most
+ * of the time but could be different when we're pausing one activity before we resume
+ * another activity.
+ */
+ ActivityRecord mLastResumedActivity;
+
+ /**
+ * The activity that is currently being traced as the active resumed activity.
+ *
+ * @see #updateResumedAppTrace
+ */
+ private @Nullable ActivityRecord mTracedResumedActivity;
+
+ /** If non-null, we are tracking the time the user spends in the currently focused app. */
+ AppTimeTracker mCurAppTimeTracker;
+
+ private FontScaleSettingObserver mFontScaleSettingObserver;
+
+ private final class FontScaleSettingObserver extends ContentObserver {
+ private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
+ private final Uri mHideErrorDialogsUri = Settings.Global.getUriFor(HIDE_ERROR_DIALOGS);
+
+ public FontScaleSettingObserver() {
+ super(mH);
+ final ContentResolver resolver = mContext.getContentResolver();
+ resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
+ resolver.registerContentObserver(mHideErrorDialogsUri, false, this,
+ UserHandle.USER_ALL);
+ }
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
+ if (mFontScaleUri.equals(uri)) {
+ updateFontScaleIfNeeded(userId);
+ } else if (mHideErrorDialogsUri.equals(uri)) {
+ synchronized (mGlobalLock) {
+ updateShouldShowDialogsLocked(getGlobalConfiguration());
+ }
+ }
+ }
+ }
+
ActivityTaskManagerService(Context context) {
mContext = context;
+ mUiContext = ActivityThread.currentActivityThread().getSystemUiContext();
mLifecycleManager = new ClientLifecycleManager();
}
@@ -386,6 +502,17 @@
mRecentTasks.onSystemReadyLocked();
}
+ void onInitPowerManagement() {
+ mStackSupervisor.initPowerManagement();
+ final PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
+ mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
+ mVoiceWakeLock.setReferenceCounted(false);
+ }
+
+ void installSystemProviders() {
+ mFontScaleSettingObserver = new FontScaleSettingObserver();
+ }
+
void retrieveSettings(ContentResolver resolver) {
final boolean freeformWindowManagement =
mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
@@ -498,6 +625,26 @@
mLockTaskController.setWindowManager(wm);
}
+ UserManagerService getUserManager() {
+ if (mUserManager == null) {
+ IBinder b = ServiceManager.getService(Context.USER_SERVICE);
+ mUserManager = (UserManagerService) IUserManager.Stub.asInterface(b);
+ }
+ return mUserManager;
+ }
+
+ AppOpsService getAppOpsService() {
+ if (mAppOpsService == null) {
+ IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE);
+ mAppOpsService = (AppOpsService) IAppOpsService.Stub.asInterface(b);
+ }
+ return mAppOpsService;
+ }
+
+ boolean hasUserRestriction(String restriction, int userId) {
+ return getUserManager().hasUserRestriction(restriction, userId);
+ }
+
protected RecentTasks createRecentTasks() {
return new RecentTasks(this, mStackSupervisor);
}
@@ -2979,6 +3126,64 @@
}
}
+ private void onLocalVoiceInteractionStartedLocked(IBinder activity,
+ IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
+ ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
+ if (activityToCallback == null) return;
+ activityToCallback.setVoiceSessionLocked(voiceSession);
+
+ // Inform the activity
+ try {
+ activityToCallback.app.getThread().scheduleLocalVoiceInteractionStarted(activity,
+ voiceInteractor);
+ long token = Binder.clearCallingIdentity();
+ try {
+ startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ // TODO: VI Should we cache the activity so that it's easier to find later
+ // rather than scan through all the stacks and activities?
+ } catch (RemoteException re) {
+ activityToCallback.clearVoiceSessionLocked();
+ // TODO: VI Should this terminate the voice session?
+ }
+ }
+
+ private void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
+ Slog.d(TAG, "<<< startRunningVoiceLocked()");
+ mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
+ if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
+ boolean wasRunningVoice = mRunningVoice != null;
+ mRunningVoice = session;
+ if (!wasRunningVoice) {
+ mVoiceWakeLock.acquire();
+ updateSleepIfNeededLocked();
+ }
+ }
+ }
+
+ void finishRunningVoiceLocked() {
+ if (mRunningVoice != null) {
+ mRunningVoice = null;
+ mVoiceWakeLock.release();
+ updateSleepIfNeededLocked();
+ }
+ }
+
+ @Override
+ public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
+ synchronized (mGlobalLock) {
+ if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
+ if (keepAwake) {
+ mVoiceWakeLock.acquire();
+ } else {
+ mVoiceWakeLock.release();
+ }
+ }
+ }
+ }
+
@Override
public ComponentName getActivityClassForToken(IBinder token) {
synchronized (mGlobalLock) {
@@ -3516,7 +3721,7 @@
if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
throw new SecurityException("Only focused activity can call startVoiceInteraction");
}
- if (mAm.mRunningVoice != null || activity.getTask().voiceSession != null
+ if (mRunningVoice != null || activity.getTask().voiceSession != null
|| activity.voiceSession != null) {
Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
return;
@@ -3720,10 +3925,10 @@
mAmInternal.enforceCallingPermission(
Manifest.permission.INTERACT_ACROSS_USERS_FULL, "getLastResumedActivityUserId()");
synchronized (mGlobalLock) {
- if (mAm.mLastResumedActivity == null) {
+ if (mLastResumedActivity == null) {
return getCurrentUserId();
}
- return mAm.mLastResumedActivity.userId;
+ return mLastResumedActivity.userId;
}
}
@@ -3949,12 +4154,39 @@
|| transit == TRANSIT_TASK_TO_FRONT;
}
- void dumpVrControllerLocked(PrintWriter pw) {
- pw.println(" mVrController=" + mVrController);
+ void dumpSleepStates(PrintWriter pw, boolean testPssMode) {
+ synchronized (mGlobalLock) {
+ pw.println(" mSleepTokens=" + mStackSupervisor.mSleepTokens);
+ if (mRunningVoice != null) {
+ pw.println(" mRunningVoice=" + mRunningVoice);
+ pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
+ }
+ pw.println(" mSleeping=" + mSleeping);
+ pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + testPssMode);
+ pw.println(" mVrController=" + mVrController);
+ }
}
- void writeVrControllerToProto(ProtoOutputStream proto, long fieldId) {
- mVrController.writeToProto(proto, fieldId);
+ void writeSleepStateToProto(ProtoOutputStream proto) {
+ for (ActivityTaskManagerInternal.SleepToken st : mStackSupervisor.mSleepTokens) {
+ proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEP_TOKENS,
+ st.toString());
+ }
+
+ if (mRunningVoice != null) {
+ final long vrToken = proto.start(
+ ActivityManagerServiceDumpProcessesProto.RUNNING_VOICE);
+ proto.write(ActivityManagerServiceDumpProcessesProto.Voice.SESSION,
+ mRunningVoice.toString());
+ mVoiceWakeLock.writeToProto(
+ proto, ActivityManagerServiceDumpProcessesProto.Voice.WAKELOCK);
+ proto.end(vrToken);
+ }
+
+ proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SLEEPING, mSleeping);
+ proto.write(ActivityManagerServiceDumpProcessesProto.SleepStatus.SHUTTING_DOWN,
+ mShuttingDown);
+ mVrController.writeToProto(proto, ActivityManagerServiceDumpProcessesProto.VR_CONTROLLER);
}
int getCurrentUserId() {
@@ -3967,6 +4199,15 @@
}
}
+ public Configuration getConfiguration() {
+ Configuration ci;
+ synchronized(mGlobalLock) {
+ ci = new Configuration(getGlobalConfiguration());
+ ci.userSetLocale = false;
+ }
+ return ci;
+ }
+
/**
* Current global configuration information. Contains general settings for the entire system,
* also corresponds to the merged configuration of the default display.
@@ -4129,7 +4370,7 @@
mTempConfig, mAmInternal.getCurrentUserId());
// TODO: If our config changes, should we auto dismiss any currently showing dialogs?
- mAm.updateShouldShowDialogsLocked(mTempConfig);
+ updateShouldShowDialogsLocked(mTempConfig);
AttributeCache ac = AttributeCache.instance();
if (ac != null) {
@@ -4288,6 +4529,220 @@
return changes;
}
+ private void updateEventDispatchingLocked(boolean booted) {
+ mWindowManager.setEventDispatching(booted && !mShuttingDown);
+ }
+
+ void enableScreenAfterBoot(boolean booted) {
+ EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
+ SystemClock.uptimeMillis());
+ mWindowManager.enableScreenAfterBoot();
+
+ synchronized (mGlobalLock) {
+ updateEventDispatchingLocked(booted);
+ }
+ }
+
+ boolean canShowErrorDialogs() {
+ return mShowDialogs && !mSleeping && !mShuttingDown
+ && !mKeyguardController.isKeyguardOrAodShowing(DEFAULT_DISPLAY)
+ && !hasUserRestriction(UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS,
+ mAm.mUserController.getCurrentUserId())
+ && !(UserManager.isDeviceInDemoMode(mContext)
+ && mAm.mUserController.getCurrentUser().isDemo());
+ }
+
+ /**
+ * Decide based on the configuration whether we should show the ANR,
+ * crash, etc dialogs. The idea is that if there is no affordance to
+ * press the on-screen buttons, or the user experience would be more
+ * greatly impacted than the crash itself, we shouldn't show the dialog.
+ *
+ * A thought: SystemUI might also want to get told about this, the Power
+ * dialog / global actions also might want different behaviors.
+ */
+ private void updateShouldShowDialogsLocked(Configuration config) {
+ final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
+ && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
+ && config.navigation == Configuration.NAVIGATION_NONAV);
+ int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
+ final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
+ && !(modeType == Configuration.UI_MODE_TYPE_WATCH && Build.IS_USER)
+ && modeType != Configuration.UI_MODE_TYPE_TELEVISION
+ && modeType != Configuration.UI_MODE_TYPE_VR_HEADSET);
+ final boolean hideDialogsSet = Settings.Global.getInt(mContext.getContentResolver(),
+ HIDE_ERROR_DIALOGS, 0) != 0;
+ mShowDialogs = inputMethodExists && uiModeSupportsDialogs && !hideDialogsSet;
+ }
+
+ private void updateFontScaleIfNeeded(@UserIdInt int userId) {
+ final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
+ FONT_SCALE, 1.0f, userId);
+
+ synchronized (this) {
+ if (getGlobalConfiguration().fontScale == scaleFactor) {
+ return;
+ }
+
+ final Configuration configuration
+ = mWindowManager.computeNewConfiguration(DEFAULT_DISPLAY);
+ configuration.fontScale = scaleFactor;
+ updatePersistentConfiguration(configuration, userId);
+ }
+ }
+
+ // Actually is sleeping or shutting down or whatever else in the future
+ // is an inactive state.
+ boolean isSleepingOrShuttingDownLocked() {
+ return isSleepingLocked() || mShuttingDown;
+ }
+
+ boolean isSleepingLocked() {
+ return mSleeping;
+ }
+
+ /**
+ * Update AMS states when an activity is resumed. This should only be called by
+ * {@link ActivityStack#onActivityStateChanged(
+ * ActivityRecord, ActivityStack.ActivityState, String)} when an activity is resumed.
+ */
+ void setResumedActivityUncheckLocked(ActivityRecord r, String reason) {
+ final TaskRecord task = r.getTask();
+ if (task.isActivityTypeStandard()) {
+ if (mCurAppTimeTracker != r.appTimeTracker) {
+ // We are switching app tracking. Complete the current one.
+ if (mCurAppTimeTracker != null) {
+ mCurAppTimeTracker.stop();
+ mH.obtainMessage(
+ REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
+ mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
+ mCurAppTimeTracker = null;
+ }
+ if (r.appTimeTracker != null) {
+ mCurAppTimeTracker = r.appTimeTracker;
+ startTimeTrackingFocusedActivityLocked();
+ }
+ } else {
+ startTimeTrackingFocusedActivityLocked();
+ }
+ } else {
+ r.appTimeTracker = null;
+ }
+ // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
+ // TODO: Probably not, because we don't want to resume voice on switching
+ // back to this activity
+ if (task.voiceInteractor != null) {
+ startRunningVoiceLocked(task.voiceSession, r.info.applicationInfo.uid);
+ } else {
+ finishRunningVoiceLocked();
+
+ if (mLastResumedActivity != null) {
+ final IVoiceInteractionSession session;
+
+ final TaskRecord lastResumedActivityTask = mLastResumedActivity.getTask();
+ if (lastResumedActivityTask != null
+ && lastResumedActivityTask.voiceSession != null) {
+ session = lastResumedActivityTask.voiceSession;
+ } else {
+ session = mLastResumedActivity.voiceSession;
+ }
+
+ if (session != null) {
+ // We had been in a voice interaction session, but now focused has
+ // move to something different. Just finish the session, we can't
+ // return to it and retain the proper state and synchronization with
+ // the voice interaction service.
+ finishVoiceTask(session);
+ }
+ }
+ }
+
+ if (mLastResumedActivity != null && r.userId != mLastResumedActivity.userId) {
+ mAmInternal.sendForegroundProfileChanged(r.userId);
+ }
+ updateResumedAppTrace(r);
+ mLastResumedActivity = r;
+
+ mWindowManager.setFocusedApp(r.appToken, true);
+
+ applyUpdateLockStateLocked(r);
+ applyUpdateVrModeLocked(r);
+
+ EventLogTags.writeAmSetResumedActivity(
+ r == null ? -1 : r.userId,
+ r == null ? "NULL" : r.shortComponentName,
+ reason);
+ }
+
+ ActivityTaskManagerInternal.SleepToken acquireSleepToken(String tag, int displayId) {
+ synchronized (mGlobalLock) {
+ final ActivityTaskManagerInternal.SleepToken token = mStackSupervisor.createSleepTokenLocked(tag, displayId);
+ updateSleepIfNeededLocked();
+ return token;
+ }
+ }
+
+ void updateSleepIfNeededLocked() {
+ final boolean shouldSleep = !mStackSupervisor.hasAwakeDisplay();
+ final boolean wasSleeping = mSleeping;
+ boolean updateOomAdj = false;
+
+ if (!shouldSleep) {
+ // If wasSleeping is true, we need to wake up activity manager state from when
+ // we started sleeping. In either case, we need to apply the sleep tokens, which
+ // will wake up stacks or put them to sleep as appropriate.
+ if (wasSleeping) {
+ mSleeping = false;
+ startTimeTrackingFocusedActivityLocked();
+ mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
+ mStackSupervisor.comeOutOfSleepIfNeededLocked();
+ }
+ mStackSupervisor.applySleepTokensLocked(true /* applyToStacks */);
+ if (wasSleeping) {
+ updateOomAdj = true;
+ }
+ } else if (!mSleeping && shouldSleep) {
+ mSleeping = true;
+ if (mCurAppTimeTracker != null) {
+ mCurAppTimeTracker.stop();
+ }
+ mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
+ mStackSupervisor.goingToSleepLocked();
+ updateResumedAppTrace(null /* resumed */);
+ updateOomAdj = true;
+ }
+ if (updateOomAdj) {
+ mH.post(mAmInternal::updateOomAdj);
+ }
+ }
+
+ void updateOomAdj() {
+ mH.post(mAmInternal::updateOomAdj);
+ }
+
+ private void startTimeTrackingFocusedActivityLocked() {
+ final ActivityRecord resumedActivity = mStackSupervisor.getResumedActivityLocked();
+ if (!mSleeping && mCurAppTimeTracker != null && resumedActivity != null) {
+ mCurAppTimeTracker.start(resumedActivity.packageName);
+ }
+ }
+
+ private void updateResumedAppTrace(@Nullable ActivityRecord resumed) {
+ if (mTracedResumedActivity != null) {
+ Trace.asyncTraceEnd(TRACE_TAG_ACTIVITY_MANAGER,
+ constructResumedTraceName(mTracedResumedActivity.packageName), 0);
+ }
+ if (resumed != null) {
+ Trace.asyncTraceBegin(TRACE_TAG_ACTIVITY_MANAGER,
+ constructResumedTraceName(resumed.packageName), 0);
+ }
+ mTracedResumedActivity = resumed;
+ }
+
+ private String constructResumedTraceName(String packageName) {
+ return "focused app: " + packageName;
+ }
+
/** Helper method that requests bounds from WM and applies them to stack. */
private void resizeStackWithBoundsFromWindowManager(int stackId, boolean deferResume) {
final Rect newStackBounds = new Rect();
@@ -4396,23 +4851,47 @@
}
final class H extends Handler {
+ static final int REPORT_TIME_TRACKER_MSG = 1;
+
public H(Looper looper) {
super(looper, null, true);
}
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case REPORT_TIME_TRACKER_MSG: {
+ AppTimeTracker tracker = (AppTimeTracker) msg.obj;
+ tracker.deliverResult(mContext);
+ } break;
+ }
+ }
}
final class UiHandler extends Handler {
+ static final int DISMISS_DIALOG_UI_MSG = 1;
public UiHandler() {
super(com.android.server.UiThread.get().getLooper(), null, true);
}
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case DISMISS_DIALOG_UI_MSG: {
+ final Dialog d = (Dialog) msg.obj;
+ d.dismiss();
+ break;
+ }
+ }
+ }
}
final class LocalService extends ActivityTaskManagerInternal {
@Override
public SleepToken acquireSleepToken(String tag, int displayId) {
Preconditions.checkNotNull(tag);
- return mAm.acquireSleepToken(tag, displayId);
+ return ActivityTaskManagerService.this.acquireSleepToken(tag, displayId);
}
@Override
@@ -4427,7 +4906,7 @@
public void onLocalVoiceInteractionStarted(IBinder activity,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
synchronized (mGlobalLock) {
- mAm.onLocalVoiceInteractionStartedLocked(activity, voiceSession, voiceInteractor);
+ onLocalVoiceInteractionStartedLocked(activity, voiceSession, voiceInteractor);
}
}
@@ -4669,5 +5148,96 @@
}
}
}
+
+ @Override
+ public int getTopProcessState() {
+ synchronized (mGlobalLock) {
+ return mTopProcessState;
+ }
+ }
+
+ @Override
+ public boolean isSleeping() {
+ synchronized (mGlobalLock) {
+ return isSleepingLocked();
+ }
+ }
+
+ @Override
+ public boolean isShuttingDown() {
+ synchronized (mGlobalLock) {
+ return mShuttingDown;
+ }
+ }
+
+ @Override
+ public boolean shuttingDown(boolean booted, int timeout) {
+ synchronized (mGlobalLock) {
+ mShuttingDown = true;
+ mStackSupervisor.prepareForShutdownLocked();
+ updateEventDispatchingLocked(booted);
+ return mStackSupervisor.shutdownLocked(timeout);
+ }
+ }
+
+ @Override
+ public void enableScreenAfterBoot(boolean booted) {
+ synchronized (mGlobalLock) {
+ EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
+ SystemClock.uptimeMillis());
+ mWindowManager.enableScreenAfterBoot();
+ updateEventDispatchingLocked(booted);
+ }
+ }
+
+ @Override
+ public boolean showStrictModeViolationDialog() {
+ synchronized (mGlobalLock) {
+ return mShowDialogs && !mSleeping && !mShuttingDown;
+ }
+ }
+
+ @Override
+ public void showSystemReadyErrorDialogsIfNeeded() {
+ synchronized (mGlobalLock) {
+ try {
+ if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
+ Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
+ + " data partition or your device will be unstable.");
+ mUiHandler.post(() -> {
+ if (mShowDialogs) {
+ AlertDialog d = new BaseErrorDialog(mUiContext);
+ d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
+ d.setCancelable(false);
+ d.setTitle(mUiContext.getText(R.string.android_system_label));
+ d.setMessage(mUiContext.getText(R.string.system_error_wipe_data));
+ d.setButton(DialogInterface.BUTTON_POSITIVE,
+ mUiContext.getText(R.string.ok),
+ mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
+ d.show();
+ }
+ });
+ }
+ } catch (RemoteException e) {
+ }
+
+ if (!Build.isBuildConsistent()) {
+ Slog.e(TAG, "Build fingerprint is not consistent, warning user");
+ mUiHandler.post(() -> {
+ if (mShowDialogs) {
+ AlertDialog d = new BaseErrorDialog(mUiContext);
+ d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
+ d.setCancelable(false);
+ d.setTitle(mUiContext.getText(R.string.android_system_label));
+ d.setMessage(mUiContext.getText(R.string.system_error_manufacturer));
+ d.setButton(DialogInterface.BUTTON_POSITIVE,
+ mUiContext.getText(R.string.ok),
+ mUiHandler.obtainMessage(DISMISS_DIALOG_UI_MSG, d));
+ d.show();
+ }
+ });
+ }
+ }
+ }
}
}
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index 7db98b3..27567a7 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -824,7 +824,8 @@
mService.mUserController.getCurrentUserId()) != 0;
final boolean crashSilenced = mAppsNotReportingCrashes != null &&
mAppsNotReportingCrashes.contains(proc.info.packageName);
- if ((mService.canShowErrorDialogs() || showBackground) && !crashSilenced
+ if ((mService.mActivityTaskManager.canShowErrorDialogs() || showBackground)
+ && !crashSilenced
&& (showFirstCrash || showFirstCrashDevOption || data.repeating)) {
proc.crashDialog = dialogToShow = new AppErrorDialog(mContext, mService, data);
} else {
@@ -901,7 +902,7 @@
synchronized (mService) {
// PowerManager.reboot() can block for a long time, so ignore ANRs while shutting down.
- if (mService.mShuttingDown) {
+ if (mService.mActivityTaskManager.mShuttingDown) {
Slog.i(TAG, "During shutdown skipping ANR: " + app + " " + annotation);
return;
} else if (app.isNotResponding()) {
@@ -1122,7 +1123,7 @@
boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(),
Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0;
- if (mService.canShowErrorDialogs() || showBackground) {
+ if (mService.mActivityTaskManager.canShowErrorDialogs() || showBackground) {
dialogToShow = new AppNotRespondingDialog(mService, mContext, data);
proc.anrDialog = dialogToShow;
} else {
diff --git a/services/core/java/com/android/server/am/KeyguardController.java b/services/core/java/com/android/server/am/KeyguardController.java
index 657e0eb..efde70d 100644
--- a/services/core/java/com/android/server/am/KeyguardController.java
+++ b/services/core/java/com/android/server/am/KeyguardController.java
@@ -58,7 +58,7 @@
private static final String TAG = TAG_WITH_CLASS_NAME ? "KeyguardController" : TAG_AM;
- private final ActivityManagerService mService;
+ private final ActivityTaskManagerService mService;
private final ActivityStackSupervisor mStackSupervisor;
private WindowManagerService mWindowManager;
private boolean mKeyguardShowing;
@@ -72,7 +72,7 @@
private SleepToken mSleepToken;
private int mSecondaryDisplayShowing = INVALID_DISPLAY;
- KeyguardController(ActivityManagerService service,
+ KeyguardController(ActivityTaskManagerService service,
ActivityStackSupervisor stackSupervisor) {
mService = service;
mStackSupervisor = stackSupervisor;
diff --git a/services/core/java/com/android/server/am/SafeActivityOptions.java b/services/core/java/com/android/server/am/SafeActivityOptions.java
index fef3b86..f7de7f4 100644
--- a/services/core/java/com/android/server/am/SafeActivityOptions.java
+++ b/services/core/java/com/android/server/am/SafeActivityOptions.java
@@ -230,7 +230,7 @@
// Check permission for remote animations
final RemoteAnimationAdapter adapter = options.getRemoteAnimationAdapter();
- if (adapter != null && supervisor.mService.mAm.checkPermission(
+ if (adapter != null && supervisor.mService.checkPermission(
CONTROL_REMOTE_APP_TRANSITION_ANIMATIONS, callingPid, callingUid)
!= PERMISSION_GRANTED) {
final String msg = "Permission Denial: starting " + getIntentString(intent)
diff --git a/services/core/java/com/android/server/biometrics/face/FaceService.java b/services/core/java/com/android/server/biometrics/face/FaceService.java
index d2a29e4..35679a88 100644
--- a/services/core/java/com/android/server/biometrics/face/FaceService.java
+++ b/services/core/java/com/android/server/biometrics/face/FaceService.java
@@ -541,7 +541,7 @@
@Override
protected boolean hasReachedEnrollmentLimit(int userId) {
final int limit = getContext().getResources().getInteger(
- com.android.internal.R.integer.config_face_MaxTemplatesPerUser);
+ com.android.internal.R.integer.config_faceMaxTemplatesPerUser);
final int enrolled = FaceService.this.getEnrolledFaces(userId).size();
if (enrolled >= limit) {
Slog.w(TAG, "Too many faces registered");
diff --git a/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java b/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java
index fbee86a..9e6b659 100644
--- a/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java
+++ b/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java
@@ -379,7 +379,7 @@
// that adding routes that already exist does not cause an
// error (EEXIST is silently ignored).
mNMService.addInterfaceToLocalNetwork(mIfaceName, toBeAdded);
- } catch (RemoteException e) {
+ } catch (Exception e) {
mLog.e("Failed to add IPv6 routes to local table: " + e);
}
diff --git a/services/core/java/com/android/server/notification/GroupHelper.java b/services/core/java/com/android/server/notification/GroupHelper.java
index ce805aad..b1cd627 100644
--- a/services/core/java/com/android/server/notification/GroupHelper.java
+++ b/services/core/java/com/android/server/notification/GroupHelper.java
@@ -32,16 +32,17 @@
private static final String TAG = "GroupHelper";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
- protected static final int AUTOGROUP_AT_COUNT = 4;
protected static final String AUTOGROUP_KEY = "ranker_group";
private final Callback mCallback;
+ private final int mAutoGroupAtCount;
// Map of user : <Map of package : notification keys>. Only contains notifications that are not
// grouped by the app (aka no group or sort key).
Map<Integer, Map<String, LinkedHashSet<String>>> mUngroupedNotifications = new HashMap<>();
- public GroupHelper(Callback callback) {;
+ public GroupHelper(int autoGroupAtCount, Callback callback) {
+ mAutoGroupAtCount = autoGroupAtCount;
mCallback = callback;
}
@@ -68,7 +69,7 @@
notificationsForPackage.add(sbn.getKey());
ungroupedNotificationsByUser.put(sbn.getPackageName(), notificationsForPackage);
- if (notificationsForPackage.size() >= AUTOGROUP_AT_COUNT
+ if (notificationsForPackage.size() >= mAutoGroupAtCount
|| autogroupSummaryExists) {
notificationsToGroup.addAll(notificationsForPackage);
}
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 6402b7b..88edc95 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -400,6 +400,7 @@
private SnoozeHelper mSnoozeHelper;
private GroupHelper mGroupHelper;
+ private int mAutoGroupAtCount;
private boolean mIsTelevision;
private MetricsLogger mMetricsLogger;
@@ -1565,7 +1566,9 @@
}
private GroupHelper getGroupHelper() {
- return new GroupHelper(new GroupHelper.Callback() {
+ mAutoGroupAtCount =
+ getContext().getResources().getInteger(R.integer.config_autoGroupAtCount);
+ return new GroupHelper(mAutoGroupAtCount, new GroupHelper.Callback() {
@Override
public void addAutoGroup(String key) {
synchronized (mNotificationLock) {
@@ -4976,27 +4979,31 @@
}
protected void playInCallNotification() {
- new Thread() {
- @Override
- public void run() {
- final long identity = Binder.clearCallingIdentity();
- try {
- final IRingtonePlayer player = mAudioManager.getRingtonePlayer();
- if (player != null) {
- if (mCallNotificationToken != null) {
- player.stop(mCallNotificationToken);
+ if (mAudioManager.getRingerModeInternal() == AudioManager.RINGER_MODE_NORMAL
+ && Settings.Secure.getInt(getContext().getContentResolver(),
+ Settings.Secure.IN_CALL_NOTIFICATION_ENABLED, 1) != 0) {
+ new Thread() {
+ @Override
+ public void run() {
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ final IRingtonePlayer player = mAudioManager.getRingtonePlayer();
+ if (player != null) {
+ if (mCallNotificationToken != null) {
+ player.stop(mCallNotificationToken);
+ }
+ mCallNotificationToken = new Binder();
+ player.play(mCallNotificationToken, mInCallNotificationUri,
+ mInCallNotificationAudioAttributes,
+ mInCallNotificationVolume, false);
}
- mCallNotificationToken = new Binder();
- player.play(mCallNotificationToken, mInCallNotificationUri,
- mInCallNotificationAudioAttributes,
- mInCallNotificationVolume, false);
+ } catch (RemoteException e) {
+ } finally {
+ Binder.restoreCallingIdentity(identity);
}
- } catch (RemoteException e) {
- } finally {
- Binder.restoreCallingIdentity(identity);
}
- }
- }.start();
+ }.start();
+ }
}
@GuardedBy("mToastQueue")
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java
index f0807b9..72f11f7 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -34,6 +34,7 @@
import com.android.internal.os.BackgroundThread;
import com.android.server.SystemService;
+import dalvik.system.BlockGuard;
import dalvik.system.VMRuntime;
import java.io.FileDescriptor;
@@ -239,6 +240,11 @@
long[] ceDataInodes, String[] codePaths, PackageStats stats)
throws InstallerException {
if (!checkBeforeRemote()) return;
+ if (codePaths != null) {
+ for (String codePath : codePaths) {
+ BlockGuard.getVmPolicy().onPathAccess(codePath);
+ }
+ }
try {
final long[] res = mInstalld.getAppSize(uuid, packageNames, userId, flags,
appId, ceDataInodes, codePaths);
@@ -296,6 +302,9 @@
@Nullable String profileName, @Nullable String dexMetadataPath,
@Nullable String compilationReason) throws InstallerException {
assertValidInstructionSet(instructionSet);
+ BlockGuard.getVmPolicy().onPathAccess(apkPath);
+ BlockGuard.getVmPolicy().onPathAccess(outputPath);
+ BlockGuard.getVmPolicy().onPathAccess(dexMetadataPath);
if (!checkBeforeRemote()) return;
try {
mInstalld.dexopt(apkPath, uid, pkgName, instructionSet, dexoptNeeded, outputPath,
@@ -319,6 +328,7 @@
public boolean dumpProfiles(int uid, String packageName, String profileName, String codePath)
throws InstallerException {
if (!checkBeforeRemote()) return false;
+ BlockGuard.getVmPolicy().onPathAccess(codePath);
try {
return mInstalld.dumpProfiles(uid, packageName, profileName, codePath);
} catch (Exception e) {
@@ -339,6 +349,8 @@
public void idmap(String targetApkPath, String overlayApkPath, int uid)
throws InstallerException {
if (!checkBeforeRemote()) return;
+ BlockGuard.getVmPolicy().onPathAccess(targetApkPath);
+ BlockGuard.getVmPolicy().onPathAccess(overlayApkPath);
try {
mInstalld.idmap(targetApkPath, overlayApkPath, uid);
} catch (Exception e) {
@@ -348,6 +360,7 @@
public void removeIdmap(String overlayApkPath) throws InstallerException {
if (!checkBeforeRemote()) return;
+ BlockGuard.getVmPolicy().onPathAccess(overlayApkPath);
try {
mInstalld.removeIdmap(overlayApkPath);
} catch (Exception e) {
@@ -358,6 +371,7 @@
public void rmdex(String codePath, String instructionSet) throws InstallerException {
assertValidInstructionSet(instructionSet);
if (!checkBeforeRemote()) return;
+ BlockGuard.getVmPolicy().onPathAccess(codePath);
try {
mInstalld.rmdex(codePath, instructionSet);
} catch (Exception e) {
@@ -367,6 +381,7 @@
public void rmPackageDir(String packageDir) throws InstallerException {
if (!checkBeforeRemote()) return;
+ BlockGuard.getVmPolicy().onPathAccess(packageDir);
try {
mInstalld.rmPackageDir(packageDir);
} catch (Exception e) {
@@ -439,6 +454,7 @@
public void linkNativeLibraryDirectory(String uuid, String packageName, String nativeLibPath32,
int userId) throws InstallerException {
if (!checkBeforeRemote()) return;
+ BlockGuard.getVmPolicy().onPathAccess(nativeLibPath32);
try {
mInstalld.linkNativeLibraryDirectory(uuid, packageName, nativeLibPath32, userId);
} catch (Exception e) {
@@ -459,6 +475,8 @@
public void linkFile(String relativePath, String fromBase, String toBase)
throws InstallerException {
if (!checkBeforeRemote()) return;
+ BlockGuard.getVmPolicy().onPathAccess(fromBase);
+ BlockGuard.getVmPolicy().onPathAccess(toBase);
try {
mInstalld.linkFile(relativePath, fromBase, toBase);
} catch (Exception e) {
@@ -469,6 +487,8 @@
public void moveAb(String apkPath, String instructionSet, String outputPath)
throws InstallerException {
if (!checkBeforeRemote()) return;
+ BlockGuard.getVmPolicy().onPathAccess(apkPath);
+ BlockGuard.getVmPolicy().onPathAccess(outputPath);
try {
mInstalld.moveAb(apkPath, instructionSet, outputPath);
} catch (Exception e) {
@@ -479,6 +499,8 @@
public void deleteOdex(String apkPath, String instructionSet, String outputPath)
throws InstallerException {
if (!checkBeforeRemote()) return;
+ BlockGuard.getVmPolicy().onPathAccess(apkPath);
+ BlockGuard.getVmPolicy().onPathAccess(outputPath);
try {
mInstalld.deleteOdex(apkPath, instructionSet, outputPath);
} catch (Exception e) {
@@ -489,6 +511,7 @@
public void installApkVerity(String filePath, FileDescriptor verityInput, int contentSize)
throws InstallerException {
if (!checkBeforeRemote()) return;
+ BlockGuard.getVmPolicy().onPathAccess(filePath);
try {
mInstalld.installApkVerity(filePath, verityInput, contentSize);
} catch (Exception e) {
@@ -499,6 +522,7 @@
public void assertFsverityRootHashMatches(String filePath, @NonNull byte[] expectedHash)
throws InstallerException {
if (!checkBeforeRemote()) return;
+ BlockGuard.getVmPolicy().onPathAccess(filePath);
try {
mInstalld.assertFsverityRootHashMatches(filePath, expectedHash);
} catch (Exception e) {
@@ -512,6 +536,7 @@
assertValidInstructionSet(isas[i]);
}
if (!checkBeforeRemote()) return false;
+ BlockGuard.getVmPolicy().onPathAccess(apkPath);
try {
return mInstalld.reconcileSecondaryDexFile(apkPath, packageName, uid, isas,
volumeUuid, flags);
@@ -523,6 +548,7 @@
public byte[] hashSecondaryDexFile(String dexPath, String packageName, int uid,
@Nullable String volumeUuid, int flags) throws InstallerException {
if (!checkBeforeRemote()) return new byte[0];
+ BlockGuard.getVmPolicy().onPathAccess(dexPath);
try {
return mInstalld.hashSecondaryDexFile(dexPath, packageName, uid, volumeUuid, flags);
} catch (Exception e) {
@@ -571,6 +597,8 @@
public boolean prepareAppProfile(String pkg, @UserIdInt int userId, @AppIdInt int appId,
String profileName, String codePath, String dexMetadataPath) throws InstallerException {
if (!checkBeforeRemote()) return false;
+ BlockGuard.getVmPolicy().onPathAccess(codePath);
+ BlockGuard.getVmPolicy().onPathAccess(dexMetadataPath);
try {
return mInstalld.prepareAppProfile(pkg, userId, appId, profileName, codePath,
dexMetadataPath);
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
index 3885cf9..bfecd9d 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerInternal.java
@@ -266,4 +266,12 @@
public abstract void onProcessAdded(WindowProcessController proc);
public abstract void onProcessRemoved(String name, int uid);
public abstract void onCleanUpApplicationRecord(WindowProcessController proc);
+ public abstract int getTopProcessState();
+
+ public abstract boolean isSleeping();
+ public abstract boolean isShuttingDown();
+ public abstract boolean shuttingDown(boolean booted, int timeout);
+ public abstract void enableScreenAfterBoot(boolean booted);
+ public abstract boolean showStrictModeViolationDialog();
+ public abstract void showSystemReadyErrorDialogsIfNeeded();
}
diff --git a/services/robotests/src/android/app/backup/BackupUtilsTest.java b/services/robotests/src/android/app/backup/BackupUtilsTest.java
new file mode 100644
index 0000000..04a2a14
--- /dev/null
+++ b/services/robotests/src/android/app/backup/BackupUtilsTest.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package android.app.backup;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.app.backup.FullBackup.BackupScheme.PathWithRequiredFlags;
+import android.content.Context;
+import android.platform.test.annotations.Presubmit;
+
+import com.android.server.testing.FrameworkRobolectricTestRunner;
+import com.android.server.testing.SystemLoaderPackages;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.robolectric.RuntimeEnvironment;
+import org.robolectric.annotation.Config;
+import org.robolectric.annotation.internal.DoNotInstrument;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+@RunWith(FrameworkRobolectricTestRunner.class)
+@Config(manifest = Config.NONE, sdk = 26)
+@SystemLoaderPackages({"android.app.backup"})
+@Presubmit
+@DoNotInstrument
+public class BackupUtilsTest {
+ private Context mContext;
+
+ @Before
+ public void setUp() throws Exception {
+ mContext = RuntimeEnvironment.application;
+ }
+
+ @Test
+ public void testIsFileSpecifiedInPathList_whenFileAndPathListHasIt() throws Exception {
+ boolean isSpecified =
+ BackupUtils.isFileSpecifiedInPathList(file("a/b.txt"), paths(file("a/b.txt")));
+
+ assertThat(isSpecified).isTrue();
+ }
+
+ @Test
+ public void testIsFileSpecifiedInPathList_whenFileAndPathListHasItsDirectory()
+ throws Exception {
+ boolean isSpecified =
+ BackupUtils.isFileSpecifiedInPathList(file("a/b.txt"), paths(directory("a")));
+
+ assertThat(isSpecified).isTrue();
+ }
+
+ @Test
+ public void testIsFileSpecifiedInPathList_whenFileAndPathListHasOtherFile() throws Exception {
+ boolean isSpecified =
+ BackupUtils.isFileSpecifiedInPathList(file("a/b.txt"), paths(file("a/c.txt")));
+
+ assertThat(isSpecified).isFalse();
+ }
+
+ @Test
+ public void testIsFileSpecifiedInPathList_whenFileAndPathListEmpty() throws Exception {
+ boolean isSpecified = BackupUtils.isFileSpecifiedInPathList(file("a/b.txt"), paths());
+
+ assertThat(isSpecified).isFalse();
+ }
+
+ @Test
+ public void testIsFileSpecifiedInPathList_whenDirectoryAndPathListHasIt() throws Exception {
+ boolean isSpecified =
+ BackupUtils.isFileSpecifiedInPathList(directory("a"), paths(directory("a")));
+
+ assertThat(isSpecified).isTrue();
+ }
+
+ @Test
+ public void testIsFileSpecifiedInPathList_whenDirectoryAndPathListEmpty() throws Exception {
+ boolean isSpecified = BackupUtils.isFileSpecifiedInPathList(directory("a"), paths());
+
+ assertThat(isSpecified).isFalse();
+ }
+
+ @Test
+ public void testIsFileSpecifiedInPathList_whenDirectoryAndPathListHasParent() throws Exception {
+ boolean isSpecified =
+ BackupUtils.isFileSpecifiedInPathList(directory("a/b"), paths(directory("a")));
+
+ assertThat(isSpecified).isFalse();
+ }
+
+ @Test
+ public void testIsFileSpecifiedInPathList_whenFileAndPathListDoesntContainDirectory()
+ throws Exception {
+ boolean isSpecified =
+ BackupUtils.isFileSpecifiedInPathList(file("a/b.txt"), paths(directory("c")));
+
+ assertThat(isSpecified).isFalse();
+ }
+
+ @Test
+ public void testIsFileSpecifiedInPathList_whenFileAndPathListHasDirectoryWhoseNameIsPrefix()
+ throws Exception {
+ boolean isSpecified =
+ BackupUtils.isFileSpecifiedInPathList(file("a/b.txt"), paths(directory("a/b")));
+
+ assertThat(isSpecified).isFalse();
+ }
+
+ @Test
+ public void testIsFileSpecifiedInPathList_whenFileAndPathListHasDirectoryWhoseNameIsPrefix2()
+ throws Exception {
+ boolean isSpecified =
+ BackupUtils.isFileSpecifiedInPathList(
+ file("name/subname.txt"), paths(directory("nam")));
+
+ assertThat(isSpecified).isFalse();
+ }
+
+ @Test
+ public void
+ testIsFileSpecifiedInPathList_whenFileAndPathListContainsFirstNotRelatedAndSecondContainingDirectory()
+ throws Exception {
+ boolean isSpecified =
+ BackupUtils.isFileSpecifiedInPathList(
+ file("a/b.txt"), paths(directory("b"), directory("a")));
+
+ assertThat(isSpecified).isTrue();
+ }
+
+ @Test
+ public void
+ testIsFileSpecifiedInPathList_whenDirectoryAndPathListContainsFirstNotRelatedAndSecondSameDirectory()
+ throws Exception {
+ boolean isSpecified =
+ BackupUtils.isFileSpecifiedInPathList(
+ directory("a/b"), paths(directory("b"), directory("a/b")));
+
+ assertThat(isSpecified).isTrue();
+ }
+
+ @Test
+ public void
+ testIsFileSpecifiedInPathList_whenFileAndPathListContainsFirstNotRelatedFileAndSecondSameFile()
+ throws Exception {
+ boolean isSpecified =
+ BackupUtils.isFileSpecifiedInPathList(
+ file("a/b.txt"), paths(directory("b"), file("a/b.txt")));
+
+ assertThat(isSpecified).isTrue();
+ }
+
+ private File file(String path) throws IOException {
+ File file = new File(mContext.getDataDir(), path);
+ File parent = file.getParentFile();
+ parent.mkdirs();
+ file.createNewFile();
+ if (!file.isFile()) {
+ throw new IOException("Couldn't create file");
+ }
+ return file;
+ }
+
+ private File directory(String path) throws IOException {
+ File directory = new File(mContext.getDataDir(), path);
+ directory.mkdirs();
+ if (!directory.isDirectory()) {
+ throw new IOException("Couldn't create directory");
+ }
+ return directory;
+ }
+
+ private Collection<PathWithRequiredFlags> paths(File... files) {
+ return Stream.of(files)
+ .map(file -> new PathWithRequiredFlags(file.getPath(), 0))
+ .collect(Collectors.toList());
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
index 1dd7b4c..41c8955 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityTestsBase.java
@@ -126,6 +126,7 @@
void setupActivityManagerService(ActivityManagerService am, ActivityTaskManagerService atm) {
atm.setActivityManagerService(am);
atm.mAmInternal = am.new LocalService();
+ am.mAtmInternal = atm.new LocalService();
// Makes sure the supervisor is using with the spy object.
atm.mStackSupervisor.setService(atm);
doReturn(mock(IPackageManager.class)).when(am).getPackageManager();
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
index 8d4c5b1..84ef0c9 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/GroupHelperTest.java
@@ -50,13 +50,14 @@
public class GroupHelperTest extends UiServiceTestCase {
private @Mock GroupHelper.Callback mCallback;
+ private final static int AUTOGROUP_AT_COUNT = 4;
private GroupHelper mGroupHelper;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- mGroupHelper = new GroupHelper(mCallback);
+ mGroupHelper = new GroupHelper(AUTOGROUP_AT_COUNT, mCallback);
}
private StatusBarNotification getSbn(String pkg, int id, String tag,
@@ -79,7 +80,7 @@
@Test
public void testNoGroup_postingUnderLimit() throws Exception {
final String pkg = "package";
- for (int i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT - 1; i++) {
+ for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
mGroupHelper.onNotificationPosted(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM),
false);
}
@@ -94,12 +95,12 @@
public void testNoGroup_multiPackage() throws Exception {
final String pkg = "package";
final String pkg2 = "package2";
- for (int i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT - 1; i++) {
+ for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
mGroupHelper.onNotificationPosted(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM),
false);
}
mGroupHelper.onNotificationPosted(
- getSbn(pkg2, GroupHelper.AUTOGROUP_AT_COUNT, "four", UserHandle.SYSTEM), false);
+ getSbn(pkg2, AUTOGROUP_AT_COUNT, "four", UserHandle.SYSTEM), false);
verify(mCallback, never()).addAutoGroupSummary(
eq(UserHandle.USER_SYSTEM), eq(pkg), anyString());
verify(mCallback, never()).addAutoGroup(anyString());
@@ -110,13 +111,12 @@
@Test
public void testNoGroup_multiUser() throws Exception {
final String pkg = "package";
- for (int i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT - 1; i++) {
+ for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
mGroupHelper.onNotificationPosted(getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM),
false);
}
mGroupHelper.onNotificationPosted(
- getSbn(pkg, GroupHelper.AUTOGROUP_AT_COUNT, "four", UserHandle.ALL),
- false);
+ getSbn(pkg, AUTOGROUP_AT_COUNT, "four", UserHandle.ALL), false);
verify(mCallback, never()).addAutoGroupSummary(anyInt(), eq(pkg), anyString());
verify(mCallback, never()).addAutoGroup(anyString());
verify(mCallback, never()).removeAutoGroup(anyString());
@@ -126,13 +126,12 @@
@Test
public void testNoGroup_someAreGrouped() throws Exception {
final String pkg = "package";
- for (int i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT - 1; i++) {
+ for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
mGroupHelper.onNotificationPosted(
getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM), false);
}
mGroupHelper.onNotificationPosted(
- getSbn(pkg, GroupHelper.AUTOGROUP_AT_COUNT, "four", UserHandle.SYSTEM, "a"),
- false);
+ getSbn(pkg, AUTOGROUP_AT_COUNT, "four", UserHandle.SYSTEM, "a"), false);
verify(mCallback, never()).addAutoGroupSummary(
eq(UserHandle.USER_SYSTEM), eq(pkg), anyString());
verify(mCallback, never()).addAutoGroup(anyString());
@@ -144,12 +143,12 @@
@Test
public void testPostingOverLimit() throws Exception {
final String pkg = "package";
- for (int i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT; i++) {
+ for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
mGroupHelper.onNotificationPosted(
getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM), false);
}
verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString());
- verify(mCallback, times(GroupHelper.AUTOGROUP_AT_COUNT)).addAutoGroup(anyString());
+ verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString());
verify(mCallback, never()).removeAutoGroup(anyString());
verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
}
@@ -158,18 +157,18 @@
public void testDropToZeroRemoveGroup() throws Exception {
final String pkg = "package";
List<StatusBarNotification> posted = new ArrayList<>();
- for (int i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT; i++) {
+ for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
final StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
posted.add(sbn);
mGroupHelper.onNotificationPosted(sbn, false);
}
verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString());
- verify(mCallback, times(GroupHelper.AUTOGROUP_AT_COUNT)).addAutoGroup(anyString());
+ verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString());
verify(mCallback, never()).removeAutoGroup(anyString());
verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
Mockito.reset(mCallback);
- for (int i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT - 1; i++) {
+ for (int i = 0; i < AUTOGROUP_AT_COUNT - 1; i++) {
mGroupHelper.onNotificationRemoved(posted.remove(0));
}
verify(mCallback, never()).removeAutoGroup(anyString());
@@ -185,28 +184,28 @@
public void testAppStartsGrouping() throws Exception {
final String pkg = "package";
List<StatusBarNotification> posted = new ArrayList<>();
- for (int i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT; i++) {
+ for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
final StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
posted.add(sbn);
mGroupHelper.onNotificationPosted(sbn, false);
}
verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString());
- verify(mCallback, times(GroupHelper.AUTOGROUP_AT_COUNT)).addAutoGroup(anyString());
+ verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString());
verify(mCallback, never()).removeAutoGroup(anyString());
verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
Mockito.reset(mCallback);
int i = 0;
- for (i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT - 2; i++) {
+ for (i = 0; i < AUTOGROUP_AT_COUNT - 2; i++) {
final StatusBarNotification sbn =
getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, "app group");
mGroupHelper.onNotificationPosted(sbn, false);
}
- verify(mCallback, times(GroupHelper.AUTOGROUP_AT_COUNT - 2)).removeAutoGroup(anyString());
+ verify(mCallback, times(AUTOGROUP_AT_COUNT - 2)).removeAutoGroup(anyString());
verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
Mockito.reset(mCallback);
- for (; i < GroupHelper.AUTOGROUP_AT_COUNT; i++) {
+ for (; i < AUTOGROUP_AT_COUNT; i++) {
final StatusBarNotification sbn =
getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM, "app group");
mGroupHelper.onNotificationPosted(sbn, false);
@@ -220,13 +219,13 @@
throws Exception {
final String pkg = "package";
List<StatusBarNotification> posted = new ArrayList<>();
- for (int i = 0; i < GroupHelper.AUTOGROUP_AT_COUNT; i++) {
+ for (int i = 0; i < AUTOGROUP_AT_COUNT; i++) {
final StatusBarNotification sbn = getSbn(pkg, i, String.valueOf(i), UserHandle.SYSTEM);
posted.add(sbn);
mGroupHelper.onNotificationPosted(sbn, false);
}
verify(mCallback, times(1)).addAutoGroupSummary(anyInt(), eq(pkg), anyString());
- verify(mCallback, times(GroupHelper.AUTOGROUP_AT_COUNT)).addAutoGroup(anyString());
+ verify(mCallback, times(AUTOGROUP_AT_COUNT)).addAutoGroup(anyString());
verify(mCallback, never()).removeAutoGroup(anyString());
verify(mCallback, never()).removeAutoGroupSummary(anyInt(), anyString());
Mockito.reset(mCallback);
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index 92aa152..57e9f66 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -244,7 +244,7 @@
Slog.w(TAG, "setKeepAwake does not match active session");
return;
}
- mAm.setVoiceKeepAwake(mActiveSession.mSession, keepAwake);
+ mAtm.setVoiceKeepAwake(mActiveSession.mSession, keepAwake);
} catch (RemoteException e) {
throw new IllegalStateException("Unexpected remote error", e);
}
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index f60332e..cabf444 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -80,6 +80,30 @@
public static final String
KEY_CARRIER_VOLTE_PROVISIONED_BOOL = "carrier_volte_provisioned_bool";
+ /**
+ * Boolean indicating if the "Call forwarding" item is visible in the Call Settings menu.
+ * true means visible. false means gone.
+ * @hide
+ */
+ public static final String KEY_CALL_FORWARDING_VISIBILITY_BOOL =
+ "call_forwarding_visibility_bool";
+
+ /**
+ * Boolean indicating if the "Caller ID" item is visible in the Additional Settings menu.
+ * true means visible. false means gone.
+ * @hide
+ */
+ public static final String KEY_ADDITIONAL_SETTINGS_CALLER_ID_VISIBILITY_BOOL =
+ "additional_settings_caller_id_visibility_bool";
+
+ /**
+ * Boolean indicating if the "Call Waiting" item is visible in the Additional Settings menu.
+ * true means visible. false means gone.
+ * @hide
+ */
+ public static final String KEY_ADDITIONAL_SETTINGS_CALL_WAITING_VISIBILITY_BOOL =
+ "additional_settings_call_waiting_visibility_bool";
+
/**
* Boolean indicating if the "Call barring" item is visible in the Call Settings menu.
* true means visible. false means gone.
@@ -116,6 +140,14 @@
public static final String
KEY_SIM_NETWORK_UNLOCK_ALLOW_DISMISS_BOOL = "sim_network_unlock_allow_dismiss_bool";
+ /**
+ * Flag indicating whether or not sending emergency SMS messages over IMS
+ * is supported when in LTE/limited LTE (Emergency only) service mode..
+ *
+ */
+ public static final String
+ KEY_SUPPORT_EMERGENCY_SMS_OVER_IMS_BOOL = "support_emergency_sms_over_ims_bool";
+
/** Flag indicating if the phone is a world phone */
public static final String KEY_WORLD_PHONE_BOOL = "world_phone_bool";
@@ -1034,6 +1066,26 @@
public static final String KEY_CARRIER_NAME_STRING = "carrier_name_string";
/**
+ * Override the registered PLMN name using #KEY_CDMA_HOME_REGISTERED_PLMN_NAME_STRING.
+ *
+ * If true, then the registered PLMN name (only for CDMA/CDMA-LTE and only when not roaming)
+ * will be #KEY_CDMA_HOME_REGISTERED_PLMN_NAME_STRING. If false, or if phone type is not
+ * CDMA/CDMA-LTE or if roaming, then #KEY_CDMA_HOME_REGISTERED_PLMN_NAME_STRING will be ignored.
+ * @hide
+ */
+ public static final String KEY_CDMA_HOME_REGISTERED_PLMN_NAME_OVERRIDE_BOOL =
+ "cdma_home_registered_plmn_name_override_bool";
+
+ /**
+ * String to identify registered PLMN name in CarrierConfig app. This string overrides
+ * registered PLMN name if #KEY_CDMA_HOME_REGISTERED_PLMN_NAME_OVERRIDE_BOOL is true, phone type
+ * is CDMA/CDMA-LTE and device is not in roaming state; otherwise, it will be ignored.
+ * @hide
+ */
+ public static final String KEY_CDMA_HOME_REGISTERED_PLMN_NAME_STRING =
+ "cdma_home_registered_plmn_name_string";
+
+ /**
* If this is true, the SIM card (through Customer Service Profile EF file) will be able to
* prevent manual operator selection. If false, this SIM setting will be ignored and manual
* operator selection will always be available. See CPHS4_2.WW6, CPHS B.4.7.1 for more
@@ -1548,7 +1600,7 @@
public static final String KEY_EDITABLE_WFC_ROAMING_MODE_BOOL =
"editable_wfc_roaming_mode_bool";
- /**
+ /**
* Determine whether current lpp_mode used for E-911 needs to be kept persistently.
* {@code false} - not keeping the lpp_mode means using default configuration of gps.conf
* when sim is not presented.
@@ -2018,6 +2070,9 @@
sDefaults.putBoolean(KEY_CARRIER_VOLTE_PROVISIONED_BOOL, false);
sDefaults.putBoolean(KEY_CALL_BARRING_VISIBILITY_BOOL, false);
+ sDefaults.putBoolean(KEY_CALL_FORWARDING_VISIBILITY_BOOL, true);
+ sDefaults.putBoolean(KEY_ADDITIONAL_SETTINGS_CALLER_ID_VISIBILITY_BOOL, true);
+ sDefaults.putBoolean(KEY_ADDITIONAL_SETTINGS_CALL_WAITING_VISIBILITY_BOOL, true);
sDefaults.putBoolean(KEY_IGNORE_SIM_NETWORK_LOCKED_EVENTS_BOOL, false);
sDefaults.putBoolean(KEY_MDN_IS_ADDITIONAL_VOICEMAIL_NUMBER_BOOL, false);
sDefaults.putBoolean(KEY_OPERATOR_SELECTION_EXPAND_BOOL, true);
@@ -2025,6 +2080,7 @@
sDefaults.putBoolean(KEY_SHOW_APN_SETTING_CDMA_BOOL, false);
sDefaults.putBoolean(KEY_SHOW_CDMA_CHOICES_BOOL, false);
sDefaults.putBoolean(KEY_SMS_REQUIRES_DESTINATION_NUMBER_CONVERSION_BOOL, false);
+ sDefaults.putBoolean(KEY_SUPPORT_EMERGENCY_SMS_OVER_IMS_BOOL, false);
sDefaults.putBoolean(KEY_SHOW_ONSCREEN_DIAL_BUTTON_BOOL, true);
sDefaults.putBoolean(KEY_SIM_NETWORK_UNLOCK_ALLOW_DISMISS_BOOL, true);
sDefaults.putBoolean(KEY_SUPPORT_PAUSE_IMS_VIDEO_CALLS_BOOL, false);
@@ -2132,6 +2188,8 @@
sDefaults.putBoolean(KEY_CONFIG_WIFI_DISABLE_IN_ECBM, false);
sDefaults.putBoolean(KEY_CARRIER_NAME_OVERRIDE_BOOL, false);
sDefaults.putString(KEY_CARRIER_NAME_STRING, "");
+ sDefaults.putBoolean(KEY_CDMA_HOME_REGISTERED_PLMN_NAME_OVERRIDE_BOOL, false);
+ sDefaults.putString(KEY_CDMA_HOME_REGISTERED_PLMN_NAME_STRING, "");
sDefaults.putBoolean(KEY_SUPPORT_DIRECT_FDN_DIALING_BOOL, false);
sDefaults.putBoolean(KEY_CARRIER_DEFAULT_DATA_ROAMING_ENABLED_BOOL, false);
sDefaults.putBoolean(KEY_SKIP_CF_FAIL_TO_DISABLE_DIALOG_BOOL, false);
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index fa7988d..ae999c3 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -30,6 +30,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
+import java.util.Objects;
/**
* Contains phone state and service related information.
@@ -723,38 +724,40 @@
@Override
public int hashCode() {
- return ((mVoiceRegState * 31)
- + (mDataRegState * 37)
- + mVoiceRoamingType
- + mDataRoamingType
- + mChannelNumber
- + Arrays.hashCode(mCellBandwidths)
- + (mIsManualNetworkSelection ? 1 : 0)
- + ((null == mVoiceOperatorAlphaLong) ? 0 : mVoiceOperatorAlphaLong.hashCode())
- + ((null == mVoiceOperatorAlphaShort) ? 0 : mVoiceOperatorAlphaShort.hashCode())
- + ((null == mVoiceOperatorNumeric) ? 0 : mVoiceOperatorNumeric.hashCode())
- + ((null == mDataOperatorAlphaLong) ? 0 : mDataOperatorAlphaLong.hashCode())
- + ((null == mDataOperatorAlphaShort) ? 0 : mDataOperatorAlphaShort.hashCode())
- + ((null == mDataOperatorNumeric) ? 0 : mDataOperatorNumeric.hashCode())
- + mCdmaRoamingIndicator
- + mCdmaDefaultRoamingIndicator
- + (mIsEmergencyOnly ? 1 : 0)
- + (mIsDataRoamingFromRegistration ? 1 : 0));
+ return Objects.hash(
+ mVoiceRegState,
+ mDataRegState,
+ mVoiceRoamingType,
+ mDataRoamingType,
+ mChannelNumber,
+ mCellBandwidths,
+ mVoiceOperatorAlphaLong,
+ mVoiceOperatorAlphaShort,
+ mVoiceOperatorNumeric,
+ mDataOperatorAlphaLong,
+ mDataOperatorAlphaShort,
+ mDataOperatorNumeric,
+ mIsManualNetworkSelection,
+ mRilVoiceRadioTechnology,
+ mRilDataRadioTechnology,
+ mCssIndicator,
+ mNetworkId,
+ mSystemId,
+ mCdmaRoamingIndicator,
+ mCdmaDefaultRoamingIndicator,
+ mCdmaEriIconIndex,
+ mCdmaEriIconMode,
+ mIsEmergencyOnly,
+ mIsDataRoamingFromRegistration,
+ mIsUsingCarrierAggregation,
+ mLteEarfcnRsrpBoost,
+ mNetworkRegistrationStates);
}
@Override
public boolean equals (Object o) {
- ServiceState s;
-
- try {
- s = (ServiceState) o;
- } catch (ClassCastException ex) {
- return false;
- }
-
- if (o == null) {
- return false;
- }
+ if (!(o instanceof ServiceState)) return false;
+ ServiceState s = (ServiceState) o;
return (mVoiceRegState == s.mVoiceRegState
&& mDataRegState == s.mDataRegState
diff --git a/telephony/java/android/telephony/data/ApnSetting.java b/telephony/java/android/telephony/data/ApnSetting.java
index f875a98..5dc0cff 100644
--- a/telephony/java/android/telephony/data/ApnSetting.java
+++ b/telephony/java/android/telephony/data/ApnSetting.java
@@ -70,7 +70,12 @@
private static final String UNSPECIFIED_STRING = "";
/**
- * All APN types.
+ * APN type for none. Should only be used for initialization.
+ * @hide
+ */
+ public static final int TYPE_NONE = ApnTypes.NONE;
+ /**
+ * APN type for all APNs.
* @hide
*/
public static final int TYPE_ALL = ApnTypes.ALL;
diff --git a/telephony/java/com/android/internal/telephony/DctConstants.java b/telephony/java/com/android/internal/telephony/DctConstants.java
index e546917..86cb1b7 100644
--- a/telephony/java/com/android/internal/telephony/DctConstants.java
+++ b/telephony/java/com/android/internal/telephony/DctConstants.java
@@ -103,19 +103,6 @@
/***** Constants *****/
- public static final int APN_INVALID_ID = -1;
- public static final int APN_DEFAULT_ID = 0;
- public static final int APN_MMS_ID = 1;
- public static final int APN_SUPL_ID = 2;
- public static final int APN_DUN_ID = 3;
- public static final int APN_HIPRI_ID = 4;
- public static final int APN_IMS_ID = 5;
- public static final int APN_FOTA_ID = 6;
- public static final int APN_CBS_ID = 7;
- public static final int APN_IA_ID = 8;
- public static final int APN_EMERGENCY_ID = 9;
- public static final int APN_NUM_TYPES = 10;
-
public static final int INVALID = -1;
public static final int DISABLED = 0;
public static final int ENABLED = 1;