Merge "Complete frontend APIs"
diff --git a/Android.bp b/Android.bp
index 536f688..742a70e5 100644
--- a/Android.bp
+++ b/Android.bp
@@ -833,6 +833,7 @@
name: "dataloader_aidl",
srcs: [
"core/java/android/content/pm/DataLoaderParamsParcel.aidl",
+ "core/java/android/content/pm/DataLoaderType.aidl",
"core/java/android/content/pm/FileSystemControlParcel.aidl",
"core/java/android/content/pm/IDataLoaderStatusListener.aidl",
"core/java/android/content/pm/IPackageInstallerSessionFileSystemConnector.aidl",
diff --git a/api/current.txt b/api/current.txt
index 86aa80b..0d7ce9d 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -3955,6 +3955,7 @@
public class ActivityManager {
method public int addAppTask(@NonNull android.app.Activity, @NonNull android.content.Intent, @Nullable android.app.ActivityManager.TaskDescription, @NonNull android.graphics.Bitmap);
+ method public void appNotResponding(@NonNull String);
method public boolean clearApplicationUserData();
method public void clearWatchHeapLimit();
method @RequiresPermission(android.Manifest.permission.DUMP) public void dumpPackageState(java.io.FileDescriptor, String);
@@ -51681,6 +51682,7 @@
method public boolean isScrollContainer();
method public boolean isScrollbarFadingEnabled();
method @android.view.ViewDebug.ExportedProperty public boolean isSelected();
+ method public final boolean isShowingLayoutBounds();
method public boolean isShown();
method @android.view.ViewDebug.ExportedProperty public boolean isSoundEffectsEnabled();
method public final boolean isTemporarilyDetached();
diff --git a/api/removed.txt b/api/removed.txt
index 8b30d0a..fb6d576 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -435,15 +435,6 @@
field @Deprecated public static final String TIMESTAMP = "timestamp";
}
- public final class MediaStore {
- method @Deprecated @NonNull public static java.util.Set<java.lang.String> getAllVolumeNames(@NonNull android.content.Context);
- method @Deprecated public static boolean getIncludePending(@NonNull android.net.Uri);
- method @Deprecated @NonNull public static android.net.Uri setIncludeTrashed(@NonNull android.net.Uri);
- method @Deprecated public static void trash(@NonNull android.content.Context, @NonNull android.net.Uri);
- method @Deprecated public static void trash(@NonNull android.content.Context, @NonNull android.net.Uri, long);
- method @Deprecated public static void untrash(@NonNull android.content.Context, @NonNull android.net.Uri);
- }
-
public static interface MediaStore.Audio.AudioColumns extends android.provider.MediaStore.MediaColumns {
field public static final String ALBUM = "album";
field public static final String ARTIST = "artist";
diff --git a/api/system-current.txt b/api/system-current.txt
index a551568..c0f8ceb 100755
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -1934,10 +1934,12 @@
}
public class DataLoaderParams {
- ctor public DataLoaderParams(@NonNull String, @NonNull String, @Nullable java.util.Map<java.lang.String,android.os.ParcelFileDescriptor>);
+ method @NonNull public static final android.content.pm.DataLoaderParams forIncremental(@NonNull android.content.ComponentName, @NonNull String, @Nullable java.util.Map<java.lang.String,android.os.ParcelFileDescriptor>);
+ method @NonNull public static final android.content.pm.DataLoaderParams forStreaming(@NonNull android.content.ComponentName, @NonNull String);
+ method @NonNull public final String getArguments();
+ method @NonNull public final android.content.ComponentName getComponentName();
method @NonNull public final java.util.Map<java.lang.String,android.os.ParcelFileDescriptor> getDynamicArgs();
- method @NonNull public final String getPackageName();
- method @NonNull public final String getStaticArgs();
+ method @NonNull public final int getType();
}
public final class InstantAppInfo implements android.os.Parcelable {
@@ -2050,11 +2052,11 @@
public static class PackageInstaller.SessionParams implements android.os.Parcelable {
method @RequiresPermission(android.Manifest.permission.ALLOCATE_AGGRESSIVE) public void setAllocateAggressive(boolean);
method @Deprecated public void setAllowDowngrade(boolean);
+ method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setDataLoaderParams(@NonNull android.content.pm.DataLoaderParams);
method public void setDontKillApp(boolean);
method public void setEnableRollback(boolean);
method public void setEnableRollback(boolean, int);
method @RequiresPermission(android.Manifest.permission.INSTALL_GRANT_RUNTIME_PERMISSIONS) public void setGrantedRuntimePermissions(String[]);
- method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setIncrementalParams(@NonNull android.content.pm.DataLoaderParams);
method @RequiresPermission(android.Manifest.permission.INSTALL_PACKAGES) public void setInstallAsApex();
method public void setInstallAsInstantApp(boolean);
method public void setInstallAsVirtualPreload();
@@ -5392,11 +5394,15 @@
ctor public EasyConnectStatusCallback();
method public abstract void onConfiguratorSuccess(int);
method public abstract void onEnrolleeSuccess(int);
- method public abstract void onFailure(int);
+ method public void onFailure(int);
+ method public void onFailure(int, @Nullable String, @NonNull android.util.SparseArray<int[]>, @NonNull int[]);
method public abstract void onProgress(int);
field public static final int EASY_CONNECT_EVENT_FAILURE_AUTHENTICATION = -2; // 0xfffffffe
field public static final int EASY_CONNECT_EVENT_FAILURE_BUSY = -5; // 0xfffffffb
+ field public static final int EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK = -10; // 0xfffffff6
field public static final int EASY_CONNECT_EVENT_FAILURE_CONFIGURATION = -4; // 0xfffffffc
+ field public static final int EASY_CONNECT_EVENT_FAILURE_ENROLLEE_AUTHENTICATION = -11; // 0xfffffff5
+ field public static final int EASY_CONNECT_EVENT_FAILURE_ENROLLEE_REJECTED_CONFIGURATION = -12; // 0xfffffff4
field public static final int EASY_CONNECT_EVENT_FAILURE_GENERIC = -7; // 0xfffffff9
field public static final int EASY_CONNECT_EVENT_FAILURE_INVALID_NETWORK = -9; // 0xfffffff7
field public static final int EASY_CONNECT_EVENT_FAILURE_INVALID_URI = -1; // 0xffffffff
@@ -5404,7 +5410,10 @@
field public static final int EASY_CONNECT_EVENT_FAILURE_NOT_SUPPORTED = -8; // 0xfffffff8
field public static final int EASY_CONNECT_EVENT_FAILURE_TIMEOUT = -6; // 0xfffffffa
field public static final int EASY_CONNECT_EVENT_PROGRESS_AUTHENTICATION_SUCCESS = 0; // 0x0
+ field public static final int EASY_CONNECT_EVENT_PROGRESS_CONFIGURATION_ACCEPTED = 3; // 0x3
+ field public static final int EASY_CONNECT_EVENT_PROGRESS_CONFIGURATION_SENT_WAITING_RESPONSE = 2; // 0x2
field public static final int EASY_CONNECT_EVENT_PROGRESS_RESPONSE_PENDING = 1; // 0x1
+ field public static final int EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_APPLIED = 1; // 0x1
field public static final int EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_SENT = 0; // 0x0
}
@@ -8972,6 +8981,34 @@
field public static final String CELL_BROADCAST_SERVICE_INTERFACE = "android.telephony.CellBroadcastService";
}
+ public abstract class CellIdentity implements android.os.Parcelable {
+ method @NonNull public abstract android.telephony.CellLocation asCellLocation();
+ }
+
+ public final class CellIdentityCdma extends android.telephony.CellIdentity {
+ method @NonNull public android.telephony.cdma.CdmaCellLocation asCellLocation();
+ }
+
+ public final class CellIdentityGsm extends android.telephony.CellIdentity {
+ method @NonNull public android.telephony.gsm.GsmCellLocation asCellLocation();
+ }
+
+ public final class CellIdentityLte extends android.telephony.CellIdentity {
+ method @NonNull public android.telephony.gsm.GsmCellLocation asCellLocation();
+ }
+
+ public final class CellIdentityNr extends android.telephony.CellIdentity {
+ method @NonNull public android.telephony.CellLocation asCellLocation();
+ }
+
+ public final class CellIdentityTdscdma extends android.telephony.CellIdentity {
+ method @NonNull public android.telephony.gsm.GsmCellLocation asCellLocation();
+ }
+
+ public final class CellIdentityWcdma extends android.telephony.CellIdentity {
+ method @NonNull public android.telephony.gsm.GsmCellLocation asCellLocation();
+ }
+
public final class DataFailCause {
field public static final int ACCESS_ATTEMPT_ALREADY_IN_PROGRESS = 2219; // 0x8ab
field public static final int ACCESS_BLOCK = 2087; // 0x827
@@ -9571,6 +9608,7 @@
}
public final class PreciseCallState implements android.os.Parcelable {
+ ctor public PreciseCallState(int, int, int, int, int);
method public int describeContents();
method public int getBackgroundCallState();
method public int getForegroundCallState();
diff --git a/api/test-current.txt b/api/test-current.txt
index 503941c..08a2160 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -4359,6 +4359,7 @@
method public void setAutofilled(boolean);
method public final void setFocusedInCluster();
method public void setIsRootNamespace(boolean);
+ method public final void setShowingLayoutBounds(boolean);
}
public class ViewConfiguration {
diff --git a/core/java/android/annotation/RequiresPermission.java b/core/java/android/annotation/RequiresPermission.java
index 59d419f..e5c0654 100644
--- a/core/java/android/annotation/RequiresPermission.java
+++ b/core/java/android/annotation/RequiresPermission.java
@@ -15,8 +15,6 @@
*/
package android.annotation;
-import android.content.Intent;
-
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
@@ -57,7 +55,7 @@
* <p>
* When specified on a parameter, the annotation indicates that the method requires
* a permission which depends on the value of the parameter. For example, consider
- * {@link android.app.Activity#startActivity(Intent)}:
+ * {@link android.app.Activity#startActivity(android.content.Intent)}:
* <pre>{@code
* public void startActivity(@RequiresPermission Intent intent) { ... }
* }</pre>
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 68bdfae..3f9f7fb 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -4547,4 +4547,17 @@
throw e.rethrowFromSystemServer();
}
}
+
+ /**
+ * Method for the app to tell system that it's wedged and would like to trigger an ANR.
+ *
+ * @param reason The description of that what happened
+ */
+ public void appNotResponding(@NonNull final String reason) {
+ try {
+ getService().appNotResponding(reason);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
}
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 112bd30..e8494c4 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -583,4 +583,9 @@
* unlockProgressListener can be null if monitoring progress is not necessary.
*/
boolean startUserInForegroundWithListener(int userid, IProgressListener unlockProgressListener);
+
+ /**
+ * Method for the app to tell system that it's wedged and would like to trigger an ANR.
+ */
+ void appNotResponding(String reason);
}
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index c5a147a..7967708 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -11050,6 +11050,7 @@
case ACTION_MEDIA_SCANNER_FINISHED:
case ACTION_MEDIA_SCANNER_SCAN_FILE:
case ACTION_PACKAGE_NEEDS_VERIFICATION:
+ case ACTION_PACKAGE_NEEDS_INTEGRITY_VERIFICATION:
case ACTION_PACKAGE_VERIFIED:
case ACTION_PACKAGE_ENABLE_ROLLBACK:
// Ignore legacy actions
diff --git a/core/java/android/content/pm/DataLoaderParams.java b/core/java/android/content/pm/DataLoaderParams.java
index af4b99a..60d7bb3 100644
--- a/core/java/android/content/pm/DataLoaderParams.java
+++ b/core/java/android/content/pm/DataLoaderParams.java
@@ -19,6 +19,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
+import android.content.ComponentName;
import android.os.ParcelFileDescriptor;
import java.util.Arrays;
@@ -26,7 +27,7 @@
import java.util.stream.Collectors;
/**
- * This class represents the parameters used to configure an Incremental Data Loader.
+ * This class represents the parameters used to configure a Data Loader.
*
* WARNING: This is a system API to aid internal development.
* Use at your own risk. It will change or be removed without warning.
@@ -34,13 +35,41 @@
*/
@SystemApi
public class DataLoaderParams {
- @NonNull private final DataLoaderParamsParcel mData;
+ @NonNull
+ private final DataLoaderParamsParcel mData;
- public DataLoaderParams(@NonNull String url, @NonNull String packageName,
+ /**
+ * Creates and populates set of Data Loader parameters for Streaming installation.
+ *
+ * @param componentName Data Loader component supporting Streaming installation.
+ * @param arguments free form installation arguments
+ */
+ public static final @NonNull DataLoaderParams forStreaming(@NonNull ComponentName componentName,
+ @NonNull String arguments) {
+ return new DataLoaderParams(DataLoaderType.STREAMING, componentName, arguments, null);
+ }
+
+ /**
+ * Creates and populates set of Data Loader parameters for Incremental installation.
+ *
+ * @param componentName Data Loader component supporting Incremental installation.
+ * @param arguments free form installation arguments
+ * @param namedFds TODO(b/146080380) remove
+ */
+ public static final @NonNull DataLoaderParams forIncremental(
+ @NonNull ComponentName componentName, @NonNull String arguments,
@Nullable Map<String, ParcelFileDescriptor> namedFds) {
+ return new DataLoaderParams(DataLoaderType.INCREMENTAL, componentName, arguments, namedFds);
+ }
+
+ /** @hide */
+ public DataLoaderParams(@NonNull @DataLoaderType int type, @NonNull ComponentName componentName,
+ @NonNull String arguments, @Nullable Map<String, ParcelFileDescriptor> namedFds) {
DataLoaderParamsParcel data = new DataLoaderParamsParcel();
- data.staticArgs = url;
- data.packageName = packageName;
+ data.type = type;
+ data.packageName = componentName.getPackageName();
+ data.className = componentName.getClassName();
+ data.arguments = arguments;
if (namedFds == null || namedFds.isEmpty()) {
data.dynamicArgs = new NamedParcelFileDescriptor[0];
} else {
@@ -56,39 +85,42 @@
mData = data;
}
- /**
- * @hide
- */
- public DataLoaderParams(@NonNull DataLoaderParamsParcel data) {
+ /** @hide */
+ DataLoaderParams(@NonNull DataLoaderParamsParcel data) {
mData = data;
}
- /**
- * @return static server's URL
- */
- public final @NonNull String getStaticArgs() {
- return mData.staticArgs;
- }
-
- /**
- * @return data loader's package name
- */
- public final @NonNull String getPackageName() {
- return mData.packageName;
- }
-
- /**
- * @hide
- */
+ /** @hide */
public final @NonNull DataLoaderParamsParcel getData() {
return mData;
}
/**
- * @return data loader's dynamic arguments such as file descriptors
+ * @return data loader type
+ */
+ public final @NonNull @DataLoaderType int getType() {
+ return mData.type;
+ }
+
+ /**
+ * @return data loader's component name
+ */
+ public final @NonNull ComponentName getComponentName() {
+ return new ComponentName(mData.packageName, mData.className);
+ }
+
+ /**
+ * @return data loader's arguments
+ */
+ public final @NonNull String getArguments() {
+ return mData.arguments;
+ }
+
+ /**
+ * @return data loader's dynamic arguments such as file descriptors TODO: remove
*/
public final @NonNull Map<String, ParcelFileDescriptor> getDynamicArgs() {
return Arrays.stream(mData.dynamicArgs).collect(
- Collectors.toMap(p->p.name, p->p.fd));
+ Collectors.toMap(p -> p.name, p -> p.fd));
}
}
diff --git a/core/java/android/content/pm/DataLoaderParamsParcel.aidl b/core/java/android/content/pm/DataLoaderParamsParcel.aidl
index 3316398..e05843b 100644
--- a/core/java/android/content/pm/DataLoaderParamsParcel.aidl
+++ b/core/java/android/content/pm/DataLoaderParamsParcel.aidl
@@ -16,6 +16,7 @@
package android.content.pm;
+import android.content.pm.DataLoaderType;
import android.content.pm.NamedParcelFileDescriptor;
/**
@@ -23,7 +24,9 @@
* @hide
*/
parcelable DataLoaderParamsParcel {
+ DataLoaderType type;
@utf8InCpp String packageName;
- @utf8InCpp String staticArgs;
+ @utf8InCpp String className;
+ @utf8InCpp String arguments;
NamedParcelFileDescriptor[] dynamicArgs;
}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/qualifiers/BgHandler.java b/core/java/android/content/pm/DataLoaderType.aidl
similarity index 60%
copy from packages/SystemUI/src/com/android/systemui/dagger/qualifiers/BgHandler.java
copy to core/java/android/content/pm/DataLoaderType.aidl
index bc6b83b..7d726f5 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/qualifiers/BgHandler.java
+++ b/core/java/android/content/pm/DataLoaderType.aidl
@@ -14,17 +14,24 @@
* limitations under the License.
*/
-package com.android.systemui.dagger.qualifiers;
+package android.content.pm;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-
-import javax.inject.Qualifier;
-
-@Qualifier
-@Documented
-@Retention(RUNTIME)
-public @interface BgHandler {
+/**
+ * Types of Data Loader for an installation session.
+ * @hide
+ */
+@Backing(type="int")
+enum DataLoaderType {
+ /**
+ * Default value, legacy installation.
+ */
+ NONE = 0,
+ /**
+ * Streaming installation using data loader.
+ */
+ STREAMING = 1,
+ /**
+ * Streaming installation using Incremental FileSystem.
+ */
+ INCREMENTAL = 2,
}
diff --git a/core/java/android/content/pm/IDataLoader.aidl b/core/java/android/content/pm/IDataLoader.aidl
index c65bd6a..b5baa93 100644
--- a/core/java/android/content/pm/IDataLoader.aidl
+++ b/core/java/android/content/pm/IDataLoader.aidl
@@ -27,7 +27,9 @@
*/
oneway interface IDataLoader {
void create(int id, in Bundle params, IDataLoaderStatusListener listener);
- void start(in List<InstallationFile> fileInfos);
+ void start();
void stop();
void destroy();
+
+ void prepareImage(in List<InstallationFile> addedFiles, in List<String> removedFiles);
}
diff --git a/core/java/android/content/pm/IDataLoaderStatusListener.aidl b/core/java/android/content/pm/IDataLoaderStatusListener.aidl
index a60d6ee..5011faa 100644
--- a/core/java/android/content/pm/IDataLoaderStatusListener.aidl
+++ b/core/java/android/content/pm/IDataLoaderStatusListener.aidl
@@ -22,13 +22,18 @@
*/
oneway interface IDataLoaderStatusListener {
/** Data loader status */
- const int DATA_LOADER_READY = 0;
- const int DATA_LOADER_NOT_READY = 1;
- const int DATA_LOADER_RUNNING = 2;
+ const int DATA_LOADER_CREATED = 0;
+ const int DATA_LOADER_DESTROYED = 1;
+
+ const int DATA_LOADER_STARTED = 2;
const int DATA_LOADER_STOPPED = 3;
- const int DATA_LOADER_SLOW_CONNECTION = 4;
- const int DATA_LOADER_NO_CONNECTION = 5;
- const int DATA_LOADER_CONNECTION_OK = 6;
+
+ const int DATA_LOADER_IMAGE_READY = 4;
+ const int DATA_LOADER_IMAGE_NOT_READY = 5;
+
+ const int DATA_LOADER_SLOW_CONNECTION = 6;
+ const int DATA_LOADER_NO_CONNECTION = 7;
+ const int DATA_LOADER_CONNECTION_OK = 8;
/** Data loader status callback */
void onStatusChanged(in int dataLoaderId, in int status);
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 3d6d849..e4a0bc0 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -1461,10 +1461,7 @@
/** {@hide} */
public long requiredInstalledVersionCode = PackageManager.VERSION_CODE_HIGHEST;
/** {@hide} */
- public DataLoaderParams incrementalParams;
- /** TODO(b/146080380): add a class name to make it fully compatible with ComponentName.
- * {@hide} */
- public String dataLoaderPackageName;
+ public DataLoaderParams dataLoaderParams;
/** {@hide} */
public int rollbackDataPolicy = PackageManager.RollbackDataPolicy.RESTORE;
@@ -1503,10 +1500,8 @@
DataLoaderParamsParcel dataLoaderParamsParcel = source.readParcelable(
DataLoaderParamsParcel.class.getClassLoader());
if (dataLoaderParamsParcel != null) {
- incrementalParams = new DataLoaderParams(
- dataLoaderParamsParcel);
+ dataLoaderParams = new DataLoaderParams(dataLoaderParamsParcel);
}
- dataLoaderPackageName = source.readString();
rollbackDataPolicy = source.readInt();
}
@@ -1531,8 +1526,7 @@
ret.isMultiPackage = isMultiPackage;
ret.isStaged = isStaged;
ret.requiredInstalledVersionCode = requiredInstalledVersionCode;
- ret.incrementalParams = incrementalParams;
- ret.dataLoaderPackageName = dataLoaderPackageName;
+ ret.dataLoaderParams = dataLoaderParams;
ret.rollbackDataPolicy = rollbackDataPolicy;
return ret;
}
@@ -1893,29 +1887,18 @@
}
/**
- * Set Incremental data loader params.
+ * Set the data loader params for the session.
+ * This also switches installation into data provider mode and disallow direct writes into
+ * staging folder.
+ *
* WARNING: This is a system API to aid internal development.
* Use at your own risk. It will change or be removed without warning.
* {@hide}
*/
@SystemApi
@RequiresPermission(Manifest.permission.INSTALL_PACKAGES)
- public void setIncrementalParams(@NonNull DataLoaderParams incrementalParams) {
- this.incrementalParams = incrementalParams;
- }
-
- /**
- * Set the data provider params for the session.
- * This also switches installation into callback mode and disallow direct writes into
- * staging folder.
- * TODO(b/146080380): unify dataprovider params with Incremental.
- *
- * @param dataLoaderPackageName name of the dataLoader package
- * {@hide}
- */
- @RequiresPermission(Manifest.permission.INSTALL_PACKAGES)
- public void setDataLoaderPackageName(String dataLoaderPackageName) {
- this.dataLoaderPackageName = dataLoaderPackageName;
+ public void setDataLoaderParams(@NonNull DataLoaderParams dataLoaderParams) {
+ this.dataLoaderParams = dataLoaderParams;
}
/** {@hide} */
@@ -1938,7 +1921,7 @@
pw.printPair("isMultiPackage", isMultiPackage);
pw.printPair("isStaged", isStaged);
pw.printPair("requiredInstalledVersionCode", requiredInstalledVersionCode);
- pw.printPair("dataLoaderPackageName", dataLoaderPackageName);
+ pw.printPair("dataLoaderParams", dataLoaderParams);
pw.printPair("rollbackDataPolicy", rollbackDataPolicy);
pw.println();
}
@@ -1969,12 +1952,11 @@
dest.writeBoolean(isMultiPackage);
dest.writeBoolean(isStaged);
dest.writeLong(requiredInstalledVersionCode);
- if (incrementalParams != null) {
- dest.writeParcelable(incrementalParams.getData(), flags);
+ if (dataLoaderParams != null) {
+ dest.writeParcelable(dataLoaderParams.getData(), flags);
} else {
dest.writeParcelable(null, flags);
}
- dest.writeString(dataLoaderPackageName);
dest.writeInt(rollbackDataPolicy);
}
diff --git a/core/java/android/os/incremental/IncrementalFileStorages.java b/core/java/android/os/incremental/IncrementalFileStorages.java
index fb94fc9..2138d553 100644
--- a/core/java/android/os/incremental/IncrementalFileStorages.java
+++ b/core/java/android/os/incremental/IncrementalFileStorages.java
@@ -87,8 +87,8 @@
mPackageName = packageName;
mStageDir = stageDir;
mIncrementalManager = incrementalManager;
- if (dataLoaderParams.getPackageName().equals("local")) {
- final String incrementalPath = dataLoaderParams.getStaticArgs();
+ if (dataLoaderParams.getComponentName().getPackageName().equals("local")) {
+ final String incrementalPath = dataLoaderParams.getArguments();
mDefaultStorage = mIncrementalManager.openStorage(incrementalPath);
mDefaultDir = incrementalPath;
return;
diff --git a/core/java/android/service/dataloader/DataLoaderService.java b/core/java/android/service/dataloader/DataLoaderService.java
index 54a4fa6..75f252e 100644
--- a/core/java/android/service/dataloader/DataLoaderService.java
+++ b/core/java/android/service/dataloader/DataLoaderService.java
@@ -16,7 +16,6 @@
package android.service.dataloader;
-import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
@@ -27,19 +26,16 @@
import android.content.pm.FileSystemControlParcel;
import android.content.pm.IDataLoader;
import android.content.pm.IDataLoaderStatusListener;
-import android.content.pm.IPackageInstallerSessionFileSystemConnector;
import android.content.pm.InstallationFile;
import android.content.pm.NamedParcelFileDescriptor;
import android.os.Bundle;
import android.os.IBinder;
import android.os.ParcelFileDescriptor;
-import android.os.RemoteException;
import android.util.ExceptionUtils;
import android.util.Slog;
import java.io.IOException;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
+import java.util.Collection;
import java.util.List;
/**
@@ -55,88 +51,35 @@
*/
@SystemApi
public abstract class DataLoaderService extends Service {
- private static final String TAG = "IncrementalDataLoaderService";
+ private static final String TAG = "DataLoaderService";
private final DataLoaderBinderService mBinder = new DataLoaderBinderService();
- /** @hide */
- public static final int DATA_LOADER_READY =
- IDataLoaderStatusListener.DATA_LOADER_READY;
- /** @hide */
- public static final int DATA_LOADER_NOT_READY =
- IDataLoaderStatusListener.DATA_LOADER_NOT_READY;
- /** @hide */
- public static final int DATA_LOADER_RUNNING =
- IDataLoaderStatusListener.DATA_LOADER_RUNNING;
- /** @hide */
- public static final int DATA_LOADER_STOPPED =
- IDataLoaderStatusListener.DATA_LOADER_STOPPED;
- /** @hide */
- public static final int DATA_LOADER_SLOW_CONNECTION =
- IDataLoaderStatusListener.DATA_LOADER_SLOW_CONNECTION;
- /** @hide */
- public static final int DATA_LOADER_NO_CONNECTION =
- IDataLoaderStatusListener.DATA_LOADER_NO_CONNECTION;
- /** @hide */
- public static final int DATA_LOADER_CONNECTION_OK =
- IDataLoaderStatusListener.DATA_LOADER_CONNECTION_OK;
-
- /** @hide */
- @Retention(RetentionPolicy.SOURCE)
- @IntDef(prefix = {"DATA_LOADER_"}, value = {
- DATA_LOADER_READY,
- DATA_LOADER_NOT_READY,
- DATA_LOADER_RUNNING,
- DATA_LOADER_STOPPED,
- DATA_LOADER_SLOW_CONNECTION,
- DATA_LOADER_NO_CONNECTION,
- DATA_LOADER_CONNECTION_OK
- })
- public @interface DataLoaderStatus {
- }
-
/**
- * Managed DataLoader interface. Each instance corresponds to a single Incremental File System
- * instance.
+ * Managed DataLoader interface. Each instance corresponds to a single installation session.
* @hide
*/
- public abstract static class DataLoader {
+ public interface DataLoader {
/**
- * A virtual constructor used to do simple initialization. Not ready to serve any data yet.
- * All heavy-lifting has to be done in onStart.
+ * A virtual constructor.
*
- * @param params Data loader configuration parameters.
- * @param connector IncFS API wrapper.
- * @param listener Used for reporting internal state to IncrementalService.
+ * @param dataLoaderParams parameters set in the installation session
+ * @param connector FS API wrapper
* @return True if initialization of a Data Loader was successful. False will be reported to
- * IncrementalService and can cause an unmount of an IFS instance.
+ * PackageManager and fail the installation
*/
- public abstract boolean onCreate(@NonNull DataLoaderParams params,
- @NonNull FileSystemConnector connector,
- @NonNull StatusListener listener);
+ boolean onCreate(@NonNull DataLoaderParams dataLoaderParams,
+ @NonNull FileSystemConnector connector);
/**
- * Start the data loader. After this method returns data loader is considered to be ready to
- * receive callbacks from IFS, supply data via connector and send status updates via
- * callbacks.
+ * Prepare installation image. After this method succeeds installer will validate the files
+ * and continue installation.
*
- * @return True if Data Loader was able to start. False will be reported to
- * IncrementalService and can cause an unmount of an IFS instance.
+ * @param addedFiles list of files created in this installation session.
+ * @param removedFiles list of files removed in this installation session.
+ * @return false if unable to create and populate all addedFiles.
*/
- public abstract boolean onStart();
-
- /**
- * Stop the data loader. Use to stop any additional threads and free up resources. Data
- * loader is not longer responsible for supplying data. Start/Stop pair can be called
- * multiple times e.g. if IFS detects corruption and data needs to be re-loaded.
- */
- public abstract void onStop();
-
- /**
- * Virtual destructor. Use to cleanup all internal state. After this method returns, the
- * data loader can no longer use connector or callbacks. For any additional operations with
- * this instance of IFS a new DataLoader will be created using createDataLoader method.
- */
- public abstract void onDestroy();
+ boolean onPrepareImage(Collection<InstallationFile> addedFiles,
+ Collection<String> removedFiles);
}
/**
@@ -145,7 +88,9 @@
* @return An instance of a DataLoader.
* @hide
*/
- public abstract @Nullable DataLoader onCreateDataLoader();
+ public @Nullable DataLoader onCreateDataLoader() {
+ return null;
+ }
/**
* @hide
@@ -160,148 +105,125 @@
@Override
public void create(int id, @NonNull Bundle options,
@NonNull IDataLoaderStatusListener listener)
- throws IllegalArgumentException, RuntimeException {
+ throws IllegalArgumentException, RuntimeException {
mId = id;
- final DataLoaderParamsParcel params = options.getParcelable("params");
+ final DataLoaderParamsParcel params = options.getParcelable("params");
if (params == null) {
- throw new IllegalArgumentException("Must specify Incremental data loader params");
+ throw new IllegalArgumentException("Must specify data loader params");
}
- final FileSystemControlParcel control =
- options.getParcelable("control");
+ final FileSystemControlParcel control = options.getParcelable("control");
if (control == null) {
- throw new IllegalArgumentException("Must specify Incremental control parcel");
+ throw new IllegalArgumentException("Must specify control parcel");
}
- mStatusListener = listener;
try {
if (!nativeCreateDataLoader(id, control, params, listener)) {
Slog.e(TAG, "Failed to create native loader for " + mId);
}
} catch (Exception ex) {
+ Slog.e(TAG, "Failed to create native loader for " + mId, ex);
destroy();
throw new RuntimeException(ex);
} finally {
// Closing FDs.
- if (control.incremental.cmd != null) {
- try {
- control.incremental.cmd.close();
- } catch (IOException e) {
- Slog.e(TAG, "Failed to close IncFs CMD file descriptor " + e);
+ if (control.incremental != null) {
+ if (control.incremental.cmd != null) {
+ try {
+ control.incremental.cmd.close();
+ } catch (IOException e) {
+ Slog.e(TAG, "Failed to close IncFs CMD file descriptor " + e);
+ }
+ }
+ if (control.incremental.log != null) {
+ try {
+ control.incremental.log.close();
+ } catch (IOException e) {
+ Slog.e(TAG, "Failed to close IncFs LOG file descriptor " + e);
+ }
}
}
- if (control.incremental.log != null) {
- try {
- control.incremental.log.close();
- } catch (IOException e) {
- Slog.e(TAG, "Failed to close IncFs LOG file descriptor " + e);
- }
- }
- NamedParcelFileDescriptor[] fds = params.dynamicArgs;
- for (NamedParcelFileDescriptor nfd : fds) {
- try {
- nfd.fd.close();
- } catch (IOException e) {
- Slog.e(TAG,
- "Failed to close DynamicArgs parcel file descriptor " + e);
+ if (params.dynamicArgs != null) {
+ NamedParcelFileDescriptor[] fds = params.dynamicArgs;
+ for (NamedParcelFileDescriptor nfd : fds) {
+ try {
+ nfd.fd.close();
+ } catch (IOException e) {
+ Slog.e(TAG, "Failed to close DynamicArgs parcel file descriptor " + e);
+ }
}
}
}
}
@Override
- public void start(List<InstallationFile> fileInfos) {
+ public void start() {
if (!nativeStartDataLoader(mId)) {
- Slog.e(TAG, "Failed to start loader: loader not found for " + mId);
+ Slog.e(TAG, "Failed to start loader: " + mId);
}
}
@Override
public void stop() {
if (!nativeStopDataLoader(mId)) {
- Slog.w(TAG, "Failed to stop loader: loader not found for " + mId);
+ Slog.w(TAG, "Failed to stop loader: " + mId);
}
}
@Override
public void destroy() {
if (!nativeDestroyDataLoader(mId)) {
- Slog.w(TAG, "Failed to destroy loader: loader not found for " + mId);
+ Slog.w(TAG, "Failed to destroy loader: " + mId);
+ }
+ }
+
+ @Override
+ public void prepareImage(List<InstallationFile> addedFiles, List<String> removedFiles) {
+ if (!nativePrepareImage(mId, addedFiles, removedFiles)) {
+ Slog.w(TAG, "Failed to destroy loader: " + mId);
}
}
}
/**
- *
* Used by the DataLoaderService implementations.
*
* @hide
*/
public static final class FileSystemConnector {
/**
- * Creates a wrapper for an installation session connector.
+ * Create a wrapper for a native instance.
+ *
* @hide
*/
- FileSystemConnector(IPackageInstallerSessionFileSystemConnector connector) {
- mConnector = connector;
+ FileSystemConnector(long nativeInstance) {
+ mNativeInstance = nativeInstance;
}
/**
* Write data to an installation file from an arbitrary FD.
*
- * @param name name of file previously added to the installation session.
- * @param offsetBytes offset into the file to begin writing at, or 0 to
- * start at the beginning of the file.
- * @param lengthBytes total size of the file being written, used to
- * preallocate the underlying disk space, or -1 if unknown.
- * The system may clear various caches as needed to allocate
- * this space.
- * @param incomingFd FD to read bytes from.
- * @throws IOException if trouble opening the file for writing, such as
- * lack of disk space or unavailable media.
+ * @param name name of file previously added to the installation session.
+ * @param offsetBytes offset into the file to begin writing at, or 0 to start at the
+ * beginning of the file.
+ * @param lengthBytes total size of the file being written, used to preallocate the
+ * underlying disk space, or -1 if unknown. The system may clear various
+ * caches as needed to allocate this space.
+ * @param incomingFd FD to read bytes from.
+ * @throws IOException if trouble opening the file for writing, such as lack of disk space
+ * or unavailable media.
*/
public void writeData(String name, long offsetBytes, long lengthBytes,
ParcelFileDescriptor incomingFd) throws IOException {
try {
- mConnector.writeData(name, offsetBytes, lengthBytes, incomingFd);
+ nativeWriteData(mNativeInstance, name, offsetBytes, lengthBytes, incomingFd);
} catch (RuntimeException e) {
ExceptionUtils.maybeUnwrapIOException(e);
throw e;
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
}
}
- private final IPackageInstallerSessionFileSystemConnector mConnector;
- }
-
- /**
- * Wrapper for native reporting DataLoader statuses.
- * @hide
- */
- public static final class StatusListener {
- /**
- * Creates a wrapper for a native instance.
- * @hide
- */
- StatusListener(long nativeInstance) {
- mNativeInstance = nativeInstance;
- }
-
- /**
- * Report the status of DataLoader. Used for system-wide notifications e.g., disabling
- * applications which rely on this data loader to function properly.
- *
- * @param status status to report.
- * @return True if status was reported successfully.
- */
- public boolean onStatusChanged(@DataLoaderStatus int status) {
- return nativeReportStatus(mNativeInstance, status);
- }
-
private final long mNativeInstance;
}
- private IDataLoaderStatusListener mStatusListener = null;
-
/* Native methods */
private native boolean nativeCreateDataLoader(int storageId,
@NonNull FileSystemControlParcel control,
@@ -314,5 +236,10 @@
private native boolean nativeDestroyDataLoader(int storageId);
- private static native boolean nativeReportStatus(long nativeInstance, int status);
+ private native boolean nativePrepareImage(int storageId,
+ Collection<InstallationFile> addedFiles, Collection<String> removedFiles);
+
+ private static native void nativeWriteData(long nativeInstance, String name, long offsetBytes,
+ long lengthBytes, ParcelFileDescriptor incomingFd);
+
}
diff --git a/core/java/android/telephony/PhoneStateListener.java b/core/java/android/telephony/PhoneStateListener.java
index 51a9c86..e5f2c3a 100644
--- a/core/java/android/telephony/PhoneStateListener.java
+++ b/core/java/android/telephony/PhoneStateListener.java
@@ -24,7 +24,6 @@
import android.annotation.UnsupportedAppUsage;
import android.os.Binder;
import android.os.Build;
-import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.Looper;
@@ -993,8 +992,11 @@
() -> mExecutor.execute(() -> psl.onCallForwardingIndicatorChanged(cfi)));
}
- public void onCellLocationChanged(Bundle bundle) {
- CellLocation location = CellLocation.newFromBundle(bundle);
+ public void onCellLocationChanged(CellIdentity cellIdentity) {
+ // There is no system/public API to create an CellIdentity in system server,
+ // so the server pass a null to indicate an empty initial location.
+ CellLocation location =
+ cellIdentity == null ? CellLocation.getEmpty() : cellIdentity.asCellLocation();
PhoneStateListener psl = mPhoneStateListenerWeakRef.get();
if (psl == null) return;
diff --git a/core/java/android/telephony/TelephonyRegistryManager.java b/core/java/android/telephony/TelephonyRegistryManager.java
index f574160..1b2feda 100644
--- a/core/java/android/telephony/TelephonyRegistryManager.java
+++ b/core/java/android/telephony/TelephonyRegistryManager.java
@@ -22,7 +22,6 @@
import android.annotation.TestApi;
import android.content.Context;
import android.os.Binder;
-import android.os.Bundle;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.telephony.Annotation.CallState;
@@ -633,10 +632,14 @@
}
/**
- * TODO change from bundle to CellLocation?
+ * Notify {@link android.telephony.CellLocation} changed.
+ *
+ * <p>To be compatible with {@link TelephonyRegistry}, use {@link CellIdentity} which is
+ * parcelable, and convert to CellLocation in client code.
+ *
* @hide
*/
- public void notifyCellLocation(int subId, Bundle cellLocation) {
+ public void notifyCellLocation(int subId, CellIdentity cellLocation) {
try {
sRegistry.notifyCellLocationForSubscriber(subId, cellLocation);
} catch (RemoteException ex) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 1a5b3e5..0db80e2 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -6162,10 +6162,27 @@
mRenderNode = RenderNode.create(getClass().getName(), new ViewAnimationHostBridge(this));
}
- final boolean debugDraw() {
+ /**
+ * Returns {@code true} when the View is attached and the system developer setting to show
+ * the layout bounds is enabled or {@code false} otherwise.
+ */
+ public final boolean isShowingLayoutBounds() {
return DEBUG_DRAW || mAttachInfo != null && mAttachInfo.mDebugLayout;
}
+ /**
+ * Used to test isShowingLayoutBounds(). This sets the local value used
+ * by that function. This method does nothing if the layout isn't attached.
+ *
+ * @hide
+ */
+ @TestApi
+ public final void setShowingLayoutBounds(boolean debugLayout) {
+ if (mAttachInfo != null) {
+ mAttachInfo.mDebugLayout = debugLayout;
+ }
+ }
+
private static SparseArray<String> getAttributeMap() {
if (mAttributeMap == null) {
mAttributeMap = new SparseArray<>();
@@ -20881,7 +20898,7 @@
if (mOverlay != null && !mOverlay.isEmpty()) {
mOverlay.getOverlayView().draw(canvas);
}
- if (debugDraw()) {
+ if (isShowingLayoutBounds()) {
debugDrawFocus(canvas);
}
} else {
@@ -22026,7 +22043,7 @@
// Step 7, draw the default focus highlight
drawDefaultFocusHighlight(canvas);
- if (debugDraw()) {
+ if (isShowingLayoutBounds()) {
debugDrawFocus(canvas);
}
@@ -22201,7 +22218,7 @@
// Step 6, draw decorations (foreground, scrollbars)
onDrawForeground(canvas);
- if (debugDraw()) {
+ if (isShowingLayoutBounds()) {
debugDrawFocus(canvas);
}
}
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 21e9e31..5fb7177 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -681,7 +681,7 @@
private void initViewGroup() {
// ViewGroup doesn't draw by default
- if (!debugDraw()) {
+ if (!isShowingLayoutBounds()) {
setFlags(WILL_NOT_DRAW, DRAW_MASK);
}
mGroupFlags |= FLAG_CLIP_CHILDREN;
@@ -4156,7 +4156,7 @@
}
if (usingRenderNodeProperties) canvas.insertInorderBarrier();
- if (debugDraw()) {
+ if (isShowingLayoutBounds()) {
onDebugDraw(canvas);
}
diff --git a/core/java/com/android/internal/app/SuspendedAppActivity.java b/core/java/com/android/internal/app/SuspendedAppActivity.java
index 33b2113..c610ac4 100644
--- a/core/java/com/android/internal/app/SuspendedAppActivity.java
+++ b/core/java/com/android/internal/app/SuspendedAppActivity.java
@@ -45,12 +45,14 @@
public static final String EXTRA_SUSPENDING_PACKAGE =
PACKAGE_NAME + ".extra.SUSPENDING_PACKAGE";
public static final String EXTRA_DIALOG_INFO = PACKAGE_NAME + ".extra.DIALOG_INFO";
+ public static final String EXTRA_ACTIVITY_OPTIONS = PACKAGE_NAME + ".extra.ACTIVITY_OPTIONS";
private Intent mMoreDetailsIntent;
private int mUserId;
private PackageManager mPm;
private Resources mSuspendingAppResources;
private SuspendDialogInfo mSuppliedDialogInfo;
+ private Bundle mOptions;
private CharSequence getAppLabel(String packageName) {
try {
@@ -143,6 +145,7 @@
getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_DIALOG);
final Intent intent = getIntent();
+ mOptions = intent.getBundleExtra(EXTRA_ACTIVITY_OPTIONS);
mUserId = intent.getIntExtra(Intent.EXTRA_USER_ID, -1);
if (mUserId < 0) {
Slog.wtf(TAG, "Invalid user: " + mUserId);
@@ -178,20 +181,22 @@
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case AlertDialog.BUTTON_NEUTRAL:
- startActivityAsUser(mMoreDetailsIntent, UserHandle.of(mUserId));
- Slog.i(TAG, "Started more details activity");
+ startActivityAsUser(mMoreDetailsIntent, mOptions, UserHandle.of(mUserId));
+ Slog.i(TAG, "Started activity: " + mMoreDetailsIntent.getAction()
+ + " in user " + mUserId);
break;
}
finish();
}
public static Intent createSuspendedAppInterceptIntent(String suspendedPackage,
- String suspendingPackage, SuspendDialogInfo dialogInfo, int userId) {
+ String suspendingPackage, SuspendDialogInfo dialogInfo, Bundle options, int userId) {
return new Intent()
.setClassName("android", SuspendedAppActivity.class.getName())
.putExtra(EXTRA_SUSPENDED_PACKAGE, suspendedPackage)
.putExtra(EXTRA_DIALOG_INFO, dialogInfo)
.putExtra(EXTRA_SUSPENDING_PACKAGE, suspendingPackage)
+ .putExtra(EXTRA_ACTIVITY_OPTIONS, options)
.putExtra(Intent.EXTRA_USER_ID, userId)
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
diff --git a/core/java/com/android/internal/os/Zygote.java b/core/java/com/android/internal/os/Zygote.java
index c390a51..2248b88 100644
--- a/core/java/com/android/internal/os/Zygote.java
+++ b/core/java/com/android/internal/os/Zygote.java
@@ -316,7 +316,9 @@
* @param appDataDir null-ok The data directory of the app.
* @param isTopApp True if the process is for top (high priority) application.
* @param pkgDataInfoList A list that stores related packages and its app data
- * info: volume uuid and inode.
+ * volume uuid and CE dir inode. For example, pkgDataInfoList = [app_a_pkg_name,
+ * app_a_data_volume_uuid, app_a_ce_inode, app_b_pkg_name, app_b_data_volume_uuid,
+ * app_b_ce_inode, ...];
*/
private static void specializeAppProcess(int uid, int gid, int[] gids, int runtimeFlags,
int[][] rlimits, int mountExternal, String seInfo, String niceName,
diff --git a/core/java/com/android/internal/telephony/IPhoneStateListener.aidl b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl
index cb67309..6c7e3dc 100644
--- a/core/java/com/android/internal/telephony/IPhoneStateListener.aidl
+++ b/core/java/com/android/internal/telephony/IPhoneStateListener.aidl
@@ -16,8 +16,8 @@
package com.android.internal.telephony;
-import android.os.Bundle;
import android.telephony.CallAttributes;
+import android.telephony.CellIdentity;
import android.telephony.CellInfo;
import android.telephony.DataConnectionRealTimeInfo;
import android.telephony.PhoneCapability;
@@ -37,8 +37,8 @@
void onMessageWaitingIndicatorChanged(boolean mwi);
void onCallForwardingIndicatorChanged(boolean cfi);
- // we use bundle here instead of CellLocation so it can get the right subclass
- void onCellLocationChanged(in Bundle location);
+ // Uses CellIdentity which is Parcelable here; will convert to CellLocation in client.
+ void onCellLocationChanged(in CellIdentity location);
void onCallStateChanged(int state, String incomingNumber);
void onDataConnectionStateChanged(int state, int networkType);
void onDataActivity(int direction);
@@ -63,4 +63,3 @@
void onCallDisconnectCauseChanged(in int disconnectCause, in int preciseDisconnectCause);
void onImsCallDisconnectCauseChanged(in ImsReasonInfo imsReasonInfo);
}
-
diff --git a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
index f954679..4e40503 100644
--- a/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
+++ b/core/java/com/android/internal/telephony/ITelephonyRegistry.aidl
@@ -19,8 +19,8 @@
import android.content.Intent;
import android.net.LinkProperties;
import android.net.NetworkCapabilities;
-import android.os.Bundle;
import android.telephony.CallQuality;
+import android.telephony.CellIdentity;
import android.telephony.CellInfo;
import android.telephony.ims.ImsReasonInfo;
import android.telephony.PhoneCapability;
@@ -66,9 +66,9 @@
int phoneId, int subId, String apnType, in PreciseDataConnectionState preciseState);
@UnsupportedAppUsage
void notifyDataConnectionFailed(String apnType);
- @UnsupportedAppUsage(maxTargetSdk = 28)
- void notifyCellLocation(in Bundle cellLocation);
- void notifyCellLocationForSubscriber(in int subId, in Bundle cellLocation);
+ // Uses CellIdentity which is Parcelable here; will convert to CellLocation in client.
+ void notifyCellLocation(in CellIdentity cellLocation);
+ void notifyCellLocationForSubscriber(in int subId, in CellIdentity cellLocation);
@UnsupportedAppUsage
void notifyCellInfo(in List<CellInfo> cellInfo);
void notifyPreciseCallState(int phoneId, int subId, int ringingCallState,
diff --git a/core/jni/android_service_DataLoaderService.cpp b/core/jni/android_service_DataLoaderService.cpp
index 381b386..a62d127 100644
--- a/core/jni/android_service_DataLoaderService.cpp
+++ b/core/jni/android_service_DataLoaderService.cpp
@@ -51,13 +51,19 @@
}
-static jboolean nativeReportStatus(JNIEnv* env,
- jobject clazz,
- jlong self,
- jint status) {
- auto listener = (DataLoaderStatusListenerPtr)self;
- return DataLoader_StatusListener_reportStatus(listener,
- (DataLoaderStatus)status);
+static jboolean nativePrepareImage(JNIEnv* env, jobject thiz, jint storageId, jobject addedFiles, jobject removedFiles) {
+ return DataLoaderService_OnPrepareImage(storageId, addedFiles, removedFiles);
+}
+
+static void nativeWriteData(JNIEnv* env,
+ jobject clazz,
+ jlong self,
+ jstring name,
+ jlong offsetBytes,
+ jlong lengthBytes,
+ jobject incomingFd) {
+ auto connector = (DataLoaderFilesystemConnectorPtr)self;
+ return DataLoader_FilesystemConnector_writeData(connector, name, offsetBytes, lengthBytes, incomingFd);
}
static const JNINativeMethod dlc_method_table[] = {
@@ -69,7 +75,8 @@
{"nativeStartDataLoader", "(I)Z", (void*)nativeStartDataLoader},
{"nativeStopDataLoader", "(I)Z", (void*)nativeStopDataLoader},
{"nativeDestroyDataLoader", "(I)Z", (void*)nativeDestroyDataLoader},
- {"nativeReportStatus", "(JI)Z", (void*)nativeReportStatus},
+ {"nativePrepareImage", "(ILjava/util/Collection;Ljava/util/Collection;)Z", (void*)nativePrepareImage},
+ {"nativeWriteData", "(JLjava/lang/String;JJLandroid/os/ParcelFileDescriptor;)V", (void*)nativeWriteData},
};
} // namespace
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 1165d2d..44a902c 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -4113,7 +4113,7 @@
<permission android:name="android.permission.INTENT_FILTER_VERIFICATION_AGENT"
android:protectionLevel="signature|privileged" />
- <!-- Must be required by intent filter verifier receiver, to ensure that only the
+ <!-- Must be required by intent filter verifier rintent-filtereceiver, to ensure that only the
system can interact with it.
@hide
-->
@@ -5143,6 +5143,12 @@
android:permission="android.permission.BIND_JOB_SERVICE" >
</service>
-</application>
+ <service android:name="com.android.server.pm.PackageManagerShellCommandDataLoader">
+ <intent-filter>
+ <action android:name="android.intent.action.LOAD_DATA" />
+ </intent-filter>
+ </service>
+
+ </application>
</manifest>
diff --git a/core/tests/overlaytests/device/res/layout/layout.xml b/core/tests/overlaytests/device/res/layout/layout.xml
new file mode 100644
index 0000000..e12c715
--- /dev/null
+++ b/core/tests/overlaytests/device/res/layout/layout.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2019 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.
+ -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <LinearLayout android:id="@id/view_1"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <com.android.overlaytest.view.TestTextView
+ android:id="@id/view_2"
+ android:layout_width="match_parent"
+ android:layout_height="100dp"
+ app:customAttribute="none"/>
+
+ <com.android.overlaytest.view.TestTextView
+ android:id="@id/view_3"
+ android:layout_width="match_parent"
+ android:layout_height="100dp"
+ app:customAttribute="none" />
+ </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/core/tests/overlaytests/device/res/values/config.xml b/core/tests/overlaytests/device/res/values/config.xml
index c692a262..e918268 100644
--- a/core/tests/overlaytests/device/res/values/config.xml
+++ b/core/tests/overlaytests/device/res/values/config.xml
@@ -56,4 +56,16 @@
<item>17</item>
<item>19</item>
</integer-array>
+
+ <attr name="customAttribute" />
+ <id name="view_1" />
+ <id name="view_2" />
+ <id name="view_3" />
+
+ <!-- Stabilize the ids of attributes and ids used in test layouts so that they differ from the
+ overlay resource ids -->
+ <public type="attr" name="customAttribute" id="0x7f200000"/>
+ <public type="id" name="view_1" id="0x7f210000"/>
+ <public type="id" name="view_2" id="0x7f210001"/>
+ <public type="id" name="view_3" id="0x7f210002"/>
</resources>
diff --git a/core/tests/overlaytests/device/src/com/android/overlaytest/OverlayBaseTest.java b/core/tests/overlaytests/device/src/com/android/overlaytest/OverlayBaseTest.java
index fdb6bbb..636f4c8 100644
--- a/core/tests/overlaytests/device/src/com/android/overlaytest/OverlayBaseTest.java
+++ b/core/tests/overlaytests/device/src/com/android/overlaytest/OverlayBaseTest.java
@@ -18,20 +18,26 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
+import android.content.Context;
import android.content.res.AssetManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
import android.os.LocaleList;
import android.util.AttributeSet;
+import android.util.TypedValue;
import android.util.Xml;
+import android.view.LayoutInflater;
+import android.view.View;
import androidx.test.InstrumentationRegistry;
import com.android.internal.util.ArrayUtils;
+import com.android.overlaytest.view.TestTextView;
import org.junit.Before;
import org.junit.Ignore;
@@ -45,6 +51,7 @@
@Ignore
public abstract class OverlayBaseTest {
+ private Context mContext;
private Resources mResources;
private final int mMode;
static final int MODE_NO_OVERLAY = 0;
@@ -61,7 +68,8 @@
@Before
public void setUp() {
- mResources = InstrumentationRegistry.getContext().getResources();
+ mContext = InstrumentationRegistry.getContext();
+ mResources = mContext.getResources();
}
private int calculateRawResourceChecksum(int resId) throws Throwable {
@@ -321,6 +329,50 @@
assertEquals("com.android.overlaytest", contents);
}
+ @Test
+ public void testRewrite() throws Throwable {
+ final TypedValue result = new TypedValue();
+ mResources.getValue(R.string.str, result, true);
+ assertEquals(result.resourceId & 0xff000000, 0x7f000000);
+ }
+
+ @Test
+ public void testOverlayLayout() throws Throwable {
+ final LayoutInflater inflater = LayoutInflater.from(mContext);
+ final View layout = inflater.inflate(R.layout.layout, null);
+ assertNotNull(layout.findViewById(R.id.view_1));
+
+ final TestTextView view2 = layout.findViewById(R.id.view_2);
+ assertNotNull(view2);
+ switch (mMode) {
+ case MODE_NO_OVERLAY:
+ assertEquals("none", view2.getCustomAttributeValue());
+ break;
+ case MODE_SINGLE_OVERLAY:
+ assertEquals("single", view2.getCustomAttributeValue());
+ break;
+ case MODE_MULTIPLE_OVERLAYS:
+ assertEquals("multiple", view2.getCustomAttributeValue());
+ break;
+ default:
+ fail("Unknown mode " + mMode);
+ }
+
+ final TestTextView view3 = layout.findViewById(R.id.view_3);
+ assertNotNull(view3);
+ switch (mMode) {
+ case MODE_NO_OVERLAY:
+ assertEquals("none", view3.getCustomAttributeValue());
+ break;
+ case MODE_SINGLE_OVERLAY:
+ case MODE_MULTIPLE_OVERLAYS:
+ assertEquals("overlaid", view3.getCustomAttributeValue());
+ break;
+ default:
+ fail("Unknown mode " + mMode);
+ }
+ }
+
/*
* testMatrix* tests
*
diff --git a/core/tests/overlaytests/device/src/com/android/overlaytest/view/TestTextView.java b/core/tests/overlaytests/device/src/com/android/overlaytest/view/TestTextView.java
new file mode 100644
index 0000000..2245e2b
--- /dev/null
+++ b/core/tests/overlaytests/device/src/com/android/overlaytest/view/TestTextView.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.overlaytest.view;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.util.AttributeSet;
+import android.widget.TextView;
+
+public class TestTextView extends TextView {
+
+ private final String mCustomAttributeValue;
+
+ public TestTextView(Context context, AttributeSet attrs) {
+ this(context, attrs, com.android.internal.R.attr.textViewStyle, 0);
+ }
+
+ public TestTextView(Context context, AttributeSet attrs,
+ int defStyleAttr,
+ int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+
+ int[] testResources = new int[]{com.android.overlaytest.R.attr.customAttribute};
+ final Resources.Theme theme = context.getTheme();
+ TypedArray typedArray = theme.obtainStyledAttributes(attrs, testResources, defStyleAttr,
+ defStyleRes);
+ mCustomAttributeValue = typedArray.getString(0);
+ }
+
+ public String getCustomAttributeValue() {
+ return mCustomAttributeValue;
+ }
+}
diff --git a/core/tests/overlaytests/device/test-apps/AppOverlayOne/AndroidManifest.xml b/core/tests/overlaytests/device/test-apps/AppOverlayOne/AndroidManifest.xml
index 7d28408..873ca3c 100644
--- a/core/tests/overlaytests/device/test-apps/AppOverlayOne/AndroidManifest.xml
+++ b/core/tests/overlaytests/device/test-apps/AppOverlayOne/AndroidManifest.xml
@@ -19,5 +19,6 @@
android:versionCode="1"
android:versionName="1.0">
<application android:hasCode="false" />
- <overlay android:targetPackage="com.android.overlaytest" />
+ <overlay android:targetPackage="com.android.overlaytest"
+ android:resourcesMap="@xml/overlays"/>
</manifest>
diff --git a/core/tests/overlaytests/device/test-apps/AppOverlayOne/res/layout/layout.xml b/core/tests/overlaytests/device/test-apps/AppOverlayOne/res/layout/layout.xml
new file mode 100644
index 0000000..7b63605
--- /dev/null
+++ b/core/tests/overlaytests/device/test-apps/AppOverlayOne/res/layout/layout.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2019 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.
+ -->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <LinearLayout android:id="@+id/view_1"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <com.android.overlaytest.view.TestTextView
+ android:id="@+id/view_2"
+ android:layout_width="match_parent"
+ android:layout_height="100dp"
+ app:customAttribute="@string/str" />
+
+ <com.android.overlaytest.view.TestTextView
+ android:id="@+id/view_3"
+ android:layout_width="match_parent"
+ android:layout_height="100dp"
+ app:customAttribute="overlaid" />
+ </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/core/tests/overlaytests/device/test-apps/AppOverlayOne/res/values/config.xml b/core/tests/overlaytests/device/test-apps/AppOverlayOne/res/values/config.xml
index 972137a..74c4963 100644
--- a/core/tests/overlaytests/device/test-apps/AppOverlayOne/res/values/config.xml
+++ b/core/tests/overlaytests/device/test-apps/AppOverlayOne/res/values/config.xml
@@ -1,7 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="str">single</string>
- <string name="str2">single</string>
<integer name="matrix_101000">300</integer>
<integer name="matrix_101001">300</integer>
<integer name="matrix_101010">300</integer>
@@ -18,7 +17,6 @@
<integer name="matrix_111101">300</integer>
<integer name="matrix_111110">300</integer>
<integer name="matrix_111111">300</integer>
- <bool name="usually_false">true</bool>
<integer-array name="fibonacci">
<item>21</item>
<item>13</item>
@@ -29,7 +27,10 @@
<item>1</item>
<item>1</item>
</integer-array>
+
<!-- The following integer does not exist in the original package. Idmap
generation should therefore ignore it. -->
<integer name="integer_not_in_original_package">0</integer>
+
+ <attr name="customAttribute" />
</resources>
diff --git a/core/tests/overlaytests/device/test-apps/AppOverlayOne/res/xml/overlays.xml b/core/tests/overlaytests/device/test-apps/AppOverlayOne/res/xml/overlays.xml
new file mode 100644
index 0000000..38e5fa1
--- /dev/null
+++ b/core/tests/overlaytests/device/test-apps/AppOverlayOne/res/xml/overlays.xml
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2019 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.
+ -->
+<overlay>
+ <item target="drawable/drawable" value="@drawable/drawable"/>
+ <item target="layout/layout" value="@layout/layout"/>
+ <item target="raw/lorem_ipsum" value="@raw/lorem_ipsum"/>
+ <item target="xml/integer" value="@xml/integer"/>
+ <item target="string/str" value="@string/str"/>
+ <item target="string/str2" value="single"/>
+
+ <item target="integer/matrix_100100" value="@integer/matrix_100100"/>
+ <item target="integer/matrix_100101" value="@integer/matrix_100101"/>
+ <item target="integer/matrix_100110" value="@integer/matrix_100110"/>
+ <item target="integer/matrix_100110" value="@integer/matrix_100110"/>
+ <item target="integer/matrix_100111" value="@integer/matrix_100111"/>
+ <item target="integer/matrix_101000" value="@integer/matrix_101000"/>
+ <item target="integer/matrix_101001" value="@integer/matrix_101001"/>
+ <item target="integer/matrix_101010" value="@integer/matrix_101010"/>
+ <item target="integer/matrix_101011" value="@integer/matrix_101011"/>
+ <item target="integer/matrix_101100" value="@integer/matrix_101100"/>
+ <item target="integer/matrix_101101" value="@integer/matrix_101101"/>
+ <item target="integer/matrix_101110" value="@integer/matrix_101110"/>
+ <item target="integer/matrix_101111" value="@integer/matrix_101111"/>
+ <item target="integer/matrix_110100" value="@integer/matrix_110100"/>
+ <item target="integer/matrix_110101" value="@integer/matrix_110101"/>
+ <item target="integer/matrix_110110" value="@integer/matrix_110110"/>
+ <item target="integer/matrix_110111" value="@integer/matrix_110111"/>
+ <item target="integer/matrix_111000" value="@integer/matrix_111000"/>
+ <item target="integer/matrix_111001" value="@integer/matrix_111001"/>
+ <item target="integer/matrix_111010" value="@integer/matrix_111010"/>
+ <item target="integer/matrix_111011" value="@integer/matrix_111011"/>
+ <item target="integer/matrix_111100" value="@integer/matrix_111100"/>
+ <item target="integer/matrix_111101" value="@integer/matrix_111101"/>
+ <item target="integer/matrix_111110" value="@integer/matrix_111110"/>
+ <item target="integer/matrix_111111" value="@integer/matrix_111111"/>
+
+ <item target="bool/usually_false" value="true"/>
+
+ <item target="array/fibonacci" value="@array/fibonacci"/>
+
+ <item target="attr/customAttribute" value="@attr/customAttribute"/>
+ <item target="id/view_1" value="@id/view_1"/>
+ <item target="id/view_2" value="@id/view_2"/>
+ <item target="id/view_3" value="@id/view_3"/>
+</overlay>
+
+
diff --git a/libs/androidfw/Idmap.cpp b/libs/androidfw/Idmap.cpp
index ce3bfff..0b2fd9e 100644
--- a/libs/androidfw/Idmap.cpp
+++ b/libs/androidfw/Idmap.cpp
@@ -57,7 +57,7 @@
const char16_t* OverlayStringPool::stringAt(size_t idx, size_t* outLen) const {
const size_t offset = dtohl(data_header_->string_pool_index_offset);
- if (idmap_string_pool_ != nullptr && idx >= size() && idx >= offset) {
+ if (idmap_string_pool_ != nullptr && idx >= ResStringPool::size() && idx >= offset) {
return idmap_string_pool_->stringAt(idx - offset, outLen);
}
@@ -66,13 +66,17 @@
const char* OverlayStringPool::string8At(size_t idx, size_t* outLen) const {
const size_t offset = dtohl(data_header_->string_pool_index_offset);
- if (idmap_string_pool_ != nullptr && idx >= size() && idx >= offset) {
+ if (idmap_string_pool_ != nullptr && idx >= ResStringPool::size() && idx >= offset) {
return idmap_string_pool_->string8At(idx - offset, outLen);
}
return ResStringPool::string8At(idx, outLen);
}
+size_t OverlayStringPool::size() const {
+ return ResStringPool::size() + (idmap_string_pool_ != nullptr ? idmap_string_pool_->size() : 0U);
+}
+
OverlayDynamicRefTable::OverlayDynamicRefTable(const Idmap_data_header* data_header,
const Idmap_overlay_entry* entries,
uint8_t target_assigned_package_id)
diff --git a/libs/androidfw/include/androidfw/Idmap.h b/libs/androidfw/include/androidfw/Idmap.h
index ab4c9c2..ccb57f3 100644
--- a/libs/androidfw/include/androidfw/Idmap.h
+++ b/libs/androidfw/include/androidfw/Idmap.h
@@ -40,8 +40,9 @@
class OverlayStringPool : public ResStringPool {
public:
virtual ~OverlayStringPool();
- virtual const char16_t* stringAt(size_t idx, size_t* outLen) const;
- virtual const char* string8At(size_t idx, size_t* outLen) const;
+ const char16_t* stringAt(size_t idx, size_t* outLen) const override;
+ const char* string8At(size_t idx, size_t* outLen) const override;
+ size_t size() const override;
explicit OverlayStringPool(const LoadedIdmap* loaded_idmap);
private:
@@ -53,8 +54,8 @@
// resources to the resource id of corresponding target resources.
class OverlayDynamicRefTable : public DynamicRefTable {
public:
- virtual ~OverlayDynamicRefTable() = default;
- virtual status_t lookupResourceId(uint32_t* resId) const;
+ ~OverlayDynamicRefTable() override = default;
+ status_t lookupResourceId(uint32_t* resId) const override;
private:
explicit OverlayDynamicRefTable(const Idmap_data_header* data_header,
diff --git a/libs/androidfw/include/androidfw/ResourceTypes.h b/libs/androidfw/include/androidfw/ResourceTypes.h
index b603326..35cebd4 100644
--- a/libs/androidfw/include/androidfw/ResourceTypes.h
+++ b/libs/androidfw/include/androidfw/ResourceTypes.h
@@ -520,7 +520,7 @@
ssize_t indexOfString(const char16_t* str, size_t strLen) const;
- size_t size() const;
+ virtual size_t size() const;
size_t styleCount() const;
size_t bytes() const;
const void* data() const;
diff --git a/media/jni/android_media_MediaMetricsJNI.cpp b/media/jni/android_media_MediaMetricsJNI.cpp
index 37aca08..b82d8e2 100644
--- a/media/jni/android_media_MediaMetricsJNI.cpp
+++ b/media/jni/android_media_MediaMetricsJNI.cpp
@@ -18,6 +18,7 @@
#include <binder/Parcel.h>
#include <jni.h>
+#include <media/IMediaMetricsService.h>
#include <media/MediaMetricsItem.h>
#include <nativehelper/JNIHelp.h>
#include <variant>
@@ -150,14 +151,12 @@
return (jint)BAD_VALUE;
}
- // TODO: directly record item to MediaMetrics service.
- mediametrics::Item item;
- if (item.readFromByteString((char *)buffer, length) != NO_ERROR) {
- ALOGW("%s: cannot read from byte string", __func__);
- return (jint)BAD_VALUE;
+ sp<IMediaMetricsService> service = mediametrics::BaseItem::getService();
+ if (service == nullptr) {
+ ALOGW("Cannot retrieve mediametrics service");
+ return (jint)NO_INIT;
}
- item.selfrecord();
- return (jint)NO_ERROR;
+ return (jint)service->submitBuffer((char *)buffer, length);
}
// Helper function to convert a native PersistableBundle to a Java
diff --git a/media/jni/android_media_MediaMuxer.cpp b/media/jni/android_media_MediaMuxer.cpp
index f0aa4c3..0c1e9a2 100644
--- a/media/jni/android_media_MediaMuxer.cpp
+++ b/media/jni/android_media_MediaMuxer.cpp
@@ -26,11 +26,15 @@
#include <unistd.h>
#include <fcntl.h>
+#include <android/api-level.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MediaMuxer.h>
+extern "C" int android_get_application_target_sdk_version();
+
namespace android {
struct fields_t {
@@ -229,10 +233,31 @@
status_t err = muxer->stop();
- if (err != OK) {
- jniThrowException(env, "java/lang/IllegalStateException",
- "Failed to stop the muxer");
- return;
+ if (android_get_application_target_sdk_version() >= __ANDROID_API_R__) {
+ switch (err) {
+ case OK:
+ break;
+ case ERROR_IO: {
+ jniThrowException(env, "java/lang/UncheckedIOException",
+ "Muxer stopped unexpectedly");
+ return;
+ }
+ case ERROR_MALFORMED: {
+ jniThrowException(env, "java/io/IOError",
+ "Failure of reading or writing operation");
+ return;
+ }
+ default: {
+ jniThrowException(env, "java/lang/IllegalStateException",
+ "Failed to stop the muxer");
+ return;
+ }
+ }
+ } else {
+ if (err != OK) {
+ jniThrowException(env, "java/lang/IllegalStateException", "Failed to stop the muxer");
+ return;
+ }
}
}
diff --git a/packages/CarSystemUI/src/com/android/systemui/car/CarDeviceProvisionedControllerImpl.java b/packages/CarSystemUI/src/com/android/systemui/car/CarDeviceProvisionedControllerImpl.java
index ab1feef..38d5211b 100644
--- a/packages/CarSystemUI/src/com/android/systemui/car/CarDeviceProvisionedControllerImpl.java
+++ b/packages/CarSystemUI/src/com/android/systemui/car/CarDeviceProvisionedControllerImpl.java
@@ -27,7 +27,7 @@
import com.android.systemui.Dependency;
import com.android.systemui.broadcast.BroadcastDispatcher;
-import com.android.systemui.dagger.qualifiers.MainHandler;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.statusbar.policy.DeviceProvisionedControllerImpl;
import javax.inject.Inject;
@@ -54,7 +54,7 @@
private final ContentResolver mContentResolver;
@Inject
- public CarDeviceProvisionedControllerImpl(Context context, @MainHandler Handler mainHandler,
+ public CarDeviceProvisionedControllerImpl(Context context, @Main Handler mainHandler,
BroadcastDispatcher broadcastDispatcher) {
super(context, mainHandler, broadcastDispatcher);
mContentResolver = context.getContentResolver();
diff --git a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBar.java b/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBar.java
index e0b0922..59a084e 100644
--- a/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBar.java
+++ b/packages/CarSystemUI/src/com/android/systemui/navigationbar/car/CarNavigationBar.java
@@ -35,7 +35,7 @@
import com.android.systemui.SystemUI;
import com.android.systemui.car.CarDeviceProvisionedController;
import com.android.systemui.car.CarDeviceProvisionedListener;
-import com.android.systemui.dagger.qualifiers.MainHandler;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.NavigationBarController;
@@ -93,7 +93,7 @@
DeviceProvisionedController deviceProvisionedController,
CommandQueue commandQueue,
Lazy<FacetButtonTaskStackListener> facetButtonTaskStackListenerLazy,
- @MainHandler Handler mainHandler,
+ @Main Handler mainHandler,
Lazy<KeyguardStateController> keyguardStateControllerLazy,
Lazy<NavigationBarController> navigationBarControllerLazy,
SuperStatusBarViewFactory superStatusBarViewFactory,
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarTrustAgentUnlockDialogHelper.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarTrustAgentUnlockDialogHelper.java
index 2d57be1..b2f8aad 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarTrustAgentUnlockDialogHelper.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/CarTrustAgentUnlockDialogHelper.java
@@ -37,7 +37,7 @@
import com.android.internal.widget.LockPatternUtils;
import com.android.systemui.R;
-import com.android.systemui.dagger.qualifiers.MainResources;
+import com.android.systemui.dagger.qualifiers.Main;
import javax.inject.Inject;
import javax.inject.Singleton;
@@ -68,7 +68,7 @@
private OnHideListener mOnHideListener;
@Inject
- CarTrustAgentUnlockDialogHelper(Context context, @MainResources Resources resources,
+ CarTrustAgentUnlockDialogHelper(Context context, @Main Resources resources,
UserManager userManager, WindowManager windowManager) {
mContext = context;
mResources = resources;
diff --git a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
index 3d74868..f8fc3bb 100644
--- a/packages/CarSystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
+++ b/packages/CarSystemUI/src/com/android/systemui/statusbar/car/FullscreenUserSwitcher.java
@@ -38,7 +38,7 @@
import com.android.internal.widget.LockPatternUtils;
import com.android.systemui.R;
import com.android.systemui.car.CarServiceProvider;
-import com.android.systemui.dagger.qualifiers.MainResources;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.statusbar.car.CarTrustAgentUnlockDialogHelper.OnHideListener;
import com.android.systemui.statusbar.car.UserGridRecyclerView.UserRecord;
@@ -78,7 +78,7 @@
@Inject
public FullscreenUserSwitcher(
Context context,
- @MainResources Resources resources,
+ @Main Resources resources,
UserManager userManager,
CarServiceProvider carServiceProvider,
CarTrustAgentUnlockDialogHelper carTrustAgentUnlockDialogHelper) {
diff --git a/packages/Incremental/NativeAdbDataLoader/jni/com_android_incremental_nativeadb_DataLoaderService.cpp b/packages/Incremental/NativeAdbDataLoader/jni/com_android_incremental_nativeadb_DataLoaderService.cpp
index de92fcd5..4e49302 100644
--- a/packages/Incremental/NativeAdbDataLoader/jni/com_android_incremental_nativeadb_DataLoaderService.cpp
+++ b/packages/Incremental/NativeAdbDataLoader/jni/com_android_incremental_nativeadb_DataLoaderService.cpp
@@ -177,8 +177,7 @@
android::dataloader::ServiceParamsPtr) final {
CHECK(ifs) << "ifs can't be null";
CHECK(statusListener) << "statusListener can't be null";
- ALOGE("[AdbDataLoader] onCreate: %s/%s/%d", params.staticArgs().c_str(),
- params.packageName().c_str(), (int)params.dynamicArgs().size());
+ ALOGE("[AdbDataLoader] onCreate: %d/%s/%s/%s/%d", params.type(), params.packageName().c_str(), params.className().c_str(), params.arguments().c_str(), (int)params.dynamicArgs().size());
if (params.dynamicArgs().empty()) {
ALOGE("[AdbDataLoader] Invalid DataLoaderParams. Need in/out FDs.");
@@ -204,7 +203,7 @@
}
std::string logFile;
- if (const auto packageName = extractPackageName(params.staticArgs()); !packageName.empty()) {
+ if (const auto packageName = extractPackageName(params.arguments()); !packageName.empty()) {
logFile = android::base::GetProperty("adb.readlog." + packageName, "");
}
if (logFile.empty()) {
@@ -288,8 +287,7 @@
"inode=%d. Ignore.",
static_cast<int>(ino));
mRequestedFiles.erase(fileId);
- mStatusListener->reportStatus(
- INCREMENTAL_DATA_LOADER_NO_CONNECTION);
+ mStatusListener->reportStatus(DATA_LOADER_NO_CONNECTION);
}
}
sendRequest(mOutFd, BLOCK_MISSING, fileId, blockIdx);
@@ -337,7 +335,7 @@
}
if (res < 0) {
ALOGE("[AdbDataLoader] failed to poll. Abort.");
- mStatusListener->reportStatus(INCREMENTAL_DATA_LOADER_NO_CONNECTION);
+ mStatusListener->reportStatus(DATA_LOADER_NO_CONNECTION);
break;
}
if (res == mEventFd) {
@@ -346,7 +344,7 @@
}
if (!readChunk(mInFd, data)) {
ALOGE("[AdbDataLoader] failed to read a message. Abort.");
- mStatusListener->reportStatus(INCREMENTAL_DATA_LOADER_NO_CONNECTION);
+ mStatusListener->reportStatus(DATA_LOADER_NO_CONNECTION);
break;
}
auto remainingData = std::span(data);
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index 4fb3be2..c238d7d 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -42,6 +42,7 @@
"res",
],
static_libs: [
+ "WindowManager-Shell",
"SystemUIPluginLib",
"SystemUISharedLib",
"SettingsLib",
diff --git a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
index caf5ee0..255693b 100644
--- a/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
+++ b/packages/SystemUI/src/com/android/keyguard/CarrierTextController.java
@@ -43,7 +43,7 @@
import com.android.settingslib.WirelessUtils;
import com.android.systemui.Dependency;
import com.android.systemui.R;
-import com.android.systemui.dagger.qualifiers.MainResources;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.keyguard.WakefulnessLifecycle;
import java.util.List;
@@ -608,7 +608,7 @@
private boolean mShowMissingSim;
@Inject
- public Builder(Context context, @MainResources Resources resources) {
+ public Builder(Context context, @Main Resources resources) {
mContext = context;
mSeparator = resources.getString(
com.android.internal.R.string.kg_text_message_separator);
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index fb7a269..694c623 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -101,7 +101,7 @@
import com.android.systemui.Dumpable;
import com.android.systemui.R;
import com.android.systemui.broadcast.BroadcastDispatcher;
-import com.android.systemui.dagger.qualifiers.MainLooper;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.TaskStackChangeListener;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
@@ -1496,7 +1496,7 @@
@VisibleForTesting
@Inject
- protected KeyguardUpdateMonitor(Context context, @MainLooper Looper mainLooper,
+ protected KeyguardUpdateMonitor(Context context, @Main Looper mainLooper,
BroadcastDispatcher broadcastDispatcher,
DumpController dumpController) {
mContext = context;
diff --git a/packages/SystemUI/src/com/android/systemui/Dependency.java b/packages/SystemUI/src/com/android/systemui/Dependency.java
index 94e7c68c..a9ca04b 100644
--- a/packages/SystemUI/src/com/android/systemui/Dependency.java
+++ b/packages/SystemUI/src/com/android/systemui/Dependency.java
@@ -39,10 +39,8 @@
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.bubbles.BubbleController;
import com.android.systemui.colorextraction.SysuiColorExtractor;
-import com.android.systemui.dagger.qualifiers.BgHandler;
-import com.android.systemui.dagger.qualifiers.BgLooper;
-import com.android.systemui.dagger.qualifiers.MainHandler;
-import com.android.systemui.dagger.qualifiers.MainLooper;
+import com.android.systemui.dagger.qualifiers.Background;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dock.DockManager;
import com.android.systemui.fragments.FragmentService;
import com.android.systemui.keyguard.ScreenLifecycle;
@@ -297,10 +295,10 @@
@Inject Lazy<SensorPrivacyManager> mSensorPrivacyManager;
@Inject Lazy<AutoHideController> mAutoHideController;
@Inject Lazy<ForegroundServiceNotificationListener> mForegroundServiceNotificationListener;
- @Inject @BgLooper Lazy<Looper> mBgLooper;
- @Inject @BgHandler Lazy<Handler> mBgHandler;
- @Inject @MainLooper Lazy<Looper> mMainLooper;
- @Inject @MainHandler Lazy<Handler> mMainHandler;
+ @Inject @Background Lazy<Looper> mBgLooper;
+ @Inject @Background Lazy<Handler> mBgHandler;
+ @Inject @Main Lazy<Looper> mMainLooper;
+ @Inject @Main Lazy<Handler> mMainHandler;
@Inject @Named(TIME_TICK_HANDLER_NAME) Lazy<Handler> mTimeTickHandler;
@Nullable
@Inject @Named(LEAK_REPORT_EMAIL_NAME) Lazy<String> mLeakReportEmail;
diff --git a/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java b/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java
index 41dd5bbf..82e665b 100644
--- a/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java
+++ b/packages/SystemUI/src/com/android/systemui/ForegroundServiceController.java
@@ -24,7 +24,7 @@
import com.android.internal.messages.nano.SystemMessageProto;
import com.android.systemui.appops.AppOpsController;
-import com.android.systemui.dagger.qualifiers.MainHandler;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.util.Assert;
@@ -50,7 +50,7 @@
@Inject
public ForegroundServiceController(NotificationEntryManager entryManager,
- AppOpsController appOpsController, @MainHandler Handler mainHandler) {
+ AppOpsController appOpsController, @Main Handler mainHandler) {
mEntryManager = entryManager;
mMainHandler = mainHandler;
appOpsController.addCallback(APP_OPS, (code, uid, packageName, active) -> {
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index 9ce277e..0e736dc 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -68,7 +68,7 @@
import com.android.internal.util.Preconditions;
import com.android.systemui.RegionInterceptingFrameLayout.RegionInterceptableView;
import com.android.systemui.broadcast.BroadcastDispatcher;
-import com.android.systemui.dagger.qualifiers.MainHandler;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.fragments.FragmentHostManager;
import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
import com.android.systemui.plugins.qs.QS;
@@ -147,7 +147,7 @@
@Inject
public ScreenDecorations(Context context,
Lazy<StatusBar> statusBarLazy,
- @MainHandler Handler handler,
+ @Main Handler handler,
BroadcastDispatcher broadcastDispatcher,
TunerService tunerService) {
super(context);
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIService.java b/packages/SystemUI/src/com/android/systemui/SystemUIService.java
index 1645957..41d8314 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIService.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIService.java
@@ -27,7 +27,7 @@
import android.util.Slog;
import com.android.internal.os.BinderInternal;
-import com.android.systemui.dagger.qualifiers.MainHandler;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.shared.plugins.PluginManager;
import com.android.systemui.shared.plugins.PluginManagerImpl;
@@ -41,7 +41,7 @@
private final Handler mMainHandler;
@Inject
- public SystemUIService(@MainHandler Handler mainHandler) {
+ public SystemUIService(@Main Handler mainHandler) {
super();
mMainHandler = mainHandler;
}
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java
index 6178ff2..895207d 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/WindowMagnification.java
@@ -22,7 +22,7 @@
import android.provider.Settings;
import com.android.systemui.SystemUI;
-import com.android.systemui.dagger.qualifiers.MainHandler;
+import com.android.systemui.dagger.qualifiers.Main;
import javax.inject.Inject;
import javax.inject.Singleton;
@@ -36,7 +36,7 @@
private final Handler mHandler;
@Inject
- public WindowMagnification(Context context, @MainHandler Handler mainHandler) {
+ public WindowMagnification(Context context, @Main Handler mainHandler) {
super(context);
mHandler = mainHandler;
}
diff --git a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java
index bad6b54..b083123 100644
--- a/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/appops/AppOpsControllerImpl.java
@@ -30,7 +30,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.DumpController;
import com.android.systemui.Dumpable;
-import com.android.systemui.dagger.qualifiers.BgLooper;
+import com.android.systemui.dagger.qualifiers.Background;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -81,7 +81,7 @@
};
@Inject
- public AppOpsControllerImpl(Context context, @BgLooper Looper bgLooper,
+ public AppOpsControllerImpl(Context context, @Background Looper bgLooper,
DumpController dumpController) {
this(context, bgLooper, new PermissionFlagsCache(context), dumpController);
}
diff --git a/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt b/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt
index 5cc70bc..8cb0cc5 100644
--- a/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt
+++ b/packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt
@@ -28,8 +28,8 @@
import android.util.SparseArray
import com.android.internal.annotations.VisibleForTesting
import com.android.systemui.Dumpable
-import com.android.systemui.dagger.qualifiers.BgLooper
-import com.android.systemui.dagger.qualifiers.MainHandler
+import com.android.systemui.dagger.qualifiers.Background
+import com.android.systemui.dagger.qualifiers.Main
import java.io.FileDescriptor
import java.io.PrintWriter
import javax.inject.Inject
@@ -62,8 +62,8 @@
@Singleton
open class BroadcastDispatcher @Inject constructor (
private val context: Context,
- @MainHandler private val mainHandler: Handler,
- @BgLooper private val bgLooper: Looper
+ @Main private val mainHandler: Handler,
+ @Background private val bgLooper: Looper
) : Dumpable {
// Only modify in BG thread
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java
index db85fa0..4663b1c 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/FalsingManagerProxy.java
@@ -30,7 +30,7 @@
import com.android.systemui.Dependency;
import com.android.systemui.classifier.brightline.BrightLineFalsingManager;
import com.android.systemui.classifier.brightline.FalsingDataProvider;
-import com.android.systemui.dagger.qualifiers.MainHandler;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.FalsingPlugin;
import com.android.systemui.plugins.PluginListener;
@@ -61,7 +61,7 @@
@Inject
FalsingManagerProxy(Context context, PluginManager pluginManager,
- @MainHandler Handler handler,
+ @Main Handler handler,
ProximitySensor proximitySensor,
DeviceConfigProxy deviceConfig) {
mProximitySensor = proximitySensor;
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
index 0d161ce..8d10552 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/DependencyProvider.java
@@ -25,8 +25,6 @@
import android.hardware.display.NightDisplayListener;
import android.os.Handler;
import android.os.HandlerThread;
-import android.os.Looper;
-import android.os.Process;
import android.os.ServiceManager;
import android.util.DisplayMetrics;
import android.view.IWindowManager;
@@ -35,10 +33,8 @@
import com.android.internal.logging.MetricsLogger;
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.ViewMediatorCallback;
-import com.android.systemui.dagger.qualifiers.BgHandler;
-import com.android.systemui.dagger.qualifiers.BgLooper;
-import com.android.systemui.dagger.qualifiers.MainHandler;
-import com.android.systemui.dagger.qualifiers.MainLooper;
+import com.android.systemui.dagger.qualifiers.Background;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.doze.AlwaysOnDisplayPolicy;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.plugins.PluginInitializerImpl;
@@ -82,35 +78,6 @@
return new Handler(thread.getLooper());
}
- @Singleton
- @Provides
- @BgLooper
- public Looper provideBgLooper() {
- HandlerThread thread = new HandlerThread("SysUiBg",
- Process.THREAD_PRIORITY_BACKGROUND);
- thread.start();
- return thread.getLooper();
- }
-
- /** Main Looper */
- @Provides
- @MainLooper
- public Looper provideMainLooper() {
- return Looper.getMainLooper();
- }
-
- @Provides
- @BgHandler
- public Handler provideBgHandler(@BgLooper Looper bgLooper) {
- return new Handler(bgLooper);
- }
-
- @Provides
- @MainHandler
- public Handler provideMainHandler(@MainLooper Looper mainLooper) {
- return new Handler(mainLooper);
- }
-
/** */
@Provides
public AmbientDisplayConfiguration provideAmbientDispalyConfiguration(Context context) {
@@ -175,7 +142,7 @@
@Singleton
@Provides
public NightDisplayListener provideNightDisplayListener(Context context,
- @BgHandler Handler bgHandler) {
+ @Background Handler bgHandler) {
return new NightDisplayListener(context, bgHandler);
}
@@ -188,7 +155,7 @@
@Singleton
@Provides
public NavigationBarController provideNavigationBarController(Context context,
- @MainHandler Handler mainHandler, CommandQueue commandQueue) {
+ @Main Handler mainHandler, CommandQueue commandQueue) {
return new NavigationBarController(context, mainHandler, commandQueue);
}
@@ -201,7 +168,7 @@
@Singleton
@Provides
public AutoHideController provideAutoHideController(Context context,
- @MainHandler Handler mainHandler,
+ @Main Handler mainHandler,
NotificationRemoteInputManager notificationRemoteInputManager,
IWindowManager iWindowManager) {
return new AutoHideController(context, mainHandler, notificationRemoteInputManager,
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/SystemServicesModule.java b/packages/SystemUI/src/com/android/systemui/dagger/SystemServicesModule.java
index 534f350..0b73ab6 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/SystemServicesModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dagger/SystemServicesModule.java
@@ -44,8 +44,8 @@
import com.android.internal.statusbar.IStatusBarService;
import com.android.internal.util.LatencyTracker;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
-import com.android.systemui.dagger.qualifiers.BgHandler;
-import com.android.systemui.dagger.qualifiers.MainResources;
+import com.android.systemui.dagger.qualifiers.Background;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.shared.system.PackageManagerWrapper;
import javax.inject.Singleton;
@@ -126,7 +126,7 @@
@Provides
@Nullable
static LocalBluetoothManager provideLocalBluetoothController(Context context,
- @BgHandler Handler bgHandler) {
+ @Background Handler bgHandler) {
return LocalBluetoothManager.create(context, bgHandler, UserHandle.ALL);
}
@@ -150,7 +150,7 @@
}
@Provides
- @MainResources
+ @Main
static Resources provideResources(Context context) {
return context.getResources();
}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/qualifiers/BgLooper.java b/packages/SystemUI/src/com/android/systemui/dagger/qualifiers/BgLooper.java
deleted file mode 100644
index 2aadda1..0000000
--- a/packages/SystemUI/src/com/android/systemui/dagger/qualifiers/BgLooper.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.dagger.qualifiers;
-
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-
-import javax.inject.Qualifier;
-
-@Qualifier
-@Documented
-@Retention(RUNTIME)
-public @interface BgLooper {
-}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/qualifiers/MainHandler.java b/packages/SystemUI/src/com/android/systemui/dagger/qualifiers/MainHandler.java
deleted file mode 100644
index 79661fa..0000000
--- a/packages/SystemUI/src/com/android/systemui/dagger/qualifiers/MainHandler.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.dagger.qualifiers;
-
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-
-import javax.inject.Qualifier;
-
-@Qualifier
-@Documented
-@Retention(RUNTIME)
-public @interface MainHandler {
-}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/qualifiers/MainLooper.java b/packages/SystemUI/src/com/android/systemui/dagger/qualifiers/MainLooper.java
deleted file mode 100644
index 750d7d7..0000000
--- a/packages/SystemUI/src/com/android/systemui/dagger/qualifiers/MainLooper.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.dagger.qualifiers;
-
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-
-import javax.inject.Qualifier;
-
-@Qualifier
-@Documented
-@Retention(RUNTIME)
-public @interface MainLooper {
-}
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/qualifiers/MainResources.java b/packages/SystemUI/src/com/android/systemui/dagger/qualifiers/MainResources.java
deleted file mode 100644
index 3daeda5..0000000
--- a/packages/SystemUI/src/com/android/systemui/dagger/qualifiers/MainResources.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.dagger.qualifiers;
-
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-
-import javax.inject.Qualifier;
-
-@Qualifier
-@Documented
-@Retention(RUNTIME)
-public @interface MainResources {
- // TODO: use attribute to get other, non-main resources?
-}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSCarrierGroupController.java b/packages/SystemUI/src/com/android/systemui/qs/QSCarrierGroupController.java
index ac94858..fb10642 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSCarrierGroupController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSCarrierGroupController.java
@@ -32,8 +32,8 @@
import androidx.annotation.VisibleForTesting;
import com.android.keyguard.CarrierTextController;
-import com.android.systemui.dagger.qualifiers.BgHandler;
-import com.android.systemui.dagger.qualifiers.MainLooper;
+import com.android.systemui.dagger.qualifiers.Background;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.statusbar.policy.NetworkController;
@@ -111,7 +111,7 @@
}
private QSCarrierGroupController(QSCarrierGroup view, ActivityStarter activityStarter,
- @BgHandler Handler bgHandler, @MainLooper Looper mainLooper,
+ @Background Handler bgHandler, @Main Looper mainLooper,
NetworkController networkController,
CarrierTextController.Builder carrierTextControllerBuilder) {
mActivityStarter = activityStarter;
@@ -308,8 +308,8 @@
private final CarrierTextController.Builder mCarrierTextControllerBuilder;
@Inject
- public Builder(ActivityStarter activityStarter, @BgHandler Handler handler,
- @MainLooper Looper looper, NetworkController networkController,
+ public Builder(ActivityStarter activityStarter, @Background Handler handler,
+ @Main Looper looper, NetworkController networkController,
CarrierTextController.Builder carrierTextControllerBuilder) {
mActivityStarter = activityStarter;
mHandler = handler;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
index c01bc8fe..86ed274 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileHost.java
@@ -34,8 +34,8 @@
import com.android.systemui.Dumpable;
import com.android.systemui.R;
import com.android.systemui.broadcast.BroadcastDispatcher;
-import com.android.systemui.dagger.qualifiers.BgLooper;
-import com.android.systemui.dagger.qualifiers.MainHandler;
+import com.android.systemui.dagger.qualifiers.Background;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.PluginListener;
import com.android.systemui.plugins.qs.QSFactory;
import com.android.systemui.plugins.qs.QSTile;
@@ -96,8 +96,8 @@
public QSTileHost(Context context,
StatusBarIconController iconController,
QSFactoryImpl defaultFactory,
- @MainHandler Handler mainHandler,
- @BgLooper Looper bgLooper,
+ @Main Handler mainHandler,
+ @Background Looper bgLooper,
PluginManager pluginManager,
TunerService tunerService,
Provider<AutoTileManager> autoTiles,
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
index c9813db..02c4beb 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/GlobalScreenshot.java
@@ -68,7 +68,7 @@
import android.widget.Toast;
import com.android.systemui.R;
-import com.android.systemui.dagger.qualifiers.MainResources;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.statusbar.phone.StatusBar;
@@ -186,7 +186,7 @@
*/
@Inject
public GlobalScreenshot(
- Context context, @MainResources Resources resources, LayoutInflater layoutInflater,
+ Context context, @Main Resources resources, LayoutInflater layoutInflater,
ScreenshotNotificationsController screenshotNotificationsController) {
mContext = context;
mNotificationsController = screenshotNotificationsController;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java b/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java
index 61043fb..a8188b3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NavigationBarController.java
@@ -35,7 +35,7 @@
import com.android.internal.statusbar.RegisterStatusBarResult;
import com.android.systemui.Dependency;
import com.android.systemui.assist.AssistHandleViewController;
-import com.android.systemui.dagger.qualifiers.MainHandler;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.fragments.FragmentHostManager;
import com.android.systemui.plugins.DarkIconDispatcher;
import com.android.systemui.statusbar.CommandQueue.Callbacks;
@@ -65,7 +65,7 @@
SparseArray<NavigationBarFragment> mNavigationBars = new SparseArray<>();
@Inject
- public NavigationBarController(Context context, @MainHandler Handler handler,
+ public NavigationBarController(Context context, @Main Handler handler,
CommandQueue commandQueue) {
mContext = context;
mHandler = handler;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java
index 97dd3da..8dd801b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationListener.java
@@ -30,7 +30,7 @@
import android.service.notification.StatusBarNotification;
import android.util.Log;
-import com.android.systemui.dagger.qualifiers.MainHandler;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.statusbar.phone.NotificationListenerWithPlugins;
import java.util.ArrayList;
@@ -58,7 +58,7 @@
public NotificationListener(
Context context,
NotificationManager notificationManager,
- @MainHandler Handler mainHandler) {
+ @Main Handler mainHandler) {
mContext = context;
mNotificationManager = notificationManager;
mMainHandler = mainHandler;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
index 0f3f6b7..2e369b3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
@@ -48,7 +48,7 @@
import com.android.systemui.Dependency;
import com.android.systemui.Dumpable;
import com.android.systemui.broadcast.BroadcastDispatcher;
-import com.android.systemui.dagger.qualifiers.MainHandler;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
import com.android.systemui.recents.OverviewProxyService;
@@ -190,7 +190,7 @@
IStatusBarService iStatusBarService,
KeyguardManager keyguardManager,
StatusBarStateController statusBarStateController,
- @MainHandler Handler mainHandler,
+ @Main Handler mainHandler,
DeviceProvisionedController deviceProvisionedController,
KeyguardStateController keyguardStateController) {
mContext = context;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
index f6f3ac1..43d0399 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
@@ -50,7 +50,7 @@
import com.android.internal.statusbar.NotificationVisibility;
import com.android.systemui.Dumpable;
import com.android.systemui.R;
-import com.android.systemui.dagger.qualifiers.MainHandler;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.notification.NotificationEntryListener;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
@@ -263,7 +263,7 @@
NotificationEntryManager notificationEntryManager,
Lazy<StatusBar> statusBarLazy,
StatusBarStateController statusBarStateController,
- @MainHandler Handler mainHandler,
+ @Main Handler mainHandler,
RemoteInputUriController remoteInputUriController) {
mContext = context;
mLockscreenUserManager = lockscreenUserManager;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
index 1648196..6b0b5df 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationViewHierarchyManager.java
@@ -27,7 +27,7 @@
import com.android.systemui.R;
import com.android.systemui.bubbles.BubbleController;
-import com.android.systemui.dagger.qualifiers.MainHandler;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.notification.DynamicPrivacyController;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
@@ -93,7 +93,7 @@
private boolean mIsHandleDynamicPrivacyChangeScheduled;
@Inject
- public NotificationViewHierarchyManager(Context context, @MainHandler Handler mainHandler,
+ public NotificationViewHierarchyManager(Context context, @Main Handler mainHandler,
NotificationLockscreenUserManager notificationLockscreenUserManager,
NotificationGroupManager groupManager,
VisualStabilityManager visualStabilityManager,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java
index 1b57308..99718abb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/VisualStabilityManager.java
@@ -23,7 +23,7 @@
import androidx.collection.ArraySet;
import com.android.systemui.Dumpable;
-import com.android.systemui.dagger.qualifiers.MainHandler;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.statusbar.NotificationPresenter;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
@@ -62,7 +62,7 @@
@Inject
public VisualStabilityManager(
- NotificationEntryManager notificationEntryManager, @MainHandler Handler handler) {
+ NotificationEntryManager notificationEntryManager, @Main Handler handler) {
mHandler = handler;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ForegroundCoordinator.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ForegroundCoordinator.java
index ee841c2..62342b1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ForegroundCoordinator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ForegroundCoordinator.java
@@ -24,7 +24,7 @@
import com.android.systemui.ForegroundServiceController;
import com.android.systemui.appops.AppOpsController;
-import com.android.systemui.dagger.qualifiers.MainHandler;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.statusbar.notification.collection.NotifCollection;
import com.android.systemui.statusbar.notification.collection.NotifCollectionListener;
import com.android.systemui.statusbar.notification.collection.NotifLifetimeExtender;
@@ -63,7 +63,7 @@
public ForegroundCoordinator(
ForegroundServiceController foregroundServiceController,
AppOpsController appOpsController,
- @MainHandler Handler mainHandler) {
+ @Main Handler mainHandler) {
mForegroundServiceController = foregroundServiceController;
mAppOpsController = appOpsController;
mMainHandler = mainHandler;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleHubViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleHubViewController.kt
index e9d6a0f..ec1d6de 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleHubViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleHubViewController.kt
@@ -23,7 +23,7 @@
import android.os.UserHandle
import android.provider.Settings
import android.view.View
-import com.android.systemui.dagger.qualifiers.MainHandler
+import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.statusbar.notification.stack.NotificationSectionsManager
import javax.inject.Inject
@@ -164,7 +164,7 @@
@Singleton
class PeopleHubSettingChangeDataSourceImpl @Inject constructor(
- @MainHandler private val handler: Handler,
+ @Main private val handler: Handler,
context: Context
) : DataSource<Boolean> {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
index 9dd7f48..6f2abba 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationGutsManager.java
@@ -42,7 +42,7 @@
import com.android.internal.logging.nano.MetricsProto;
import com.android.systemui.Dependency;
import com.android.systemui.Dumpable;
-import com.android.systemui.dagger.qualifiers.MainHandler;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.NotificationLifetimeExtender;
@@ -108,7 +108,7 @@
@Inject
public NotificationGutsManager(Context context, VisualStabilityManager visualStabilityManager,
- Lazy<StatusBar> statusBarLazy, @MainHandler Handler mainHandler,
+ Lazy<StatusBar> statusBarLazy, @Main Handler mainHandler,
AccessibilityManager accessibilityManager) {
mContext = context;
mVisualStabilityManager = visualStabilityManager;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideController.java
index f9b9367..3165597 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoHideController.java
@@ -23,7 +23,7 @@
import android.view.IWindowManager;
import android.view.MotionEvent;
-import com.android.systemui.dagger.qualifiers.MainHandler;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.statusbar.NotificationRemoteInputManager;
import javax.inject.Inject;
@@ -52,7 +52,7 @@
};
@Inject
- public AutoHideController(Context context, @MainHandler Handler handler,
+ public AutoHideController(Context context, @Main Handler handler,
NotificationRemoteInputManager notificationRemoteInputManager,
IWindowManager iWindowManager) {
mHandler = handler;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
index 837517e..0680c7f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/AutoTileManager.java
@@ -21,7 +21,7 @@
import android.provider.Settings.Secure;
import com.android.internal.annotations.VisibleForTesting;
-import com.android.systemui.dagger.qualifiers.BgHandler;
+import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.qs.AutoAddTracker;
import com.android.systemui.qs.QSTileHost;
import com.android.systemui.qs.SecureSetting;
@@ -57,7 +57,7 @@
@Inject
public AutoTileManager(Context context, AutoAddTracker autoAddTracker, QSTileHost host,
- @BgHandler Handler handler,
+ @Background Handler handler,
HotspotController hotspotController,
DataSaverController dataSaverController,
ManagedProfileController managedProfileController,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
index 250f730..4880520 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/BiometricUnlockController.java
@@ -37,7 +37,7 @@
import com.android.systemui.Dependency;
import com.android.systemui.DumpController;
import com.android.systemui.Dumpable;
-import com.android.systemui.dagger.qualifiers.MainResources;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.keyguard.ScreenLifecycle;
import com.android.systemui.keyguard.WakefulnessLifecycle;
@@ -165,7 +165,7 @@
StatusBarWindowController statusBarWindowController,
KeyguardStateController keyguardStateController, Handler handler,
KeyguardUpdateMonitor keyguardUpdateMonitor,
- @MainResources Resources resources,
+ @Main Resources resources,
KeyguardBypassController keyguardBypassController, DozeParameters dozeParameters,
MetricsLogger metricsLogger, DumpController dumpController) {
mContext = context;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
index bc48235..f5999f5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/DozeParameters.java
@@ -25,7 +25,7 @@
import android.util.MathUtils;
import com.android.systemui.R;
-import com.android.systemui.dagger.qualifiers.MainResources;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.doze.AlwaysOnDisplayPolicy;
import com.android.systemui.doze.DozeScreenState;
import com.android.systemui.tuner.TunerService;
@@ -58,7 +58,7 @@
@Inject
protected DozeParameters(
- @MainResources Resources resources,
+ @Main Resources resources,
AmbientDisplayConfiguration ambientDisplayConfiguration,
AlwaysOnDisplayPolicy alwaysOnDisplayPolicy,
PowerManager powerManager,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java
index 183adeb..4ee13bf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockscreenWallpaper.java
@@ -43,7 +43,7 @@
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.systemui.DumpController;
import com.android.systemui.Dumpable;
-import com.android.systemui.dagger.qualifiers.MainHandler;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.statusbar.NotificationMediaManager;
import libcore.io.IoUtils;
@@ -83,7 +83,7 @@
KeyguardUpdateMonitor keyguardUpdateMonitor,
DumpController dumpController,
NotificationMediaManager mediaManager,
- @MainHandler Handler mainHandler) {
+ @Main Handler mainHandler) {
dumpController.registerDumpable(getClass().getSimpleName(), this);
mWallpaperManager = wallpaperManager;
mCurrentUserId = ActivityManager.getCurrentUser();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
index ebe2117..d4cf272 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarFragment.java
@@ -93,7 +93,7 @@
import com.android.systemui.assist.AssistHandleViewController;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.broadcast.BroadcastDispatcher;
-import com.android.systemui.dagger.qualifiers.MainHandler;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.fragments.FragmentHostManager;
import com.android.systemui.fragments.FragmentHostManager.FragmentListener;
import com.android.systemui.model.SysUiState;
@@ -274,7 +274,7 @@
CommandQueue commandQueue, Divider divider,
Optional<Recents> recentsOptional, Lazy<StatusBar> statusBarLazy,
ShadeController shadeController,
- @MainHandler Handler mainHandler) {
+ @Main Handler mainHandler) {
mAccessibilityManagerWrapper = accessibilityManagerWrapper;
mDeviceProvisionedController = deviceProvisionedController;
mStatusBarStateController = statusBarStateController;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
index 4c5bbce..2b9fc8d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -45,7 +45,7 @@
import com.android.systemui.Dumpable;
import com.android.systemui.R;
import com.android.systemui.colorextraction.SysuiColorExtractor;
-import com.android.systemui.dagger.qualifiers.MainResources;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dock.DockManager;
import com.android.systemui.statusbar.ScrimView;
import com.android.systemui.statusbar.notification.stack.ViewState;
@@ -192,7 +192,7 @@
@Inject
public ScrimController(LightBarController lightBarController, DozeParameters dozeParameters,
AlarmManager alarmManager, KeyguardStateController keyguardStateController,
- @MainResources Resources resources,
+ @Main Resources resources,
DelayedWakeLock.Builder delayedWakeLockBuilder, Handler handler,
KeyguardUpdateMonitor keyguardUpdateMonitor, SysuiColorExtractor sysuiColorExtractor,
DockManager dockManager) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
index 3123f8d..fa584d2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarter.java
@@ -52,8 +52,8 @@
import com.android.systemui.UiOffloadThread;
import com.android.systemui.assist.AssistManager;
import com.android.systemui.bubbles.BubbleController;
-import com.android.systemui.dagger.qualifiers.BgHandler;
-import com.android.systemui.dagger.qualifiers.MainHandler;
+import com.android.systemui.dagger.qualifiers.Background;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.CommandQueue;
@@ -549,8 +549,8 @@
NotificationInterruptionStateProvider notificationInterruptionStateProvider,
MetricsLogger metricsLogger,
LockPatternUtils lockPatternUtils,
- @MainHandler Handler mainThreadHandler,
- @BgHandler Handler backgroundHandler,
+ @Main Handler mainThreadHandler,
+ @Background Handler backgroundHandler,
ActivityIntentHelper activityIntentHelper,
BubbleController bubbleController,
ShadeController shadeController,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
index f94b2ee..ce498a3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarWindowController.java
@@ -41,7 +41,7 @@
import com.android.systemui.Dumpable;
import com.android.systemui.R;
import com.android.systemui.colorextraction.SysuiColorExtractor;
-import com.android.systemui.dagger.qualifiers.MainResources;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.keyguard.KeyguardViewMediator;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.plugins.statusbar.StatusBarStateController.StateListener;
@@ -105,7 +105,7 @@
ConfigurationController configurationController,
KeyguardBypassController keyguardBypassController, SysuiColorExtractor colorExtractor,
SuperStatusBarViewFactory superStatusBarViewFactory,
- @MainResources Resources resources) {
+ @Main Resources resources) {
mContext = context;
mWindowManager = windowManager;
mActivityManager = activityManager;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
index dc80906..f132058 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryControllerImpl.java
@@ -34,8 +34,8 @@
import com.android.settingslib.fuelgauge.Estimate;
import com.android.settingslib.utils.PowerUtil;
import com.android.systemui.broadcast.BroadcastDispatcher;
-import com.android.systemui.dagger.qualifiers.BgHandler;
-import com.android.systemui.dagger.qualifiers.MainHandler;
+import com.android.systemui.dagger.qualifiers.Background;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.power.EnhancedEstimates;
import java.io.FileDescriptor;
@@ -82,7 +82,7 @@
@Inject
BatteryControllerImpl(Context context, EnhancedEstimates enhancedEstimates,
PowerManager powerManager, BroadcastDispatcher broadcastDispatcher,
- @MainHandler Handler mainHandler, @BgHandler Handler bgHandler) {
+ @Main Handler mainHandler, @Background Handler bgHandler) {
mContext = context;
mMainHandler = mainHandler;
mBgHandler = bgHandler;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
index 6ededd246..0fc3d84 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/BluetoothControllerImpl.java
@@ -34,8 +34,8 @@
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.bluetooth.LocalBluetoothProfile;
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
-import com.android.systemui.dagger.qualifiers.BgLooper;
-import com.android.systemui.dagger.qualifiers.MainLooper;
+import com.android.systemui.dagger.qualifiers.Background;
+import com.android.systemui.dagger.qualifiers.Main;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -75,8 +75,8 @@
/**
*/
@Inject
- public BluetoothControllerImpl(Context context, @BgLooper Looper bgLooper,
- @MainLooper Looper mainLooper, @Nullable LocalBluetoothManager localBluetoothManager) {
+ public BluetoothControllerImpl(Context context, @Background Looper bgLooper,
+ @Main Looper mainLooper, @Nullable LocalBluetoothManager localBluetoothManager) {
mLocalBluetoothManager = localBluetoothManager;
mBgHandler = new Handler(bgLooper);
mHandler = new H(mainLooper);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImpl.java
index f6b770c..a3e2e76 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImpl.java
@@ -25,7 +25,7 @@
import android.util.Log;
import com.android.systemui.broadcast.BroadcastDispatcher;
-import com.android.systemui.dagger.qualifiers.MainHandler;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.settings.CurrentUserTracker;
import java.util.ArrayList;
@@ -50,7 +50,7 @@
/**
*/
@Inject
- public DeviceProvisionedControllerImpl(Context context, @MainHandler Handler mainHandler,
+ public DeviceProvisionedControllerImpl(Context context, @Main Handler mainHandler,
BroadcastDispatcher broadcastDispatcher) {
super(broadcastDispatcher);
mContext = context;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
index cd6ec05..df9c3f4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HotspotControllerImpl.java
@@ -26,7 +26,7 @@
import android.os.UserManager;
import android.util.Log;
-import com.android.systemui.dagger.qualifiers.MainHandler;
+import com.android.systemui.dagger.qualifiers.Main;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -59,7 +59,7 @@
* Controller used to retrieve information related to a hotspot.
*/
@Inject
- public HotspotControllerImpl(Context context, @MainHandler Handler mainHandler) {
+ public HotspotControllerImpl(Context context, @Main Handler mainHandler) {
mContext = context;
mConnectivityManager =
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
index d36bd75..570f153 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/LocationControllerImpl.java
@@ -37,7 +37,7 @@
import com.android.systemui.BootCompleteCache;
import com.android.systemui.broadcast.BroadcastDispatcher;
-import com.android.systemui.dagger.qualifiers.BgLooper;
+import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.util.Utils;
import java.util.ArrayList;
@@ -69,7 +69,7 @@
private final H mHandler = new H();
@Inject
- public LocationControllerImpl(Context context, @BgLooper Looper bgLooper,
+ public LocationControllerImpl(Context context, @Background Looper bgLooper,
BroadcastDispatcher broadcastDispatcher, BootCompleteCache bootCompleteCache) {
mContext = context;
mBroadcastDispatcher = broadcastDispatcher;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index 24492bf..f20a47b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -64,7 +64,7 @@
import com.android.systemui.Dumpable;
import com.android.systemui.R;
import com.android.systemui.broadcast.BroadcastDispatcher;
-import com.android.systemui.dagger.qualifiers.BgLooper;
+import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.settings.CurrentUserTracker;
import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
import com.android.systemui.statusbar.policy.MobileSignalController.MobileIconGroup;
@@ -177,7 +177,7 @@
* Construct this controller object and register for updates.
*/
@Inject
- public NetworkControllerImpl(Context context, @BgLooper Looper bgLooper,
+ public NetworkControllerImpl(Context context, @Background Looper bgLooper,
DeviceProvisionedController deviceProvisionedController,
BroadcastDispatcher broadcastDispatcher) {
this(context, (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE),
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
index c161458..019ef3b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SecurityControllerImpl.java
@@ -49,7 +49,7 @@
import com.android.internal.net.VpnConfig;
import com.android.systemui.R;
import com.android.systemui.broadcast.BroadcastDispatcher;
-import com.android.systemui.dagger.qualifiers.BgHandler;
+import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.settings.CurrentUserTracker;
import java.io.FileDescriptor;
@@ -101,7 +101,7 @@
/**
*/
@Inject
- public SecurityControllerImpl(Context context, @BgHandler Handler bgHandler,
+ public SecurityControllerImpl(Context context, @Background Handler bgHandler,
BroadcastDispatcher broadcastDispatcher) {
this(context, bgHandler, broadcastDispatcher, null);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyConstants.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyConstants.java
index 347d300..86fe3008 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyConstants.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyConstants.java
@@ -28,7 +28,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.config.sysui.SystemUiDeviceConfigFlags;
import com.android.systemui.R;
-import com.android.systemui.dagger.qualifiers.MainHandler;
+import com.android.systemui.dagger.qualifiers.Main;
import javax.inject.Inject;
import javax.inject.Singleton;
@@ -65,7 +65,7 @@
private final KeyValueListParser mParser = new KeyValueListParser(',');
@Inject
- public SmartReplyConstants(@MainHandler Handler handler, Context context) {
+ public SmartReplyConstants(@Main Handler handler, Context context) {
mHandler = handler;
mContext = context;
final Resources resources = mContext.getResources();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
index 13c0db9..2907cd4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserSwitcherController.java
@@ -60,7 +60,7 @@
import com.android.systemui.R;
import com.android.systemui.SystemUISecondaryUserService;
import com.android.systemui.broadcast.BroadcastDispatcher;
-import com.android.systemui.dagger.qualifiers.MainHandler;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.qs.DetailAdapter;
import com.android.systemui.qs.tiles.UserDetailView;
@@ -113,7 +113,7 @@
@Inject
public UserSwitcherController(Context context, KeyguardStateController keyguardStateController,
- @MainHandler Handler handler, ActivityStarter activityStarter,
+ @Main Handler handler, ActivityStarter activityStarter,
BroadcastDispatcher broadcastDispatcher) {
mContext = context;
mBroadcastDispatcher = broadcastDispatcher;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
index a2028e6..4376a01 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/ZenModeControllerImpl.java
@@ -40,7 +40,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.Dumpable;
import com.android.systemui.broadcast.BroadcastDispatcher;
-import com.android.systemui.dagger.qualifiers.MainHandler;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.qs.GlobalSetting;
import com.android.systemui.settings.CurrentUserTracker;
import com.android.systemui.util.Utils;
@@ -78,7 +78,7 @@
private NotificationManager.Policy mConsolidatedNotificationPolicy;
@Inject
- public ZenModeControllerImpl(Context context, @MainHandler Handler handler,
+ public ZenModeControllerImpl(Context context, @Main Handler handler,
BroadcastDispatcher broadcastDispatcher) {
super(broadcastDispatcher);
mContext = context;
diff --git a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
index f9d39b0..7758aba 100644
--- a/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
+++ b/packages/SystemUI/src/com/android/systemui/theme/ThemeOverlayController.java
@@ -36,7 +36,7 @@
import com.android.systemui.R;
import com.android.systemui.SystemUI;
import com.android.systemui.broadcast.BroadcastDispatcher;
-import com.android.systemui.dagger.qualifiers.BgHandler;
+import com.android.systemui.dagger.qualifiers.Background;
import com.google.android.collect.Sets;
@@ -70,7 +70,7 @@
@Inject
public ThemeOverlayController(Context context, BroadcastDispatcher broadcastDispatcher,
- @BgHandler Handler bgHandler) {
+ @Background Handler bgHandler) {
super(context);
mBroadcastDispatcher = broadcastDispatcher;
mBgHandler = bgHandler;
diff --git a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
index ce0032e..19f0ba2 100644
--- a/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/tuner/TunerServiceImpl.java
@@ -35,7 +35,7 @@
import com.android.systemui.DejankUtils;
import com.android.systemui.DemoMode;
import com.android.systemui.broadcast.BroadcastDispatcher;
-import com.android.systemui.dagger.qualifiers.MainHandler;
+import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.qs.QSTileHost;
import com.android.systemui.settings.CurrentUserTracker;
import com.android.systemui.statusbar.phone.StatusBarIconController;
@@ -82,7 +82,7 @@
/**
*/
@Inject
- public TunerServiceImpl(Context context, @MainHandler Handler mainHandler,
+ public TunerServiceImpl(Context context, @Main Handler mainHandler,
LeakDetector leakDetector, BroadcastDispatcher broadcastDispatcher) {
mContext = context;
mContentResolver = mContext.getContentResolver();
diff --git a/packages/SystemUI/src/com/android/systemui/util/concurrency/ConcurrencyModule.java b/packages/SystemUI/src/com/android/systemui/util/concurrency/ConcurrencyModule.java
index 3e90581..1c5d979 100644
--- a/packages/SystemUI/src/com/android/systemui/util/concurrency/ConcurrencyModule.java
+++ b/packages/SystemUI/src/com/android/systemui/util/concurrency/ConcurrencyModule.java
@@ -18,15 +18,17 @@
import android.content.Context;
import android.os.Handler;
+import android.os.HandlerThread;
import android.os.Looper;
+import android.os.Process;
import com.android.systemui.dagger.qualifiers.Background;
-import com.android.systemui.dagger.qualifiers.BgLooper;
import com.android.systemui.dagger.qualifiers.Main;
-import com.android.systemui.dagger.qualifiers.MainLooper;
import java.util.concurrent.Executor;
+import javax.inject.Singleton;
+
import dagger.Module;
import dagger.Provides;
@@ -35,11 +37,51 @@
*/
@Module
public abstract class ConcurrencyModule {
+ /** Background Looper */
+ @Provides
+ @Singleton
+ @Background
+ public static Looper provideBgLooper() {
+ HandlerThread thread = new HandlerThread("SysUiBg",
+ Process.THREAD_PRIORITY_BACKGROUND);
+ thread.start();
+ return thread.getLooper();
+ }
+
+ /** Main Looper */
+ @Provides
+ @Main
+ public static Looper provideMainLooper() {
+ return Looper.getMainLooper();
+ }
+
+ /**
+ * Background Handler.
+ *
+ * Prefer the Background Executor when possible.
+ */
+ @Provides
+ @Background
+ public static Handler provideBgHandler(@Background Looper bgLooper) {
+ return new Handler(bgLooper);
+ }
+
+ /**
+ * Main Handler.
+ *
+ * Prefer the Main Executor when possible.
+ */
+ @Provides
+ @Main
+ public static Handler provideMainHandler(@Main Looper mainLooper) {
+ return new Handler(mainLooper);
+ }
+
/**
* Provide a Background-Thread Executor by default.
*/
@Provides
- public static Executor provideExecutor(@BgLooper Looper looper) {
+ public static Executor provideExecutor(@Background Looper looper) {
return new ExecutorImpl(new Handler(looper));
}
@@ -48,7 +90,7 @@
*/
@Provides
@Background
- public static Executor provideBackgroundExecutor(@BgLooper Looper looper) {
+ public static Executor provideBackgroundExecutor(@Background Looper looper) {
return new ExecutorImpl(new Handler(looper));
}
@@ -65,7 +107,7 @@
* Provide a Background-Thread Executor by default.
*/
@Provides
- public static DelayableExecutor provideDelayableExecutor(@BgLooper Looper looper) {
+ public static DelayableExecutor provideDelayableExecutor(@Background Looper looper) {
return new ExecutorImpl(new Handler(looper));
}
@@ -74,7 +116,7 @@
*/
@Provides
@Background
- public static DelayableExecutor provideBackgroundDelayableExecutor(@BgLooper Looper looper) {
+ public static DelayableExecutor provideBackgroundDelayableExecutor(@Background Looper looper) {
return new ExecutorImpl(new Handler(looper));
}
@@ -83,7 +125,7 @@
*/
@Provides
@Main
- public static DelayableExecutor provideMainDelayableExecutor(@MainLooper Looper looper) {
+ public static DelayableExecutor provideMainDelayableExecutor(@Main Looper looper) {
return new ExecutorImpl(new Handler(looper));
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java b/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java
index bff405c..2c7c52e 100644
--- a/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java
@@ -47,7 +47,7 @@
import com.android.systemui.Dumpable;
import com.android.systemui.R;
import com.android.systemui.SystemUI;
-import com.android.systemui.dagger.qualifiers.BgLooper;
+import com.android.systemui.dagger.qualifiers.Background;
import com.android.systemui.plugins.ActivityStarter;
import com.android.systemui.plugins.qs.QSTile;
import com.android.systemui.qs.QSHost;
@@ -109,7 +109,7 @@
@Inject
public GarbageMonitor(
Context context,
- @BgLooper Looper bgLooper,
+ @Background Looper bgLooper,
LeakDetector leakDetector,
LeakReporter leakReporter) {
mContext = context.getApplicationContext();
diff --git a/packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensor.java b/packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensor.java
index a96977a..b5bede4 100644
--- a/packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensor.java
+++ b/packages/SystemUI/src/com/android/systemui/util/sensors/ProximitySensor.java
@@ -26,7 +26,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.R;
-import com.android.systemui.dagger.qualifiers.MainResources;
+import com.android.systemui.dagger.qualifiers.Main;
import java.util.ArrayList;
import java.util.List;
@@ -65,7 +65,7 @@
};
@Inject
- public ProximitySensor(@MainResources Resources resources,
+ public ProximitySensor(@Main Resources resources,
AsyncSensorManager sensorManager) {
mSensorManager = sensorManager;
Sensor sensor = findBrightnessSensor(resources);
diff --git a/packages/SystemUI/src/com/android/systemui/wm/DisplayWindowController.java b/packages/SystemUI/src/com/android/systemui/wm/DisplayWindowController.java
index aed90eb..951d6dd 100644
--- a/packages/SystemUI/src/com/android/systemui/wm/DisplayWindowController.java
+++ b/packages/SystemUI/src/com/android/systemui/wm/DisplayWindowController.java
@@ -31,7 +31,7 @@
import android.view.IWindowManager;
import android.view.WindowContainerTransaction;
-import com.android.systemui.dagger.qualifiers.MainHandler;
+import com.android.systemui.dagger.qualifiers.Main;
import java.util.ArrayList;
@@ -160,7 +160,7 @@
};
@Inject
- public DisplayWindowController(Context context, @MainHandler Handler mainHandler,
+ public DisplayWindowController(Context context, @Main Handler mainHandler,
IWindowManager wmService) {
mHandler = mainHandler;
mContext = context;
diff --git a/packages/WindowManager/OWNERS b/packages/WindowManager/OWNERS
new file mode 100644
index 0000000..063d459
--- /dev/null
+++ b/packages/WindowManager/OWNERS
@@ -0,0 +1,3 @@
+set noparent
+
+include ../../services/core/java/com/android/server/wm/OWNERS
\ No newline at end of file
diff --git a/packages/WindowManager/Shell/Android.bp b/packages/WindowManager/Shell/Android.bp
new file mode 100644
index 0000000..b8934dc
--- /dev/null
+++ b/packages/WindowManager/Shell/Android.bp
@@ -0,0 +1,29 @@
+// Copyright (C) 2019 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.
+
+android_library {
+ name: "WindowManager-Shell",
+ srcs: [
+ "src/**/*.java",
+ "src/**/I*.aidl",
+ ],
+ resource_dirs: [
+ "res",
+ ],
+ manifest: "AndroidManifest.xml",
+
+ platform_apis: true,
+ sdk_version: "current",
+ min_sdk_version: "system_current",
+}
diff --git a/packages/WindowManager/Shell/AndroidManifest.xml b/packages/WindowManager/Shell/AndroidManifest.xml
new file mode 100644
index 0000000..ea8a5c3
--- /dev/null
+++ b/packages/WindowManager/Shell/AndroidManifest.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2019 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.wm.shell">
+</manifest>
diff --git a/packages/WindowManager/Shell/OWNERS b/packages/WindowManager/Shell/OWNERS
new file mode 100644
index 0000000..4390004
--- /dev/null
+++ b/packages/WindowManager/Shell/OWNERS
@@ -0,0 +1,4 @@
+# sysui owners
+hwwang@google.com
+mrenouf@google.com
+winsonc@google.com
\ No newline at end of file
diff --git a/packages/WindowManager/Shell/res/values/config.xml b/packages/WindowManager/Shell/res/values/config.xml
new file mode 100644
index 0000000..c894eb0
--- /dev/null
+++ b/packages/WindowManager/Shell/res/values/config.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2019, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<resources>
+</resources>
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/dagger/qualifiers/BgHandler.java b/packages/WindowManager/Shell/src/com/android/wm/shell/WindowManagerShell.java
similarity index 67%
rename from packages/SystemUI/src/com/android/systemui/dagger/qualifiers/BgHandler.java
rename to packages/WindowManager/Shell/src/com/android/wm/shell/WindowManagerShell.java
index bc6b83b..273bd27 100644
--- a/packages/SystemUI/src/com/android/systemui/dagger/qualifiers/BgHandler.java
+++ b/packages/WindowManager/Shell/src/com/android/wm/shell/WindowManagerShell.java
@@ -14,17 +14,10 @@
* limitations under the License.
*/
-package com.android.systemui.dagger.qualifiers;
+package com.android.wm.shell;
-import static java.lang.annotation.RetentionPolicy.RUNTIME;
-
-import java.lang.annotation.Documented;
-import java.lang.annotation.Retention;
-
-import javax.inject.Qualifier;
-
-@Qualifier
-@Documented
-@Retention(RUNTIME)
-public @interface BgHandler {
+/**
+ * Interface for the shell.
+ */
+public class WindowManagerShell {
}
diff --git a/packages/WindowManager/Shell/tests/Android.bp b/packages/WindowManager/Shell/tests/Android.bp
new file mode 100644
index 0000000..78fa45e
--- /dev/null
+++ b/packages/WindowManager/Shell/tests/Android.bp
@@ -0,0 +1,45 @@
+// Copyright (C) 2019 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.
+
+android_test {
+ name: "WindowManagerShellTests",
+
+ srcs: ["**/*.java"],
+
+ static_libs: [
+ "WindowManager-Shell",
+ "junit",
+ "androidx.test.runner",
+ "androidx.test.rules",
+ "androidx.test.ext.junit",
+ "mockito-target-extended-minus-junit4",
+ "truth-prebuilt",
+ ],
+ libs: [
+ "android.test.mock",
+ "android.test.base",
+ "android.test.runner",
+ ],
+ jni_libs: [
+ "libdexmakerjvmtiagent",
+ "libstaticjvmtiagent",
+ ],
+
+ sdk_version: "current",
+ platform_apis: true,
+
+ optimize: {
+ enabled: false,
+ },
+}
diff --git a/packages/WindowManager/Shell/tests/AndroidManifest.xml b/packages/WindowManager/Shell/tests/AndroidManifest.xml
new file mode 100644
index 0000000..a8f795e
--- /dev/null
+++ b/packages/WindowManager/Shell/tests/AndroidManifest.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ package="com.android.wm.shell.tests">
+
+ <application android:debuggable="true" android:largeHeap="true">
+ <uses-library android:name="android.test.mock" />
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <instrumentation
+ android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:label="Tests for WindowManager-Shell"
+ android:targetPackage="com.android.wm.shell.tests">
+ </instrumentation>
+</manifest>
diff --git a/packages/WindowManager/Shell/tests/AndroidTest.xml b/packages/WindowManager/Shell/tests/AndroidTest.xml
new file mode 100644
index 0000000..4dce4db
--- /dev/null
+++ b/packages/WindowManager/Shell/tests/AndroidTest.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2019 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.
+-->
+<configuration description="Runs Tests for WindowManagerShellLib">
+ <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+ <option name="cleanup-apks" value="true" />
+ <option name="install-arg" value="-t" />
+ <option name="test-file-name" value="WindowManagerShellTests.apk" />
+ </target_preparer>
+
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-suite-tag" value="framework-base-presubmit" />
+ <option name="test-tag" value="WindowManagerShellTests" />
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+ <option name="package" value="com.android.wm.shell.tests" />
+ <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
+ <option name="hidden-api-checks" value="false"/>
+ </test>
+</configuration>
diff --git a/packages/WindowManager/Shell/tests/res/values/config.xml b/packages/WindowManager/Shell/tests/res/values/config.xml
new file mode 100644
index 0000000..c894eb0
--- /dev/null
+++ b/packages/WindowManager/Shell/tests/res/values/config.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+** Copyright 2019, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+
+<resources>
+</resources>
\ No newline at end of file
diff --git a/packages/WindowManager/Shell/tests/src/com/android/wm/shell/tests/WindowManagerShellTest.java b/packages/WindowManager/Shell/tests/src/com/android/wm/shell/tests/WindowManagerShellTest.java
new file mode 100644
index 0000000..376875b
--- /dev/null
+++ b/packages/WindowManager/Shell/tests/src/com/android/wm/shell/tests/WindowManagerShellTest.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.tests;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import com.android.wm.shell.WindowManagerShell;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Tests for the shell.
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class WindowManagerShellTest {
+
+ WindowManagerShell mShell;
+
+ @Test
+ public void testNothing() {
+ // Do nothing
+ }
+}
diff --git a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
index 81ce359..26245b1 100644
--- a/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
+++ b/services/appwidget/java/com/android/server/appwidget/AppWidgetServiceImpl.java
@@ -635,7 +635,7 @@
mPackageManagerInternal.getSuspendedDialogInfo(providerPackage,
suspendingPackage, providerUserId);
onClickIntent = SuspendedAppActivity.createSuspendedAppInterceptIntent(
- providerPackage, suspendingPackage, dialogInfo, providerUserId);
+ providerPackage, suspendingPackage, dialogInfo, null, providerUserId);
}
} else if (provider.maskedByQuietProfile) {
showBadge = true;
diff --git a/services/core/java/android/content/pm/PackageManagerInternal.java b/services/core/java/android/content/pm/PackageManagerInternal.java
index f363a73..40a7dfc 100644
--- a/services/core/java/android/content/pm/PackageManagerInternal.java
+++ b/services/core/java/android/content/pm/PackageManagerInternal.java
@@ -67,6 +67,27 @@
public static final int PACKAGE_COMPANION = 14;
@IntDef(value = {
+ INTEGRITY_VERIFICATION_ALLOW,
+ INTEGRITY_VERIFICATION_REJECT,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface IntegrityVerificationResult {}
+
+ /**
+ * Used as the {@code verificationCode} argument for
+ * {@link PackageManagerInternal#setIntegrityVerificationResult(int, int)} to indicate that the
+ * integrity component allows the install to proceed.
+ */
+ public static final int INTEGRITY_VERIFICATION_ALLOW = 1;
+
+ /**
+ * Used as the {@code verificationCode} argument for
+ * {@link PackageManagerInternal#setIntegrityVerificationResult(int, int)} to indicate that the
+ * integrity component does not allow install to proceed.
+ */
+ public static final int INTEGRITY_VERIFICATION_REJECT = 0;
+
+ @IntDef(value = {
PACKAGE_SYSTEM,
PACKAGE_SETUP_WIZARD,
PACKAGE_INSTALLER,
@@ -842,13 +863,13 @@
* {@link Intent#ACTION_PACKAGE_NEEDS_INTEGRITY_VERIFICATION package verification
* broadcast} to respond to the package manager. The response must include
* the {@code verificationCode} which is one of
- * {@link PackageManager#VERIFICATION_ALLOW} or
- * {@link PackageManager#VERIFICATION_REJECT}.
+ * {@link #INTEGRITY_VERIFICATION_ALLOW} and {@link #INTEGRITY_VERIFICATION_REJECT}.
*
* @param verificationId pending package identifier as passed via the
* {@link PackageManager#EXTRA_VERIFICATION_ID} Intent extra.
- * @param verificationResult either {@link PackageManager#VERIFICATION_ALLOW}
- * or {@link PackageManager#VERIFICATION_REJECT}.
+ * @param verificationResult either {@link #INTEGRITY_VERIFICATION_ALLOW}
+ * or {@link #INTEGRITY_VERIFICATION_REJECT}.
*/
- public abstract void setIntegrityVerificationResult(int verificationId, int verificationResult);
+ public abstract void setIntegrityVerificationResult(int verificationId,
+ @IntegrityVerificationResult int verificationResult);
}
diff --git a/services/core/java/com/android/server/TelephonyRegistry.java b/services/core/java/com/android/server/TelephonyRegistry.java
index 13eb556..46ff718 100644
--- a/services/core/java/com/android/server/TelephonyRegistry.java
+++ b/services/core/java/com/android/server/TelephonyRegistry.java
@@ -46,6 +46,7 @@
import android.telephony.Annotation.SrvccState;
import android.telephony.CallAttributes;
import android.telephony.CallQuality;
+import android.telephony.CellIdentity;
import android.telephony.CellInfo;
import android.telephony.CellLocation;
import android.telephony.DataFailCause;
@@ -207,7 +208,7 @@
// Connection state of default APN type data (i.e. internet) of phones
private int[] mDataConnectionState;
- private Bundle[] mCellLocation;
+ private CellIdentity[] mCellIdentity;
private int[] mDataConnectionNetworkType;
@@ -295,7 +296,7 @@
int numPhones = getTelephonyManager().getPhoneCount();
for (int sub = 0; sub < numPhones; sub++) {
TelephonyRegistry.this.notifyCellLocationForSubscriber(sub,
- mCellLocation[sub]);
+ mCellIdentity[sub]);
}
break;
}
@@ -404,7 +405,7 @@
mSignalStrength = copyOf(mSignalStrength, mNumPhones);
mMessageWaiting = copyOf(mMessageWaiting, mNumPhones);
mCallForwarding = copyOf(mCallForwarding, mNumPhones);
- mCellLocation = copyOf(mCellLocation, mNumPhones);
+ mCellIdentity = copyOf(mCellIdentity, mNumPhones);
mSrvccState = copyOf(mSrvccState, mNumPhones);
mPreciseCallState = copyOf(mPreciseCallState, mNumPhones);
mForegroundCallState = copyOf(mForegroundCallState, mNumPhones);
@@ -439,31 +440,22 @@
mUserMobileDataState[i] = false;
mMessageWaiting[i] = false;
mCallForwarding[i] = false;
- mCellLocation[i] = new Bundle();
+ mCellIdentity[i] = null;
mCellInfo.add(i, null);
mImsReasonInfo.add(i, null);
mSrvccState[i] = TelephonyManager.SRVCC_STATE_HANDOVER_NONE;
mCallDisconnectCause[i] = DisconnectCause.NOT_VALID;
mCallPreciseDisconnectCause[i] = PreciseDisconnectCause.NOT_VALID;
mCallQuality[i] = createCallQuality();
- mCallAttributes[i] = new CallAttributes(new PreciseCallState(),
+ mCallAttributes[i] = new CallAttributes(createPreciseCallState(),
TelephonyManager.NETWORK_TYPE_UNKNOWN, createCallQuality());
mCallNetworkType[i] = TelephonyManager.NETWORK_TYPE_UNKNOWN;
- mPreciseCallState[i] = new PreciseCallState();
+ mPreciseCallState[i] = createPreciseCallState();
mRingingCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
mForegroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
mBackgroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
mPreciseDataConnectionStates.add(new HashMap<String, PreciseDataConnectionState>());
}
-
- // Note that location can be null for non-phone builds like
- // like the generic one.
- CellLocation location = CellLocation.getEmpty();
- if (location != null) {
- for (int i = oldNumPhones; i < mNumPhones; i++) {
- location.fillInNotifierBundle(mCellLocation[i]);
- }
- }
}
private void cutListToSize(List list, int size) {
@@ -503,7 +495,7 @@
mSignalStrength = new SignalStrength[numPhones];
mMessageWaiting = new boolean[numPhones];
mCallForwarding = new boolean[numPhones];
- mCellLocation = new Bundle[numPhones];
+ mCellIdentity = new CellIdentity[numPhones];
mSrvccState = new int[numPhones];
mPreciseCallState = new PreciseCallState[numPhones];
mForegroundCallState = new int[numPhones];
@@ -532,31 +524,23 @@
mUserMobileDataState[i] = false;
mMessageWaiting[i] = false;
mCallForwarding[i] = false;
- mCellLocation[i] = new Bundle();
+ mCellIdentity[i] = null;
mCellInfo.add(i, null);
mImsReasonInfo.add(i, null);
mSrvccState[i] = TelephonyManager.SRVCC_STATE_HANDOVER_NONE;
mCallDisconnectCause[i] = DisconnectCause.NOT_VALID;
mCallPreciseDisconnectCause[i] = PreciseDisconnectCause.NOT_VALID;
mCallQuality[i] = createCallQuality();
- mCallAttributes[i] = new CallAttributes(new PreciseCallState(),
+ mCallAttributes[i] = new CallAttributes(createPreciseCallState(),
TelephonyManager.NETWORK_TYPE_UNKNOWN, createCallQuality());
mCallNetworkType[i] = TelephonyManager.NETWORK_TYPE_UNKNOWN;
- mPreciseCallState[i] = new PreciseCallState();
+ mPreciseCallState[i] = createPreciseCallState();
mRingingCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
mForegroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
mBackgroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
mPreciseDataConnectionStates.add(new HashMap<String, PreciseDataConnectionState>());
}
- // Note that location can be null for non-phone builds like
- // like the generic one.
- if (location != null) {
- for (int i = 0; i < numPhones; i++) {
- location.fillInNotifierBundle(mCellLocation[i]);
- }
- }
-
mAppOps = mContext.getSystemService(AppOpsManager.class);
}
@@ -837,11 +821,10 @@
}
if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION)) {
try {
- if (DBG_LOC) log("listen: mCellLocation = "
- + mCellLocation[phoneId]);
+ if (DBG_LOC) log("listen: mCellIdentity = " + mCellIdentity[phoneId]);
if (checkFineLocationAccess(r, Build.VERSION_CODES.Q)) {
- r.callback.onCellLocationChanged(
- new Bundle(mCellLocation[phoneId]));
+ // null will be translated to empty CellLocation object in client.
+ r.callback.onCellLocationChanged(mCellIdentity[phoneId]);
}
} catch (RemoteException ex) {
remove(r.binder);
@@ -1629,11 +1612,13 @@
broadcastDataConnectionFailed(apnType, subId);
}
- public void notifyCellLocation(Bundle cellLocation) {
- notifyCellLocationForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, cellLocation);
+ @Override
+ public void notifyCellLocation(CellIdentity cellLocation) {
+ notifyCellLocationForSubscriber(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, cellLocation);
}
- public void notifyCellLocationForSubscriber(int subId, Bundle cellLocation) {
+ @Override
+ public void notifyCellLocationForSubscriber(int subId, CellIdentity cellLocation) {
log("notifyCellLocationForSubscriber: subId=" + subId
+ " cellLocation=" + cellLocation);
if (!checkNotifyPermission("notifyCellLocation()")) {
@@ -1646,7 +1631,7 @@
int phoneId = getPhoneIdFromSubId(subId);
synchronized (mRecords) {
if (validatePhoneId(phoneId)) {
- mCellLocation[phoneId] = cellLocation;
+ mCellIdentity[phoneId] = cellLocation;
for (Record r : mRecords) {
if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION) &&
idMatch(r.subId, subId, phoneId) &&
@@ -1656,7 +1641,7 @@
log("notifyCellLocation: cellLocation=" + cellLocation
+ " r=" + r);
}
- r.callback.onCellLocationChanged(new Bundle(cellLocation));
+ r.callback.onCellLocationChanged(cellLocation);
} catch (RemoteException ex) {
mRemoveList.add(r.binder);
}
@@ -2093,7 +2078,7 @@
pw.println("mCallForwarding=" + mCallForwarding[i]);
pw.println("mDataActivity=" + mDataActivity[i]);
pw.println("mDataConnectionState=" + mDataConnectionState[i]);
- pw.println("mCellLocation=" + mCellLocation[i]);
+ pw.println("mCellIdentity=" + mCellIdentity[i]);
pw.println("mCellInfo=" + mCellInfo.get(i));
pw.println("mImsCallDisconnectCause=" + mImsReasonInfo.get(i));
pw.println("mSrvccState=" + mSrvccState[i]);
@@ -2583,10 +2568,13 @@
if (validateEventsAndUserLocked(r, PhoneStateListener.LISTEN_CELL_LOCATION)) {
try {
- if (DBG_LOC) log("checkPossibleMissNotify: onCellLocationChanged mCellLocation = "
- + mCellLocation[phoneId]);
+ if (DBG_LOC) {
+ log("checkPossibleMissNotify: onCellLocationChanged mCellIdentity = "
+ + mCellIdentity[phoneId]);
+ }
if (checkFineLocationAccess(r, Build.VERSION_CODES.Q)) {
- r.callback.onCellLocationChanged(new Bundle(mCellLocation[phoneId]));
+ // null will be translated to empty CellLocation object in client.
+ r.callback.onCellLocationChanged(mCellIdentity[phoneId]);
}
} catch (RemoteException ex) {
mRemoveList.add(r.binder);
@@ -2678,6 +2666,15 @@
}
}
+ /** Returns a new PreciseCallState object with default values. */
+ private static PreciseCallState createPreciseCallState() {
+ return new PreciseCallState(PreciseCallState.PRECISE_CALL_STATE_NOT_VALID,
+ PreciseCallState.PRECISE_CALL_STATE_NOT_VALID,
+ PreciseCallState.PRECISE_CALL_STATE_NOT_VALID,
+ DisconnectCause.NOT_VALID,
+ PreciseDisconnectCause.NOT_VALID);
+ }
+
/** Returns a new CallQuality object with default values. */
private static CallQuality createCallQuality() {
return new CallQuality(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 6dc49b7..d7a46fe 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -7558,6 +7558,26 @@
});
}
+ @Override
+ public void appNotResponding(final String reason) {
+ final int callingPid = Binder.getCallingPid();
+
+ synchronized (mPidsSelfLocked) {
+ final ProcessRecord app = mPidsSelfLocked.get(callingPid);
+ if (app == null) {
+ throw new SecurityException("Unknown process: " + callingPid);
+ }
+
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ app.appNotResponding(
+ null, app.info, null, null, false, "App requested: " + reason);
+ }
+ });
+ }
+ }
+
public final void installSystemProviders() {
List<ProviderInfo> providers;
synchronized (this) {
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 0b74840..9f23cdaf 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -2335,7 +2335,7 @@
} else {
final Op switchOp = switchCode != code ? getOpLocked(ops, switchCode, true) : op;
final int mode = switchOp.evalMode();
- if (switchOp.mode != AppOpsManager.MODE_ALLOWED) {
+ if (mode != AppOpsManager.MODE_ALLOWED) {
if (DEBUG) Slog.d(TAG, "noteOperation: reject #" + mode + " for code "
+ switchCode + " (" + code + ") uid " + uid + " package "
+ packageName);
diff --git a/services/core/java/com/android/server/incremental/IncrementalManagerService.java b/services/core/java/com/android/server/incremental/IncrementalManagerService.java
index 3049522..d673ec8 100644
--- a/services/core/java/com/android/server/incremental/IncrementalManagerService.java
+++ b/services/core/java/com/android/server/incremental/IncrementalManagerService.java
@@ -17,6 +17,7 @@
package com.android.server.incremental;
import android.annotation.NonNull;
+import android.content.ComponentName;
import android.content.Context;
import android.content.pm.DataLoaderManager;
import android.content.pm.DataLoaderParamsParcel;
@@ -85,7 +86,8 @@
DataLoaderParamsParcel params,
IDataLoaderStatusListener listener) {
Bundle dataLoaderParams = new Bundle();
- dataLoaderParams.putCharSequence("packageName", params.packageName);
+ dataLoaderParams.putParcelable("componentName",
+ new ComponentName(params.packageName, params.className));
dataLoaderParams.putParcelable("control", control);
dataLoaderParams.putParcelable("params", params);
DataLoaderManager dataLoaderManager = mContext.getSystemService(DataLoaderManager.class);
@@ -109,8 +111,7 @@
return false;
}
try {
- // TODO: fix file list
- dataLoader.start(null);
+ dataLoader.start();
return true;
} catch (RemoteException ex) {
return false;
diff --git a/services/core/java/com/android/server/incremental/IncrementalManagerShellCommand.java b/services/core/java/com/android/server/incremental/IncrementalManagerShellCommand.java
index 6a8434a..a68f777 100644
--- a/services/core/java/com/android/server/incremental/IncrementalManagerShellCommand.java
+++ b/services/core/java/com/android/server/incremental/IncrementalManagerShellCommand.java
@@ -19,6 +19,7 @@
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.content.ComponentName;
import android.content.Context;
import android.content.IIntentReceiver;
import android.content.IIntentSender;
@@ -111,14 +112,14 @@
pw.println("File names and sizes don't match.");
return ERROR_DATA_LOADER_INIT;
}
- final DataLoaderParams params = new DataLoaderParams(
- "", LOADER_PACKAGE_NAME, dataLoaderDynamicArgs);
+ final DataLoaderParams params = DataLoaderParams.forIncremental(
+ new ComponentName(LOADER_PACKAGE_NAME, ""), "", dataLoaderDynamicArgs);
PackageInstaller.SessionParams sessionParams = new PackageInstaller.SessionParams(
PackageInstaller.SessionParams.MODE_FULL_INSTALL);
sessionParams.installFlags |= PackageManager.INSTALL_ALL_USERS;
// Replace existing if same package is already installed
sessionParams.installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
- sessionParams.setIncrementalParams(params);
+ sessionParams.setDataLoaderParams(params);
try {
int sessionId = packageInstaller.createSession(sessionParams);
diff --git a/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java b/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
index 39c1b85..5c4479a 100644
--- a/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
+++ b/services/core/java/com/android/server/integrity/AppIntegrityManagerServiceImpl.java
@@ -23,7 +23,6 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.os.Handler;
import android.os.HandlerThread;
@@ -36,6 +35,8 @@
class AppIntegrityManagerServiceImpl {
private static final String TAG = "AppIntegrityManagerServiceImpl";
+ private static final String PACKAGE_MIME_TYPE = "application/vnd.android.package-archive";
+
private final Context mContext;
private final Handler mHandler;
private final PackageManagerInternal mPackageManagerInternal;
@@ -51,6 +52,11 @@
IntentFilter integrityVerificationFilter = new IntentFilter();
integrityVerificationFilter.addAction(ACTION_PACKAGE_NEEDS_INTEGRITY_VERIFICATION);
+ try {
+ integrityVerificationFilter.addDataType(PACKAGE_MIME_TYPE);
+ } catch (IntentFilter.MalformedMimeTypeException e) {
+ throw new RuntimeException("Mime type malformed: should never happen.", e);
+ }
mContext.registerReceiver(
new BroadcastReceiver() {
@@ -74,7 +80,8 @@
int verificationId = intent.getIntExtra(EXTRA_VERIFICATION_ID, -1);
// TODO: implement this method.
Slog.i(TAG, "Received integrity verification intent " + intent.toString());
+ Slog.i(TAG, "Extras " + intent.getExtras());
mPackageManagerInternal.setIntegrityVerificationResult(
- verificationId, PackageManager.VERIFICATION_ALLOW);
+ verificationId, PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW);
}
}
diff --git a/services/core/java/com/android/server/integrity/serializer/RuleXmlSerializer.java b/services/core/java/com/android/server/integrity/serializer/RuleXmlSerializer.java
index cfe50c6..ebf6a2e 100644
--- a/services/core/java/com/android/server/integrity/serializer/RuleXmlSerializer.java
+++ b/services/core/java/com/android/server/integrity/serializer/RuleXmlSerializer.java
@@ -16,6 +16,10 @@
package com.android.server.integrity.serializer;
+import static com.android.server.integrity.serializer.RuleIndexingDetails.APP_CERTIFICATE_INDEXED;
+import static com.android.server.integrity.serializer.RuleIndexingDetails.NOT_INDEXED;
+import static com.android.server.integrity.serializer.RuleIndexingDetails.PACKAGE_NAME_INDEXED;
+
import android.content.integrity.AtomicFormula;
import android.content.integrity.CompoundFormula;
import android.content.integrity.Formula;
@@ -29,6 +33,7 @@
import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.util.List;
+import java.util.Map;
import java.util.Optional;
/** A helper class to serialize rules from the {@link Rule} model to Xml representation. */
@@ -75,13 +80,32 @@
}
}
- private void serializeRules(List<Rule> rules, XmlSerializer xmlSerializer) throws IOException {
- xmlSerializer.startTag(NAMESPACE, RULE_LIST_TAG);
+ private void serializeRules(List<Rule> rules, XmlSerializer xmlSerializer)
+ throws RuleSerializeException {
+ try {
+ // Determine the indexing groups and the order of the rules within each indexed group.
+ Map<Integer, List<Rule>> indexedRules =
+ RuleIndexingDetailsIdentifier.splitRulesIntoIndexBuckets(rules);
+
+ // Write the XML formatted rules in order.
+ xmlSerializer.startTag(NAMESPACE, RULE_LIST_TAG);
+
+ serializeRuleList(indexedRules.get(PACKAGE_NAME_INDEXED), xmlSerializer);
+ serializeRuleList(indexedRules.get(APP_CERTIFICATE_INDEXED), xmlSerializer);
+ serializeRuleList(indexedRules.get(NOT_INDEXED), xmlSerializer);
+
+ xmlSerializer.endTag(NAMESPACE, RULE_LIST_TAG);
+ xmlSerializer.endDocument();
+ } catch (Exception e) {
+ throw new RuleSerializeException(e.getMessage(), e);
+ }
+ }
+
+ private void serializeRuleList(List<Rule> rules, XmlSerializer xmlSerializer)
+ throws IOException {
for (Rule rule : rules) {
serializeRule(rule, xmlSerializer);
}
- xmlSerializer.endTag(NAMESPACE, RULE_LIST_TAG);
- xmlSerializer.endDocument();
}
private void serializeRule(Rule rule, XmlSerializer xmlSerializer) throws IOException {
diff --git a/services/core/java/com/android/server/pm/DataLoaderManagerService.java b/services/core/java/com/android/server/pm/DataLoaderManagerService.java
index 0719797..0dfea7f 100644
--- a/services/core/java/com/android/server/pm/DataLoaderManagerService.java
+++ b/services/core/java/com/android/server/pm/DataLoaderManagerService.java
@@ -76,13 +76,12 @@
return false;
}
}
- CharSequence packageNameSeq = params.getCharSequence("packageName");
- if (packageNameSeq == null) {
- Slog.e(TAG, "Must specify package name.");
+ ComponentName componentName = params.getParcelable("componentName");
+ if (componentName == null) {
+ Slog.e(TAG, "Must specify component name.");
return false;
}
- String packageName = packageNameSeq.toString();
- ComponentName dataLoaderComponent = getDataLoaderServiceName(packageName);
+ ComponentName dataLoaderComponent = resolveDataLoaderComponentName(componentName);
if (dataLoaderComponent == null) {
return false;
}
@@ -103,22 +102,23 @@
/**
* Find the ComponentName of the data loader service provider, given its package name.
*
- * @param packageName the package name of the provider.
+ * @param componentName the name of the provider.
* @return ComponentName of the data loader service provider. Null if provider not found.
*/
- private @Nullable ComponentName getDataLoaderServiceName(String packageName) {
+ private @Nullable ComponentName resolveDataLoaderComponentName(
+ ComponentName componentName) {
final PackageManager pm = mContext.getPackageManager();
if (pm == null) {
Slog.e(TAG, "PackageManager is not available.");
return null;
}
Intent intent = new Intent(Intent.ACTION_LOAD_DATA);
- intent.setPackage(packageName);
+ intent.setComponent(componentName);
List<ResolveInfo> services =
pm.queryIntentServicesAsUser(intent, 0, UserHandle.getCallingUserId());
if (services == null || services.isEmpty()) {
Slog.e(TAG,
- "Failed to find data loader service provider in package " + packageName);
+ "Failed to find data loader service provider in " + componentName);
return null;
}
@@ -128,23 +128,21 @@
int numServices = services.size();
for (int i = 0; i < numServices; i++) {
ResolveInfo ri = services.get(i);
- ComponentName componentName = new ComponentName(
+ ComponentName resolved = new ComponentName(
ri.serviceInfo.packageName, ri.serviceInfo.name);
// There should only be one matching provider inside the given package.
// If there's more than one, return the first one found.
try {
- ApplicationInfo ai = pm.getApplicationInfo(componentName.getPackageName(), 0);
+ ApplicationInfo ai = pm.getApplicationInfo(resolved.getPackageName(), 0);
if (checkLoader && !ai.isPrivilegedApp()) {
Slog.w(TAG,
- "Data loader: " + componentName.getPackageName()
- + " is not a privileged app, skipping.");
+ "Data loader: " + resolved + " is not a privileged app, skipping.");
continue;
}
- return componentName;
+ return resolved;
} catch (PackageManager.NameNotFoundException ex) {
Slog.w(TAG,
- "Privileged data loader: " + componentName.getPackageName()
- + " not found, skipping.");
+ "Privileged data loader: " + resolved + " not found, skipping.");
}
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index a54534b..47a41f5 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -257,8 +257,9 @@
}
// Don't hold mSessions lock when calling restoreSession, since it might trigger an APK
// atomic install which needs to query sessions, which requires lock on mSessions.
+ boolean isDeviceUpgrading = mPm.isDeviceUpgrading();
for (PackageInstallerSession session : stagedSessionsToRestore) {
- if (mPm.isDeviceUpgrading() && !session.isStagedAndInTerminalState()) {
+ if (isDeviceUpgrading && !session.isStagedAndInTerminalState()) {
session.setStagedSessionFailed(SessionInfo.STAGED_SESSION_ACTIVATION_FAILED,
"Build fingerprint has changed");
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index c12395e..ac183dc 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -16,6 +16,8 @@
package com.android.server.pm;
+import static android.content.pm.DataLoaderType.INCREMENTAL;
+import static android.content.pm.DataLoaderType.STREAMING;
import static android.content.pm.PackageManager.INSTALL_FAILED_ABORTED;
import static android.content.pm.PackageManager.INSTALL_FAILED_BAD_SIGNATURE;
import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
@@ -49,12 +51,18 @@
import android.annotation.Nullable;
import android.app.admin.DevicePolicyEventLogger;
import android.app.admin.DevicePolicyManagerInternal;
+import android.content.ComponentName;
import android.content.Context;
import android.content.IIntentReceiver;
import android.content.IIntentSender;
import android.content.Intent;
import android.content.IntentSender;
import android.content.pm.ApplicationInfo;
+import android.content.pm.DataLoaderManager;
+import android.content.pm.DataLoaderParams;
+import android.content.pm.FileSystemControlParcel;
+import android.content.pm.IDataLoader;
+import android.content.pm.IDataLoaderStatusListener;
import android.content.pm.IPackageInstallObserver2;
import android.content.pm.IPackageInstallerSession;
import android.content.pm.IPackageInstallerSessionFileSystemConnector;
@@ -84,6 +92,7 @@
import android.os.ParcelFileDescriptor;
import android.os.ParcelableException;
import android.os.Process;
+import android.os.RemoteException;
import android.os.RevocableFileDescriptor;
import android.os.SystemProperties;
import android.os.UserHandle;
@@ -127,12 +136,12 @@
import java.io.FileFilter;
import java.io.FileOutputStream;
import java.io.IOException;
-import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
public class PackageInstallerSession extends IPackageInstallerSession.Stub {
private static final String TAG = "PackageInstallerSession";
@@ -189,7 +198,11 @@
private static final String ATTR_VOLUME_UUID = "volumeUuid";
private static final String ATTR_NAME = "name";
private static final String ATTR_INSTALL_REASON = "installRason";
- private static final String ATTR_DATA_LOADER_PACKAGE_NAME = "dataLoaderPackageName";
+ private static final String ATTR_IS_DATALOADER = "isDataLoader";
+ private static final String ATTR_DATALOADER_TYPE = "dataLoaderType";
+ private static final String ATTR_DATALOADER_PACKAGE_NAME = "dataLoaderPackageName";
+ private static final String ATTR_DATALOADER_CLASS_NAME = "dataLoaderClassName";
+ private static final String ATTR_DATALOADER_ARGUMENTS = "dataLoaderArguments";
private static final String ATTR_LENGTH_BYTES = "lengthBytes";
private static final String ATTR_METADATA = "metadata";
@@ -414,7 +427,15 @@
};
private boolean isDataLoaderInstallation() {
- return !TextUtils.isEmpty(params.dataLoaderPackageName);
+ return params.dataLoaderParams != null;
+ }
+
+ private boolean isStreamingInstallation() {
+ return isDataLoaderInstallation() && params.dataLoaderParams.getType() == STREAMING;
+ }
+
+ private boolean isIncrementalInstallation() {
+ return isDataLoaderInstallation() && params.dataLoaderParams.getType() == INCREMENTAL;
}
/**
@@ -525,14 +546,13 @@
stagedSessionErrorMessage != null ? stagedSessionErrorMessage : "";
// TODO(b/136132412): sanity check if session should not be incremental
- if (!params.isStaged && params.incrementalParams != null
- && !params.incrementalParams.getPackageName().isEmpty()) {
+ if (!params.isStaged && isIncrementalInstallation()) {
IncrementalManager incrementalManager = (IncrementalManager) mContext.getSystemService(
Context.INCREMENTAL_SERVICE);
if (incrementalManager != null) {
mIncrementalFileStorages =
new IncrementalFileStorages(mPackageName, stageDir, incrementalManager,
- params.incrementalParams);
+ params.dataLoaderParams);
}
}
}
@@ -714,7 +734,7 @@
public void removeSplit(String splitName) {
if (isDataLoaderInstallation()) {
throw new IllegalStateException(
- "Cannot remove splits in a callback installation session.");
+ "Cannot remove splits in a data loader installation session.");
}
if (TextUtils.isEmpty(params.appPackageName)) {
throw new IllegalStateException("Must specify package name to remove a split");
@@ -753,7 +773,7 @@
private void assertCanWrite(boolean reverseMode) {
if (isDataLoaderInstallation()) {
throw new IllegalStateException(
- "Cannot write regular files in a callback installation session.");
+ "Cannot write regular files in a data loader installation session.");
}
synchronized (mLock) {
assertCallerIsOwnerOrRootLocked();
@@ -894,7 +914,7 @@
public ParcelFileDescriptor openRead(String name) {
if (isDataLoaderInstallation()) {
throw new IllegalStateException(
- "Cannot read regular files in a callback installation session.");
+ "Cannot read regular files in a data loader installation session.");
}
synchronized (mLock) {
assertCallerIsOwnerOrRootLocked();
@@ -1663,7 +1683,7 @@
computeProgressLocked(true);
// Unpack native libraries for non-incremental installation
- if (params.incrementalParams == null) {
+ if (isIncrementalInstallation()) {
extractNativeLibraries(stageDir, params.abiOverride, mayInheritNativeLibs());
}
}
@@ -2382,7 +2402,7 @@
}
if (!isDataLoaderInstallation()) {
throw new IllegalStateException(
- "Cannot add files to non-callback installation session.");
+ "Cannot add files to non-data loader installation session.");
}
// Use installer provided name for now; we always rename later
if (!FileUtils.isValidExtFilename(name)) {
@@ -2401,7 +2421,7 @@
public void removeFile(String name) {
if (!isDataLoaderInstallation()) {
throw new IllegalStateException(
- "Cannot add files to non-callback installation session.");
+ "Cannot add files to non-data loader installation session.");
}
if (TextUtils.isEmpty(params.appPackageName)) {
throw new IllegalStateException("Must specify package name to remove a split");
@@ -2415,76 +2435,121 @@
}
}
+ static class Notificator {
+ private int mValue = 0;
+
+ void setValue(int value) {
+ synchronized (this) {
+ mValue = value;
+ this.notify();
+ }
+ }
+ int waitForValue() {
+ synchronized (this) {
+ while (mValue == 0) {
+ try {
+ this.wait();
+ } catch (InterruptedException e) {
+ // Happens if someone interrupts your thread.
+ }
+ }
+ return mValue;
+ }
+ }
+ }
+
/**
* Makes sure files are present in staging location.
*/
private void prepareDataLoader()
throws PackageManagerException, StreamingException {
- if (!isDataLoaderInstallation()) {
+ if (!isStreamingInstallation()) {
return;
}
FileSystemConnector connector = new FileSystemConnector();
- FileInfo[] addedFiles = mFiles.stream().filter(
- file -> sAddedFilter.accept(new File(file.name))).toArray(FileInfo[]::new);
- String[] removedFiles = mFiles.stream().filter(
+ List<InstallationFile> addedFiles = mFiles.stream().filter(
+ file -> sAddedFilter.accept(new File(file.name))).map(
+ file -> new InstallationFile(
+ file.name, file.lengthBytes, file.metadata)).collect(
+ Collectors.toList());
+ List<String> removedFiles = mFiles.stream().filter(
file -> sRemovedFilter.accept(new File(file.name))).map(
- file -> file.name.substring(0,
- file.name.length() - REMOVE_MARKER_EXTENSION.length())).toArray(
- String[]::new);
+ file -> file.name.substring(
+ 0, file.name.length() - REMOVE_MARKER_EXTENSION.length())).collect(
+ Collectors.toList());
- DataLoader dataLoader = new DataLoader();
- try {
- dataLoader.onCreate(connector);
-
- if (!dataLoader.onPrepareImage(addedFiles, removedFiles)) {
- throw new PackageManagerException(INSTALL_FAILED_MEDIA_UNAVAILABLE,
- "Failed to prepare image.");
- }
- } catch (IOException e) {
- throw new StreamingException(e);
- } finally {
- dataLoader.onDestroy();
- }
- }
-
- static class DataLoader {
- private ParcelFileDescriptor mInFd = null;
- private FileSystemConnector mConnector = null;
-
- void onCreate(FileSystemConnector connector) throws IOException {
- mConnector = connector;
+ DataLoaderManager dataLoaderManager = mContext.getSystemService(DataLoaderManager.class);
+ if (dataLoaderManager == null) {
+ throw new PackageManagerException(INSTALL_FAILED_MEDIA_UNAVAILABLE,
+ "Failed to find data loader manager service");
}
- void onDestroy() {
- IoUtils.closeQuietly(mInFd);
- }
+ // TODO(b/146080380): make this code async.
+ final Notificator created = new Notificator();
+ final Notificator started = new Notificator();
+ final Notificator imageReady = new Notificator();
- private static final String STDIN_PATH = "-";
- boolean onPrepareImage(FileInfo[] addedFiles, String[] removedFiles) throws IOException {
- for (FileInfo fileInfo : addedFiles) {
- String filePath = new String(fileInfo.metadata, StandardCharsets.UTF_8);
- if (STDIN_PATH.equals(filePath) || TextUtils.isEmpty(filePath)) {
- if (mInFd == null) {
- Slog.e(TAG, "Invalid stdin file descriptor.");
- return false;
+ IDataLoaderStatusListener listener = new IDataLoaderStatusListener.Stub() {
+ @Override
+ public void onStatusChanged(int dataLoaderId, int status) {
+ switch (status) {
+ case IDataLoaderStatusListener.DATA_LOADER_CREATED: {
+ created.setValue(1);
+ break;
}
- ParcelFileDescriptor inFd = ParcelFileDescriptor.dup(mInFd.getFileDescriptor());
- mConnector.writeData(fileInfo.name, 0, fileInfo.lengthBytes, inFd);
- } else {
- File localFile = new File(filePath);
- ParcelFileDescriptor incomingFd = null;
- try {
- incomingFd = ParcelFileDescriptor.open(localFile,
- ParcelFileDescriptor.MODE_READ_ONLY);
- mConnector.writeData(fileInfo.name, 0, localFile.length(), incomingFd);
- } finally {
- IoUtils.closeQuietly(incomingFd);
+ case IDataLoaderStatusListener.DATA_LOADER_STARTED: {
+ started.setValue(1);
+ break;
+ }
+ case IDataLoaderStatusListener.DATA_LOADER_IMAGE_READY: {
+ imageReady.setValue(1);
+ break;
+ }
+ case IDataLoaderStatusListener.DATA_LOADER_IMAGE_NOT_READY: {
+ imageReady.setValue(2);
+ break;
}
}
}
- return true;
+ };
+
+ final DataLoaderParams params = this.params.dataLoaderParams;
+
+ final FileSystemControlParcel control = new FileSystemControlParcel();
+ control.callback = connector;
+
+ Bundle dataLoaderParams = new Bundle();
+ dataLoaderParams.putParcelable("componentName", params.getComponentName());
+ dataLoaderParams.putParcelable("control", control);
+ dataLoaderParams.putParcelable("params", params.getData());
+
+ if (!dataLoaderManager.initializeDataLoader(sessionId, dataLoaderParams, listener)) {
+ throw new PackageManagerException(INSTALL_FAILED_MEDIA_UNAVAILABLE,
+ "Failed to initialize data loader");
+ }
+ created.waitForValue();
+
+ IDataLoader dataLoader = dataLoaderManager.getDataLoader(sessionId);
+ if (dataLoader == null) {
+ throw new PackageManagerException(INSTALL_FAILED_MEDIA_UNAVAILABLE,
+ "Failure to obtain data loader");
+ }
+
+ try {
+ dataLoader.start();
+ started.waitForValue();
+
+ dataLoader.prepareImage(addedFiles, removedFiles);
+ if (imageReady.waitForValue() == 2) {
+ throw new PackageManagerException(INSTALL_FAILED_MEDIA_UNAVAILABLE,
+ "Failed to prepare image.");
+ }
+
+ dataLoader.destroy();
+ } catch (RemoteException e) {
+ throw new StreamingException(e);
}
}
@@ -2846,7 +2911,17 @@
writeStringAttribute(out, ATTR_VOLUME_UUID, params.volumeUuid);
writeIntAttribute(out, ATTR_INSTALL_REASON, params.installReason);
- writeStringAttribute(out, ATTR_DATA_LOADER_PACKAGE_NAME, params.dataLoaderPackageName);
+ final boolean isDataLoader = params.dataLoaderParams != null;
+ writeBooleanAttribute(out, ATTR_IS_DATALOADER, isDataLoader);
+ if (isDataLoader) {
+ writeIntAttribute(out, ATTR_DATALOADER_TYPE, params.dataLoaderParams.getType());
+ writeStringAttribute(out, ATTR_DATALOADER_PACKAGE_NAME,
+ params.dataLoaderParams.getComponentName().getPackageName());
+ writeStringAttribute(out, ATTR_DATALOADER_CLASS_NAME,
+ params.dataLoaderParams.getComponentName().getClassName());
+ writeStringAttribute(out, ATTR_DATALOADER_ARGUMENTS,
+ params.dataLoaderParams.getArguments());
+ }
writeGrantedRuntimePermissionsLocked(out, params.grantedRuntimePermissions);
writeWhitelistedRestrictedPermissionsLocked(out,
@@ -2957,7 +3032,15 @@
params.volumeUuid = readStringAttribute(in, ATTR_VOLUME_UUID);
params.installReason = readIntAttribute(in, ATTR_INSTALL_REASON);
- params.dataLoaderPackageName = readStringAttribute(in, ATTR_DATA_LOADER_PACKAGE_NAME);
+ if (readBooleanAttribute(in, ATTR_IS_DATALOADER)) {
+ params.dataLoaderParams = new DataLoaderParams(
+ readIntAttribute(in, ATTR_DATALOADER_TYPE),
+ new ComponentName(
+ readStringAttribute(in, ATTR_DATALOADER_PACKAGE_NAME),
+ readStringAttribute(in, ATTR_DATALOADER_CLASS_NAME)),
+ readStringAttribute(in, ATTR_DATALOADER_ARGUMENTS),
+ null);
+ }
final File appIconFile = buildAppIconFile(sessionId, sessionsDir);
if (appIconFile.exists()) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index da104ee..785ca7d 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -27,6 +27,8 @@
import static android.content.Intent.ACTION_MAIN;
import static android.content.Intent.CATEGORY_DEFAULT;
import static android.content.Intent.CATEGORY_HOME;
+import static android.content.Intent.EXTRA_PACKAGE_NAME;
+import static android.content.Intent.EXTRA_VERSION_CODE;
import static android.content.pm.PackageManager.CERT_INPUT_RAW_X509;
import static android.content.pm.PackageManager.CERT_INPUT_SHA256;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
@@ -34,6 +36,7 @@
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
+import static android.content.pm.PackageManager.EXTRA_VERIFICATION_ID;
import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKED_COMPAT;
@@ -558,6 +561,11 @@
private static final boolean DEFAULT_VERIFY_ENABLE = true;
/**
+ * Whether integrity verification is enabled by default.
+ */
+ private static final boolean DEFAULT_INTEGRITY_VERIFY_ENABLE = true;
+
+ /**
* The default maximum time to wait for the verification agent to return in
* milliseconds.
*/
@@ -1444,6 +1452,7 @@
static final int DEFERRED_NO_KILL_POST_DELETE = 23;
static final int DEFERRED_NO_KILL_INSTALL_OBSERVER = 24;
static final int INTEGRITY_VERIFICATION_COMPLETE = 25;
+ static final int CHECK_PENDING_INTEGRITY_VERIFICATION = 26;
static final int DEFERRED_NO_KILL_POST_DELETE_DELAY_MS = 3 * 1000;
static final int DEFERRED_NO_KILL_INSTALL_OBSERVER_DELAY_MS = 500;
@@ -1707,13 +1716,13 @@
final int verificationId = msg.arg1;
final PackageVerificationState state = mPendingVerification.get(verificationId);
- if ((state != null) && !state.timeoutExtended()) {
+ if ((state != null) && !state.isVerificationComplete()
+ && !state.timeoutExtended()) {
final InstallParams params = state.getInstallParams();
final InstallArgs args = params.mArgs;
final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
Slog.i(TAG, "Verification timed out for " + originUri);
- mPendingVerification.remove(verificationId);
final UserHandle user = args.getUser();
if (getDefaultVerificationResponse(user)
@@ -1728,11 +1737,54 @@
PackageManager.VERIFICATION_REJECT, user);
params.setReturnCode(
PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE);
+ state.setVerifierResponse(Binder.getCallingUid(),
+ PackageManager.VERIFICATION_REJECT);
+ }
+
+ if (state.areAllVerificationsComplete()) {
+ mPendingVerification.remove(verificationId);
}
Trace.asyncTraceEnd(
TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
+
params.handleVerificationFinished();
+
+ }
+ break;
+ }
+ case CHECK_PENDING_INTEGRITY_VERIFICATION: {
+ final int verificationId = msg.arg1;
+ final PackageVerificationState state = mPendingVerification.get(verificationId);
+
+ if (state != null && !state.isIntegrityVerificationComplete()) {
+ final InstallParams params = state.getInstallParams();
+ final InstallArgs args = params.mArgs;
+ final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
+
+ Slog.i(TAG, "Integrity verification timed out for " + originUri);
+
+ state.setIntegrityVerificationResult(
+ getDefaultIntegrityVerificationResponse());
+
+ if (getDefaultIntegrityVerificationResponse()
+ == PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW) {
+ Slog.i(TAG, "Integrity check times out, continuing with " + originUri);
+ } else {
+ params.setReturnCode(
+ PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE);
+ }
+
+ if (state.areAllVerificationsComplete()) {
+ mPendingVerification.remove(verificationId);
+ }
+
+ Trace.asyncTraceEnd(
+ TRACE_TAG_PACKAGE_MANAGER,
+ "integrity_verification",
+ verificationId);
+
+ params.handleIntegrityVerificationFinished();
}
break;
}
@@ -1741,7 +1793,9 @@
final PackageVerificationState state = mPendingVerification.get(verificationId);
if (state == null) {
- Slog.w(TAG, "Invalid verification token " + verificationId + " received");
+ Slog.w(TAG, "Verification with id " + verificationId
+ + " not found."
+ + " It may be invalid or overridden by integrity verification");
break;
}
@@ -1750,8 +1804,6 @@
state.setVerifierResponse(response.callerUid, response.code);
if (state.isVerificationComplete()) {
- mPendingVerification.remove(verificationId);
-
final InstallParams params = state.getInstallParams();
final InstallArgs args = params.mArgs;
final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
@@ -1764,6 +1816,10 @@
PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE);
}
+ if (state.areAllVerificationsComplete()) {
+ mPendingVerification.remove(verificationId);
+ }
+
Trace.asyncTraceEnd(
TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
@@ -1773,7 +1829,40 @@
break;
}
case INTEGRITY_VERIFICATION_COMPLETE: {
- // TODO: implement this case.
+ final int verificationId = msg.arg1;
+
+ final PackageVerificationState state = mPendingVerification.get(verificationId);
+ if (state == null) {
+ Slog.w(TAG, "Integrity verification with id " + verificationId
+ + " not found. It may be invalid or overridden by verifier");
+ break;
+ }
+
+ final int response = (Integer) msg.obj;
+
+ final InstallParams params = state.getInstallParams();
+ final InstallArgs args = params.mArgs;
+ final Uri originUri = Uri.fromFile(args.origin.resolvedFile);
+
+ state.setIntegrityVerificationResult(response);
+
+ if (response == PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW) {
+ Slog.i(TAG, "Integrity check passed for " + originUri);
+ } else {
+ params.setReturnCode(
+ PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE);
+ }
+
+ if (state.areAllVerificationsComplete()) {
+ mPendingVerification.remove(verificationId);
+ }
+
+ Trace.asyncTraceEnd(
+ TRACE_TAG_PACKAGE_MANAGER,
+ "integrity_verification",
+ verificationId);
+
+ params.handleIntegrityVerificationFinished();
break;
}
case START_INTENT_FILTER_VERIFICATIONS: {
@@ -13099,6 +13188,15 @@
}
/**
+ * Get the default integrity verification response code.
+ */
+ private int getDefaultIntegrityVerificationResponse() {
+ // We are not exposing this as a user-configurable setting because we don't want to provide
+ // an easy way to get around the integrity check.
+ return PackageManager.VERIFICATION_REJECT;
+ }
+
+ /**
* Check whether or not package verification has been enabled.
*
* @return true if verification should be performed
@@ -13141,6 +13239,15 @@
}
}
+ /**
+ * Check whether or not integrity verification has been enabled.
+ */
+ private boolean isIntegrityVerificationEnabled() {
+ // We are not exposing this as a user-configurable setting because we don't want to provide
+ // an easy way to get around the integrity check.
+ return DEFAULT_INTEGRITY_VERIFY_ENABLE;
+ }
+
@Override
public void verifyIntentFilter(int id, int verificationCode, List<String> failedDomains)
throws RemoteException {
@@ -13851,6 +13958,7 @@
@NonNull final InstallSource installSource;
final String volumeUuid;
private boolean mVerificationCompleted;
+ private boolean mIntegrityVerificationCompleted;
private boolean mEnableRollbackCompleted;
private InstallArgs mArgs;
int mRet;
@@ -14112,155 +14220,30 @@
final InstallArgs args = createInstallArgs(this);
mVerificationCompleted = true;
+ mIntegrityVerificationCompleted = true;
mEnableRollbackCompleted = true;
mArgs = args;
if (ret == PackageManager.INSTALL_SUCCEEDED) {
- // TODO: http://b/22976637
- // Apps installed for "all" users use the device owner to verify the app
- UserHandle verifierUser = getUser();
- if (verifierUser == UserHandle.ALL) {
- verifierUser = UserHandle.SYSTEM;
- }
+ final int verificationId = mPendingVerificationToken++;
- /*
- * Determine if we have any installed package verifiers. If we
- * do, then we'll defer to them to verify the packages.
- */
- final int requiredUid = mRequiredVerifierPackage == null ? -1
- : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
- verifierUser.getIdentifier());
- final int installerUid =
- verificationInfo == null ? -1 : verificationInfo.installerUid;
- if (!origin.existing && requiredUid != -1
- && isVerificationEnabled(
- verifierUser.getIdentifier(), installFlags, installerUid)) {
- final Intent verification = new Intent(
- Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
- verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
- verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
- PACKAGE_MIME_TYPE);
- verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
-
- // Query all live verifiers based on current user state
- final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification,
- PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier(),
- false /*allowDynamicSplits*/);
-
- if (DEBUG_VERIFY) {
- Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
- + verification.toString() + " with " + pkgLite.verifiers.length
- + " optional verifiers");
- }
-
- final int verificationId = mPendingVerificationToken++;
-
- verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
-
- verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
- installSource.initiatingPackageName);
-
- verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS,
- installFlags);
-
- verification.putExtra(PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME,
- pkgLite.packageName);
-
- verification.putExtra(PackageManager.EXTRA_VERIFICATION_VERSION_CODE,
- pkgLite.versionCode);
-
- verification.putExtra(PackageManager.EXTRA_VERIFICATION_LONG_VERSION_CODE,
- pkgLite.getLongVersionCode());
-
- if (verificationInfo != null) {
- if (verificationInfo.originatingUri != null) {
- verification.putExtra(Intent.EXTRA_ORIGINATING_URI,
- verificationInfo.originatingUri);
- }
- if (verificationInfo.referrer != null) {
- verification.putExtra(Intent.EXTRA_REFERRER,
- verificationInfo.referrer);
- }
- if (verificationInfo.originatingUid >= 0) {
- verification.putExtra(Intent.EXTRA_ORIGINATING_UID,
- verificationInfo.originatingUid);
- }
- if (verificationInfo.installerUid >= 0) {
- verification.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
- verificationInfo.installerUid);
- }
- }
-
- final PackageVerificationState verificationState = new PackageVerificationState(
- requiredUid, this);
-
+ // Perform package verification (unless we are simply moving the package).
+ if (!origin.existing) {
+ PackageVerificationState verificationState =
+ new PackageVerificationState(this);
mPendingVerification.append(verificationId, verificationState);
- final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
- receivers, verificationState);
+ sendIntegrityVerificationRequest(verificationId, pkgLite, verificationState);
+ ret = sendPackageVerificationRequest(
+ verificationId, pkgLite, verificationState);
- DeviceIdleInternal idleController =
- mInjector.getLocalDeviceIdleController();
- final long idleDuration = getVerificationTimeout();
-
- /*
- * If any sufficient verifiers were listed in the package
- * manifest, attempt to ask them.
- */
- if (sufficientVerifiers != null) {
- final int N = sufficientVerifiers.size();
- if (N == 0) {
- Slog.i(TAG, "Additional verifiers required, but none installed.");
- ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
- } else {
- for (int i = 0; i < N; i++) {
- final ComponentName verifierComponent = sufficientVerifiers.get(i);
- idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
- verifierComponent.getPackageName(), idleDuration,
- verifierUser.getIdentifier(), false, "package verifier");
-
- final Intent sufficientIntent = new Intent(verification);
- sufficientIntent.setComponent(verifierComponent);
- mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
- }
- }
- }
-
- final ComponentName requiredVerifierComponent = matchComponentForVerifier(
- mRequiredVerifierPackage, receivers);
- if (ret == PackageManager.INSTALL_SUCCEEDED
- && mRequiredVerifierPackage != null) {
- Trace.asyncTraceBegin(
- TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
- /*
- * Send the intent to the required verification agent,
- * but only start the verification timeout after the
- * target BroadcastReceivers have run.
- */
- verification.setComponent(requiredVerifierComponent);
- idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
- mRequiredVerifierPackage, idleDuration,
- verifierUser.getIdentifier(), false, "package verifier");
- mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
- android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
- new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- final Message msg = mHandler
- .obtainMessage(CHECK_PENDING_VERIFICATION);
- msg.arg1 = verificationId;
- mHandler.sendMessageDelayed(msg, getVerificationTimeout());
- }
- }, null, 0, null, null);
-
- /*
- * We don't want the copy to proceed until verification
- * succeeds.
- */
- mVerificationCompleted = false;
+ // If both verifications are skipped, we should remove the state.
+ if (verificationState.areAllVerificationsComplete()) {
+ mPendingVerification.remove(verificationId);
}
}
+
if ((installFlags & PackageManager.INSTALL_ENABLE_ROLLBACK) != 0) {
// TODO(ruhler) b/112431924: Don't do this in case of 'move'?
final int enableRollbackToken = mPendingEnableRollbackToken++;
@@ -14316,6 +14299,228 @@
mRet = ret;
}
+ /**
+ * Send a request to check the integrity of the package.
+ */
+ void sendIntegrityVerificationRequest(
+ int verificationId,
+ PackageInfoLite pkgLite,
+ PackageVerificationState verificationState) {
+ if (!isIntegrityVerificationEnabled()) {
+ // Consider the integrity check as passed.
+ verificationState.setIntegrityVerificationResult(
+ PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW);
+ return;
+ }
+
+ final Intent integrityVerification =
+ new Intent(Intent.ACTION_PACKAGE_NEEDS_INTEGRITY_VERIFICATION);
+
+ integrityVerification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
+ PACKAGE_MIME_TYPE);
+
+ final int flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
+ | Intent.FLAG_RECEIVER_REGISTERED_ONLY
+ | Intent.FLAG_RECEIVER_FOREGROUND;
+ integrityVerification.addFlags(flags);
+
+ integrityVerification.putExtra(EXTRA_VERIFICATION_ID, verificationId);
+ integrityVerification.putExtra(EXTRA_PACKAGE_NAME, pkgLite.packageName);
+ integrityVerification.putExtra(EXTRA_VERSION_CODE, pkgLite.versionCode);
+ populateInstallerExtras(integrityVerification);
+
+ // send to integrity component only.
+ integrityVerification.setPackage("android");
+
+ DeviceIdleInternal idleController =
+ mInjector.getLocalDeviceIdleController();
+ final long idleDuration = getVerificationTimeout();
+
+ idleController.addPowerSaveTempWhitelistAppDirect(Process.myUid(),
+ idleDuration,
+ false, "integrity component");
+ mContext.sendOrderedBroadcastAsUser(integrityVerification, UserHandle.SYSTEM,
+ /* receiverPermission= */ null,
+ new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final Message msg =
+ mHandler.obtainMessage(CHECK_PENDING_INTEGRITY_VERIFICATION);
+ msg.arg1 = verificationId;
+ // TODO: do we want to use the same timeout?
+ mHandler.sendMessageDelayed(msg, getVerificationTimeout());
+ }
+ }, /* scheduler= */ null,
+ /* initialCode= */ 0,
+ /* initialData= */ null,
+ /* initialExtras= */ null);
+
+ Trace.asyncTraceBegin(
+ TRACE_TAG_PACKAGE_MANAGER, "integrity_verification", verificationId);
+
+ // stop the copy until verification succeeds.
+ mIntegrityVerificationCompleted = false;
+ }
+
+ /**
+ * Send a request to verifier(s) to verify the package if necessary, and return
+ * {@link PackageManager#INSTALL_SUCCEEDED} if succeeded.
+ */
+ int sendPackageVerificationRequest(
+ int verificationId,
+ PackageInfoLite pkgLite,
+ PackageVerificationState verificationState) {
+ int ret = INSTALL_SUCCEEDED;
+
+ // TODO: http://b/22976637
+ // Apps installed for "all" users use the device owner to verify the app
+ UserHandle verifierUser = getUser();
+ if (verifierUser == UserHandle.ALL) {
+ verifierUser = UserHandle.SYSTEM;
+ }
+
+ /*
+ * Determine if we have any installed package verifiers. If we
+ * do, then we'll defer to them to verify the packages.
+ */
+ final int requiredUid = mRequiredVerifierPackage == null ? -1
+ : getPackageUid(mRequiredVerifierPackage, MATCH_DEBUG_TRIAGED_MISSING,
+ verifierUser.getIdentifier());
+ verificationState.setRequiredVerifierUid(requiredUid);
+ final int installerUid =
+ verificationInfo == null ? -1 : verificationInfo.installerUid;
+ if (!origin.existing && requiredUid != -1
+ && isVerificationEnabled(
+ verifierUser.getIdentifier(), installFlags, installerUid)) {
+ final Intent verification = new Intent(
+ Intent.ACTION_PACKAGE_NEEDS_VERIFICATION);
+ verification.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+ verification.setDataAndType(Uri.fromFile(new File(origin.resolvedPath)),
+ PACKAGE_MIME_TYPE);
+ verification.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
+
+ // Query all live verifiers based on current user state
+ final List<ResolveInfo> receivers = queryIntentReceiversInternal(verification,
+ PACKAGE_MIME_TYPE, 0, verifierUser.getIdentifier(),
+ false /*allowDynamicSplits*/);
+
+ if (DEBUG_VERIFY) {
+ Slog.d(TAG, "Found " + receivers.size() + " verifiers for intent "
+ + verification.toString() + " with " + pkgLite.verifiers.length
+ + " optional verifiers");
+ }
+
+ verification.putExtra(PackageManager.EXTRA_VERIFICATION_ID, verificationId);
+
+ verification.putExtra(
+ PackageManager.EXTRA_VERIFICATION_INSTALL_FLAGS, installFlags);
+
+ verification.putExtra(
+ PackageManager.EXTRA_VERIFICATION_PACKAGE_NAME, pkgLite.packageName);
+
+ verification.putExtra(
+ PackageManager.EXTRA_VERIFICATION_VERSION_CODE, pkgLite.versionCode);
+
+ verification.putExtra(
+ PackageManager.EXTRA_VERIFICATION_LONG_VERSION_CODE,
+ pkgLite.getLongVersionCode());
+
+ populateInstallerExtras(verification);
+
+ final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
+ receivers, verificationState);
+
+ DeviceIdleInternal idleController =
+ mInjector.getLocalDeviceIdleController();
+ final long idleDuration = getVerificationTimeout();
+
+ /*
+ * If any sufficient verifiers were listed in the package
+ * manifest, attempt to ask them.
+ */
+ if (sufficientVerifiers != null) {
+ final int n = sufficientVerifiers.size();
+ if (n == 0) {
+ Slog.i(TAG, "Additional verifiers required, but none installed.");
+ ret = PackageManager.INSTALL_FAILED_VERIFICATION_FAILURE;
+ } else {
+ for (int i = 0; i < n; i++) {
+ final ComponentName verifierComponent = sufficientVerifiers.get(i);
+ idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
+ verifierComponent.getPackageName(), idleDuration,
+ verifierUser.getIdentifier(), false, "package verifier");
+
+ final Intent sufficientIntent = new Intent(verification);
+ sufficientIntent.setComponent(verifierComponent);
+ mContext.sendBroadcastAsUser(sufficientIntent, verifierUser);
+ }
+ }
+ }
+
+ final ComponentName requiredVerifierComponent = matchComponentForVerifier(
+ mRequiredVerifierPackage, receivers);
+ if (mRequiredVerifierPackage != null) {
+ /*
+ * Send the intent to the required verification agent,
+ * but only start the verification timeout after the
+ * target BroadcastReceivers have run.
+ */
+ verification.setComponent(requiredVerifierComponent);
+ idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
+ mRequiredVerifierPackage, idleDuration,
+ verifierUser.getIdentifier(), false, "package verifier");
+ mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
+ android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
+ new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ final Message msg = mHandler
+ .obtainMessage(CHECK_PENDING_VERIFICATION);
+ msg.arg1 = verificationId;
+ mHandler.sendMessageDelayed(msg, getVerificationTimeout());
+ }
+ }, null, 0, null, null);
+
+ Trace.asyncTraceBegin(
+ TRACE_TAG_PACKAGE_MANAGER, "verification", verificationId);
+
+ /*
+ * We don't want the copy to proceed until verification
+ * succeeds.
+ */
+ mVerificationCompleted = false;
+ }
+ } else {
+ verificationState.setVerifierResponse(
+ requiredUid, PackageManager.VERIFICATION_ALLOW);
+ }
+ return ret;
+ }
+
+ void populateInstallerExtras(Intent intent) {
+ intent.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_PACKAGE,
+ installSource.initiatingPackageName);
+
+ if (verificationInfo != null) {
+ if (verificationInfo.originatingUri != null) {
+ intent.putExtra(Intent.EXTRA_ORIGINATING_URI,
+ verificationInfo.originatingUri);
+ }
+ if (verificationInfo.referrer != null) {
+ intent.putExtra(Intent.EXTRA_REFERRER,
+ verificationInfo.referrer);
+ }
+ if (verificationInfo.originatingUid >= 0) {
+ intent.putExtra(Intent.EXTRA_ORIGINATING_UID,
+ verificationInfo.originatingUid);
+ }
+ if (verificationInfo.installerUid >= 0) {
+ intent.putExtra(PackageManager.EXTRA_VERIFICATION_INSTALLER_UID,
+ verificationInfo.installerUid);
+ }
+ }
+ }
+
void setReturnCode(int ret) {
if (mRet == PackageManager.INSTALL_SUCCEEDED) {
// Only update mRet if it was previously INSTALL_SUCCEEDED to
@@ -14325,10 +14530,28 @@
}
void handleVerificationFinished() {
- mVerificationCompleted = true;
- handleReturnCode();
+ if (!mVerificationCompleted) {
+ mVerificationCompleted = true;
+ if (mIntegrityVerificationCompleted || mRet != INSTALL_SUCCEEDED) {
+ mIntegrityVerificationCompleted = true;
+ handleReturnCode();
+ }
+ // integrity verification still pending.
+ }
}
+ void handleIntegrityVerificationFinished() {
+ if (!mIntegrityVerificationCompleted) {
+ mIntegrityVerificationCompleted = true;
+ if (mVerificationCompleted || mRet != INSTALL_SUCCEEDED) {
+ mVerificationCompleted = true;
+ handleReturnCode();
+ }
+ // verifier still pending
+ }
+ }
+
+
void handleRollbackEnabled() {
// TODO(ruhler) b/112431924: Consider halting the install if we
// couldn't enable rollback.
@@ -14338,7 +14561,8 @@
@Override
void handleReturnCode() {
- if (mVerificationCompleted && mEnableRollbackCompleted) {
+ if (mVerificationCompleted
+ && mIntegrityVerificationCompleted && mEnableRollbackCompleted) {
if ((installFlags & PackageManager.INSTALL_DRY_RUN) != 0) {
String packageName = "";
try {
@@ -22673,7 +22897,6 @@
if (ps != null) {
return ps.getCeDataInode(userId);
}
- Slog.e(TAG, "failed to find package " + packageName);
return 0;
}
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index dfffbd6..10e2780 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -34,6 +34,7 @@
import android.content.Intent;
import android.content.IntentSender;
import android.content.pm.ApplicationInfo;
+import android.content.pm.DataLoaderParams;
import android.content.pm.FeatureInfo;
import android.content.pm.IPackageDataObserver;
import android.content.pm.IPackageInstaller;
@@ -136,7 +137,9 @@
private final static String ART_PROFILE_SNAPSHOT_DEBUG_LOCATION = "/data/misc/profman/";
private static final int DEFAULT_WAIT_MS = 60 * 1000;
- private static final String PM_SHELL_DATALOADER = "com.android.pm.dataloader";
+ private static final String DATA_LOADER_PACKAGE = "android";
+ private static final String DATA_LOADER_CLASS =
+ "com.android.server.pm.PackageManagerShellCommandDataLoader";
final IPackageManager mInterface;
final IPermissionManager mPermissionManager;
@@ -1159,8 +1162,10 @@
private int runStreamingInstall() throws RemoteException {
final InstallParams params = makeInstallParams();
- if (TextUtils.isEmpty(params.sessionParams.dataLoaderPackageName)) {
- params.sessionParams.setDataLoaderPackageName(PM_SHELL_DATALOADER);
+ if (params.sessionParams.dataLoaderParams == null) {
+ final DataLoaderParams dataLoaderParams = DataLoaderParams.forStreaming(
+ new ComponentName(DATA_LOADER_PACKAGE, DATA_LOADER_CLASS), "");
+ params.sessionParams.setDataLoaderParams(dataLoaderParams);
}
return doRunInstall(params);
}
@@ -1171,7 +1176,7 @@
private int doRunInstall(final InstallParams params) throws RemoteException {
final PrintWriter pw = getOutPrintWriter();
- final boolean streaming = !TextUtils.isEmpty(params.sessionParams.dataLoaderPackageName);
+ final boolean streaming = params.sessionParams.dataLoaderParams != null;
ArrayList<String> inPaths = getRemainingArgs();
if (inPaths.isEmpty()) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommandDataLoader.java b/services/core/java/com/android/server/pm/PackageManagerShellCommandDataLoader.java
new file mode 100644
index 0000000..1ee9ab8
--- /dev/null
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommandDataLoader.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.pm;
+
+import android.annotation.NonNull;
+import android.content.pm.DataLoaderParams;
+import android.content.pm.InstallationFile;
+import android.os.ParcelFileDescriptor;
+import android.service.dataloader.DataLoaderService;
+import android.text.TextUtils;
+import android.util.Slog;
+
+import libcore.io.IoUtils;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.util.Collection;
+
+/**
+ * Callback data loader for PackageManagerShellCommand installations.
+ */
+public class PackageManagerShellCommandDataLoader extends DataLoaderService {
+ public static final String TAG = "PackageManagerShellCommandDataLoader";
+
+ static class DataLoader implements DataLoaderService.DataLoader {
+ private ParcelFileDescriptor mInFd = null;
+ private FileSystemConnector mConnector = null;
+
+ private static final String STDIN_PATH = "-";
+
+ @Override
+ public boolean onCreate(@NonNull DataLoaderParams dataLoaderParams,
+ @NonNull FileSystemConnector connector) {
+ mConnector = connector;
+ return true;
+ }
+ @Override
+ public boolean onPrepareImage(Collection<InstallationFile> addedFiles,
+ Collection<String> removedFiles) {
+ try {
+ for (InstallationFile fileInfo : addedFiles) {
+ String filePath = new String(fileInfo.getMetadata(), StandardCharsets.UTF_8);
+ if (STDIN_PATH.equals(filePath) || TextUtils.isEmpty(filePath)) {
+ // TODO(b/146080380): add support for STDIN installations.
+ if (mInFd == null) {
+ Slog.e(TAG, "Invalid stdin file descriptor.");
+ return false;
+ }
+ ParcelFileDescriptor inFd = ParcelFileDescriptor.dup(
+ mInFd.getFileDescriptor());
+ mConnector.writeData(fileInfo.getName(), 0, fileInfo.getSize(), inFd);
+ } else {
+ File localFile = new File(filePath);
+ ParcelFileDescriptor incomingFd = null;
+ try {
+ // TODO(b/146080380): open files via callback into shell command.
+ incomingFd = ParcelFileDescriptor.open(localFile,
+ ParcelFileDescriptor.MODE_READ_ONLY);
+ mConnector.writeData(fileInfo.getName(), 0, localFile.length(),
+ incomingFd);
+ } finally {
+ IoUtils.closeQuietly(incomingFd);
+ }
+ }
+ }
+ return true;
+ } catch (IOException e) {
+ return false;
+ }
+ }
+ }
+
+ @Override
+ public DataLoaderService.DataLoader onCreateDataLoader() {
+ return new DataLoader();
+ }
+}
diff --git a/services/core/java/com/android/server/pm/PackageVerificationState.java b/services/core/java/com/android/server/pm/PackageVerificationState.java
index c50bf59..ea7af90 100644
--- a/services/core/java/com/android/server/pm/PackageVerificationState.java
+++ b/services/core/java/com/android/server/pm/PackageVerificationState.java
@@ -22,18 +22,17 @@
import com.android.server.pm.PackageManagerService.InstallParams;
/**
- * Tracks the package verification state for a particular package. Each package
- * verification has a required verifier and zero or more sufficient verifiers.
- * Only one of the sufficient verifier list must return affirmative to allow the
- * package to be considered verified. If there are zero sufficient verifiers,
- * then package verification is considered complete.
+ * Tracks the package verification state for a particular package. Each package verification has a
+ * required verifier and zero or more sufficient verifiers. Only one of the sufficient verifier list
+ * must return affirmative to allow the package to be considered verified. If there are zero
+ * sufficient verifiers, then package verification is considered complete.
*/
class PackageVerificationState {
private final InstallParams mParams;
private final SparseBooleanArray mSufficientVerifierUids;
- private final int mRequiredVerifierUid;
+ private int mRequiredVerifierUid;
private boolean mSufficientVerificationComplete;
@@ -45,16 +44,13 @@
private boolean mExtendedTimeout;
+ private boolean mIntegrityVerificationComplete;
+
/**
- * Create a new package verification state where {@code requiredVerifierUid}
- * is the user ID for the package that must reply affirmative before things
- * can continue.
- *
- * @param requiredVerifierUid user ID of required package verifier
- * @param args
+ * Create a new package verification state where {@code requiredVerifierUid} is the user ID for
+ * the package that must reply affirmative before things can continue.
*/
- PackageVerificationState(int requiredVerifierUid, InstallParams params) {
- mRequiredVerifierUid = requiredVerifierUid;
+ PackageVerificationState(InstallParams params) {
mParams = params;
mSufficientVerifierUids = new SparseBooleanArray();
mExtendedTimeout = false;
@@ -64,6 +60,11 @@
return mParams;
}
+ /** Sets the user ID of the required package verifier. */
+ void setRequiredVerifierUid(int uid) {
+ mRequiredVerifierUid = uid;
+ }
+
/**
* Add a verifier which is added to our sufficient list.
*
@@ -74,8 +75,8 @@
}
/**
- * Should be called when a verification is received from an agent so the
- * state of the package verification can be tracked.
+ * Should be called when a verification is received from an agent so the state of the package
+ * verification can be tracked.
*
* @param uid user ID of the verifying agent
* @return {@code true} if the verifying agent actually exists in our list
@@ -114,9 +115,8 @@
}
/**
- * Returns whether verification is considered complete. This means that the
- * required verifier and at least one of the sufficient verifiers has
- * returned a positive verification.
+ * Returns whether verification is considered complete. This means that the required verifier
+ * and at least one of the sufficient verifiers has returned a positive verification.
*
* @return {@code true} when verification is considered complete
*/
@@ -133,8 +133,8 @@
}
/**
- * Returns whether installation should be allowed. This should only be
- * called after {@link #isVerificationComplete()} returns {@code true}.
+ * Returns whether installation should be allowed. This should only be called after {@link
+ * #isVerificationComplete()} returns {@code true}.
*
* @return {@code true} if installation should be allowed
*/
@@ -150,9 +150,7 @@
return true;
}
- /**
- * Extend the timeout for this Package to be verified.
- */
+ /** Extend the timeout for this Package to be verified. */
void extendTimeout() {
if (!mExtendedTimeout) {
mExtendedTimeout = true;
@@ -167,4 +165,16 @@
boolean timeoutExtended() {
return mExtendedTimeout;
}
+
+ void setIntegrityVerificationResult(int code) {
+ mIntegrityVerificationComplete = true;
+ }
+
+ boolean isIntegrityVerificationComplete() {
+ return mIntegrityVerificationComplete;
+ }
+
+ boolean areAllVerificationsComplete() {
+ return mIntegrityVerificationComplete && isVerificationComplete();
+ }
}
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 1503282..834e924 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -6308,6 +6308,11 @@
resolveSizeCompatModeConfiguration(newParentConfiguration);
} else {
super.resolveOverrideConfiguration(newParentConfiguration);
+ // We ignore activities' requested orientation in multi-window modes. Task level may
+ // take them into consideration when calculating bounds.
+ if (getParent() != null && getParent().inMultiWindowMode()) {
+ resolvedConfig.orientation = Configuration.ORIENTATION_UNDEFINED;
+ }
applyAspectRatio(resolvedConfig.windowConfiguration.getBounds(),
newParentConfiguration.windowConfiguration.getAppBounds(),
newParentConfiguration.windowConfiguration.getBounds());
diff --git a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
index be3a613..1355424 100644
--- a/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
+++ b/services/core/java/com/android/server/wm/ActivityStartInterceptor.java
@@ -252,7 +252,8 @@
final SuspendDialogInfo dialogInfo = pmi.getSuspendedDialogInfo(suspendedPackage,
suspendingPackage, mUserId);
mIntent = SuspendedAppActivity.createSuspendedAppInterceptIntent(suspendedPackage,
- suspendingPackage, dialogInfo, mUserId);
+ suspendingPackage, dialogInfo, deferCrossProfileAppsAnimationIfNecessary(),
+ mUserId);
mCallingPid = mRealCallingPid;
mCallingUid = mRealCallingUid;
mResolvedType = null;
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index fd95ac5..45c012e 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -1881,7 +1881,10 @@
if (inOutConfig.screenWidthDp == Configuration.SCREEN_WIDTH_DP_UNDEFINED
|| inOutConfig.screenHeightDp == Configuration.SCREEN_HEIGHT_DP_UNDEFINED) {
- if (insideParentBounds && mStack != null) {
+ if (insideParentBounds && WindowConfiguration.isFloating(windowingMode)) {
+ mTmpNonDecorBounds.set(mTmpFullBounds);
+ mTmpStableBounds.set(mTmpFullBounds);
+ } else if (insideParentBounds && mStack != null) {
final DisplayInfo di = new DisplayInfo();
mStack.getDisplay().mDisplay.getDisplayInfo(di);
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index 1313eeb..3039d69 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -2368,43 +2368,12 @@
final Region region = inputWindowHandle.touchableRegion;
setTouchableRegionCropIfNeeded(inputWindowHandle);
- if (modal && mActivityRecord != null) {
- // Limit the outer touch to the activity stack region.
+ if (modal) {
flags |= FLAG_NOT_TOUCH_MODAL;
- // If the inner bounds of letterbox is available, then it will be used as the touchable
- // region so it won't cover the touchable letterbox and the touch events can slip to
- // activity from letterbox.
- mActivityRecord.getLetterboxInnerBounds(mTmpRect);
- if (mTmpRect.isEmpty()) {
- // If this is a modal window we need to dismiss it if it's not full screen and the
- // touch happens outside of the frame that displays the content. This means we need
- // to intercept touches outside of that window. The dim layer user associated with
- // the window (task or stack) will give us the good bounds, as they would be used to
- // display the dim layer.
- final Task task = getTask();
- if (task != null) {
- task.getDimBounds(mTmpRect);
- } else {
- getStack().getDimBounds(mTmpRect);
- }
- }
- if (inFreeformWindowingMode()) {
- // For freeform windows we the touch region to include the whole surface for the
- // shadows.
- final DisplayMetrics displayMetrics = getDisplayContent().getDisplayMetrics();
- final int delta = WindowManagerService.dipToPixel(
- RESIZE_HANDLE_WIDTH_IN_DP, displayMetrics);
- mTmpRect.inset(-delta, -delta);
- }
- region.set(mTmpRect);
- cropRegionToStackBoundsIfNeeded(region);
- subtractTouchExcludeRegionIfNeeded(region);
- } else if (modal && mTapExcludeRegionHolder != null) {
- final Region touchExcludeRegion = Region.obtain();
- amendTapExcludeRegion(touchExcludeRegion);
- if (!touchExcludeRegion.isEmpty()) {
- // Remove touch modal because there are some areas that cannot be touched.
- flags |= FLAG_NOT_TOUCH_MODAL;
+ if (mActivityRecord != null) {
+ // Limit the outer touch to the activity stack region.
+ updateRegionForModalActivityWindow(region);
+ } else {
// Give it a large touchable region at first because it was touch modal. The window
// might be moved on the display, so the touchable region should be large enough to
// ensure it covers the whole display, no matter where it is moved.
@@ -2412,15 +2381,13 @@
final int dw = mTmpRect.width();
final int dh = mTmpRect.height();
region.set(-dw, -dh, dw + dw, dh + dh);
- // Subtract the area that cannot be touched.
- region.op(touchExcludeRegion, Region.Op.DIFFERENCE);
- inputWindowHandle.setTouchableRegionCrop(null);
}
- touchExcludeRegion.recycle();
+ subtractTouchExcludeRegionIfNeeded(region);
} else {
- // Not modal or full screen modal
+ // Not modal
getTouchableRegion(region);
}
+
// Translate to surface based coordinates.
region.translate(-mWindowFrames.mFrame.left, -mWindowFrames.mFrame.top);
@@ -2436,6 +2403,41 @@
return flags;
}
+ /**
+ * Updates the region for a window in an Activity that was a touch modal. This will limit
+ * the outer touch to the activity stack region.
+ * @param outRegion The region to update.
+ */
+ private void updateRegionForModalActivityWindow(Region outRegion) {
+ // If the inner bounds of letterbox is available, then it will be used as the
+ // touchable region so it won't cover the touchable letterbox and the touch
+ // events can slip to activity from letterbox.
+ mActivityRecord.getLetterboxInnerBounds(mTmpRect);
+ if (mTmpRect.isEmpty()) {
+ // If this is a modal window we need to dismiss it if it's not full screen
+ // and the touch happens outside of the frame that displays the content. This
+ // means we need to intercept touches outside of that window. The dim layer
+ // user associated with the window (task or stack) will give us the good
+ // bounds, as they would be used to display the dim layer.
+ final Task task = getTask();
+ if (task != null) {
+ task.getDimBounds(mTmpRect);
+ } else {
+ getStack().getDimBounds(mTmpRect);
+ }
+ }
+ if (inFreeformWindowingMode()) {
+ // For freeform windows, we need the touch region to include the whole
+ // surface for the shadows.
+ final DisplayMetrics displayMetrics = getDisplayContent().getDisplayMetrics();
+ final int delta = WindowManagerService.dipToPixel(
+ RESIZE_HANDLE_WIDTH_IN_DP, displayMetrics);
+ mTmpRect.inset(-delta, -delta);
+ }
+ outRegion.set(mTmpRect);
+ cropRegionToStackBoundsIfNeeded(outRegion);
+ }
+
void checkPolicyVisibilityChange() {
if (isLegacyPolicyVisibility() != mLegacyPolicyVisibilityAfterAnim) {
if (DEBUG_VISIBILITY) {
diff --git a/services/incremental/IncrementalService.cpp b/services/incremental/IncrementalService.cpp
index c43328f..afce260 100644
--- a/services/incremental/IncrementalService.cpp
+++ b/services/incremental/IncrementalService.cpp
@@ -351,10 +351,13 @@
{
metadata::Mount m;
m.mutable_storage()->set_id(ifs->mountId);
+ m.mutable_loader()->set_type((int)dataLoaderParams.type);
m.mutable_loader()->set_package_name(dataLoaderParams.packageName);
- m.mutable_loader()->set_arguments(dataLoaderParams.staticArgs);
+ m.mutable_loader()->set_class_name(dataLoaderParams.className);
+ m.mutable_loader()->set_arguments(dataLoaderParams.arguments);
const auto metadata = m.SerializeAsString();
m.mutable_loader()->release_arguments();
+ m.mutable_loader()->release_class_name();
m.mutable_loader()->release_package_name();
if (auto err = mIncFs->makeFile(ifs->control, constants().infoMdName, INCFS_ROOT_INODE, 0,
metadata);
@@ -794,7 +797,7 @@
}
bool started = false;
std::unique_lock l(ifs->lock);
- if (ifs->dataLoaderStatus != IDataLoaderStatusListener::DATA_LOADER_READY) {
+ if (ifs->dataLoaderStatus != IDataLoaderStatusListener::DATA_LOADER_CREATED) {
if (ifs->dataLoaderReady.wait_for(l, Seconds(5)) == std::cv_status::timeout) {
LOG(ERROR) << "Timeout waiting for data loader to be ready";
return false;
@@ -917,8 +920,10 @@
}
DataLoaderParamsParcel dlParams;
+ dlParams.type = (DataLoaderType)m.loader().type();
dlParams.packageName = std::move(*m.mutable_loader()->mutable_package_name());
- dlParams.staticArgs = std::move(*m.mutable_loader()->mutable_arguments());
+ dlParams.className = std::move(*m.mutable_loader()->mutable_class_name());
+ dlParams.arguments = std::move(*m.mutable_loader()->mutable_arguments());
if (!prepareDataLoader(*ifs, &dlParams)) {
deleteStorage(*ifs);
return false;
@@ -955,7 +960,7 @@
}
std::unique_lock l(ifs.lock);
- if (ifs.dataLoaderStatus == IDataLoaderStatusListener::DATA_LOADER_READY) {
+ if (ifs.dataLoaderStatus == IDataLoaderStatusListener::DATA_LOADER_CREATED) {
LOG(INFO) << "Skipped data loader preparation because it already exists";
return true;
}
@@ -1008,20 +1013,20 @@
}
break;
}
- case IDataLoaderStatusListener::DATA_LOADER_READY: {
+ case IDataLoaderStatusListener::DATA_LOADER_CONNECTION_OK: {
+ ifs->dataLoaderStatus = IDataLoaderStatusListener::DATA_LOADER_STARTED;
+ break;
+ }
+ case IDataLoaderStatusListener::DATA_LOADER_CREATED: {
ifs->dataLoaderReady.notify_one();
break;
}
- case IDataLoaderStatusListener::DATA_LOADER_NOT_READY: {
+ case IDataLoaderStatusListener::DATA_LOADER_DESTROYED: {
ifs->dataLoaderStatus = IDataLoaderStatusListener::DATA_LOADER_STOPPED;
incrementalService.deleteStorageLocked(*ifs, std::move(l));
break;
}
- case IDataLoaderStatusListener::DATA_LOADER_RUNNING: {
- break;
- }
- case IDataLoaderStatusListener::DATA_LOADER_CONNECTION_OK: {
- ifs->dataLoaderStatus = IDataLoaderStatusListener::DATA_LOADER_RUNNING;
+ case IDataLoaderStatusListener::DATA_LOADER_STARTED: {
break;
}
case IDataLoaderStatusListener::DATA_LOADER_STOPPED: {
diff --git a/services/incremental/Metadata.proto b/services/incremental/Metadata.proto
index 0ff3c32..79f1bf8 100644
--- a/services/incremental/Metadata.proto
+++ b/services/incremental/Metadata.proto
@@ -10,7 +10,9 @@
message DataLoader {
string package_name = 1;
+ string class_name = 3;
string arguments = 2;
+ int32 type = 4;
}
message Storage {
diff --git a/services/incremental/test/IncrementalServiceTest.cpp b/services/incremental/test/IncrementalServiceTest.cpp
index f6b123d..ca1e1a9 100644
--- a/services/incremental/test/IncrementalServiceTest.cpp
+++ b/services/incremental/test/IncrementalServiceTest.cpp
@@ -138,10 +138,10 @@
.WillByDefault(Invoke(this, &MockIncrementalManager::startDataLoaderOk));
}
void setDataLoaderStatusNotReady() {
- mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_NOT_READY);
+ mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_DESTROYED);
}
void setDataLoaderStatusReady() {
- mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_READY);
+ mListener->onStatusChanged(mId, IDataLoaderStatusListener::DATA_LOADER_CREATED);
}
private:
@@ -235,7 +235,7 @@
MockServiceManager serviceManager = MockServiceManager(mVold, mIncrementalManager, mIncFs);
mIncrementalService = std::make_unique<IncrementalService>(serviceManager, mRootDir.path);
mDataLoaderParcel.packageName = "com.test";
- mDataLoaderParcel.staticArgs = "uri";
+ mDataLoaderParcel.arguments = "uri";
mIncrementalService->onSystemReady();
}
diff --git a/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java b/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java
index 37ff06a..c080332 100644
--- a/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/integrity/AppIntegrityManagerServiceImplTest.java
@@ -16,12 +16,6 @@
package com.android.server.integrity;
-import static android.content.pm.PackageManager.EXTRA_VERIFICATION_ID;
-
-import static org.mockito.Mockito.verify;
-
-import android.content.Intent;
-import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import androidx.test.InstrumentationRegistry;
@@ -56,17 +50,7 @@
}
@Test
- public void integrityVerification_allow() {
- int verificationId = 2;
- Intent integrityVerificationIntent = new Intent();
- integrityVerificationIntent.setAction(Intent.ACTION_PACKAGE_NEEDS_INTEGRITY_VERIFICATION);
- integrityVerificationIntent.putExtra(EXTRA_VERIFICATION_ID, verificationId);
-
- // We cannot send the broadcast using the context since it is a protected broadcast and
- // we will get a security exception.
- mService.handleIntegrityVerification(integrityVerificationIntent);
-
- verify(mPackageManagerInternal)
- .setIntegrityVerificationResult(verificationId, PackageManager.VERIFICATION_ALLOW);
+ public void noop() {
+ // We need this test just as a place holder since an empty test suite is treated as error.
}
}
diff --git a/services/tests/servicestests/src/com/android/server/integrity/serializer/RuleXmlSerializerTest.java b/services/tests/servicestests/src/com/android/server/integrity/serializer/RuleXmlSerializerTest.java
index ad74901..0bb2d44 100644
--- a/services/tests/servicestests/src/com/android/server/integrity/serializer/RuleXmlSerializerTest.java
+++ b/services/tests/servicestests/src/com/android/server/integrity/serializer/RuleXmlSerializerTest.java
@@ -44,48 +44,66 @@
@RunWith(JUnit4.class)
public class RuleXmlSerializerTest {
+ private static final String SAMPLE_INSTALLER_NAME = "com.test.installer";
+ private static final String SAMPLE_INSTALLER_CERT = "installer_cert";
+
@Test
- public void testXmlString_serializeEmptyRule() throws Exception {
- Rule rule = null;
+ public void testXmlString_serializeEmptyRuleList() throws Exception {
RuleSerializer xmlSerializer = new RuleXmlSerializer();
String expectedRules = "<RL />";
byte[] actualRules =
xmlSerializer.serialize(
- Collections.singletonList(rule), /* formatVersion= */ Optional.empty());
+ Collections.emptyList(), /* formatVersion= */ Optional.empty());
assertEquals(expectedRules, new String(actualRules, StandardCharsets.UTF_8));
}
@Test
- public void testXmlString_serializeMultipleRules_oneEmpty() throws Exception {
- Rule rule1 = null;
- Rule rule2 =
+ public void testXmlString_serializeMultipleRules_indexingOrderPreserved() throws Exception {
+ String packageNameA = "aaa";
+ String packageNameB = "bbb";
+ String packageNameC = "ccc";
+ String appCert1 = "cert1";
+ String appCert2 = "cert2";
+ String appCert3 = "cert3";
+ Rule installerRule =
new Rule(
- new AtomicFormula.StringAtomicFormula(
- AtomicFormula.PACKAGE_NAME,
- "com.app.test",
- /* isHashedValue= */ false),
+ new CompoundFormula(
+ CompoundFormula.AND,
+ Arrays.asList(
+ new AtomicFormula.StringAtomicFormula(
+ AtomicFormula.INSTALLER_NAME,
+ SAMPLE_INSTALLER_NAME,
+ /* isHashedValue= */ false),
+ new AtomicFormula.StringAtomicFormula(
+ AtomicFormula.INSTALLER_CERTIFICATE,
+ SAMPLE_INSTALLER_CERT,
+ /* isHashedValue= */ false))),
Rule.DENY);
- RuleSerializer xmlSerializer = new RuleXmlSerializer();
- Map<String, String> packageNameAttrs = new LinkedHashMap<>();
- packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME));
- packageNameAttrs.put("V", "com.app.test");
- packageNameAttrs.put("H", "false");
- String expectedRules =
- "<RL>"
- + generateTagWithAttribute(
- /* tag= */ "R",
- Collections.singletonMap("E", String.valueOf(Rule.DENY)),
- /* closed= */ false)
- + generateTagWithAttribute(
- /* tag= */ "AF", packageNameAttrs, /* closed= */ true)
- + "</R>"
- + "</RL>";
+ RuleSerializer xmlSerializer = new RuleXmlSerializer();
byte[] actualRules =
xmlSerializer.serialize(
- Arrays.asList(rule1, rule2), /* formatVersion= */ Optional.empty());
+ Arrays.asList(
+ installerRule,
+ getRuleWithAppCertificateAndSampleInstallerName(appCert1),
+ getRuleWithPackageNameAndSampleInstallerName(packageNameB),
+ getRuleWithAppCertificateAndSampleInstallerName(appCert3),
+ getRuleWithPackageNameAndSampleInstallerName(packageNameC),
+ getRuleWithAppCertificateAndSampleInstallerName(appCert2),
+ getRuleWithPackageNameAndSampleInstallerName(packageNameA)),
+ /* formatVersion= */ Optional.empty());
+
+ String expectedRules = "<RL>"
+ + getSerializedCompoundRuleWithPackageNameAndSampleInstallerName(packageNameA)
+ + getSerializedCompoundRuleWithPackageNameAndSampleInstallerName(packageNameB)
+ + getSerializedCompoundRuleWithPackageNameAndSampleInstallerName(packageNameC)
+ + getSerializedCompoundRuleWithAppCertificateAndSampleInstallerName(appCert1)
+ + getSerializedCompoundRuleWithAppCertificateAndSampleInstallerName(appCert2)
+ + getSerializedCompoundRuleWithAppCertificateAndSampleInstallerName(appCert3)
+ + getSerializedCompoundRuleWithSampleInstallerNameAndCert()
+ + "</RL>";
assertEquals(expectedRules, new String(actualRules, StandardCharsets.UTF_8));
}
@@ -371,7 +389,7 @@
assertExpectException(
RuleSerializeException.class,
- /* expectedExceptionMessageRegex */ "Invalid formula type",
+ /* expectedExceptionMessageRegex */ "Malformed rule identified.",
() ->
xmlSerializer.serialize(
Collections.singletonList(rule),
@@ -393,6 +411,124 @@
return res.toString();
}
+ private Rule getRuleWithPackageNameAndSampleInstallerName(String packageName) {
+ return new Rule(
+ new CompoundFormula(
+ CompoundFormula.AND,
+ Arrays.asList(
+ new AtomicFormula.StringAtomicFormula(
+ AtomicFormula.PACKAGE_NAME,
+ packageName,
+ /* isHashedValue= */ false),
+ new AtomicFormula.StringAtomicFormula(
+ AtomicFormula.INSTALLER_NAME,
+ SAMPLE_INSTALLER_NAME,
+ /* isHashedValue= */ false))),
+ Rule.DENY);
+ }
+
+ private String getSerializedCompoundRuleWithPackageNameAndSampleInstallerName(
+ String packageName) {
+
+ Map<String, String> packageNameAttrs = new LinkedHashMap<>();
+ packageNameAttrs.put("K", String.valueOf(AtomicFormula.PACKAGE_NAME));
+ packageNameAttrs.put("V", packageName);
+ packageNameAttrs.put("H", "false");
+
+ Map<String, String> installerNameAttrs = new LinkedHashMap<>();
+ installerNameAttrs.put("K", String.valueOf(AtomicFormula.INSTALLER_NAME));
+ installerNameAttrs.put("V", SAMPLE_INSTALLER_NAME);
+ installerNameAttrs.put("H", "false");
+
+ return generateTagWithAttribute(
+ /* tag= */ "R",
+ Collections.singletonMap("E", String.valueOf(Rule.DENY)),
+ /* closed= */ false)
+ + generateTagWithAttribute(
+ /* tag= */ "OF",
+ Collections.singletonMap("C", String.valueOf(CompoundFormula.AND)),
+ /* closed= */ false)
+ + generateTagWithAttribute(
+ /* tag= */ "AF", packageNameAttrs, /* closed= */ true)
+ + generateTagWithAttribute(
+ /* tag= */ "AF", installerNameAttrs, /* closed= */ true)
+ + "</OF>"
+ + "</R>";
+ }
+
+
+ private Rule getRuleWithAppCertificateAndSampleInstallerName(String certificate) {
+ return new Rule(
+ new CompoundFormula(
+ CompoundFormula.AND,
+ Arrays.asList(
+ new AtomicFormula.StringAtomicFormula(
+ AtomicFormula.APP_CERTIFICATE,
+ certificate,
+ /* isHashedValue= */ false),
+ new AtomicFormula.StringAtomicFormula(
+ AtomicFormula.INSTALLER_NAME,
+ SAMPLE_INSTALLER_NAME,
+ /* isHashedValue= */ false))),
+ Rule.DENY);
+ }
+
+ private String getSerializedCompoundRuleWithAppCertificateAndSampleInstallerName(
+ String appCert) {
+
+ Map<String, String> packageNameAttrs = new LinkedHashMap<>();
+ packageNameAttrs.put("K", String.valueOf(AtomicFormula.APP_CERTIFICATE));
+ packageNameAttrs.put("V", appCert);
+ packageNameAttrs.put("H", "false");
+
+ Map<String, String> installerNameAttrs = new LinkedHashMap<>();
+ installerNameAttrs.put("K", String.valueOf(AtomicFormula.INSTALLER_NAME));
+ installerNameAttrs.put("V", SAMPLE_INSTALLER_NAME);
+ installerNameAttrs.put("H", "false");
+
+ return generateTagWithAttribute(
+ /* tag= */ "R",
+ Collections.singletonMap("E", String.valueOf(Rule.DENY)),
+ /* closed= */ false)
+ + generateTagWithAttribute(
+ /* tag= */ "OF",
+ Collections.singletonMap("C", String.valueOf(CompoundFormula.AND)),
+ /* closed= */ false)
+ + generateTagWithAttribute(
+ /* tag= */ "AF", packageNameAttrs, /* closed= */ true)
+ + generateTagWithAttribute(
+ /* tag= */ "AF", installerNameAttrs, /* closed= */ true)
+ + "</OF>"
+ + "</R>";
+ }
+
+ private String getSerializedCompoundRuleWithSampleInstallerNameAndCert() {
+ Map<String, String> installerNameAttrs = new LinkedHashMap<>();
+ installerNameAttrs.put("K", String.valueOf(AtomicFormula.INSTALLER_NAME));
+ installerNameAttrs.put("V", SAMPLE_INSTALLER_NAME);
+ installerNameAttrs.put("H", "false");
+
+ Map<String, String> installerCertAttrs = new LinkedHashMap<>();
+ installerCertAttrs.put("K", String.valueOf(AtomicFormula.INSTALLER_CERTIFICATE));
+ installerCertAttrs.put("V", SAMPLE_INSTALLER_CERT);
+ installerCertAttrs.put("H", "false");
+
+ return generateTagWithAttribute(
+ /* tag= */ "R",
+ Collections.singletonMap("E", String.valueOf(Rule.DENY)),
+ /* closed= */ false)
+ + generateTagWithAttribute(
+ /* tag= */ "OF",
+ Collections.singletonMap("C", String.valueOf(CompoundFormula.AND)),
+ /* closed= */ false)
+ + generateTagWithAttribute(
+ /* tag= */ "AF", installerNameAttrs, /* closed= */ true)
+ + generateTagWithAttribute(
+ /* tag= */ "AF", installerCertAttrs, /* closed= */ true)
+ + "</OF>"
+ + "</R>";
+ }
+
private Formula getInvalidFormula() {
return new Formula() {
@Override
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageVerificationStateTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageVerificationStateTest.java
index ebd3633..1fff4f0 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageVerificationStateTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageVerificationStateTest.java
@@ -17,8 +17,7 @@
package com.android.server.pm;
import android.content.pm.PackageManager;
-import com.android.server.pm.PackageVerificationState;
-
+import android.content.pm.PackageManagerInternal;
import android.test.AndroidTestCase;
public class PackageVerificationStateTest extends AndroidTestCase {
@@ -29,7 +28,8 @@
private static final int SUFFICIENT_UID_2 = 8938;
public void testPackageVerificationState_OnlyRequiredVerifier_AllowedInstall() {
- PackageVerificationState state = new PackageVerificationState(REQUIRED_UID, null);
+ PackageVerificationState state = new PackageVerificationState(null);
+ state.setRequiredVerifierUid(REQUIRED_UID);
assertFalse("Verification should not be marked as complete yet",
state.isVerificationComplete());
@@ -44,7 +44,8 @@
}
public void testPackageVerificationState_OnlyRequiredVerifier_DeniedInstall() {
- PackageVerificationState state = new PackageVerificationState(REQUIRED_UID, null);
+ PackageVerificationState state = new PackageVerificationState(null);
+ state.setRequiredVerifierUid(REQUIRED_UID);
assertFalse("Verification should not be marked as complete yet",
state.isVerificationComplete());
@@ -59,7 +60,8 @@
}
public void testPackageVerificationState_RequiredAndOneSufficient_RequiredDeniedInstall() {
- PackageVerificationState state = new PackageVerificationState(REQUIRED_UID, null);
+ PackageVerificationState state = new PackageVerificationState(null);
+ state.setRequiredVerifierUid(REQUIRED_UID);
assertFalse("Verification should not be marked as complete yet",
state.isVerificationComplete());
@@ -84,7 +86,8 @@
}
public void testPackageVerificationState_RequiredAndOneSufficient_SufficientDeniedInstall() {
- PackageVerificationState state = new PackageVerificationState(REQUIRED_UID, null);
+ PackageVerificationState state = new PackageVerificationState(null);
+ state.setRequiredVerifierUid(REQUIRED_UID);
assertFalse("Verification should not be marked as complete yet",
state.isVerificationComplete());
@@ -109,7 +112,8 @@
}
public void testPackageVerificationState_RequiredAndTwoSufficient_OneSufficientIsEnough() {
- PackageVerificationState state = new PackageVerificationState(REQUIRED_UID, null);
+ PackageVerificationState state = new PackageVerificationState(null);
+ state.setRequiredVerifierUid(REQUIRED_UID);
assertFalse("Verification should not be marked as complete yet",
state.isVerificationComplete());
@@ -135,7 +139,8 @@
}
public void testPackageVerificationState_RequiredAndTwoSufficient_SecondSufficientIsEnough() {
- PackageVerificationState state = new PackageVerificationState(REQUIRED_UID, null);
+ PackageVerificationState state = new PackageVerificationState(null);
+ state.setRequiredVerifierUid(REQUIRED_UID);
assertFalse("Verification should not be marked as complete yet",
state.isVerificationComplete());
@@ -166,7 +171,8 @@
}
public void testPackageVerificationState_RequiredAndTwoSufficient_RequiredOverrides() {
- PackageVerificationState state = new PackageVerificationState(REQUIRED_UID, null);
+ PackageVerificationState state = new PackageVerificationState(null);
+ state.setRequiredVerifierUid(REQUIRED_UID);
assertFalse("Verification should not be marked as complete yet",
state.isVerificationComplete());
@@ -202,4 +208,55 @@
assertTrue("Installation should be marked as allowed still",
state.isInstallAllowed());
}
+
+ public void testAreAllVerificationsComplete_onlyVerificationPasses() {
+ PackageVerificationState state = new PackageVerificationState(null);
+ state.setRequiredVerifierUid(REQUIRED_UID);
+ assertFalse(state.areAllVerificationsComplete());
+
+ state.setVerifierResponse(REQUIRED_UID, PackageManager.VERIFICATION_ALLOW);
+
+ assertFalse(state.areAllVerificationsComplete());
+ }
+
+ public void testAreAllVerificationsComplete_onlyIntegrityCheckPasses() {
+ PackageVerificationState state = new PackageVerificationState(null);
+ state.setRequiredVerifierUid(REQUIRED_UID);
+ assertFalse(state.areAllVerificationsComplete());
+
+ state.setIntegrityVerificationResult(PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW);
+
+ assertFalse(state.areAllVerificationsComplete());
+ }
+
+ public void testAreAllVerificationsComplete_bothPasses() {
+ PackageVerificationState state = new PackageVerificationState(null);
+ state.setRequiredVerifierUid(REQUIRED_UID);
+ assertFalse(state.areAllVerificationsComplete());
+
+ state.setIntegrityVerificationResult(PackageManagerInternal.INTEGRITY_VERIFICATION_ALLOW);
+ state.setVerifierResponse(REQUIRED_UID, PackageManager.VERIFICATION_ALLOW);
+
+ assertTrue(state.areAllVerificationsComplete());
+ }
+
+ public void testAreAllVerificationsComplete_onlyVerificationFails() {
+ PackageVerificationState state = new PackageVerificationState(null);
+ state.setRequiredVerifierUid(REQUIRED_UID);
+ assertFalse(state.areAllVerificationsComplete());
+
+ state.setVerifierResponse(REQUIRED_UID, PackageManager.VERIFICATION_REJECT);
+
+ assertFalse(state.areAllVerificationsComplete());
+ }
+
+ public void testAreAllVerificationsComplete_onlyIntegrityCheckFails() {
+ PackageVerificationState state = new PackageVerificationState(null);
+ state.setRequiredVerifierUid(REQUIRED_UID);
+ assertFalse(state.areAllVerificationsComplete());
+
+ state.setIntegrityVerificationResult(PackageManagerInternal.INTEGRITY_VERIFICATION_REJECT);
+
+ assertFalse(state.areAllVerificationsComplete());
+ }
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index 89723d1..65704c8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -19,6 +19,7 @@
import static android.content.pm.ActivityInfo.CONFIG_ORIENTATION;
import static android.content.pm.ActivityInfo.CONFIG_SCREEN_LAYOUT;
import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.content.res.Configuration.ORIENTATION_PORTRAIT;
import static android.os.Process.NOBODY_UID;
@@ -62,6 +63,7 @@
import static org.mockito.Mockito.never;
import android.app.ActivityOptions;
+import android.app.WindowConfiguration;
import android.app.servertransaction.ActivityConfigurationChangeItem;
import android.app.servertransaction.ClientTransaction;
import android.app.servertransaction.PauseActivityItem;
@@ -70,6 +72,7 @@
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
+import android.graphics.Rect;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.platform.test.annotations.Presubmit;
@@ -376,6 +379,64 @@
}
@Test
+ public void ignoreRequestedOrientationInFreeformWindows() {
+ mStack.setWindowingMode(WindowConfiguration.WINDOWING_MODE_FREEFORM);
+ final Rect stableRect = new Rect();
+ mStack.getDisplay().mDisplayContent.getStableRect(stableRect);
+ final boolean isScreenPortrait = stableRect.width() <= stableRect.height();
+ final Rect bounds = new Rect(stableRect);
+ if (isScreenPortrait) {
+ // Landscape bounds
+ final int newHeight = stableRect.width() - 10;
+ bounds.top = stableRect.top + (stableRect.height() - newHeight) / 2;
+ bounds.bottom = bounds.top + newHeight;
+ } else {
+ // Portrait bounds
+ final int newWidth = stableRect.height() - 10;
+ bounds.left = stableRect.left + (stableRect.width() - newWidth) / 2;
+ bounds.right = bounds.left + newWidth;
+ }
+ mTask.setBounds(bounds);
+
+ // Requests orientation that's different from its bounds.
+ mActivity.setRequestedOrientation(
+ isScreenPortrait ? SCREEN_ORIENTATION_PORTRAIT : SCREEN_ORIENTATION_LANDSCAPE);
+
+ // Asserts it has orientation derived from bounds.
+ assertEquals(isScreenPortrait ? ORIENTATION_LANDSCAPE : ORIENTATION_PORTRAIT,
+ mActivity.getConfiguration().orientation);
+ }
+
+ @Test
+ public void ignoreRequestedOrientationInSplitWindows() {
+ mStack.setWindowingMode(WindowConfiguration.WINDOWING_MODE_SPLIT_SCREEN_PRIMARY);
+ final Rect stableRect = new Rect();
+ mStack.getDisplay().mDisplayContent.getStableRect(stableRect);
+ final boolean isScreenPortrait = stableRect.width() <= stableRect.height();
+ final Rect bounds = new Rect(stableRect);
+ if (isScreenPortrait) {
+ // Landscape bounds
+ final int newHeight = stableRect.width() - 10;
+ bounds.top = stableRect.top + (stableRect.height() - newHeight) / 2;
+ bounds.bottom = bounds.top + newHeight;
+ } else {
+ // Portrait bounds
+ final int newWidth = stableRect.height() - 10;
+ bounds.left = stableRect.left + (stableRect.width() - newWidth) / 2;
+ bounds.right = bounds.left + newWidth;
+ }
+ mTask.setBounds(bounds);
+
+ // Requests orientation that's different from its bounds.
+ mActivity.setRequestedOrientation(
+ isScreenPortrait ? SCREEN_ORIENTATION_PORTRAIT : SCREEN_ORIENTATION_LANDSCAPE);
+
+ // Asserts it has orientation derived from bounds.
+ assertEquals(isScreenPortrait ? ORIENTATION_LANDSCAPE : ORIENTATION_PORTRAIT,
+ mActivity.getConfiguration().orientation);
+ }
+
+ @Test
public void testShouldMakeActive_deferredResume() {
mActivity.setState(ActivityStack.ActivityState.STOPPED, "Testing");
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
index 1a18df5..de6d752 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
@@ -427,6 +427,61 @@
assertNotEquals(origScreenH, task.getConfiguration().screenHeightDp);
}
+ @Test
+ public void testInsetDisregardedWhenFreeformOverlapsNavBar() {
+ DisplayContent display = mService.mRootActivityContainer.getDefaultDisplay();
+ ActivityStack stack = display.createStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD,
+ true /* onTop */);
+ DisplayInfo displayInfo = new DisplayInfo();
+ mService.mContext.getDisplay().getDisplayInfo(displayInfo);
+ final int displayHeight = displayInfo.logicalHeight;
+ final Task task = new TaskBuilder(mSupervisor).setStack(stack).build();
+ final Configuration inOutConfig = new Configuration();
+ final Configuration parentConfig = new Configuration();
+ final int longSide = 1200;
+ final int shortSide = 600;
+ parentConfig.densityDpi = 400;
+ parentConfig.screenHeightDp = 200; // 200 * 400 / 160 = 500px
+ parentConfig.screenWidthDp = 100; // 100 * 400 / 160 = 250px
+ parentConfig.windowConfiguration.setRotation(ROTATION_0);
+
+ final float density = 2.5f; // densityDpi / DENSITY_DEFAULT_SCALE = 400 / 160.0f
+ final int longSideDp = 480; // longSide / density = 1200 / 400 * 160
+ final int shortSideDp = 240; // shortSide / density = 600 / 400 * 160
+ final int screenLayout = parentConfig.screenLayout
+ & (Configuration.SCREENLAYOUT_LONG_MASK | Configuration.SCREENLAYOUT_SIZE_MASK);
+ final int reducedScreenLayout =
+ Configuration.reduceScreenLayout(screenLayout, longSideDp, shortSideDp);
+
+ // Portrait bounds overlapping with navigation bar, without insets.
+ inOutConfig.windowConfiguration.getBounds().set(0,
+ displayHeight - 10 - longSide,
+ shortSide,
+ displayHeight - 10);
+ // Set to freeform mode to verify bug fix.
+ inOutConfig.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);
+
+ task.computeConfigResourceOverrides(inOutConfig, parentConfig);
+
+ assertEquals(parentConfig.screenWidthDp, inOutConfig.screenWidthDp);
+ assertEquals(parentConfig.screenHeightDp, inOutConfig.screenHeightDp);
+ assertEquals(reducedScreenLayout, inOutConfig.screenLayout);
+
+ inOutConfig.setToDefaults();
+ // Landscape bounds overlapping with navigtion bar, without insets.
+ inOutConfig.windowConfiguration.getBounds().set(0,
+ displayHeight - 10 - shortSide,
+ longSide,
+ displayHeight - 10);
+ inOutConfig.windowConfiguration.setWindowingMode(WINDOWING_MODE_FREEFORM);
+
+ task.computeConfigResourceOverrides(inOutConfig, parentConfig);
+
+ assertEquals(parentConfig.screenWidthDp, inOutConfig.screenWidthDp);
+ assertEquals(parentConfig.screenHeightDp, inOutConfig.screenHeightDp);
+ assertEquals(reducedScreenLayout, inOutConfig.screenLayout);
+ }
+
/** Ensures that the alias intent won't have target component resolved. */
@Test
public void testTaskIntentActivityAlias() {
diff --git a/telephony/java/android/telephony/Annotation.java b/telephony/java/android/telephony/Annotation.java
index 3940a3b..9b9997f 100644
--- a/telephony/java/android/telephony/Annotation.java
+++ b/telephony/java/android/telephony/Annotation.java
@@ -485,6 +485,86 @@
PreciseCallState.PRECISE_CALL_STATE_DISCONNECTING})
public @interface PreciseCallStates {}
+ @IntDef(value = {
+ DisconnectCause.NOT_VALID,
+ DisconnectCause.NOT_DISCONNECTED,
+ DisconnectCause.INCOMING_MISSED,
+ DisconnectCause.NORMAL,
+ DisconnectCause.LOCAL,
+ DisconnectCause.BUSY,
+ DisconnectCause.CONGESTION,
+ DisconnectCause.MMI,
+ DisconnectCause.INVALID_NUMBER,
+ DisconnectCause.NUMBER_UNREACHABLE,
+ DisconnectCause.SERVER_UNREACHABLE,
+ DisconnectCause.INVALID_CREDENTIALS,
+ DisconnectCause.OUT_OF_NETWORK,
+ DisconnectCause.SERVER_ERROR,
+ DisconnectCause.TIMED_OUT,
+ DisconnectCause.LOST_SIGNAL,
+ DisconnectCause.LIMIT_EXCEEDED,
+ DisconnectCause.INCOMING_REJECTED,
+ DisconnectCause.POWER_OFF,
+ DisconnectCause.OUT_OF_SERVICE,
+ DisconnectCause.ICC_ERROR,
+ DisconnectCause.CALL_BARRED,
+ DisconnectCause.FDN_BLOCKED,
+ DisconnectCause.CS_RESTRICTED,
+ DisconnectCause.CS_RESTRICTED_NORMAL,
+ DisconnectCause.CS_RESTRICTED_EMERGENCY,
+ DisconnectCause.UNOBTAINABLE_NUMBER,
+ DisconnectCause.CDMA_LOCKED_UNTIL_POWER_CYCLE,
+ DisconnectCause.CDMA_DROP,
+ DisconnectCause.CDMA_INTERCEPT,
+ DisconnectCause.CDMA_REORDER,
+ DisconnectCause.CDMA_SO_REJECT,
+ DisconnectCause.CDMA_RETRY_ORDER,
+ DisconnectCause.CDMA_ACCESS_FAILURE,
+ DisconnectCause.CDMA_PREEMPTED,
+ DisconnectCause.CDMA_NOT_EMERGENCY,
+ DisconnectCause.CDMA_ACCESS_BLOCKED,
+ DisconnectCause.ERROR_UNSPECIFIED,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface DisconnectCauses {
+ }
+
+ @IntDef(value = {
+ PreciseDisconnectCause.NOT_VALID,
+ PreciseDisconnectCause.NO_DISCONNECT_CAUSE_AVAILABLE,
+ PreciseDisconnectCause.UNOBTAINABLE_NUMBER,
+ PreciseDisconnectCause.NORMAL,
+ PreciseDisconnectCause.BUSY,
+ PreciseDisconnectCause.NUMBER_CHANGED,
+ PreciseDisconnectCause.STATUS_ENQUIRY,
+ PreciseDisconnectCause.NORMAL_UNSPECIFIED,
+ PreciseDisconnectCause.NO_CIRCUIT_AVAIL,
+ PreciseDisconnectCause.TEMPORARY_FAILURE,
+ PreciseDisconnectCause.SWITCHING_CONGESTION,
+ PreciseDisconnectCause.CHANNEL_NOT_AVAIL,
+ PreciseDisconnectCause.QOS_NOT_AVAIL,
+ PreciseDisconnectCause.BEARER_NOT_AVAIL,
+ PreciseDisconnectCause.ACM_LIMIT_EXCEEDED,
+ PreciseDisconnectCause.CALL_BARRED,
+ PreciseDisconnectCause.FDN_BLOCKED,
+ PreciseDisconnectCause.IMSI_UNKNOWN_IN_VLR,
+ PreciseDisconnectCause.IMEI_NOT_ACCEPTED,
+ PreciseDisconnectCause.CDMA_LOCKED_UNTIL_POWER_CYCLE,
+ PreciseDisconnectCause.CDMA_DROP,
+ PreciseDisconnectCause.CDMA_INTERCEPT,
+ PreciseDisconnectCause.CDMA_REORDER,
+ PreciseDisconnectCause.CDMA_SO_REJECT,
+ PreciseDisconnectCause.CDMA_RETRY_ORDER,
+ PreciseDisconnectCause.CDMA_ACCESS_FAILURE,
+ PreciseDisconnectCause.CDMA_PREEMPTED,
+ PreciseDisconnectCause.CDMA_NOT_EMERGENCY,
+ PreciseDisconnectCause.CDMA_ACCESS_BLOCKED,
+ PreciseDisconnectCause.ERROR_UNSPECIFIED,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface PreciseDisconnectCauses {
+ }
+
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = {"RIL_RADIO_TECHNOLOGY_" }, value = {
ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN,
diff --git a/telephony/java/android/telephony/CellIdentity.java b/telephony/java/android/telephony/CellIdentity.java
index b7dab16..e523fba 100644
--- a/telephony/java/android/telephony/CellIdentity.java
+++ b/telephony/java/android/telephony/CellIdentity.java
@@ -19,6 +19,7 @@
import android.annotation.CallSuper;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
@@ -181,7 +182,8 @@
* @return a CellLocation object for this CellIdentity
* @hide
*/
- public abstract CellLocation asCellLocation();
+ @SystemApi
+ public abstract @NonNull CellLocation asCellLocation();
@Override
public boolean equals(Object other) {
diff --git a/telephony/java/android/telephony/CellIdentityCdma.java b/telephony/java/android/telephony/CellIdentityCdma.java
index 880d3db..54236b42 100644
--- a/telephony/java/android/telephony/CellIdentityCdma.java
+++ b/telephony/java/android/telephony/CellIdentityCdma.java
@@ -16,6 +16,7 @@
package android.telephony;
+import android.annotation.NonNull;
import android.os.Parcel;
import android.telephony.cdma.CdmaCellLocation;
@@ -198,6 +199,7 @@
}
/** @hide */
+ @NonNull
@Override
public CdmaCellLocation asCellLocation() {
CdmaCellLocation cl = new CdmaCellLocation();
diff --git a/telephony/java/android/telephony/CellIdentityGsm.java b/telephony/java/android/telephony/CellIdentityGsm.java
index 25c6577..4e4454d 100644
--- a/telephony/java/android/telephony/CellIdentityGsm.java
+++ b/telephony/java/android/telephony/CellIdentityGsm.java
@@ -16,6 +16,7 @@
package android.telephony;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
@@ -200,6 +201,7 @@
}
/** @hide */
+ @NonNull
@Override
public GsmCellLocation asCellLocation() {
GsmCellLocation cl = new GsmCellLocation();
diff --git a/telephony/java/android/telephony/CellIdentityLte.java b/telephony/java/android/telephony/CellIdentityLte.java
index 997b19f..c3fc73b 100644
--- a/telephony/java/android/telephony/CellIdentityLte.java
+++ b/telephony/java/android/telephony/CellIdentityLte.java
@@ -16,6 +16,7 @@
package android.telephony;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UnsupportedAppUsage;
import android.os.Build;
@@ -232,6 +233,7 @@
*
* @hide
*/
+ @NonNull
@Override
public GsmCellLocation asCellLocation() {
GsmCellLocation cl = new GsmCellLocation();
diff --git a/telephony/java/android/telephony/CellIdentityNr.java b/telephony/java/android/telephony/CellIdentityNr.java
index edc838c..e3fec7b 100644
--- a/telephony/java/android/telephony/CellIdentityNr.java
+++ b/telephony/java/android/telephony/CellIdentityNr.java
@@ -17,6 +17,7 @@
package android.telephony;
import android.annotation.IntRange;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.os.Parcel;
import android.telephony.gsm.GsmCellLocation;
@@ -77,6 +78,7 @@
* @return a CellLocation object for this CellIdentity.
* @hide
*/
+ @NonNull
@Override
public CellLocation asCellLocation() {
return new GsmCellLocation();
diff --git a/telephony/java/android/telephony/CellIdentityTdscdma.java b/telephony/java/android/telephony/CellIdentityTdscdma.java
index 558e346..8f812b6 100644
--- a/telephony/java/android/telephony/CellIdentityTdscdma.java
+++ b/telephony/java/android/telephony/CellIdentityTdscdma.java
@@ -171,6 +171,7 @@
}
/** @hide */
+ @NonNull
@Override
public GsmCellLocation asCellLocation() {
GsmCellLocation cl = new GsmCellLocation();
diff --git a/telephony/java/android/telephony/CellIdentityWcdma.java b/telephony/java/android/telephony/CellIdentityWcdma.java
index 031fed1..556bc32 100644
--- a/telephony/java/android/telephony/CellIdentityWcdma.java
+++ b/telephony/java/android/telephony/CellIdentityWcdma.java
@@ -16,6 +16,7 @@
package android.telephony;
+import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
@@ -196,6 +197,7 @@
}
/** @hide */
+ @NonNull
@Override
public GsmCellLocation asCellLocation() {
GsmCellLocation cl = new GsmCellLocation();
diff --git a/telephony/java/android/telephony/PreciseCallState.java b/telephony/java/android/telephony/PreciseCallState.java
index 9f75332..bfa6326 100644
--- a/telephony/java/android/telephony/PreciseCallState.java
+++ b/telephony/java/android/telephony/PreciseCallState.java
@@ -16,19 +16,18 @@
package android.telephony;
-import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
+import android.telephony.Annotation.DisconnectCauses;
import android.telephony.Annotation.PreciseCallStates;
+import android.telephony.Annotation.PreciseDisconnectCauses;
import android.telephony.DisconnectCause;
import android.telephony.PreciseDisconnectCause;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
import java.util.Objects;
/**
@@ -73,19 +72,26 @@
private @PreciseCallStates int mRingingCallState = PRECISE_CALL_STATE_NOT_VALID;
private @PreciseCallStates int mForegroundCallState = PRECISE_CALL_STATE_NOT_VALID;
private @PreciseCallStates int mBackgroundCallState = PRECISE_CALL_STATE_NOT_VALID;
- private int mDisconnectCause = DisconnectCause.NOT_VALID;
- private int mPreciseDisconnectCause = PreciseDisconnectCause.NOT_VALID;
+ private @DisconnectCauses int mDisconnectCause = DisconnectCause.NOT_VALID;
+ private @PreciseDisconnectCauses int mPreciseDisconnectCause = PreciseDisconnectCause.NOT_VALID;
/**
- * Constructor
+ * Construct PreciseCallState with parameters
+ *
+ * @param ringingCall ring call state
+ * @param foregroundCall foreground call state
+ * @param backgroundCall background call state
+ * @param disconnectCause disconnect cause
+ * @param preciseDisconnectCause precise disconnect cause
*
* @hide
*/
- @UnsupportedAppUsage
+ @SystemApi
public PreciseCallState(@PreciseCallStates int ringingCall,
@PreciseCallStates int foregroundCall,
- @PreciseCallStates int backgroundCall, int disconnectCause,
- int preciseDisconnectCause) {
+ @PreciseCallStates int backgroundCall,
+ @DisconnectCauses int disconnectCause,
+ @PreciseDisconnectCauses int preciseDisconnectCause) {
mRingingCallState = ringingCall;
mForegroundCallState = foregroundCall;
mBackgroundCallState = backgroundCall;
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 60fda09..a96325e 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -1950,14 +1950,9 @@
return null;
}
- Bundle bundle = telephony.getCellLocation(mContext.getOpPackageName(),
+ CellIdentity cellIdentity = telephony.getCellLocation(mContext.getOpPackageName(),
mContext.getFeatureId());
- if (bundle == null || bundle.isEmpty()) {
- Rlog.d(TAG, "getCellLocation returning null because CellLocation is unavailable");
- return null;
- }
-
- CellLocation cl = CellLocation.newFromBundle(bundle);
+ CellLocation cl = cellIdentity.asCellLocation();
if (cl == null || cl.isEmpty()) {
Rlog.d(TAG, "getCellLocation returning null because CellLocation is empty or"
+ " phone type doesn't match CellLocation type");
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 97b24ae..0baac71 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -30,6 +30,7 @@
import android.telecom.PhoneAccount;
import android.telecom.PhoneAccountHandle;
import android.telephony.CarrierRestrictionRules;
+import android.telephony.CellIdentity;
import android.telephony.CellInfo;
import android.telephony.ClientRequestStats;
import android.telephony.IccOpenLogicalChannelResponse;
@@ -305,7 +306,8 @@
*/
boolean isDataConnectivityPossible(int subId);
- Bundle getCellLocation(String callingPkg, String callingFeatureId);
+ // Uses CellIdentity which is Parcelable here; will convert to CellLocation in client.
+ CellIdentity getCellLocation(String callingPkg, String callingFeatureId);
/**
* Returns the ISO country code equivalent of the current registered
diff --git a/tests/ApkVerityTest/AndroidTest.xml b/tests/ApkVerityTest/AndroidTest.xml
index 51bcdea..55704ed 100644
--- a/tests/ApkVerityTest/AndroidTest.xml
+++ b/tests/ApkVerityTest/AndroidTest.xml
@@ -22,7 +22,7 @@
<target_preparer class="com.android.tradefed.targetprep.DeviceSetup">
<!-- Disable package verifier prevents it holding the target APK's fd that prevents cache
eviction. -->
- <option name="set-global-setting" key="package_verifier_enable" value="0" />
+ <option name="set-global-setting" key="verifier_verify_adb_installs" value="0" />
<option name="restore-settings" value="true" />
<!-- Skip in order to prevent reboot that confuses the test flow. -->
diff --git a/wifi/java/android/net/wifi/EasyConnectStatusCallback.java b/wifi/java/android/net/wifi/EasyConnectStatusCallback.java
index b8c82fd..4fa93ee 100644
--- a/wifi/java/android/net/wifi/EasyConnectStatusCallback.java
+++ b/wifi/java/android/net/wifi/EasyConnectStatusCallback.java
@@ -17,32 +17,46 @@
package android.net.wifi;
import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
-import android.os.Handler;
+import android.util.SparseArray;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.concurrent.Executor;
/**
* Easy Connect (DPP) Status Callback. Use this callback to get status updates (success, failure,
* progress) from the Easy Connect operation started with
- * {@link WifiManager#startEasyConnectAsConfiguratorInitiator(String,
- * int, int, Handler, EasyConnectStatusCallback)} or
- * {@link WifiManager#startEasyConnectAsEnrolleeInitiator(String,
- * Handler, EasyConnectStatusCallback)}
+ * {@link WifiManager#startEasyConnectAsConfiguratorInitiator(String, int, int, Executor,
+ * EasyConnectStatusCallback)} or {@link WifiManager#startEasyConnectAsEnrolleeInitiator(String,
+ * Executor, EasyConnectStatusCallback)}
*
* @hide
*/
@SystemApi
public abstract class EasyConnectStatusCallback {
/**
- * Easy Connect Success event: Configuration sent (Configurator mode).
+ * Easy Connect R1 Success event: Configuration sent (Configurator mode). This is the last
+ * and final Easy Connect event when either the local device or remote device implement R1.
+ * If both devices implement R2, this event will never be received, and the
+ * {@link EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_APPLIED} will be received.
*/
public static final int EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_SENT = 0;
+ /**
+ * East Connect R2 Success event: Configuration applied by Enrollee (Configurator mode).
+ * This is the last and final Easy Connect event when both the local device and remote device
+ * implement R2. If either the local device or remote device implement R1, this event will never
+ * be received, and the {@link EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_SENT} will be received.
+ */
+ public static final int EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_APPLIED = 1;
+
/** @hide */
@IntDef(prefix = {"EASY_CONNECT_EVENT_SUCCESS_"}, value = {
EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_SENT,
+ EASY_CONNECT_EVENT_SUCCESS_CONFIGURATION_APPLIED,
})
@Retention(RetentionPolicy.SOURCE)
public @interface EasyConnectSuccessStatusCode {
@@ -58,10 +72,22 @@
*/
public static final int EASY_CONNECT_EVENT_PROGRESS_RESPONSE_PENDING = 1;
+ /**
+ * Easy Connect R2 Progress event: Configuration sent to Enrollee, waiting for response
+ */
+ public static final int EASY_CONNECT_EVENT_PROGRESS_CONFIGURATION_SENT_WAITING_RESPONSE = 2;
+
+ /**
+ * Easy Connect R2 Progress event: Configuration accepted by Enrollee, waiting for response
+ */
+ public static final int EASY_CONNECT_EVENT_PROGRESS_CONFIGURATION_ACCEPTED = 3;
+
/** @hide */
@IntDef(prefix = {"EASY_CONNECT_EVENT_PROGRESS_"}, value = {
EASY_CONNECT_EVENT_PROGRESS_AUTHENTICATION_SUCCESS,
EASY_CONNECT_EVENT_PROGRESS_RESPONSE_PENDING,
+ EASY_CONNECT_EVENT_PROGRESS_CONFIGURATION_SENT_WAITING_RESPONSE,
+ EASY_CONNECT_EVENT_PROGRESS_CONFIGURATION_ACCEPTED,
})
@Retention(RetentionPolicy.SOURCE)
public @interface EasyConnectProgressStatusCode {
@@ -114,6 +140,20 @@
*/
public static final int EASY_CONNECT_EVENT_FAILURE_INVALID_NETWORK = -9;
+ /**
+ * Easy Connect R2 Failure event: Enrollee cannot find the network.
+ */
+ public static final int EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK = -10;
+
+ /**
+ * Easy Connect R2 Failure event: Enrollee failed to authenticate with the network.
+ */
+ public static final int EASY_CONNECT_EVENT_FAILURE_ENROLLEE_AUTHENTICATION = -11;
+
+ /**
+ * Easy Connect R2 Failure event: Enrollee rejected the configuration.
+ */
+ public static final int EASY_CONNECT_EVENT_FAILURE_ENROLLEE_REJECTED_CONFIGURATION = -12;
/** @hide */
@IntDef(prefix = {"EASY_CONNECT_EVENT_FAILURE_"}, value = {
@@ -126,6 +166,9 @@
EASY_CONNECT_EVENT_FAILURE_GENERIC,
EASY_CONNECT_EVENT_FAILURE_NOT_SUPPORTED,
EASY_CONNECT_EVENT_FAILURE_INVALID_NETWORK,
+ EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK,
+ EASY_CONNECT_EVENT_FAILURE_ENROLLEE_AUTHENTICATION,
+ EASY_CONNECT_EVENT_FAILURE_ENROLLEE_REJECTED_CONFIGURATION,
})
@Retention(RetentionPolicy.SOURCE)
public @interface EasyConnectFailureStatusCode {
@@ -138,9 +181,8 @@
* current Easy Connect
* session, and no further callbacks will be called. This callback is the successful outcome
* of a Easy Connect flow starting with
- * {@link WifiManager#startEasyConnectAsEnrolleeInitiator(String,
- * Handler,
- * EasyConnectStatusCallback)}.
+ * {@link WifiManager#startEasyConnectAsEnrolleeInitiator(String, Executor,
+ * EasyConnectStatusCallback)} .
*
* @param newNetworkId New Wi-Fi configuration with a network ID received from the configurator
*/
@@ -148,13 +190,11 @@
/**
* Called when a Easy Connect success event takes place, except for when configuration is
- * received from
- * an external Configurator. The callback onSuccessConfigReceived will be used in this case.
- * This callback marks the successful end of the current Easy Connect session, and no further
- * callbacks will be called. This callback is the successful outcome of a Easy Connect flow
- * starting with
- * {@link WifiManager#startEasyConnectAsConfiguratorInitiator(String, int, int, Handler,
- * EasyConnectStatusCallback)}.
+ * received from an external Configurator. The callback onSuccessConfigReceived will be used in
+ * this case. This callback marks the successful end of the current Easy Connect session, and no
+ * further callbacks will be called. This callback is the successful outcome of a Easy Connect
+ * flow starting with {@link WifiManager#startEasyConnectAsConfiguratorInitiator(String, int,
+ * int, Executor,EasyConnectStatusCallback)}.
*
* @param code Easy Connect success status code.
*/
@@ -162,12 +202,36 @@
/**
* Called when a Easy Connect Failure event takes place. This callback marks the unsuccessful
- * end of the
- * current Easy Connect session, and no further callbacks will be called.
+ * end of the current Easy Connect session, and no further callbacks will be called.
*
* @param code Easy Connect failure status code.
*/
- public abstract void onFailure(@EasyConnectFailureStatusCode int code);
+ public void onFailure(@EasyConnectFailureStatusCode int code) {}
+
+ /**
+ * Called when a Easy Connect Failure event takes place. This callback marks the unsuccessful
+ * end of the current Easy Connect session, and no further callbacks will be called.
+ *
+ * Note: Easy Connect (DPP) R2, provides additional details for the Configurator when the
+ * remote Enrollee is unable to connect to a network. The ssid, channelList and bandList
+ * inputs are initialized only for the EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK failure
+ * code, and the ssid and bandList are initialized for the
+ * EASY_CONNECT_EVENT_FAILURE_ENROLLEE_AUTHENTICATION failure code.
+ *
+ * @param code Easy Connect failure status code.
+ * @param ssid SSID of the network the Enrollee tried to connect to.
+ * @param channelListArray List of Global Operating classes and channel sets the Enrollee used
+ * to scan to find the network, see the "DPP Connection Status Object"
+ * section in the specification for the format, and Table E-4 in
+ * IEEE Std 802.11-2016 - Global operating classes for more details.
+ * @param operatingClassArray Array of bands the Enrollee supports as expressed as the Global
+ * Operating Class, see Table E-4 in IEEE Std 802.11-2016 - Global
+ * operating classes.
+ */
+ public void onFailure(@EasyConnectFailureStatusCode int code, @Nullable String ssid,
+ @NonNull SparseArray<int[]> channelListArray, @NonNull int[] operatingClassArray) {
+ onFailure(code);
+ }
/**
* Called when Easy Connect events that indicate progress take place. Can be used by UI elements
diff --git a/wifi/java/android/net/wifi/IDppCallback.aidl b/wifi/java/android/net/wifi/IDppCallback.aidl
index c452c76..d7a958a 100644
--- a/wifi/java/android/net/wifi/IDppCallback.aidl
+++ b/wifi/java/android/net/wifi/IDppCallback.aidl
@@ -38,7 +38,7 @@
/**
* Called when DPP Failure events take place.
*/
- void onFailure(int status);
+ void onFailure(int status, String ssid, String channelList, in int[] bandArray);
/**
* Called when DPP events that indicate progress take place. Can be used by UI elements
diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java
index b98d64d..5ab0583 100644
--- a/wifi/java/android/net/wifi/WifiManager.java
+++ b/wifi/java/android/net/wifi/WifiManager.java
@@ -54,6 +54,7 @@
import android.util.CloseGuard;
import android.util.Log;
import android.util.Pair;
+import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
@@ -70,6 +71,7 @@
import java.util.Map;
import java.util.Objects;
import java.util.Set;
+import java.util.StringTokenizer;
import java.util.concurrent.Executor;
/**
@@ -5177,6 +5179,7 @@
@Override
public void onSuccessConfigReceived(int newNetworkId) {
Log.d(TAG, "Easy Connect onSuccessConfigReceived callback");
+ Binder.clearCallingIdentity();
mExecutor.execute(() -> {
mEasyConnectStatusCallback.onEnrolleeSuccess(newNetworkId);
});
@@ -5185,22 +5188,28 @@
@Override
public void onSuccess(int status) {
Log.d(TAG, "Easy Connect onSuccess callback");
+ Binder.clearCallingIdentity();
mExecutor.execute(() -> {
mEasyConnectStatusCallback.onConfiguratorSuccess(status);
});
}
@Override
- public void onFailure(int status) {
+ public void onFailure(int status, String ssid, String channelList,
+ int[] operatingClassArray) {
Log.d(TAG, "Easy Connect onFailure callback");
+ Binder.clearCallingIdentity();
mExecutor.execute(() -> {
- mEasyConnectStatusCallback.onFailure(status);
+ SparseArray<int[]> channelListArray = parseDppChannelList(channelList);
+ mEasyConnectStatusCallback.onFailure(status, ssid, channelListArray,
+ operatingClassArray);
});
}
@Override
public void onProgress(int status) {
Log.d(TAG, "Easy Connect onProgress callback");
+ Binder.clearCallingIdentity();
mExecutor.execute(() -> {
mEasyConnectStatusCallback.onProgress(status);
});
@@ -5532,4 +5541,77 @@
throw e.rethrowFromSystemServer();
}
}
+
+ /**
+ * Parse the list of channels the DPP enrollee reports when it fails to find an AP.
+ *
+ * @param channelList List of channels in the format defined in the DPP specification.
+ * @return A parsed sparse array, where the operating class is the key.
+ * @hide
+ */
+ @VisibleForTesting
+ public static SparseArray<int[]> parseDppChannelList(String channelList) {
+ SparseArray<int[]> channelListArray = new SparseArray<>();
+
+ if (TextUtils.isEmpty(channelList)) {
+ return channelListArray;
+ }
+ StringTokenizer str = new StringTokenizer(channelList, ",");
+ String classStr = null;
+ List<Integer> channelsInClass = new ArrayList<>();
+
+ try {
+ while (str.hasMoreElements()) {
+ String cur = str.nextToken();
+
+ /**
+ * Example for a channel list:
+ *
+ * 81/1,2,3,4,5,6,7,8,9,10,11,115/36,40,44,48,118/52,56,60,64,121/100,104,108,112,
+ * 116,120,124,128,132,136,140,0/144,124/149,153,157,161,125/165
+ *
+ * Detect operating class by the delimiter of '/' and use a string tokenizer with
+ * ',' as a delimiter.
+ */
+ int classDelim = cur.indexOf('/');
+ if (classDelim != -1) {
+ if (classStr != null) {
+ // Store the last channel array in the sparse array, where the operating
+ // class is the key (as an integer).
+ int[] channelsArray = new int[channelsInClass.size()];
+ for (int i = 0; i < channelsInClass.size(); i++) {
+ channelsArray[i] = channelsInClass.get(i);
+ }
+ channelListArray.append(Integer.parseInt(classStr), channelsArray);
+ channelsInClass = new ArrayList<>();
+ }
+
+ // Init a new operating class and store the first channel
+ classStr = cur.substring(0, classDelim);
+ String channelStr = cur.substring(classDelim + 1);
+ channelsInClass.add(Integer.parseInt(channelStr));
+ } else {
+ if (classStr == null) {
+ // Invalid format
+ Log.e(TAG, "Cannot parse DPP channel list");
+ return new SparseArray<>();
+ }
+ channelsInClass.add(Integer.parseInt(cur));
+ }
+ }
+
+ // Store the last array
+ if (classStr != null) {
+ int[] channelsArray = new int[channelsInClass.size()];
+ for (int i = 0; i < channelsInClass.size(); i++) {
+ channelsArray[i] = channelsInClass.get(i);
+ }
+ channelListArray.append(Integer.parseInt(classStr), channelsArray);
+ }
+ return channelListArray;
+ } catch (NumberFormatException e) {
+ Log.e(TAG, "Cannot parse DPP channel list");
+ return new SparseArray<>();
+ }
+ }
}
diff --git a/wifi/tests/src/android/net/wifi/EasyConnectStatusCallbackTest.java b/wifi/tests/src/android/net/wifi/EasyConnectStatusCallbackTest.java
new file mode 100644
index 0000000..b101414
--- /dev/null
+++ b/wifi/tests/src/android/net/wifi/EasyConnectStatusCallbackTest.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.wifi;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import android.util.SparseArray;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Unit tests for {@link android.net.wifi.EasyConnectStatusCallbackTest}.
+ */
+@SmallTest
+public class EasyConnectStatusCallbackTest {
+ private EasyConnectStatusCallback mEasyConnectStatusCallback = new EasyConnectStatusCallback() {
+ @Override
+ public void onEnrolleeSuccess(int newNetworkId) {
+
+ }
+
+ @Override
+ public void onConfiguratorSuccess(int code) {
+
+ }
+
+ @Override
+ public void onProgress(int code) {
+
+ }
+
+ @Override
+ public void onFailure(int code) {
+ mOnFailureR1EventReceived = true;
+ mLastCode = code;
+ }
+ };
+ private boolean mOnFailureR1EventReceived;
+ private int mLastCode;
+
+ @Before
+ public void setUp() {
+ mOnFailureR1EventReceived = false;
+ mLastCode = 0;
+ }
+
+ /**
+ * Test that the legacy R1 onFailure is called by default if the R2 onFailure is not overridden
+ * by the app.
+ */
+ @Test
+ public void testR1OnFailureCalled() {
+
+ SparseArray<int[]> channelList = new SparseArray<>();
+ int[] channelArray = new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
+
+ channelList.append(81, channelArray);
+ mEasyConnectStatusCallback.onFailure(
+ EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK,
+ "SomeSSID", channelList, new int[] {81});
+
+ assertTrue(mOnFailureR1EventReceived);
+ assertEquals(mLastCode,
+ EasyConnectStatusCallback.EASY_CONNECT_EVENT_FAILURE_CANNOT_FIND_NETWORK);
+ }
+}
diff --git a/wifi/tests/src/android/net/wifi/WifiManagerTest.java b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
index 4a46744..8216611 100644
--- a/wifi/tests/src/android/net/wifi/WifiManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/WifiManagerTest.java
@@ -89,6 +89,7 @@
import android.os.RemoteException;
import android.os.connectivity.WifiActivityEnergyInfo;
import android.os.test.TestLooper;
+import android.util.SparseArray;
import androidx.test.filters.SmallTest;
@@ -2089,4 +2090,63 @@
.thenReturn(new Long(~WifiManager.WIFI_FEATURE_WAPI));
assertFalse(mWifiManager.isWapiSupported());
}
+
+ /*
+ * Test that DPP channel list is parsed correctly
+ */
+ @Test
+ public void testparseDppChannelList() throws Exception {
+ String channelList = "81/1,2,3,4,5,6,7,8,9,10,11,115/36,40,44,48";
+ SparseArray<int[]> expectedResult = new SparseArray<>();
+ expectedResult.append(81, new int[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11});
+ expectedResult.append(115, new int[]{36, 40, 44, 48});
+
+ SparseArray<int[]> result = WifiManager.parseDppChannelList(channelList);
+ assertEquals(expectedResult.size(), result.size());
+
+ int index = 0;
+ int key;
+
+ // Compare the two primitive int arrays
+ do {
+ try {
+ key = result.keyAt(index);
+ } catch (java.lang.ArrayIndexOutOfBoundsException e) {
+ break;
+ }
+ int[] expected = expectedResult.get(key);
+ int[] output = result.get(key);
+ assertEquals(expected.length, output.length);
+ for (int i = 0; i < output.length; i++) {
+ assertEquals(expected[i], output[i]);
+ }
+ index++;
+ } while (true);
+ }
+
+ /*
+ * Test that DPP channel list parser gracefully fails for invalid input
+ */
+ @Test
+ public void testparseDppChannelListWithInvalidFormats() throws Exception {
+ String channelList = "1,2,3,4,5,6,7,8,9,10,11,36,40,44,48";
+ SparseArray<int[]> result = WifiManager.parseDppChannelList(channelList);
+ assertEquals(result.size(), 0);
+
+ channelList = "ajgalskgjalskjg3-09683dh";
+ result = WifiManager.parseDppChannelList(channelList);
+ assertEquals(result.size(), 0);
+
+ channelList = "13/abc,46////";
+ result = WifiManager.parseDppChannelList(channelList);
+ assertEquals(result.size(), 0);
+
+ channelList = "11/4,5,13/";
+ result = WifiManager.parseDppChannelList(channelList);
+ assertEquals(result.size(), 0);
+
+ channelList = "/24,6";
+ result = WifiManager.parseDppChannelList(channelList);
+ assertEquals(result.size(), 0);
+ }
}