Merge "TIF: specify the type for COLUMN_INTERACTION_COUNT"
diff --git a/api/current.txt b/api/current.txt
index 80b6b44..f52eb11 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -30,7 +30,6 @@
field public static final java.lang.String BIND_INPUT_METHOD = "android.permission.BIND_INPUT_METHOD";
field public static final java.lang.String BIND_MIDI_DEVICE_SERVICE = "android.permission.BIND_MIDI_DEVICE_SERVICE";
field public static final java.lang.String BIND_NFC_SERVICE = "android.permission.BIND_NFC_SERVICE";
- field public static final java.lang.String BIND_NOTIFICATION_ASSISTANT_SERVICE = "android.permission.BIND_NOTIFICATION_ASSISTANT_SERVICE";
field public static final java.lang.String BIND_NOTIFICATION_LISTENER_SERVICE = "android.permission.BIND_NOTIFICATION_LISTENER_SERVICE";
field public static final java.lang.String BIND_PRINT_SERVICE = "android.permission.BIND_PRINT_SERVICE";
field public static final java.lang.String BIND_QUICK_SETTINGS_TILE = "android.permission.BIND_QUICK_SETTINGS_TILE";
@@ -298,6 +297,7 @@
field public static final int authorities = 16842776; // 0x1010018
field public static final int autoAdvanceViewId = 16843535; // 0x101030f
field public static final int autoCompleteTextViewStyle = 16842859; // 0x101006b
+ field public static final int autoFillMode = 16844116; // 0x1010554
field public static final int autoLink = 16842928; // 0x10100b0
field public static final int autoMirrored = 16843754; // 0x10103ea
field public static final int autoRemoveFromRecents = 16843847; // 0x1010447
@@ -13165,6 +13165,7 @@
field public static final deprecated int LA_88 = 10; // 0xa
field public static final deprecated int L_8 = 9; // 0x9
field public static final int OPAQUE = -1; // 0xffffffff
+ field public static final int RGBA_1010102 = 43; // 0x2b
field public static final deprecated int RGBA_4444 = 7; // 0x7
field public static final deprecated int RGBA_5551 = 6; // 0x6
field public static final int RGBA_8888 = 1; // 0x1
@@ -14395,6 +14396,7 @@
method public void writeToParcel(android.os.Parcel, int);
field public static final int BLOB = 33; // 0x21
field public static final android.os.Parcelable.Creator<android.hardware.HardwareBuffer> CREATOR;
+ field public static final int RGBA_1010102 = 43; // 0x2b
field public static final int RGBA_8888 = 1; // 0x1
field public static final int RGBA_FP16 = 22; // 0x16
field public static final int RGBX_8888 = 2; // 0x2
@@ -22479,6 +22481,7 @@
ctor public MediaRecorder();
method public static final int getAudioSourceMax();
method public int getMaxAmplitude() throws java.lang.IllegalStateException;
+ method public android.os.Bundle getMetrics();
method public android.view.Surface getSurface();
method public void pause() throws java.lang.IllegalStateException;
method public void prepare() throws java.io.IOException, java.lang.IllegalStateException;
@@ -24029,12 +24032,12 @@
field public static final java.lang.String COLUMN_DISPLAY_NAME = "display_name";
field public static final java.lang.String COLUMN_DISPLAY_NUMBER = "display_number";
field public static final java.lang.String COLUMN_INPUT_ID = "input_id";
- field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_ID = "internal_provider_id";
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1";
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2";
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3";
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
+ field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_ID = "internal_provider_id";
field public static final java.lang.String COLUMN_NETWORK_AFFILIATION = "network_affiliation";
field public static final java.lang.String COLUMN_ORIGINAL_NETWORK_ID = "original_network_id";
field public static final java.lang.String COLUMN_SEARCHABLE = "searchable";
@@ -36478,22 +36481,6 @@
package android.service.notification {
- public final class Adjustment implements android.os.Parcelable {
- ctor public Adjustment(java.lang.String, java.lang.String, android.os.Bundle, java.lang.CharSequence, int);
- ctor protected Adjustment(android.os.Parcel);
- method public int describeContents();
- method public java.lang.CharSequence getExplanation();
- method public java.lang.String getKey();
- method public java.lang.String getPackage();
- method public android.os.Bundle getSignals();
- method public int getUser();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.service.notification.Adjustment> CREATOR;
- field public static final java.lang.String KEY_CHANNEL_ID = "key_channel_id";
- field public static final java.lang.String KEY_PEOPLE = "key_people";
- field public static final java.lang.String KEY_SNOOZE_CRITERIA = "key_snooze_criteria";
- }
-
public final class Condition implements android.os.Parcelable {
ctor public Condition(android.net.Uri, java.lang.String, int);
ctor public Condition(android.net.Uri, java.lang.String, java.lang.String, java.lang.String, int, int, int);
@@ -36540,21 +36527,6 @@
field public static final java.lang.String SERVICE_INTERFACE = "android.service.notification.ConditionProviderService";
}
- public abstract class NotificationAssistantService extends android.service.notification.NotificationListenerService {
- ctor public NotificationAssistantService();
- method public final void adjustNotification(android.service.notification.Adjustment);
- method public final void adjustNotifications(java.util.List<android.service.notification.Adjustment>);
- method public void createNotificationChannel(java.lang.String, android.app.NotificationChannel);
- method public void deleteNotificationChannel(java.lang.String, java.lang.String);
- method public java.util.List<android.app.NotificationChannel> getNotificationChannels(java.lang.String);
- method public final android.os.IBinder onBind(android.content.Intent);
- method public abstract android.service.notification.Adjustment onNotificationEnqueued(android.service.notification.StatusBarNotification);
- method public abstract void onNotificationSnoozedUntilContext(android.service.notification.StatusBarNotification, java.lang.String);
- method public final void unsnoozeNotification(java.lang.String);
- method public void updateNotificationChannel(java.lang.String, android.app.NotificationChannel);
- field public static final java.lang.String SERVICE_INTERFACE = "android.service.notification.NotificationAssistantService";
- }
-
public abstract class NotificationListenerService extends android.app.Service {
ctor public NotificationListenerService();
method public final void cancelAllNotifications();
@@ -36583,7 +36555,6 @@
method public static void requestRebind(android.content.ComponentName);
method public final void requestUnbind();
method public final void setNotificationsShown(java.lang.String[]);
- method public final void snoozeNotification(java.lang.String, java.lang.String);
method public final void snoozeNotification(java.lang.String, long);
field public static final int HINT_HOST_DISABLE_CALL_EFFECTS = 4; // 0x4
field public static final int HINT_HOST_DISABLE_EFFECTS = 1; // 0x1
@@ -36620,14 +36591,12 @@
public static class NotificationListenerService.Ranking {
ctor public NotificationListenerService.Ranking();
method public boolean canShowBadge();
- method public java.util.List<java.lang.String> getAdditionalPeople();
method public android.app.NotificationChannel getChannel();
method public int getImportance();
method public java.lang.CharSequence getImportanceExplanation();
method public java.lang.String getKey();
method public java.lang.String getOverrideGroupKey();
method public int getRank();
- method public java.util.List<android.service.notification.SnoozeCriterion> getSnoozeCriteria();
method public int getSuppressedVisualEffects();
method public boolean isAmbient();
method public boolean matchesInterruptionFilter();
@@ -36641,17 +36610,6 @@
field public static final android.os.Parcelable.Creator<android.service.notification.NotificationListenerService.RankingMap> CREATOR;
}
- public final class SnoozeCriterion implements android.os.Parcelable {
- ctor public SnoozeCriterion(java.lang.String, java.lang.CharSequence, java.lang.CharSequence);
- ctor protected SnoozeCriterion(android.os.Parcel);
- method public int describeContents();
- method public java.lang.CharSequence getConfirmation();
- method public java.lang.CharSequence getExplanation();
- method public java.lang.String getId();
- method public void writeToParcel(android.os.Parcel, int);
- field public static final android.os.Parcelable.Creator<android.service.notification.SnoozeCriterion> CREATOR;
- }
-
public class StatusBarNotification implements android.os.Parcelable {
ctor public deprecated StatusBarNotification(java.lang.String, java.lang.String, int, java.lang.String, int, int, int, android.app.Notification, android.os.UserHandle, long);
ctor public StatusBarNotification(android.os.Parcel);
@@ -44552,6 +44510,7 @@
method public float getAlpha();
method public android.view.animation.Animation getAnimation();
method public android.os.IBinder getApplicationWindowToken();
+ method public int getAutoFillMode();
method public android.view.autofill.AutoFillType getAutoFillType();
method public android.view.autofill.AutoFillValue getAutoFillValue();
method public android.graphics.drawable.Drawable getBackground();
@@ -44868,6 +44827,7 @@
method public void setActivated(boolean);
method public void setAlpha(float);
method public void setAnimation(android.view.animation.Animation);
+ method public void setAutoFillMode(int);
method public void setBackground(android.graphics.drawable.Drawable);
method public void setBackgroundColor(int);
method public deprecated void setBackgroundDrawable(android.graphics.drawable.Drawable);
@@ -45008,6 +44968,9 @@
field public static final int ACCESSIBILITY_LIVE_REGION_NONE = 0; // 0x0
field public static final int ACCESSIBILITY_LIVE_REGION_POLITE = 1; // 0x1
field public static final android.util.Property<android.view.View, java.lang.Float> ALPHA;
+ field public static final int AUTO_FILL_MODE_AUTO = 1; // 0x1
+ field public static final int AUTO_FILL_MODE_INHERIT = 0; // 0x0
+ field public static final int AUTO_FILL_MODE_MANUAL = 2; // 0x2
field public static final int DRAG_FLAG_GLOBAL = 256; // 0x100
field public static final int DRAG_FLAG_GLOBAL_PERSISTABLE_URI_PERMISSION = 64; // 0x40
field public static final int DRAG_FLAG_GLOBAL_PREFIX_URI_PERMISSION = 128; // 0x80
diff --git a/api/system-current.txt b/api/system-current.txt
index e114c2b..d674c9a 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -410,6 +410,7 @@
field public static final int authorities = 16842776; // 0x1010018
field public static final int autoAdvanceViewId = 16843535; // 0x101030f
field public static final int autoCompleteTextViewStyle = 16842859; // 0x101006b
+ field public static final int autoFillMode = 16844116; // 0x1010554
field public static final int autoLink = 16842928; // 0x10100b0
field public static final int autoMirrored = 16843754; // 0x10103ea
field public static final int autoRemoveFromRecents = 16843847; // 0x1010447
@@ -8991,6 +8992,7 @@
method public abstract android.content.pm.PackageManager getPackageManager();
method public abstract java.lang.String getPackageName();
method public abstract java.lang.String getPackageResourcePath();
+ method public abstract java.io.File getPreloadsFileCache();
method public abstract android.content.res.Resources getResources();
method public abstract android.content.SharedPreferences getSharedPreferences(java.lang.String, int);
method public final java.lang.String getString(int);
@@ -9202,6 +9204,7 @@
method public android.content.pm.PackageManager getPackageManager();
method public java.lang.String getPackageName();
method public java.lang.String getPackageResourcePath();
+ method public java.io.File getPreloadsFileCache();
method public android.content.res.Resources getResources();
method public android.content.SharedPreferences getSharedPreferences(java.lang.String, int);
method public java.lang.Object getSystemService(java.lang.String);
@@ -13758,6 +13761,7 @@
field public static final deprecated int LA_88 = 10; // 0xa
field public static final deprecated int L_8 = 9; // 0x9
field public static final int OPAQUE = -1; // 0xffffffff
+ field public static final int RGBA_1010102 = 43; // 0x2b
field public static final deprecated int RGBA_4444 = 7; // 0x7
field public static final deprecated int RGBA_5551 = 6; // 0x6
field public static final int RGBA_8888 = 1; // 0x1
@@ -14988,6 +14992,7 @@
method public void writeToParcel(android.os.Parcel, int);
field public static final int BLOB = 33; // 0x21
field public static final android.os.Parcelable.Creator<android.hardware.HardwareBuffer> CREATOR;
+ field public static final int RGBA_1010102 = 43; // 0x2b
field public static final int RGBA_8888 = 1; // 0x1
field public static final int RGBA_FP16 = 22; // 0x16
field public static final int RGBX_8888 = 2; // 0x2
@@ -24124,6 +24129,7 @@
ctor public MediaRecorder();
method public static final int getAudioSourceMax();
method public int getMaxAmplitude() throws java.lang.IllegalStateException;
+ method public android.os.Bundle getMetrics();
method public android.view.Surface getSurface();
method public void pause() throws java.lang.IllegalStateException;
method public void prepare() throws java.io.IOException, java.lang.IllegalStateException;
@@ -25817,12 +25823,12 @@
field public static final java.lang.String COLUMN_DISPLAY_NAME = "display_name";
field public static final java.lang.String COLUMN_DISPLAY_NUMBER = "display_number";
field public static final java.lang.String COLUMN_INPUT_ID = "input_id";
- field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_ID = "internal_provider_id";
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1";
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2";
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3";
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
+ field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_ID = "internal_provider_id";
field public static final java.lang.String COLUMN_LOCKED = "locked";
field public static final java.lang.String COLUMN_NETWORK_AFFILIATION = "network_affiliation";
field public static final java.lang.String COLUMN_ORIGINAL_NETWORK_ID = "original_network_id";
@@ -43388,6 +43394,7 @@
method public android.content.pm.PackageManager getPackageManager();
method public java.lang.String getPackageName();
method public java.lang.String getPackageResourcePath();
+ method public java.io.File getPreloadsFileCache();
method public android.content.res.Resources getResources();
method public android.content.SharedPreferences getSharedPreferences(java.lang.String, int);
method public java.lang.Object getSystemService(java.lang.String);
@@ -47992,6 +47999,7 @@
method public float getAlpha();
method public android.view.animation.Animation getAnimation();
method public android.os.IBinder getApplicationWindowToken();
+ method public int getAutoFillMode();
method public android.view.autofill.AutoFillType getAutoFillType();
method public android.view.autofill.AutoFillValue getAutoFillValue();
method public android.graphics.drawable.Drawable getBackground();
@@ -48308,6 +48316,7 @@
method public void setActivated(boolean);
method public void setAlpha(float);
method public void setAnimation(android.view.animation.Animation);
+ method public void setAutoFillMode(int);
method public void setBackground(android.graphics.drawable.Drawable);
method public void setBackgroundColor(int);
method public deprecated void setBackgroundDrawable(android.graphics.drawable.Drawable);
@@ -48448,6 +48457,9 @@
field public static final int ACCESSIBILITY_LIVE_REGION_NONE = 0; // 0x0
field public static final int ACCESSIBILITY_LIVE_REGION_POLITE = 1; // 0x1
field public static final android.util.Property<android.view.View, java.lang.Float> ALPHA;
+ field public static final int AUTO_FILL_MODE_AUTO = 1; // 0x1
+ field public static final int AUTO_FILL_MODE_INHERIT = 0; // 0x0
+ field public static final int AUTO_FILL_MODE_MANUAL = 2; // 0x2
field public static final int DRAG_FLAG_GLOBAL = 256; // 0x100
field public static final int DRAG_FLAG_GLOBAL_PERSISTABLE_URI_PERMISSION = 64; // 0x40
field public static final int DRAG_FLAG_GLOBAL_PREFIX_URI_PERMISSION = 128; // 0x80
diff --git a/api/test-current.txt b/api/test-current.txt
index 0b39656..22a3c0f 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -30,7 +30,6 @@
field public static final java.lang.String BIND_INPUT_METHOD = "android.permission.BIND_INPUT_METHOD";
field public static final java.lang.String BIND_MIDI_DEVICE_SERVICE = "android.permission.BIND_MIDI_DEVICE_SERVICE";
field public static final java.lang.String BIND_NFC_SERVICE = "android.permission.BIND_NFC_SERVICE";
- field public static final java.lang.String BIND_NOTIFICATION_ASSISTANT_SERVICE = "android.permission.BIND_NOTIFICATION_ASSISTANT_SERVICE";
field public static final java.lang.String BIND_NOTIFICATION_LISTENER_SERVICE = "android.permission.BIND_NOTIFICATION_LISTENER_SERVICE";
field public static final java.lang.String BIND_PRINT_SERVICE = "android.permission.BIND_PRINT_SERVICE";
field public static final java.lang.String BIND_QUICK_SETTINGS_TILE = "android.permission.BIND_QUICK_SETTINGS_TILE";
@@ -298,6 +297,7 @@
field public static final int authorities = 16842776; // 0x1010018
field public static final int autoAdvanceViewId = 16843535; // 0x101030f
field public static final int autoCompleteTextViewStyle = 16842859; // 0x101006b
+ field public static final int autoFillMode = 16844116; // 0x1010554
field public static final int autoLink = 16842928; // 0x10100b0
field public static final int autoMirrored = 16843754; // 0x10103ea
field public static final int autoRemoveFromRecents = 16843847; // 0x1010447
@@ -13202,6 +13202,7 @@
field public static final deprecated int LA_88 = 10; // 0xa
field public static final deprecated int L_8 = 9; // 0x9
field public static final int OPAQUE = -1; // 0xffffffff
+ field public static final int RGBA_1010102 = 43; // 0x2b
field public static final deprecated int RGBA_4444 = 7; // 0x7
field public static final deprecated int RGBA_5551 = 6; // 0x6
field public static final int RGBA_8888 = 1; // 0x1
@@ -14433,6 +14434,7 @@
method public void writeToParcel(android.os.Parcel, int);
field public static final int BLOB = 33; // 0x21
field public static final android.os.Parcelable.Creator<android.hardware.HardwareBuffer> CREATOR;
+ field public static final int RGBA_1010102 = 43; // 0x2b
field public static final int RGBA_8888 = 1; // 0x1
field public static final int RGBA_FP16 = 22; // 0x16
field public static final int RGBX_8888 = 2; // 0x2
@@ -22575,6 +22577,7 @@
ctor public MediaRecorder();
method public static final int getAudioSourceMax();
method public int getMaxAmplitude() throws java.lang.IllegalStateException;
+ method public android.os.Bundle getMetrics();
method public android.view.Surface getSurface();
method public void pause() throws java.lang.IllegalStateException;
method public void prepare() throws java.io.IOException, java.lang.IllegalStateException;
@@ -24125,12 +24128,12 @@
field public static final java.lang.String COLUMN_DISPLAY_NAME = "display_name";
field public static final java.lang.String COLUMN_DISPLAY_NUMBER = "display_number";
field public static final java.lang.String COLUMN_INPUT_ID = "input_id";
- field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_ID = "internal_provider_id";
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1";
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2";
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3";
field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
+ field public static final java.lang.String COLUMN_INTERNAL_PROVIDER_ID = "internal_provider_id";
field public static final java.lang.String COLUMN_NETWORK_AFFILIATION = "network_affiliation";
field public static final java.lang.String COLUMN_ORIGINAL_NETWORK_ID = "original_network_id";
field public static final java.lang.String COLUMN_SEARCHABLE = "searchable";
@@ -44862,6 +44865,7 @@
method public float getAlpha();
method public android.view.animation.Animation getAnimation();
method public android.os.IBinder getApplicationWindowToken();
+ method public int getAutoFillMode();
method public android.view.autofill.AutoFillType getAutoFillType();
method public android.view.autofill.AutoFillValue getAutoFillValue();
method public android.graphics.drawable.Drawable getBackground();
@@ -45165,6 +45169,8 @@
method public static int resolveSize(int, int);
method public static int resolveSizeAndState(int, int, int);
method public boolean restoreDefaultFocus();
+ method public boolean restoreFocusInCluster(int);
+ method public boolean restoreFocusNotInCluster();
method public void restoreHierarchyState(android.util.SparseArray<android.os.Parcelable>);
method public void saveHierarchyState(android.util.SparseArray<android.os.Parcelable>);
method public void scheduleDrawable(android.graphics.drawable.Drawable, java.lang.Runnable, long);
@@ -45179,6 +45185,7 @@
method public void setActivated(boolean);
method public void setAlpha(float);
method public void setAnimation(android.view.animation.Animation);
+ method public void setAutoFillMode(int);
method public void setBackground(android.graphics.drawable.Drawable);
method public void setBackgroundColor(int);
method public deprecated void setBackgroundDrawable(android.graphics.drawable.Drawable);
@@ -45319,6 +45326,9 @@
field public static final int ACCESSIBILITY_LIVE_REGION_NONE = 0; // 0x0
field public static final int ACCESSIBILITY_LIVE_REGION_POLITE = 1; // 0x1
field public static final android.util.Property<android.view.View, java.lang.Float> ALPHA;
+ field public static final int AUTO_FILL_MODE_AUTO = 1; // 0x1
+ field public static final int AUTO_FILL_MODE_INHERIT = 0; // 0x0
+ field public static final int AUTO_FILL_MODE_MANUAL = 2; // 0x2
field public static final int DRAG_FLAG_GLOBAL = 256; // 0x100
field public static final int DRAG_FLAG_GLOBAL_PERSISTABLE_URI_PERMISSION = 64; // 0x40
field public static final int DRAG_FLAG_GLOBAL_PREFIX_URI_PERMISSION = 128; // 0x80
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index b336472..7965fc3 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -554,8 +554,12 @@
sessionParams.abiOverride = checkAbiArgument(nextOptionData());
break;
case "--ephemeral":
+ case "--instant":
sessionParams.setInstallAsInstantApp(true /*isInstantApp*/);
break;
+ case "--full":
+ sessionParams.setInstallAsInstantApp(false /*isInstantApp*/);
+ break;
case "--user":
params.userId = UserHandle.parseUserArg(nextOptionData());
break;
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 333e412..1652299 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -1687,7 +1687,7 @@
public int installExistingPackageAsUser(String packageName, int userId)
throws NameNotFoundException {
try {
- int res = mPM.installExistingPackageAsUser(packageName, userId,
+ int res = mPM.installExistingPackageAsUser(packageName, userId, 0 /*installFlags*/,
PackageManager.INSTALL_REASON_UNKNOWN);
if (res == INSTALL_FAILED_INVALID_URI) {
throw new NameNotFoundException("Package " + packageName + " doesn't exist");
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index e154d2b..045bd0a 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -638,6 +638,15 @@
}
}
+ /**
+ * @hide
+ */
+ @Nullable
+ @Override
+ public File getPreloadsFileCache() {
+ return Environment.getDataPreloadsFileCacheDirectory(getPackageName());
+ }
+
@Override
public File getFileStreamPath(String name) {
return makeFilename(getFilesDir(), name);
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index d32cf3c..739015f 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -1911,7 +1911,12 @@
mTmpRecords = new ArrayList<>();
mTmpIsPop = new ArrayList<>();
}
- executePostponedTransaction(null, null);
+ mExecutingActions = true;
+ try {
+ executePostponedTransaction(null, null);
+ } finally {
+ mExecutingActions = false;
+ }
}
public void execSingleAction(OpGenerator action, boolean allowStateLoss) {
diff --git a/core/java/android/app/ITaskStackListener.aidl b/core/java/android/app/ITaskStackListener.aidl
index 5e420c0..9834350 100644
--- a/core/java/android/app/ITaskStackListener.aidl
+++ b/core/java/android/app/ITaskStackListener.aidl
@@ -32,9 +32,10 @@
* running in the pinned stack and the activity is not actually started, but the task is either
* brought to the front or a new Intent is delivered to it.
*
- * @param sourceComponent the component name of the activity that initiated the restart attempt
+ * @param launchedFromPackage the package name of the activity that initiated the restart
+ * attempt
*/
- void onPinnedActivityRestartAttempt(in ComponentName sourceComponent);
+ void onPinnedActivityRestartAttempt(String launchedFromPackage);
/**
* Called whenever the pinned stack is done animating a resize.
diff --git a/core/java/android/app/TaskStackListener.java b/core/java/android/app/TaskStackListener.java
index 35c67d3..5a0845f 100644
--- a/core/java/android/app/TaskStackListener.java
+++ b/core/java/android/app/TaskStackListener.java
@@ -35,7 +35,7 @@
}
@Override
- public void onPinnedActivityRestartAttempt(ComponentName sourceComponent) throws RemoteException {
+ public void onPinnedActivityRestartAttempt(String launchedFromPackage) throws RemoteException {
}
@Override
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 2ace0a2..9cb3dd6 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -6343,7 +6343,6 @@
* The settings that can be updated by a profile or device owner with this method are:
* <ul>
* <li>{@link Settings.Secure#DEFAULT_INPUT_METHOD}</li>
- * <li>{@link Settings.Secure#INSTALL_NON_MARKET_APPS}</li>
* <li>{@link Settings.Secure#SKIP_FIRST_USE_HINTS}</li>
* </ul>
* <p>
@@ -6352,6 +6351,15 @@
* <li>{@link Settings.Secure#LOCATION_MODE}</li>
* </ul>
*
+ * <strong>Note: Starting from Android O, apps should no longer call this method with the
+ * setting {@link android.provider.Settings.Secure#INSTALL_NON_MARKET_APPS}, which is
+ * deprecated. Instead, device owners or profile owners should use the restriction
+ * {@link UserManager#DISALLOW_INSTALL_UNKNOWN_SOURCES}.
+ * If any app targeting {@link android.os.Build.VERSION_CODES#O} or higher calls this method
+ * with {@link android.provider.Settings.Secure#INSTALL_NON_MARKET_APPS},
+ * an {@link UnsupportedOperationException} is thrown.
+ * </strong>
+ *
* @param admin Which {@link DeviceAdminReceiver} this request is associated with.
* @param setting The name of the setting to update.
* @param value The value to update the setting to.
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 44e6ac5..44f6c43 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -1230,6 +1230,16 @@
public abstract File getExternalCacheDir();
/**
+ * Returns absolute path to application-specific directory in the preloaded cache.
+ * <p>Files stored in the cache directory can be deleted when the device runs low on storage.
+ * There is no guarantee when these files will be deleted.
+ * @hide
+ */
+ @Nullable
+ @SystemApi
+ public abstract File getPreloadsFileCache();
+
+ /**
* Returns absolute paths to application-specific directories on all
* shared/external storage devices where the application can place cache
* files it owns. These files are internal to the application, and not
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index 38cdbb4..c932b23 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -281,6 +281,13 @@
return mBase.getDir(name, mode);
}
+
+ /** @hide **/
+ @Override
+ public File getPreloadsFileCache() {
+ return mBase.getPreloadsFileCache();
+ }
+
@Override
public SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory) {
return mBase.openOrCreateDatabase(name, mode, factory);
diff --git a/core/java/android/content/IntentFilter.java b/core/java/android/content/IntentFilter.java
index e6cae69..56609eb 100644
--- a/core/java/android/content/IntentFilter.java
+++ b/core/java/android/content/IntentFilter.java
@@ -284,8 +284,6 @@
/** Whether or not the intent filter is visible to ephemeral apps. */
private boolean mVisibleToEphemeral;
- /** Whether or not the intent filter is part of an ephemeral app. */
- private boolean mEphemeral;
// These functions are the start of more optimized code for managing
// the string sets... not yet implemented.
@@ -656,19 +654,10 @@
mVisibleToEphemeral = visibleToEmphemeral;
}
/** @hide */
- public boolean isVisibleToEphemeral() {
+ public boolean isVisibleToInstantApp() {
return mVisibleToEphemeral;
}
- /** @hide */
- public void setEphemeral(boolean ephemeral) {
- mEphemeral = ephemeral;
- }
- /** @hide */
- public boolean isEphemeral() {
- return mEphemeral;
- }
-
/**
* Add a new Intent action to match against. If any actions are included
* in the filter, then an Intent's action must be one of those values for
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 1fa4181..9737b11 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -498,11 +498,12 @@
public static final int PRIVATE_FLAG_DIRECT_BOOT_AWARE = 1 << 6;
/**
- * Value for {@link #flags}: {@code true} if the application is blocked via restrictions
- * and for most purposes is considered as not installed.
- * {@hide}
+ * Value for {@link #privateFlags}: {@code true} if the application is installed
+ * as instant app.
+ *
+ * @hide
*/
- public static final int PRIVATE_FLAG_EPHEMERAL = 1 << 7;
+ public static final int PRIVATE_FLAG_INSTANT = 1 << 7;
/**
* When set, at least one component inside this application is direct boot
@@ -681,7 +682,21 @@
*
* {@hide}
*/
- public String seinfo = "default";
+ public String seInfo = "default";
+
+ /**
+ * The seinfo tag generated per-user. This value may change based upon the
+ * user's configuration. For example, when an instant app is installed for
+ * a user. It is an error if this field is ever {@code null} when trying to
+ * start a new process.
+ * <p>NOTE: We need to separate this out because we modify per-user values
+ * multiple times. This needs to be refactored since we're performing more
+ * work than necessary and these values should only be set once. When that
+ * happens, we can merge the per-user value with the seInfo state above.
+ *
+ * {@hide}
+ */
+ public String seInfoUser;
/**
* Paths to all shared libraries this application is linked against. This
@@ -1009,8 +1024,9 @@
if (resourceDirs != null) {
pw.println(prefix + "resourceDirs=" + Arrays.toString(resourceDirs));
}
- if ((flags&DUMP_FLAG_DETAILS) != 0 && seinfo != null) {
- pw.println(prefix + "seinfo=" + seinfo);
+ if ((flags&DUMP_FLAG_DETAILS) != 0 && seInfo != null) {
+ pw.println(prefix + "seinfo=" + seInfo);
+ pw.println(prefix + "seinfoUser=" + seInfoUser);
}
pw.println(prefix + "dataDir=" + dataDir);
if ((flags&DUMP_FLAG_DETAILS) != 0) {
@@ -1120,7 +1136,8 @@
primaryCpuAbi = orig.primaryCpuAbi;
secondaryCpuAbi = orig.secondaryCpuAbi;
resourceDirs = orig.resourceDirs;
- seinfo = orig.seinfo;
+ seInfo = orig.seInfo;
+ seInfoUser = orig.seInfoUser;
sharedLibraryFiles = orig.sharedLibraryFiles;
dataDir = orig.dataDir;
deviceEncryptedDataDir = deviceProtectedDataDir = orig.deviceProtectedDataDir;
@@ -1181,7 +1198,8 @@
dest.writeString(primaryCpuAbi);
dest.writeString(secondaryCpuAbi);
dest.writeStringArray(resourceDirs);
- dest.writeString(seinfo);
+ dest.writeString(seInfo);
+ dest.writeString(seInfoUser);
dest.writeStringArray(sharedLibraryFiles);
dest.writeString(dataDir);
dest.writeString(deviceProtectedDataDir);
@@ -1242,7 +1260,8 @@
primaryCpuAbi = source.readString();
secondaryCpuAbi = source.readString();
resourceDirs = source.readStringArray();
- seinfo = source.readString();
+ seInfo = source.readString();
+ seInfoUser = source.readString();
sharedLibraryFiles = source.readStringArray();
dataDir = source.readString();
deviceEncryptedDataDir = deviceProtectedDataDir = source.readString();
@@ -1330,7 +1349,6 @@
} else {
dataDir = credentialProtectedDataDir;
}
- // TODO: modify per-user ephemerality
}
/**
@@ -1415,7 +1433,7 @@
* @hide
*/
public boolean isInstantApp() {
- return (privateFlags & ApplicationInfo.PRIVATE_FLAG_EPHEMERAL) != 0;
+ return (privateFlags & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
}
/**
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 9d36a73..ffb777d 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -553,7 +553,8 @@
boolean setInstallLocation(int loc);
int getInstallLocation();
- int installExistingPackageAsUser(String packageName, int userId, int installReason);
+ int installExistingPackageAsUser(String packageName, int userId, int installFlags,
+ int installReason);
void verifyPendingInstall(int id, int verificationCode);
void extendVerificationTimeout(int id, int verificationCodeAtTimeout, long millisecondsToDelay);
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index 4de967c..278a6d0 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -1096,9 +1096,11 @@
@SystemApi
public void setInstallAsInstantApp(boolean isInstantApp) {
if (isInstantApp) {
- installFlags |= PackageManager.INSTALL_EPHEMERAL;
+ installFlags |= PackageManager.INSTALL_INSTANT_APP;
+ installFlags &= ~PackageManager.INSTALL_FULL_APP;
} else {
- installFlags &= ~PackageManager.INSTALL_EPHEMERAL;
+ installFlags &= ~PackageManager.INSTALL_INSTANT_APP;
+ installFlags |= PackageManager.INSTALL_FULL_APP;
}
}
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 308153d..5733982 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -452,17 +452,17 @@
/**
* Internal {@link PackageInfo} flag: include components that are part of an
- * ephemeral app. By default, ephemeral components are not matched.
+ * instant app. By default, instant app components are not matched.
* @hide
*/
- public static final int MATCH_EPHEMERAL = 0x00800000;
+ public static final int MATCH_INSTANT = 0x00800000;
/**
* Internal {@link PackageInfo} flag: include only components that are exposed to
* ephemeral apps.
* @hide
*/
- public static final int MATCH_VISIBLE_TO_EPHEMERAL_ONLY = 0x01000000;
+ public static final int MATCH_VISIBLE_TO_INSTANT_APP_ONLY = 0x01000000;
/**
* Internal flag used to indicate that a system component has done their
@@ -613,7 +613,7 @@
INSTALL_GRANT_RUNTIME_PERMISSIONS,
INSTALL_FORCE_VOLUME_UUID,
INSTALL_FORCE_PERMISSION_PROMPT,
- INSTALL_EPHEMERAL,
+ INSTALL_INSTANT_APP,
INSTALL_DONT_KILL_APP,
})
@Retention(RetentionPolicy.SOURCE)
@@ -714,7 +714,16 @@
*
* @hide
*/
- public static final int INSTALL_EPHEMERAL = 0x00000800;
+ public static final int INSTALL_INSTANT_APP = 0x00000800;
+
+ /**
+ * Flag parameter for {@link #installPackage} to indicate that this package is
+ * to be installed as a heavy weight app. This is fundamentally the opposite of
+ * {@link #INSTALL_INSTANT_APP}.
+ *
+ * @hide
+ */
+ public static final int INSTALL_FULL_APP = 0x00004000;
/**
* Flag parameter for {@link #installPackage} to indicate that this package contains
@@ -1185,12 +1194,12 @@
public static final int INSTALL_FAILED_ABORTED = -115;
/**
- * Installation failed return code: ephemeral app installs are incompatible with some
+ * Installation failed return code: instant app installs are incompatible with some
* other installation flags supplied for the operation; or other circumstances such
- * as trying to upgrade a system app via an ephemeral install.
+ * as trying to upgrade a system app via an instant app install.
* @hide
*/
- public static final int INSTALL_FAILED_EPHEMERAL_INVALID = -116;
+ public static final int INSTALL_FAILED_INSTANT_APP_INVALID = -116;
/** @hide */
@IntDef(flag = true, value = {
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 7a9aaaf..98e71a0 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -720,6 +720,8 @@
public final static int PARSE_COLLECT_CERTIFICATES = 1<<8;
public final static int PARSE_TRUSTED_OVERLAY = 1<<9;
public final static int PARSE_ENFORCE_CODE = 1<<10;
+ /** @deprecated remove when fixing b/34761192 */
+ @Deprecated
public final static int PARSE_IS_EPHEMERAL = 1<<11;
public final static int PARSE_FORCE_SDK = 1<<12;
@@ -2012,10 +2014,6 @@
pkg.applicationInfo.flags |= ApplicationInfo.FLAG_EXTERNAL_STORAGE;
}
- if ((flags & PARSE_IS_EPHEMERAL) != 0) {
- pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_EPHEMERAL;
- }
-
if (sa.getBoolean(com.android.internal.R.styleable.AndroidManifest_isolatedSplits, false)) {
pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_ISOLATED_SPLIT_LOADING;
}
@@ -4149,11 +4147,8 @@
ApplicationInfo.PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE;
}
- final boolean hasVisibleToEphemeral =
- sa.hasValue(R.styleable.AndroidManifestActivity_visibleToInstantApps);
- final boolean isEphemeral = ((flags & PARSE_IS_EPHEMERAL) != 0);
- final boolean visibleToEphemeral = isEphemeral
- || sa.getBoolean(R.styleable.AndroidManifestActivity_visibleToInstantApps, false);
+ final boolean visibleToEphemeral =
+ sa.getBoolean(R.styleable.AndroidManifestActivity_visibleToInstantApps, false);
if (visibleToEphemeral) {
a.info.flags |= ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL;
}
@@ -4188,8 +4183,6 @@
intent, outError)) {
return null;
}
- intent.setEphemeral(isEphemeral);
- intent.setVisibleToEphemeral(visibleToEphemeral || isWebBrowsableIntent(intent));
if (intent.countActions() == 0) {
Slog.w(TAG, "No actions in intent filter at "
+ mArchiveSourcePath + " "
@@ -4198,7 +4191,8 @@
a.intents.add(intent);
}
// adjust activity flags when we implicitly expose it via a browsable filter
- if (!hasVisibleToEphemeral && intent.isVisibleToEphemeral()) {
+ intent.setVisibleToEphemeral(visibleToEphemeral || isWebBrowsableIntent(intent));
+ if (intent.isVisibleToInstantApp()) {
a.info.flags |= ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL;
}
} else if (!receiver && parser.getName().equals("preferred")) {
@@ -4207,8 +4201,6 @@
intent, outError)) {
return null;
}
- intent.setEphemeral(isEphemeral);
- intent.setVisibleToEphemeral(visibleToEphemeral || isWebBrowsableIntent(intent));
if (intent.countActions() == 0) {
Slog.w(TAG, "No actions in preferred at "
+ mArchiveSourcePath + " "
@@ -4220,7 +4212,8 @@
owner.preferredActivityFilters.add(intent);
}
// adjust activity flags when we implicitly expose it via a browsable filter
- if (!hasVisibleToEphemeral && intent.isVisibleToEphemeral()) {
+ intent.setVisibleToEphemeral(visibleToEphemeral || isWebBrowsableIntent(intent));
+ if (intent.isVisibleToInstantApp()) {
a.info.flags |= ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL;
}
} else if (parser.getName().equals("meta-data")) {
@@ -4472,9 +4465,8 @@
}
// TODO add visibleToInstantApps attribute to activity alias
- final boolean isEphemeral = ((flags & PARSE_IS_EPHEMERAL) != 0);
- final boolean visibleToEphemeral = isEphemeral
- || ((a.info.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) != 0);
+ final boolean visibleToEphemeral =
+ ((a.info.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) != 0);
sa.recycle();
@@ -4502,13 +4494,12 @@
+ mArchiveSourcePath + " "
+ parser.getPositionDescription());
} else {
- intent.setEphemeral(isEphemeral);
- intent.setVisibleToEphemeral(visibleToEphemeral
- || isWebBrowsableIntent(intent));
+ intent.setVisibleToEphemeral(
+ visibleToEphemeral || isWebBrowsableIntent(intent));
a.intents.add(intent);
}
// adjust activity flags when we implicitly expose it via a browsable filter
- if (intent.isVisibleToEphemeral()) {
+ if (intent.isVisibleToInstantApp()) {
a.info.flags |= ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL;
}
} else if (parser.getName().equals("meta-data")) {
@@ -4649,11 +4640,8 @@
ApplicationInfo.PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE;
}
- final boolean hasVisibleToEphemeral =
- sa.hasValue(R.styleable.AndroidManifestProvider_visibleToInstantApps);
- final boolean isEphemeral = ((flags & PARSE_IS_EPHEMERAL) != 0);
- final boolean visibleToEphemeral = isEphemeral
- || sa.getBoolean(R.styleable.AndroidManifestProvider_visibleToInstantApps, false);
+ final boolean visibleToEphemeral =
+ sa.getBoolean(R.styleable.AndroidManifestProvider_visibleToInstantApps, false);
if (visibleToEphemeral) {
p.info.flags |= ProviderInfo.FLAG_VISIBLE_TO_EPHEMERAL;
}
@@ -4681,7 +4669,7 @@
p.info.authority = cpname.intern();
if (!parseProviderTags(
- res, parser, isEphemeral, hasVisibleToEphemeral, visibleToEphemeral, p, outError)) {
+ res, parser, visibleToEphemeral, p, outError)) {
return null;
}
@@ -4689,8 +4677,7 @@
}
private boolean parseProviderTags(Resources res, XmlResourceParser parser,
- boolean isEphemeral, boolean hasVisibleToEphemeral, boolean visibleToEphemeral,
- Provider outInfo, String[] outError)
+ boolean visibleToEphemeral, Provider outInfo, String[] outError)
throws XmlPullParserException, IOException {
int outerDepth = parser.getDepth();
int type;
@@ -4707,11 +4694,10 @@
intent, outError)) {
return false;
}
- intent.setEphemeral(isEphemeral);
- intent.setVisibleToEphemeral(visibleToEphemeral || isWebBrowsableIntent(intent));
outInfo.intents.add(intent);
// adjust provider flags when we implicitly expose it via a browsable filter
- if (!hasVisibleToEphemeral && intent.isVisibleToEphemeral()) {
+ intent.setVisibleToEphemeral(visibleToEphemeral || isWebBrowsableIntent(intent));
+ if (intent.isVisibleToInstantApp()) {
outInfo.info.flags |= ProviderInfo.FLAG_VISIBLE_TO_EPHEMERAL;
}
@@ -4963,11 +4949,8 @@
ApplicationInfo.PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE;
}
- final boolean hasVisibleToEphemeral =
- sa.hasValue(R.styleable.AndroidManifestService_visibleToInstantApps);
- final boolean isEphemeral = ((flags & PARSE_IS_EPHEMERAL) != 0);
- final boolean visibleToEphemeral = isEphemeral
- || sa.getBoolean(R.styleable.AndroidManifestService_visibleToInstantApps, false);
+ final boolean visibleToEphemeral =
+ sa.getBoolean(R.styleable.AndroidManifestService_visibleToInstantApps, false);
if (visibleToEphemeral) {
s.info.flags |= ServiceInfo.FLAG_VISIBLE_TO_EPHEMERAL;
}
@@ -4999,10 +4982,9 @@
intent, outError)) {
return null;
}
- intent.setEphemeral(isEphemeral);
- intent.setVisibleToEphemeral(visibleToEphemeral || isWebBrowsableIntent(intent));
// adjust activity flags when we implicitly expose it via a browsable filter
- if (!hasVisibleToEphemeral && intent.isVisibleToEphemeral()) {
+ intent.setVisibleToEphemeral(visibleToEphemeral || isWebBrowsableIntent(intent));
+ if (intent.isVisibleToInstantApp()) {
s.info.flags |= ServiceInfo.FLAG_VISIBLE_TO_EPHEMERAL;
}
s.intents.add(intent);
@@ -6482,6 +6464,9 @@
if (state.stopped) {
return true;
}
+ if (state.instantApp != p.applicationInfo.isInstantApp()) {
+ return true;
+ }
if ((flags & PackageManager.GET_META_DATA) != 0
&& (metaData != null || p.mAppMetaData != null)) {
return true;
@@ -6517,6 +6502,11 @@
} else {
ai.flags &= ~ApplicationInfo.FLAG_SUSPENDED;
}
+ if (state.instantApp) {
+ ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_INSTANT;
+ } else {
+ ai.privateFlags &= ~ApplicationInfo.PRIVATE_FLAG_INSTANT;
+ }
if (state.hidden) {
ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_HIDDEN;
} else {
@@ -6537,6 +6527,7 @@
if (ai.category == ApplicationInfo.CATEGORY_UNDEFINED) {
ai.category = FallbackCategoryProvider.getFallbackCategory(ai.packageName);
}
+ ai.seInfoUser = SELinuxUtil.assignSeinfoUser(state);
}
public static ApplicationInfo generateApplicationInfo(Package p, int flags,
diff --git a/core/java/android/content/pm/PackageUserState.java b/core/java/android/content/pm/PackageUserState.java
index e19aa99..24f1164 100644
--- a/core/java/android/content/pm/PackageUserState.java
+++ b/core/java/android/content/pm/PackageUserState.java
@@ -43,6 +43,7 @@
public boolean hidden; // Is the app restricted by owner / admin
public boolean suspended;
public boolean blockUninstall;
+ public boolean instantApp;
public int enabled;
public String lastDisableAppCaller;
public int domainVerificationStatus;
@@ -71,6 +72,7 @@
hidden = o.hidden;
suspended = o.suspended;
blockUninstall = o.blockUninstall;
+ instantApp = o.instantApp;
enabled = o.enabled;
lastDisableAppCaller = o.lastDisableAppCaller;
domainVerificationStatus = o.domainVerificationStatus;
@@ -188,6 +190,9 @@
if (blockUninstall != oldState.blockUninstall) {
return false;
}
+ if (instantApp != oldState.instantApp) {
+ return false;
+ }
if (enabled != oldState.enabled) {
return false;
}
diff --git a/core/java/android/content/pm/SELinuxUtil.java b/core/java/android/content/pm/SELinuxUtil.java
new file mode 100644
index 0000000..55b5e29
--- /dev/null
+++ b/core/java/android/content/pm/SELinuxUtil.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2017 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.content.pm;
+
+import com.android.internal.util.ArrayUtils;
+
+/**
+ * Utility methods that need to be used in application space.
+ * @hide
+ */
+public final class SELinuxUtil {
+
+ /** Append to existing seinfo label for instant apps @hide */
+ private static final String INSTANT_APP_STR = ":ephemeralapp";
+
+ /** Append to existing seinfo when modifications are complete @hide */
+ public static final String COMPLETE_STR = ":complete";
+
+ /** @hide */
+ public static String assignSeinfoUser(PackageUserState userState) {
+ String seInfo = "";
+ if (userState.instantApp)
+ seInfo += INSTANT_APP_STR;
+ seInfo += COMPLETE_STR;
+ return seInfo;
+ }
+
+}
diff --git a/core/java/android/hardware/HardwareBuffer.java b/core/java/android/hardware/HardwareBuffer.java
index e97bb2f..7b09e26 100644
--- a/core/java/android/hardware/HardwareBuffer.java
+++ b/core/java/android/hardware/HardwareBuffer.java
@@ -40,21 +40,24 @@
public final class HardwareBuffer implements Parcelable {
/** @hide */
@Retention(RetentionPolicy.SOURCE)
- @IntDef({RGBA_8888, RGBA_FP16, RGBX_8888, RGB_888, RGB_565, BLOB})
- public @interface Format {};
+ @IntDef({RGBA_8888, RGBA_FP16, RGBA_1010102, RGBX_8888, RGB_888, RGB_565, BLOB})
+ public @interface Format {
+ }
/** Format: 8 bits each red, green, blue, alpha */
- public static final int RGBA_8888 = 1;
+ public static final int RGBA_8888 = 1;
/** Format: 8 bits each red, green, blue, alpha, alpha is always 0xFF */
- public static final int RGBX_8888 = 2;
+ public static final int RGBX_8888 = 2;
/** Format: 8 bits each red, green, blue, no alpha */
- public static final int RGB_888 = 3;
+ public static final int RGB_888 = 3;
/** Format: 5 bits each red and blue, 6 bits green, no alpha */
- public static final int RGB_565 = 4;
+ public static final int RGB_565 = 4;
/** Format: 16 bits each red, green, blue, alpha */
- public static final int RGBA_FP16 = 0x16;
+ public static final int RGBA_FP16 = 0x16;
+ /** Format: 10 bits each red, green, blue, 2 bits alpha */
+ public static final int RGBA_1010102 = 0x2b;
/** Format: opaque format used for raw data transfer; must have a height of 1 */
- public static final int BLOB = 0x21;
+ public static final int BLOB = 0x21;
// Note: do not rename, this field is used by native code
private long mNativeObject;
@@ -107,7 +110,7 @@
* @param width The width in pixels of the buffer
* @param height The height in pixels of the buffer
* @param format The format of each pixel, one of {@link #RGBA_8888}, {@link #RGBA_FP16},
- * {@link #RGBX_8888}, {@link #RGB_565}, {@link #RGB_888}
+ * {@link #RGBX_8888}, {@link #RGB_565}, {@link #RGB_888}, {@link #RGBA_1010102}, {@link #BLOB}
* @param layers The number of layers in the buffer
* @param usage Flags describing how the buffer will be used, one of
* {@link #USAGE0_CPU_READ}, {@link #USAGE0_CPU_READ_OFTEN}, {@link #USAGE0_CPU_WRITE},
@@ -150,15 +153,15 @@
}
/**
- * Private use only. See {@link #create(int, int, int, int, int, long, long)}. May also be
+ * Private use only. See {@link #create(int, int, int, int, long)}. May also be
* called from JNI using an already allocated native <code>HardwareBuffer</code>.
*/
private HardwareBuffer(long nativeObject) {
mNativeObject = nativeObject;
- long nativeSize = NATIVE_HARDWARE_BUFFER_SIZE;
+ ClassLoader loader = HardwareBuffer.class.getClassLoader();
NativeAllocationRegistry registry = new NativeAllocationRegistry(
- HardwareBuffer.class.getClassLoader(), nGetNativeFinalizer(), nativeSize);
+ loader, nGetNativeFinalizer(), NATIVE_HARDWARE_BUFFER_SIZE);
mCleaner = registry.registerNativeAllocation(this, mNativeObject);
}
@@ -186,8 +189,9 @@
/**
* Returns the format of this buffer, one of {@link #RGBA_8888}, {@link #RGBA_FP16},
- * {@link #RGBX_8888}, {@link #RGB_565}, or {@link #RGB_888}.
+ * {@link #RGBX_8888}, {@link #RGB_565}, {@link #RGB_888}, {@link #RGBA_1010102}, {@link #BLOB}.
*/
+ @Format
public int getFormat() {
if (mNativeObject == 0) {
throw new IllegalStateException("This HardwareBuffer has been destroyed and its format "
@@ -291,12 +295,13 @@
* @param format The format to validate.
*
* @return True if <code>format</code> is a supported format. false otherwise.
- * See {@link #create(int, int, int, int, int, long, long)}.a
+ * See {@link #create(int, int, int, int, long)}.
*/
private static boolean isSupportedFormat(@Format int format) {
switch(format) {
case RGBA_8888:
case RGBA_FP16:
+ case RGBA_1010102:
case RGBX_8888:
case RGB_565:
case RGB_888:
diff --git a/core/java/android/os/Environment.java b/core/java/android/os/Environment.java
index 7cdb3ce..39f4d42 100644
--- a/core/java/android/os/Environment.java
+++ b/core/java/android/os/Environment.java
@@ -311,11 +311,6 @@
}
/** {@hide} */
- public static File getDataAppEphemeralDirectory(String volumeUuid) {
- return new File(getDataDirectory(volumeUuid), "app-ephemeral");
- }
-
- /** {@hide} */
public static File getDataUserCeDirectory(String volumeUuid) {
return new File(getDataDirectory(volumeUuid), "user");
}
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index aca41b8..7c8e264 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3882,6 +3882,7 @@
SCREEN_BRIGHTNESS,
SCREEN_BRIGHTNESS_MODE,
SCREEN_AUTO_BRIGHTNESS_ADJ,
+ SCREEN_BRIGHTNESS_FOR_VR,
VIBRATE_INPUT_DEVICES,
MODE_RINGER_STREAMS_AFFECTED,
TEXT_AUTO_REPLACE,
@@ -4128,20 +4129,20 @@
}
/**
- * System settings which can be accessed by ephemeral apps.
+ * System settings which can be accessed by instant apps.
* @hide
*/
- public static final Set<String> EPHEMERAL_SETTINGS = new ArraySet<>();
+ public static final Set<String> INSTANT_APP_SETTINGS = new ArraySet<>();
static {
- EPHEMERAL_SETTINGS.add(TEXT_AUTO_REPLACE);
- EPHEMERAL_SETTINGS.add(TEXT_AUTO_CAPS);
- EPHEMERAL_SETTINGS.add(TEXT_AUTO_PUNCTUATE);
- EPHEMERAL_SETTINGS.add(TEXT_SHOW_PASSWORD);
- EPHEMERAL_SETTINGS.add(DATE_FORMAT);
- EPHEMERAL_SETTINGS.add(FONT_SCALE);
- EPHEMERAL_SETTINGS.add(HAPTIC_FEEDBACK_ENABLED);
- EPHEMERAL_SETTINGS.add(TIME_12_24);
- EPHEMERAL_SETTINGS.add(SOUND_EFFECTS_ENABLED);
+ INSTANT_APP_SETTINGS.add(TEXT_AUTO_REPLACE);
+ INSTANT_APP_SETTINGS.add(TEXT_AUTO_CAPS);
+ INSTANT_APP_SETTINGS.add(TEXT_AUTO_PUNCTUATE);
+ INSTANT_APP_SETTINGS.add(TEXT_SHOW_PASSWORD);
+ INSTANT_APP_SETTINGS.add(DATE_FORMAT);
+ INSTANT_APP_SETTINGS.add(FONT_SCALE);
+ INSTANT_APP_SETTINGS.add(HAPTIC_FEEDBACK_ENABLED);
+ INSTANT_APP_SETTINGS.add(TIME_12_24);
+ INSTANT_APP_SETTINGS.add(SOUND_EFFECTS_ENABLED);
}
/**
@@ -5216,6 +5217,18 @@
public static final String INSTALL_NON_MARKET_APPS = "install_non_market_apps";
/**
+ * A flag to tell {@link com.android.server.devicepolicy.DevicePolicyManagerService} that
+ * the default for {@link #INSTALL_NON_MARKET_APPS} is reversed for this user on OTA. So it
+ * can set the restriction {@link android.os.UserManager#DISALLOW_INSTALL_UNKNOWN_SOURCES}
+ * on behalf of the profile owner if needed to make the change transparent for profile
+ * owners.
+ *
+ * @hide
+ */
+ public static final String UNKNOWN_SOURCES_DEFAULT_REVERSED =
+ "unknown_sources_default_reversed";
+
+ /**
* Comma-separated list of location providers that activities may access. Do not rely on
* this value being present in settings.db or on ContentObserver notifications on the
* corresponding Uri.
@@ -7004,17 +7017,17 @@
}
/**
- * Secure settings which can be accessed by ephemeral apps.
+ * Secure settings which can be accessed by instant apps.
* @hide
*/
- public static final Set<String> EPHEMERAL_SETTINGS = new ArraySet<>();
+ public static final Set<String> INSTANT_APP_SETTINGS = new ArraySet<>();
static {
- EPHEMERAL_SETTINGS.add(ENABLED_ACCESSIBILITY_SERVICES);
- EPHEMERAL_SETTINGS.add(ACCESSIBILITY_SPEAK_PASSWORD);
- EPHEMERAL_SETTINGS.add(ACCESSIBILITY_DISPLAY_INVERSION_ENABLED);
+ INSTANT_APP_SETTINGS.add(ENABLED_ACCESSIBILITY_SERVICES);
+ INSTANT_APP_SETTINGS.add(ACCESSIBILITY_SPEAK_PASSWORD);
+ INSTANT_APP_SETTINGS.add(ACCESSIBILITY_DISPLAY_INVERSION_ENABLED);
- EPHEMERAL_SETTINGS.add(DEFAULT_INPUT_METHOD);
- EPHEMERAL_SETTINGS.add(ENABLED_INPUT_METHODS);
+ INSTANT_APP_SETTINGS.add(DEFAULT_INPUT_METHOD);
+ INSTANT_APP_SETTINGS.add(ENABLED_INPUT_METHODS);
}
/**
@@ -10152,16 +10165,16 @@
public static final String CELL_ON = "cell_on";
/**
- * Global settings which can be accessed by ephemeral apps.
+ * Global settings which can be accessed by instant apps.
* @hide
*/
- public static final Set<String> EPHEMERAL_SETTINGS = new ArraySet<>();
+ public static final Set<String> INSTANT_APP_SETTINGS = new ArraySet<>();
static {
- EPHEMERAL_SETTINGS.add(WAIT_FOR_DEBUGGER);
- EPHEMERAL_SETTINGS.add(DEVICE_PROVISIONED);
- EPHEMERAL_SETTINGS.add(DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES);
- EPHEMERAL_SETTINGS.add(DEVELOPMENT_FORCE_RTL);
- EPHEMERAL_SETTINGS.add(EPHEMERAL_COOKIE_MAX_SIZE_BYTES);
+ INSTANT_APP_SETTINGS.add(WAIT_FOR_DEBUGGER);
+ INSTANT_APP_SETTINGS.add(DEVICE_PROVISIONED);
+ INSTANT_APP_SETTINGS.add(DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES);
+ INSTANT_APP_SETTINGS.add(DEVELOPMENT_FORCE_RTL);
+ INSTANT_APP_SETTINGS.add(EPHEMERAL_COOKIE_MAX_SIZE_BYTES);
}
/**
diff --git a/core/java/android/service/notification/Adjustment.java b/core/java/android/service/notification/Adjustment.java
index 9728fda..e39d53f 100644
--- a/core/java/android/service/notification/Adjustment.java
+++ b/core/java/android/service/notification/Adjustment.java
@@ -15,6 +15,8 @@
*/
package android.service.notification;
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.app.NotificationChannel;
import android.os.Bundle;
import android.os.Parcel;
@@ -22,7 +24,10 @@
/**
* Ranking updates from the Assistant.
+ * @hide
*/
+@SystemApi
+@TestApi
public final class Adjustment implements Parcelable {
private final String mPackage;
private final String mKey;
diff --git a/core/java/android/service/notification/NotificationAssistantService.java b/core/java/android/service/notification/NotificationAssistantService.java
index de86b2d..46609df 100644
--- a/core/java/android/service/notification/NotificationAssistantService.java
+++ b/core/java/android/service/notification/NotificationAssistantService.java
@@ -19,6 +19,8 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SdkConstant;
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.app.NotificationChannel;
import android.content.Context;
import android.content.Intent;
@@ -35,7 +37,10 @@
/**
* A service that helps the user manage notifications.
+ * @hide
*/
+@SystemApi
+@TestApi
public abstract class NotificationAssistantService extends NotificationListenerService {
private static final String TAG = "NotificationAssistants";
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index e5abdac..5f7ff67 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -16,6 +16,7 @@
package android.service.notification;
+import android.annotation.TestApi;
import android.app.NotificationChannel;
import android.os.Handler;
import android.os.Looper;
@@ -528,7 +529,10 @@
* @param key The key of the notification to snooze
* @param snoozeCriterionId The{@link SnoozeCriterion#getId()} of a context to snooze the
* notification until.
+ * @hide
*/
+ @SystemApi
+ @TestApi
public final void snoozeNotification(String key, String snoozeCriterionId) {
if (!isBound()) return;
try {
@@ -1257,7 +1261,10 @@
/**
* If the {@link NotificationAssistantService} has added people to this notification, then
* this will be non-null.
+ * @hide
*/
+ @SystemApi
+ @TestApi
public List<String> getAdditionalPeople() {
return mOverridePeople;
}
@@ -1266,7 +1273,10 @@
* Returns snooze criteria provided by the {@link NotificationAssistantService}. If your
* user interface displays options for snoozing notifications these criteria should be
* displayed as well.
+ * @hide
*/
+ @SystemApi
+ @TestApi
public List<SnoozeCriterion> getSnoozeCriteria() {
return mSnoozeCriteria;
}
diff --git a/core/java/android/service/notification/SnoozeCriterion.java b/core/java/android/service/notification/SnoozeCriterion.java
index f37f1ae..bd93eff 100644
--- a/core/java/android/service/notification/SnoozeCriterion.java
+++ b/core/java/android/service/notification/SnoozeCriterion.java
@@ -15,13 +15,18 @@
*/
package android.service.notification;
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
/**
* Represents an option to be shown to users for snoozing a notification until a given context
* instead of for a fixed amount of time.
+ * @hide
*/
+@SystemApi
+@TestApi
public final class SnoozeCriterion implements Parcelable {
private final String mId;
private final CharSequence mExplanation;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 97f46fa..df0a161 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -108,6 +108,7 @@
import android.widget.ScrollBarDrawable;
import com.android.internal.R;
+import com.android.internal.util.Preconditions;
import com.android.internal.view.TooltipPopup;
import com.android.internal.view.menu.MenuBuilder;
import com.android.internal.widget.ScrollBarUtils;
@@ -942,6 +943,37 @@
private static final int[] VISIBILITY_FLAGS = {VISIBLE, INVISIBLE, GONE};
+ /** @hide */
+ @IntDef({
+ AUTO_FILL_MODE_INHERIT,
+ AUTO_FILL_MODE_AUTO,
+ AUTO_FILL_MODE_MANUAL
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface AutoFillMode {}
+
+ /**
+ * This view inherits the autofill state from it's parent. If there is no parent it is
+ * {@link #AUTO_FILL_MODE_AUTO}.
+ * Use with {@link #setAutoFillMode(int)} and <a href="#attr_android:autoFillMode">
+ * {@code android:autoFillMode}.
+ */
+ public static final int AUTO_FILL_MODE_INHERIT = 0;
+
+ /**
+ * Allows this view to automatically trigger an auto-fill request when it get focus.
+ * Use with {@link #setAutoFillMode(int)} and <a href="#attr_android:autoFillMode">
+ * {@code android:autoFillMode}.
+ */
+ public static final int AUTO_FILL_MODE_AUTO = 1;
+
+ /**
+ * Require the user to manually force an auto-fill request.
+ * Use with {@link #setAutoFillMode(int)} and <a href="#attr_android:autoFillMode">{@code
+ * android:autoFillMode}.
+ */
+ public static final int AUTO_FILL_MODE_MANUAL = 2;
+
/**
* This view is enabled. Interpretation varies by subclass.
* Use with ENABLED_MASK when calling setFlags.
@@ -2512,7 +2544,8 @@
* x * NO LONGER NEEDED, SHOULD BE REUSED *
* 1 PFLAG3_FINGER_DOWN
* 1 PFLAG3_FOCUSED_BY_DEFAULT
- * xxxx * NO LONGER NEEDED, SHOULD BE REUSED *
+ * 11 PFLAG3_AUTO_FILL_MODE_MASK
+ * xx * NO LONGER NEEDED, SHOULD BE REUSED *
* 1 PFLAG3_OVERLAPPING_RENDERING_FORCED_VALUE
* 1 PFLAG3_HAS_OVERLAPPING_RENDERING_FORCED
* 1 PFLAG3_TEMPORARY_DETACH
@@ -2733,6 +2766,23 @@
private static final int PFLAG3_FOCUSED_BY_DEFAULT = 0x40000;
/**
+ * Shift for the place where the auto-fill mode is stored in the pflags
+ *
+ * @see #getAutoFillMode()
+ * @see #setAutoFillMode(int)
+ */
+ private static final int PFLAG3_AUTO_FILL_MODE_SHIFT = 19;
+
+ /**
+ * Mask for auto-fill modes
+ *
+ * @see #getAutoFillMode()
+ * @see #setAutoFillMode(int)
+ */
+ private static final int PFLAG3_AUTO_FILL_MODE_MASK = (AUTO_FILL_MODE_INHERIT
+ | AUTO_FILL_MODE_AUTO | AUTO_FILL_MODE_MANUAL) << PFLAG3_AUTO_FILL_MODE_SHIFT;
+
+ /**
* Whether this view has rendered elements that overlap (see {@link
* #hasOverlappingRendering()}, {@link #forceHasOverlappingRendering(boolean)}, and
* {@link #getHasOverlappingRendering()} ). The value in this bit is only valid when
@@ -4747,6 +4797,11 @@
setFocusedByDefault(a.getBoolean(attr, true));
}
break;
+ case com.android.internal.R.styleable.View_autoFillMode:
+ if (a.peekValue(attr) != null) {
+ setAutoFillMode(a.getInt(attr, AUTO_FILL_MODE_INHERIT));
+ }
+ break;
}
}
@@ -7405,16 +7460,19 @@
* This method only needs overloading if the node is marked as having extra data available.
* </p>
*
- * @param info The info to which to add the extra data
+ * @param info The info to which to add the extra data. Never {@code null}.
* @param extraDataKey A key specifying the type of extra data to add to the info. The
* extra data should be added to the {@link Bundle} returned by
- * the info's {@link AccessibilityNodeInfo#getExtras} method.
- * @param arguments A {@link Bundle} holding any arguments relevant for this request.
+ * the info's {@link AccessibilityNodeInfo#getExtras} method. Never
+ * {@code null}.
+ * @param arguments A {@link Bundle} holding any arguments relevant for this request. May be
+ * {@code null} if the service provided no arguments.
*
* @see AccessibilityNodeInfo#setExtraAvailableData
*/
public void addExtraDataToAccessibilityNodeInfo(
- AccessibilityNodeInfo info, String extraDataKey, Bundle arguments) {
+ @NonNull AccessibilityNodeInfo info, @NonNull String extraDataKey,
+ @Nullable Bundle arguments) {
}
/**
@@ -8614,6 +8672,21 @@
}
/**
+ * Set auto-fill mode for the view.
+ *
+ * @param autoFillMode One of {@link #AUTO_FILL_MODE_INHERIT}, {@link #AUTO_FILL_MODE_AUTO},
+ * or {@link #AUTO_FILL_MODE_MANUAL}.
+ * @attr ref android.R.styleable#View_autoFillMode
+ */
+ public void setAutoFillMode(@AutoFillMode int autoFillMode) {
+ Preconditions.checkArgumentInRange(autoFillMode, AUTO_FILL_MODE_INHERIT,
+ AUTO_FILL_MODE_MANUAL, "autoFillMode");
+
+ mPrivateFlags3 &= ~PFLAG3_AUTO_FILL_MODE_MASK;
+ mPrivateFlags3 |= autoFillMode << PFLAG3_AUTO_FILL_MODE_SHIFT;
+ }
+
+ /**
* Set whether this view should have sound effects enabled for events such as
* clicking and touching.
*
@@ -9217,6 +9290,23 @@
}
/**
+ * Returns the auto-fill mode for this view.
+ *
+ * @return One of {@link #AUTO_FILL_MODE_INHERIT}, {@link #AUTO_FILL_MODE_AUTO}, or
+ * {@link #AUTO_FILL_MODE_MANUAL}.
+ * @attr ref android.R.styleable#View_autoFillMode
+ */
+ @ViewDebug.ExportedProperty(mapping = {
+ @ViewDebug.IntToString(from = AUTO_FILL_MODE_INHERIT, to = "AUTO_FILL_MODE_INHERIT"),
+ @ViewDebug.IntToString(from = AUTO_FILL_MODE_AUTO, to = "AUTO_FILL_MODE_AUTO"),
+ @ViewDebug.IntToString(from = AUTO_FILL_MODE_MANUAL, to = "AUTO_FILL_MODE_MANUAL")
+ })
+ @AutoFillMode
+ public int getAutoFillMode() {
+ return (mPrivateFlags3 & PFLAG3_AUTO_FILL_MODE_MASK) >> PFLAG3_AUTO_FILL_MODE_SHIFT;
+ }
+
+ /**
* Find the nearest view in the specified direction that can take focus.
* This does not actually give focus to that view.
*
@@ -9491,7 +9581,10 @@
public void addKeyboardNavigationClusters(
@NonNull Collection<View> views,
int direction) {
- if (!(isKeyboardNavigationCluster())) {
+ if (!isKeyboardNavigationCluster()) {
+ return;
+ }
+ if (!hasFocusable()) {
return;
}
views.add(this);
@@ -9698,11 +9791,12 @@
}
/**
- * Public for testing. This will request focus for whichever View was last focused within this
+ * This will request focus for whichever View was last focused within this
* cluster before a focus-jump out of it.
*
* @hide
*/
+ @TestApi
public boolean restoreFocusInCluster(@FocusRealDirection int direction) {
// Prioritize focusableByDefault over algorithmic focus selection.
if (restoreDefaultFocus()) {
@@ -9712,6 +9806,18 @@
}
/**
+ * This will request focus for whichever View not in a cluster was last focused before a
+ * focus-jump to a cluster. If no non-cluster View has previously had focus, this will focus
+ * the "first" focusable view it finds.
+ *
+ * @hide
+ */
+ @TestApi
+ public boolean restoreFocusNotInCluster() {
+ return requestFocus(View.FOCUS_DOWN);
+ }
+
+ /**
* Gives focus to the default-focus view in the view hierarchy that has this view as a root.
* If the default-focus view cannot be found, falls back to calling {@link #requestFocus(int)}.
*
@@ -24544,17 +24650,20 @@
* the case where no accessibility delegate is set.
* </p>
*
- * @param host The View hosting the delegate.
- * @param info The info to which to add the extra data
+ * @param host The View hosting the delegate. Never {@code null}.
+ * @param info The info to which to add the extra data. Never {@code null}.
* @param extraDataKey A key specifying the type of extra data to add to the info. The
* extra data should be added to the {@link Bundle} returned by
- * the info's {@link AccessibilityNodeInfo#getExtras} method.
+ * the info's {@link AccessibilityNodeInfo#getExtras} method. Never
+ * {@code null}.
* @param arguments A {@link Bundle} holding any arguments relevant for this request.
+ * May be {@code null} if the if the service provided no arguments.
*
* @see AccessibilityNodeInfo#setExtraAvailableData
*/
- public void addExtraDataToAccessibilityNodeInfo(
- View host, AccessibilityNodeInfo info, String extraDataKey, Bundle arguments) {
+ public void addExtraDataToAccessibilityNodeInfo(@NonNull View host,
+ @NonNull AccessibilityNodeInfo info, @NonNull String extraDataKey,
+ @Nullable Bundle arguments) {
host.addExtraDataToAccessibilityNodeInfo(info, extraDataKey, arguments);
}
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 6c926c5..7aa2168 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -22,6 +22,7 @@
import android.annotation.CallSuper;
import android.annotation.IdRes;
import android.annotation.NonNull;
+import android.annotation.TestApi;
import android.annotation.UiThread;
import android.content.ClipData;
import android.content.Context;
@@ -3166,6 +3167,7 @@
/**
* @hide
*/
+ @TestApi
@Override
public boolean restoreFocusInCluster(@FocusRealDirection int direction) {
if (mFocusedInCluster != null && !mFocusedInCluster.isKeyboardNavigationCluster()
@@ -3178,6 +3180,40 @@
}
/**
+ * @hide
+ */
+ @Override
+ public boolean restoreFocusNotInCluster() {
+ if (mFocusedInCluster != null) {
+ // since clusters don't nest; we can assume that a non-null mFocusedInCluster
+ // will refer to a view not-in a cluster.
+ return restoreFocusInCluster(View.FOCUS_DOWN);
+ }
+ if (isKeyboardNavigationCluster()) {
+ return false;
+ }
+ int descendentFocusability = getDescendantFocusability();
+ if (descendentFocusability == FOCUS_BLOCK_DESCENDANTS) {
+ return super.requestFocus(FOCUS_DOWN, null);
+ }
+ if (descendentFocusability == FOCUS_BEFORE_DESCENDANTS
+ && super.requestFocus(FOCUS_DOWN, null)) {
+ return true;
+ }
+ for (int i = 0; i < mChildrenCount; ++i) {
+ View child = mChildren[i];
+ if (!child.isKeyboardNavigationCluster()
+ && child.restoreFocusNotInCluster()) {
+ return true;
+ }
+ }
+ if (descendentFocusability == FOCUS_AFTER_DESCENDANTS) {
+ return super.requestFocus(FOCUS_DOWN, null);
+ }
+ return false;
+ }
+
+ /**
* {@inheritDoc}
*
* @hide
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index bbf840f..6cdd483 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -4465,7 +4465,7 @@
private boolean performKeyboardGroupNavigation(int direction) {
final View focused = mView.findFocus();
- final View cluster = focused != null
+ View cluster = focused != null
? focused.keyboardNavigationClusterSearch(null, direction)
: keyboardNavigationClusterSearch(null, direction);
@@ -4476,6 +4476,15 @@
realDirection = View.FOCUS_DOWN;
}
+ if (cluster != null && cluster.isRootNamespace()) {
+ // the default cluster. Try to find a non-clustered view to focus.
+ if (cluster.restoreFocusNotInCluster()) {
+ return true;
+ }
+ // otherwise skip to next actual cluster
+ cluster = keyboardNavigationClusterSearch(null, direction);
+ }
+
if (cluster != null && cluster.restoreFocusInCluster(realDirection)) {
return true;
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 5572cbb..6fa8428 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -10035,6 +10035,10 @@
@Override
public void addExtraDataToAccessibilityNodeInfo(
AccessibilityNodeInfo info, String extraDataKey, Bundle arguments) {
+ // The only extra data we support requires arguments.
+ if (arguments == null) {
+ return;
+ }
if (extraDataKey.equals(EXTRA_DATA_TEXT_CHARACTER_LOCATION_KEY)) {
int positionInfoStartIndex = arguments.getInt(
EXTRA_DATA_TEXT_CHARACTER_LOCATION_ARG_START_INDEX, -1);
diff --git a/core/java/com/android/internal/content/PackageHelper.java b/core/java/com/android/internal/content/PackageHelper.java
index eec3cb0..e088717 100644
--- a/core/java/com/android/internal/content/PackageHelper.java
+++ b/core/java/com/android/internal/content/PackageHelper.java
@@ -534,7 +534,7 @@
final int prefer;
final boolean checkBoth;
boolean ephemeral = false;
- if ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) {
+ if ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
prefer = RECOMMEND_INSTALL_INTERNAL;
ephemeral = true;
checkBoth = false;
diff --git a/core/jni/android/graphics/SurfaceTexture.cpp b/core/jni/android/graphics/SurfaceTexture.cpp
index dc9b656..0099673 100644
--- a/core/jni/android/graphics/SurfaceTexture.cpp
+++ b/core/jni/android/graphics/SurfaceTexture.cpp
@@ -25,6 +25,7 @@
#include <gui/GLConsumer.h>
#include <gui/Surface.h>
+#include <gui/BufferQueue.h>
#include "core_jni_helpers.h"
diff --git a/core/jni/android_hardware_HardwareBuffer.cpp b/core/jni/android_hardware_HardwareBuffer.cpp
index 6cf5ccf..5f0664b 100644
--- a/core/jni/android_hardware_HardwareBuffer.cpp
+++ b/core/jni/android_hardware_HardwareBuffer.cpp
@@ -239,6 +239,8 @@
return AHARDWAREBUFFER_FORMAT_R8G8B8_UNORM;
case HAL_PIXEL_FORMAT_RGBA_FP16:
return AHARDWAREBUFFER_FORMAT_R16G16B16A16_SFLOAT;
+ case HAL_PIXEL_FORMAT_RGBA_1010102:
+ return AHARDWAREBUFFER_FORMAT_A2R10G10B10_UNORM_PACK32;
case HAL_PIXEL_FORMAT_BLOB:
return AHARDWAREBUFFER_FORMAT_BLOB;
default:
@@ -259,6 +261,8 @@
return HAL_PIXEL_FORMAT_RGB_888;
case AHARDWAREBUFFER_FORMAT_R16G16B16A16_SFLOAT:
return HAL_PIXEL_FORMAT_RGBA_FP16;
+ case AHARDWAREBUFFER_FORMAT_A2R10G10B10_UNORM_PACK32:
+ return HAL_PIXEL_FORMAT_RGBA_1010102;
case AHARDWAREBUFFER_FORMAT_BLOB:
return HAL_PIXEL_FORMAT_BLOB;
default:
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index 4a9cd24..6192271 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -170,6 +170,7 @@
case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_RGBX_8888:
case HAL_PIXEL_FORMAT_RGBA_FP16:
+ case HAL_PIXEL_FORMAT_RGBA_1010102:
case HAL_PIXEL_FORMAT_RGB_888:
case HAL_PIXEL_FORMAT_RGB_565:
case HAL_PIXEL_FORMAT_Y8:
diff --git a/core/jni/android_view_TextureView.cpp b/core/jni/android_view_TextureView.cpp
index 613e040..18a1360 100644
--- a/core/jni/android_view_TextureView.cpp
+++ b/core/jni/android_view_TextureView.cpp
@@ -83,7 +83,7 @@
colorType = kN32_SkColorType;
alphaType = kOpaque_SkAlphaType;
break;
- case WINDOW_FORMAT_RGBA_FP16:
+ case AHARDWAREBUFFER_FORMAT_R16G16B16A16_SFLOAT:
colorType = kRGBA_F16_SkColorType;
alphaType = kPremul_SkAlphaType;
break;
diff --git a/core/jni/include/android_runtime/android_view_Surface.h b/core/jni/include/android_runtime/android_view_Surface.h
index 07e29cb..3f1bdff 100644
--- a/core/jni/include/android_runtime/android_view_Surface.h
+++ b/core/jni/include/android_runtime/android_view_Surface.h
@@ -50,6 +50,7 @@
RAW_PRIVATE = 0x24,
RAW10 = 0x25,
RAW12 = 0x26,
+ RGBA_1010102 = 0x2b,
JPEG = 0x100,
DEPTH_POINT_CLOUD = 0x101,
YV12 = 0x32315659,
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 97fbfa5..3ca2208 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -3076,10 +3076,11 @@
<permission android:name="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"
android:protectionLevel="signature" />
- <!-- Must be required by an {@link
+ <!-- @SystemApi Must be required by an {@link
android.service.notification.NotificationAssistantService} to ensure that only the system
can bind to it.
<p>Protection level: signature
+ @hide
-->
<permission android:name="android.permission.BIND_NOTIFICATION_ASSISTANT_SERVICE"
android:protectionLevel="signature" />
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 4d5e45b..958cacf 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2287,6 +2287,17 @@
<enum name="auto" value="0x00000010" />
</attr>
+ <!-- Controls the auto-fill behavior for this view -->
+ <attr name="autoFillMode">
+ <!-- Inherit the behavior from the parent. If there is no parent it is auto. -->
+ <enum name="inherit" value="0" />
+ <!-- Allows this view to automatically trigger an auto-fill request when it get focus.
+ -->
+ <enum name="auto" value="1" />
+ <!-- The user has to manually force an auto-fill request for this view. -->
+ <enum name="manual" value="2" />
+ </attr>
+
<!-- Boolean that controls whether a view can take focus while in touch mode.
If this is true for a view, that view can gain focus when clicked on, and can keep
focus if another view is clicked on that doesn't have this attribute set to true. -->
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 78489eb..78549b5 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2796,6 +2796,7 @@
<public name="numericModifiers" />
<public name="fontProviderAuthority" />
<public name="fontProviderQuery" />
+ <public name="autoFillMode" />
</public-group>
<public-group type="style" first-id="0x010302e0">
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 039ab1f..5226fe5 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -264,6 +264,7 @@
<permission name="android.permission.INTERACT_ACROSS_USERS"/>
<permission name="android.permission.MANAGE_ACTIVITY_STACKS"/>
<permission name="android.permission.MANAGE_DEVICE_ADMINS"/>
+ <permission name="android.permission.MANAGE_USB"/>
<permission name="android.permission.MODIFY_APPWIDGET_BIND_PERMISSIONS"/>
<permission name="android.permission.MODIFY_PHONE_STATE"/>
<permission name="android.permission.MOUNT_FORMAT_FILESYSTEMS"/>
diff --git a/graphics/java/android/graphics/PixelFormat.java b/graphics/java/android/graphics/PixelFormat.java
index c3a9443..f93886d 100644
--- a/graphics/java/android/graphics/PixelFormat.java
+++ b/graphics/java/android/graphics/PixelFormat.java
@@ -29,65 +29,66 @@
/** @hide */
@Retention(RetentionPolicy.SOURCE)
- @IntDef({RGBA_8888, RGBX_8888, RGBA_F16, RGB_888, RGB_565})
- public @interface Format { };
+ @IntDef({RGBA_8888, RGBX_8888, RGBA_F16, RGBA_1010102, RGB_888, RGB_565})
+ public @interface Format { }
// NOTE: these constants must match the values from graphics/common/x.x/types.hal
- public static final int UNKNOWN = 0;
+ public static final int UNKNOWN = 0;
/** System chooses a format that supports translucency (many alpha bits) */
- public static final int TRANSLUCENT = -3;
+ public static final int TRANSLUCENT = -3;
/**
* System chooses a format that supports transparency
* (at least 1 alpha bit)
*/
- public static final int TRANSPARENT = -2;
+ public static final int TRANSPARENT = -2;
/** System chooses an opaque format (no alpha bits required) */
- public static final int OPAQUE = -1;
+ public static final int OPAQUE = -1;
- public static final int RGBA_8888 = 1;
- public static final int RGBX_8888 = 2;
- public static final int RGB_888 = 3;
- public static final int RGB_565 = 4;
+ public static final int RGBA_8888 = 1;
+ public static final int RGBX_8888 = 2;
+ public static final int RGB_888 = 3;
+ public static final int RGB_565 = 4;
@Deprecated
- public static final int RGBA_5551 = 6;
+ public static final int RGBA_5551 = 6;
@Deprecated
- public static final int RGBA_4444 = 7;
+ public static final int RGBA_4444 = 7;
@Deprecated
- public static final int A_8 = 8;
+ public static final int A_8 = 8;
@Deprecated
- public static final int L_8 = 9;
+ public static final int L_8 = 9;
@Deprecated
- public static final int LA_88 = 0xA;
+ public static final int LA_88 = 0xA;
@Deprecated
- public static final int RGB_332 = 0xB;
+ public static final int RGB_332 = 0xB;
/**
* @deprecated use {@link android.graphics.ImageFormat#NV16
* ImageFormat.NV16} instead.
*/
@Deprecated
- public static final int YCbCr_422_SP= 0x10;
+ public static final int YCbCr_422_SP = 0x10;
/**
* @deprecated use {@link android.graphics.ImageFormat#NV21
* ImageFormat.NV21} instead.
*/
@Deprecated
- public static final int YCbCr_420_SP= 0x11;
+ public static final int YCbCr_420_SP = 0x11;
/**
* @deprecated use {@link android.graphics.ImageFormat#YUY2
* ImageFormat.YUY2} instead.
*/
@Deprecated
- public static final int YCbCr_422_I = 0x14;
+ public static final int YCbCr_422_I = 0x14;
- public static final int RGBA_F16 = 0x16;
+ public static final int RGBA_F16 = 0x16;
+ public static final int RGBA_1010102 = 0x2B;
/**
* @deprecated use {@link android.graphics.ImageFormat#JPEG
@@ -103,6 +104,7 @@
switch (format) {
case RGBA_8888:
case RGBX_8888:
+ case RGBA_1010102:
info.bitsPerPixel = 32;
info.bytesPerPixel = 4;
break;
@@ -149,6 +151,7 @@
case PixelFormat.RGBA_5551:
case PixelFormat.RGBA_8888:
case PixelFormat.RGBA_F16:
+ case PixelFormat.RGBA_1010102:
case PixelFormat.TRANSLUCENT:
case PixelFormat.TRANSPARENT:
return true;
@@ -176,6 +179,7 @@
case RGB_888:
case RGB_565:
case RGBA_F16:
+ case RGBA_1010102:
return true;
}
diff --git a/media/java/android/media/MediaRecorder.java b/media/java/android/media/MediaRecorder.java
index 7a6499d..075a84f 100644
--- a/media/java/android/media/MediaRecorder.java
+++ b/media/java/android/media/MediaRecorder.java
@@ -20,6 +20,7 @@
import android.annotation.SystemApi;
import android.app.ActivityThread;
import android.hardware.Camera;
+import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
@@ -1257,6 +1258,93 @@
private native void setParameter(String nameValuePair);
+ /**
+ * Returns Metrics data about the current media container.
+ *
+ * @return the set of keys and values available for the media being
+ * handled by this instance of MediaExtractor. The keys, data types,
+ * and meaning are described in the following table.
+ *
+ * <table style="width: 0%">
+ * <thead>
+ * <tr>
+ * <th>Key</th>
+ * <th>Type</th>
+ * <th>Description</th>
+ * </tr>
+ * </thead>
+ * <tbody>
+ * <tr>
+ * <td>{@code "ht"}</td>
+ * <td>Integer</td>
+ * <td>Height of the recorded video (pixels)</td>
+ * </tr><tr>
+ * <td>{@code "wid"}</td>
+ * <td>Integer</td>
+ * <td>Width of the recorded video (pixels)</td>
+ * </tr><tr>
+ * <td>{@code "frame-rate"}</td>
+ * <td>Integer</td>
+ * <td>Framerate of captured Video (frames per second)</td>
+ * </tr><tr>
+ * <td>{@code "video-bitrate"}</td>
+ * <td>Integer</td>
+ * <td>Bit rate of encoded video (bits per second)</td>
+ * </tr><tr>
+ * <td>{@code "video-iframe-interval"}</td>
+ * <td>Integer</td>
+ * <td>Interval between encoded IFrames (seconds)</td>
+ * </tr><tr>
+ * <td>{@code "video-timescale"}</td>
+ * <td>Integer</td>
+ * <td></td>
+ * </tr><tr>
+ * <td>{@code "video-encoder-profile"}</td>
+ * <td>Integer</td>
+ * <td>Video Encoder Profile, as defined in OpenMAX IL</td>
+ * </tr><tr>
+ * <td>{@code "video-encoder-level"}</td>
+ * <td>Integer</td>
+ * <td>Video Encoder Level, as defined in OpenMAX IL</td>
+ * </tr><tr>
+ * <td>{@code "audio-bitrate"}</td>
+ * <td>Integer</td>
+ * <td>Bitrate of encoded audio (bits per second)</td>
+ * </tr><tr>
+ * <td>{@code "audio-samplerate"}</td>
+ * <td>Integer</td>
+ * <td></td>
+ * </tr><tr>
+ * <td>{@code "audio-channels"}</td>
+ * <td>Integer</td>
+ * <td>Number of Audio Channels Captured</td>
+ * </tr><tr>
+ * <td>{@code "audio-timescale"}</td>
+ * <td>Integer</td>
+ * <td></td>
+ * </tr><tr>
+ * <td>{@code "movie-timescale"}</td>
+ * <td>Integer</td>
+ * <td></td>
+ * </tr><tr>
+ * <td>{@code "movie-timescale"}</td>
+ * <td>Integer</td>
+ * <td></td>
+ * </tr><tr>
+ * <td>{@code "capture-fps"}</td>
+ * <td>Integer</td>
+ * <td></td>
+ * </tr><tr>
+ * <td>{@code "rotation"}</td>
+ * <td>Integer</td>
+ * <td>Orientation of the Video (degrees)</td>
+ * </tr>
+ * </tbody>
+ * </table>
+ */
+
+ public native Bundle getMetrics();
+
@Override
protected void finalize() { native_finalize(); }
}
diff --git a/media/jni/android_media_MediaRecorder.cpp b/media/jni/android_media_MediaRecorder.cpp
index 7c509d2..77544eb 100644
--- a/media/jni/android_media_MediaRecorder.cpp
+++ b/media/jni/android_media_MediaRecorder.cpp
@@ -28,6 +28,7 @@
#include <gui/Surface.h>
#include <camera/Camera.h>
#include <media/mediarecorder.h>
+#include <media/MediaAnalyticsItem.h>
#include <media/stagefright/PersistentSurface.h>
#include <utils/threads.h>
@@ -35,6 +36,7 @@
#include "jni.h"
#include "JNIHelp.h"
+#include "android_media_MediaMetricsJNI.h"
#include "android_runtime/AndroidRuntime.h"
#include <system/audio.h>
@@ -625,6 +627,36 @@
"java/lang/IllegalArgumentException", "native_setInputSurface failed.");
}
+static jobject
+android_media_MediaRecorder_getMetrics(JNIEnv *env, jobject thiz)
+{
+ ALOGV("android_media_MediaRecorder_getMetrics");
+
+ sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
+ if (mr == NULL) {
+ jniThrowException(env, "java/lang/IllegalStateException", NULL);
+ return NULL;
+ }
+
+ // get what we have for the metrics from the codec
+ Parcel reply;
+ status_t err = mr->getMetrics(&reply);
+ if (err != OK) {
+ ALOGE("getMetrics failed");
+ return (jobject) NULL;
+ }
+
+ // build and return the Bundle
+ MediaAnalyticsItem *item = new MediaAnalyticsItem;
+ item->readFromParcel(reply);
+ jobject mybundle = MediaMetricsJNI::writeMetricsToBundle(env, item, NULL);
+
+ // housekeeping
+ delete item;
+ item = NULL;
+ return mybundle;
+
+}
// ----------------------------------------------------------------------------
static const JNINativeMethod gMethods[] = {
@@ -655,6 +687,8 @@
(void *)android_media_MediaRecorder_native_setup},
{"native_finalize", "()V", (void *)android_media_MediaRecorder_native_finalize},
{"native_setInputSurface", "(Landroid/view/Surface;)V", (void *)android_media_MediaRecorder_setInputSurface },
+
+ {"getMetrics", "()Landroid/os/Bundle;", (void *)android_media_MediaRecorder_getMetrics},
};
// This function only registers the native methods, and is called from
diff --git a/media/mca/filterfw/jni/Android.mk b/media/mca/filterfw/jni/Android.mk
index 40576a0..9842e70 100644
--- a/media/mca/filterfw/jni/Android.mk
+++ b/media/mca/filterfw/jni/Android.mk
@@ -43,6 +43,6 @@
LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code -Wno-unused-parameter
-LOCAL_SHARED_LIBRARIES := libmedia
+LOCAL_SHARED_LIBRARIES := libmedia libgui libandroid
include $(BUILD_STATIC_LIBRARY)
diff --git a/media/mca/filterfw/native/Android.mk b/media/mca/filterfw/native/Android.mk
index 7c4703f..2e900fe 100644
--- a/media/mca/filterfw/native/Android.mk
+++ b/media/mca/filterfw/native/Android.mk
@@ -41,6 +41,8 @@
LOCAL_CFLAGS += -Wall -Werror -Wunused -Wunreachable-code
+LOCAL_STATIC_LIBRARIES := libarect
+
# TODO: Build a shared library as well?
include $(BUILD_STATIC_LIBRARY)
diff --git a/media/mca/filterfw/native/core/gl_env.cpp b/media/mca/filterfw/native/core/gl_env.cpp
index c9d33da..1bb82f8 100644
--- a/media/mca/filterfw/native/core/gl_env.cpp
+++ b/media/mca/filterfw/native/core/gl_env.cpp
@@ -26,7 +26,10 @@
#include <string>
#include <EGL/eglext.h>
+#include <gui/BufferQueue.h>
+#include <gui/Surface.h>
#include <gui/GLConsumer.h>
+#include <gui/IGraphicBufferProducer.h>
namespace android {
namespace filterfw {
diff --git a/media/mca/filterfw/native/core/gl_env.h b/media/mca/filterfw/native/core/gl_env.h
index a709638..0445301 100644
--- a/media/mca/filterfw/native/core/gl_env.h
+++ b/media/mca/filterfw/native/core/gl_env.h
@@ -27,8 +27,9 @@
#include <GLES2/gl2.h>
#include <EGL/egl.h>
-#include <gui/IGraphicBufferProducer.h>
-#include <gui/Surface.h>
+#include <utils/StrongPointer.h>
+
+struct ANativeWindow;
namespace android {
diff --git a/native/android/Android.mk b/native/android/Android.mk
index f8405ef..69544f5 100644
--- a/native/android/Android.mk
+++ b/native/android/Android.mk
@@ -37,7 +37,8 @@
libnetd_client \
LOCAL_STATIC_LIBRARIES := \
- libstorage
+ libstorage \
+ libarect
LOCAL_C_INCLUDES += \
frameworks/base/native/include \
@@ -45,6 +46,8 @@
bionic/libc/dns/include \
system/netd/include \
+LOCAL_EXPORT_STATIC_LIBRARY_HEADERS := libarect
+
LOCAL_MODULE := libandroid
LOCAL_CFLAGS += $(common_cflags)
diff --git a/native/graphics/jni/Android.mk b/native/graphics/jni/Android.mk
index 4c8a9db..ec4b35a 100644
--- a/native/graphics/jni/Android.mk
+++ b/native/graphics/jni/Android.mk
@@ -21,6 +21,7 @@
LOCAL_SHARED_LIBRARIES := \
libandroid_runtime \
libskia \
+ libui \
libandroidfw
LOCAL_C_INCLUDES += \
diff --git a/packages/PrintSpooler/res/layout/no_print_services_message.xml b/packages/PrintSpooler/res/layout/no_print_services_message.xml
new file mode 100644
index 0000000..7872658
--- /dev/null
+++ b/packages/PrintSpooler/res/layout/no_print_services_message.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2017 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"
+ android:layout_width="fill_parent"
+ android:layout_height="?android:attr/listPreferredItemHeightSmall"
+ android:paddingStart="?android:attr/listPreferredItemPaddingStart"
+ android:paddingEnd="?android:attr/listPreferredItemPaddingEnd"
+ android:orientation="horizontal"
+ android:gravity="start|center_vertical">
+
+ <RelativeLayout
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginStart="32dip">
+ <HorizontalScrollView
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content">
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textAppearance="?android:attr/textAppearanceListItem"
+ android:text="@string/print_no_print_services"
+ android:scrollHorizontally="true"
+ android:singleLine="true" />
+ </HorizontalScrollView>
+ </RelativeLayout>
+
+</LinearLayout>
diff --git a/packages/PrintSpooler/src/com/android/printspooler/ui/AddPrinterActivity.java b/packages/PrintSpooler/src/com/android/printspooler/ui/AddPrinterActivity.java
index 7b0a291..696376e 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/ui/AddPrinterActivity.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/ui/AddPrinterActivity.java
@@ -26,6 +26,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.Loader;
+import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.database.DataSetObserver;
import android.net.Uri;
@@ -97,20 +98,39 @@
*/
private RecommendedServicesAdapter mRecommendedServicesAdapter;
+ private static final String PKG_NAME_VENDING = "com.android.vending";
+ private boolean mHasVending;
+ private NoPrintServiceMessageAdapter mNoPrintServiceMessageAdapter;
+
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.add_printer_activity);
+ try {
+ getPackageManager().getPackageInfo(PKG_NAME_VENDING, 0);
+ mHasVending = true;
+ } catch (PackageManager.NameNotFoundException e) {
+ mHasVending = false;
+ }
mEnabledServicesAdapter = new EnabledServicesAdapter();
mDisabledServicesAdapter = new DisabledServicesAdapter();
- mRecommendedServicesAdapter = new RecommendedServicesAdapter();
+ if (mHasVending) {
+ mRecommendedServicesAdapter = new RecommendedServicesAdapter();
+ } else {
+ mNoPrintServiceMessageAdapter = new NoPrintServiceMessageAdapter();
+ }
ArrayList<ActionAdapter> adapterList = new ArrayList<>(3);
adapterList.add(mEnabledServicesAdapter);
- adapterList.add(mRecommendedServicesAdapter);
+ if (mHasVending) {
+ adapterList.add(mRecommendedServicesAdapter);
+ }
adapterList.add(mDisabledServicesAdapter);
+ if (!mHasVending) {
+ adapterList.add(mNoPrintServiceMessageAdapter);
+ }
setListAdapter(new CombinedAdapter(adapterList));
@@ -121,8 +141,10 @@
getLoaderManager().initLoader(LOADER_ID_ENABLED_SERVICES, null, printServiceLoaderCallbacks);
getLoaderManager().initLoader(LOADER_ID_DISABLED_SERVICES, null, printServiceLoaderCallbacks);
- getLoaderManager().initLoader(LOADER_ID_RECOMMENDED_SERVICES, null,
- new PrintServicePrintServiceRecommendationLoaderCallbacks());
+ if (mHasVending) {
+ getLoaderManager().initLoader(LOADER_ID_RECOMMENDED_SERVICES, null,
+ new PrintServicePrintServiceRecommendationLoaderCallbacks());
+ }
getLoaderManager().initLoader(LOADER_ID_ALL_SERVICES, null, printServiceLoaderCallbacks);
}
@@ -174,7 +196,11 @@
mDisabledServicesAdapter.updateData(data);
break;
case LOADER_ID_ALL_SERVICES:
- mRecommendedServicesAdapter.updateInstalledServices(data);
+ if (mHasVending) {
+ mRecommendedServicesAdapter.updateInstalledServices(data);
+ } else {
+ mNoPrintServiceMessageAdapter.updateInstalledServices(data);
+ }
default:
// not reached
}
@@ -191,7 +217,11 @@
mDisabledServicesAdapter.updateData(null);
break;
case LOADER_ID_ALL_SERVICES:
- mRecommendedServicesAdapter.updateInstalledServices(null);
+ if (mHasVending) {
+ mRecommendedServicesAdapter.updateInstalledServices(null);
+ } else {
+ mNoPrintServiceMessageAdapter.updateInstalledServices(null);
+ }
break;
default:
// not reached
@@ -804,4 +834,61 @@
filterRecommendations();
}
}
+
+ private class NoPrintServiceMessageAdapter extends ActionAdapter {
+ private boolean mHasPrintService;
+
+ void updateInstalledServices(@Nullable List<PrintServiceInfo> services) {
+ if (services == null || services.isEmpty()) {
+ mHasPrintService = false;
+ } else {
+ mHasPrintService = true;
+ }
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public int getCount() {
+ return mHasPrintService ? 0 : 1;
+ }
+
+ @Override
+ public int getViewTypeCount() {
+ return 1;
+ }
+
+ @Override
+ public int getItemViewType(int position) {
+ return 0;
+ }
+
+ @Override
+ public Object getItem(int position) {
+ return null;
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ if (convertView == null) {
+ convertView = getLayoutInflater().inflate(R.layout.no_print_services_message,
+ parent, false);
+ }
+ return convertView;
+ }
+
+ @Override
+ public boolean isEnabled(int position) {
+ return position != 0;
+ }
+
+ @Override
+ public void performAction(@IntRange(from = 0) int position) {
+ return;
+ }
+ }
}
diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml
index 5475b32..e8e9cc5 100644
--- a/packages/SettingsLib/res/values/strings.xml
+++ b/packages/SettingsLib/res/values/strings.xml
@@ -57,6 +57,8 @@
<string name="wifi_disabled_generic">Disabled</string>
<!-- Status for networked disabled from a DNS or DHCP failure -->
<string name="wifi_disabled_network_failure">IP Configuration Failure</string>
+ <!-- Status for networks disabled by the network recommendation provider -->
+ <string name="wifi_disabled_by_recommendation_provider">Not connected due to low quality network</string>
<!-- Status for networked disabled from a wifi association failure -->
<string name="wifi_disabled_wifi_failure">WiFi Connection Failure</string>
<!-- Status for networks disabled from authentication failure (wrong password
diff --git a/packages/SettingsLib/src/com/android/settingslib/users/AppRestrictionsHelper.java b/packages/SettingsLib/src/com/android/settingslib/users/AppRestrictionsHelper.java
index 4c11197..0fc9a4d 100644
--- a/packages/SettingsLib/src/com/android/settingslib/users/AppRestrictionsHelper.java
+++ b/packages/SettingsLib/src/com/android/settingslib/users/AppRestrictionsHelper.java
@@ -116,7 +116,7 @@
if (info == null || !info.enabled
|| (info.flags&ApplicationInfo.FLAG_INSTALLED) == 0) {
mIPm.installExistingPackageAsUser(packageName, mUser.getIdentifier(),
- PackageManager.INSTALL_REASON_UNKNOWN);
+ 0 /*installFlags*/, PackageManager.INSTALL_REASON_UNKNOWN);
if (DEBUG) {
Log.d(TAG, "Installing " + packageName);
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
index 82e69d8..dc9b798 100644
--- a/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
+++ b/packages/SettingsLib/src/com/android/settingslib/wifi/AccessPoint.java
@@ -503,7 +503,8 @@
// This is the active connection on non-passpoint network
summary.append(getSummary(mContext, getDetailedState(),
mInfo != null && mInfo.isEphemeral()));
- } else if (config != null && config.isPasspoint()) {
+ } else if (config != null && config.isPasspoint()
+ && config.getNetworkSelectionStatus().isNetworkEnabled()) {
String format = mContext.getString(R.string.available_via_passpoint);
summary.append(String.format(format, config.providerFriendlyName));
} else if (config != null && config.hasNoInternetAccess()) {
@@ -526,6 +527,8 @@
summary.append(mContext.getString(R.string.wifi_disabled_generic));
break;
}
+ } else if (config != null && config.getNetworkSelectionStatus().isNotRecommended()) {
+ summary.append(mContext.getString(R.string.wifi_disabled_by_recommendation_provider));
} else if (mRssi == Integer.MAX_VALUE) { // Wifi out of range
summary.append(mContext.getString(R.string.wifi_not_in_range));
} else { // In range, not disabled.
diff --git a/packages/SettingsLib/tests/integ/Android.mk b/packages/SettingsLib/tests/integ/Android.mk
index bd910dd..091f965 100644
--- a/packages/SettingsLib/tests/integ/Android.mk
+++ b/packages/SettingsLib/tests/integ/Android.mk
@@ -31,6 +31,12 @@
legacy-android-test \
truth-prebuilt
+# Code coverage puts us over the dex limit, so enable multi-dex for coverage-enabled builds
+ifeq (true,$(EMMA_INSTRUMENT))
+LOCAL_JACK_FLAGS := --multi-dex native
+LOCAL_DX_FLAGS := --multi-dex
+endif # EMMA_INSTRUMENT
+
include frameworks/base/packages/SettingsLib/common.mk
include $(BUILD_PACKAGE)
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AppRestrictionsHelperTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AppRestrictionsHelperTest.java
index 4df199c..8cfec7a 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AppRestrictionsHelperTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/users/AppRestrictionsHelperTest.java
@@ -146,7 +146,7 @@
mHelper.applyUserAppsStates(mockListener);
verify(mIpm, times(1)).installExistingPackageAsUser("app1", testUserId,
- PackageManager.INSTALL_REASON_UNKNOWN);
+ 0 /*installFlags*/, PackageManager.INSTALL_REASON_UNKNOWN);
verify(mIpm, times(1)).setApplicationHiddenSettingAsUser("app2", false, testUserId);
verify(mockListener).onDisableUiForPackage("app2");
verify(mPm, times(1)).deletePackageAsUser(eq("app3"), any(IPackageDeleteObserver.class),
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index 136f17e..7206127 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -38,7 +38,7 @@
<bool name="def_bluetooth_on">true</bool>
<bool name="def_wifi_display_on">false</bool>
- <bool name="def_install_non_market_apps">true</bool>
+ <bool name="def_install_non_market_apps">false</bool>
<bool name="def_package_verifier_enable">true</bool>
<!-- Comma-separated list of location providers.
Network location is off by default because it requires
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index d5787e6..ba657e9 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -1531,14 +1531,14 @@
}
}
- private Set<String> getEphemeralAccessibleSettings(int settingsType) {
+ private Set<String> getInstantAppAccessibleSettings(int settingsType) {
switch (settingsType) {
case SETTINGS_TYPE_GLOBAL:
- return Settings.Global.EPHEMERAL_SETTINGS;
+ return Settings.Global.INSTANT_APP_SETTINGS;
case SETTINGS_TYPE_SECURE:
- return Settings.Secure.EPHEMERAL_SETTINGS;
+ return Settings.Secure.INSTANT_APP_SETTINGS;
case SETTINGS_TYPE_SYSTEM:
- return Settings.System.EPHEMERAL_SETTINGS;
+ return Settings.System.INSTANT_APP_SETTINGS;
default:
throw new IllegalArgumentException("Invalid settings type: " + settingsType);
}
@@ -1547,7 +1547,7 @@
private List<String> getSettingsNamesLocked(int settingsType, int userId) {
ApplicationInfo ai = getCallingApplicationInfoOrThrow(userId);
if (ai.isInstantApp()) {
- return new ArrayList<String>(getEphemeralAccessibleSettings(settingsType));
+ return new ArrayList<String>(getInstantAppAccessibleSettings(settingsType));
} else {
return mSettingsRegistry.getSettingsNamesLocked(settingsType, userId);
}
@@ -1561,7 +1561,7 @@
if (!ai.isInstantApp()) {
return;
}
- if (!getEphemeralAccessibleSettings(settingsType).contains(settingName)) {
+ if (!getInstantAppAccessibleSettings(settingsType).contains(settingName)) {
throw new SecurityException("Setting " + settingName + " is not accessible from"
+ " ephemeral package " + getCallingPackage());
}
@@ -3174,9 +3174,17 @@
// setting through the UI.
final SettingsState secureSetting = getSecureSettingsLocked(userId);
if (!mUserManager.hasUserRestriction(
- UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, UserHandle.of(userId))) {
+ UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, UserHandle.of(userId))
+ && secureSetting.getSettingLocked(
+ Settings.Secure.INSTALL_NON_MARKET_APPS).getValue().equals("0")) {
+
secureSetting.insertSettingLocked(Settings.Secure.INSTALL_NON_MARKET_APPS,
"1", null, true, SettingsState.SYSTEM_PACKAGE_NAME);
+ // For managed profiles with profile owners, DevicePolicyManagerService
+ // may want to set the user restriction in this case
+ secureSetting.insertSettingLocked(
+ Settings.Secure.UNKNOWN_SOURCES_DEFAULT_REVERSED, "1", null, true,
+ SettingsState.SYSTEM_PACKAGE_NAME);
}
currentVersion = 138;
}
diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/InstallNonMarketAppsDeprecationTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/InstallNonMarketAppsDeprecationTest.java
index 51e4373..2dbe142 100644
--- a/packages/SettingsProvider/test/src/com/android/providers/settings/InstallNonMarketAppsDeprecationTest.java
+++ b/packages/SettingsProvider/test/src/com/android/providers/settings/InstallNonMarketAppsDeprecationTest.java
@@ -22,6 +22,7 @@
import android.content.Context;
import android.content.pm.UserInfo;
+import android.os.Process;
import android.os.SystemClock;
import android.os.UserManager;
import android.provider.Settings;
@@ -47,6 +48,7 @@
private UserManager mUm;
private boolean mHasUserRestriction;
+ private boolean mSystemSetUserRestriction;
private List<UserInfo> mCurrentUsers;
private String waitTillValueChanges(String errorMessage, String oldValue) {
@@ -84,6 +86,9 @@
public void setUp() {
mUm = (UserManager) getContext().getSystemService(Context.USER_SERVICE);
mHasUserRestriction = mUm.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES);
+ mSystemSetUserRestriction = mUm.getUserRestrictionSource(
+ UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, Process.myUserHandle())
+ == UserManager.RESTRICTION_SOURCE_SYSTEM;
mCurrentUsers = mUm.getUsers();
}
@@ -117,6 +122,13 @@
String value = getSetting(SETTING_TYPE_SECURE, Settings.Secure.INSTALL_NON_MARKET_APPS);
assertEquals(value, mHasUserRestriction ? "0" : "1");
+ if (mHasUserRestriction && !mSystemSetUserRestriction) {
+ // User restriction set by device policy. This case should be covered in DO/PO related
+ // tests. Pass.
+ Log.w(TAG, "User restriction set by PO/DO. Skipping testValueRespectsUserRestriction");
+ return;
+ }
+
mUm.setUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, !mHasUserRestriction);
value = waitTillValueChanges(
"Changing user restriction did not change the value of install_non_market_apps",
@@ -132,8 +144,8 @@
@After
public void tearDown() {
- if (mUm.hasUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES)
- != mHasUserRestriction) {
+ if (!mHasUserRestriction || mSystemSetUserRestriction) {
+ // The test may have modified the user restriction state. Restore it.
mUm.setUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,
mHasUserRestriction);
}
diff --git a/packages/SystemUI/res/drawable/instant_icon.xml b/packages/SystemUI/res/drawable/instant_icon.xml
new file mode 100644
index 0000000..0039c81
--- /dev/null
+++ b/packages/SystemUI/res/drawable/instant_icon.xml
@@ -0,0 +1,30 @@
+<!--
+ Copyright (C) 2015 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="40dp"
+ android:height="40dp"
+ android:viewportWidth="2.2"
+ android:viewportHeight="2.2">
+
+ <path
+ android:fillColor="#FFFFFFFF"
+ android:pathData="M.1,1.1
+ c0,.55 .45,1 1,1
+ c.55,0 1,-.45 1,-1
+ c0,-.55 -.45,-1 -1,-1
+ c-.55,0 -1,.45 -1,1z
+ M1.15,.95 l.5,0 l-.7,1 l0.1,-.7 l-.5,0 l.7,-1 z"/>
+</vector>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 7f30c83..407cddf 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -147,4 +147,6 @@
<color name="ksh_key_item_color">@color/material_grey_600</color>
<color name="ksh_key_item_background">@color/material_grey_100</color>
+ <color name="instant_apps_color">#ff4d5a64</color>
+
</resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index b825cfb..815c41f 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1810,4 +1810,13 @@
<!-- Title for the notification channel for problems with storage (i.e. low disk). [CHAR LIMIT=NONE] -->
<string name="notification_channel_storage">Storage</string>
+ <!-- App label of the instant apps notification [CHAR LIMIT=60] -->
+ <string name="instant_apps">Instant Apps</string>
+
+ <!-- Message of the instant apps notification indicating they don't need install [CHAR LIMIT=NONE] -->
+ <string name="instant_apps_message">Instant apps don\'t require installation.</string>
+
+ <!-- Action label for launching app info on the specified app [CHAR LIMIT=20] -->
+ <string name="app_info">App info</string>
+
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
index 42f1b14..ae402ef 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipManager.java
@@ -76,7 +76,7 @@
}
@Override
- public void onPinnedActivityRestartAttempt(ComponentName sourceComponent) {
+ public void onPinnedActivityRestartAttempt(String launchedFromPackage) {
if (!checkCurrentUserId(false /* debug */)) {
return;
}
@@ -84,11 +84,11 @@
// Expand the activity back to fullscreen only if it was attempted to be restarted from
// another package than the top activity in the stack
boolean expandPipToFullscreen = true;
- if (sourceComponent != null) {
+ if (launchedFromPackage != null) {
ComponentName topActivity = PipUtils.getTopPinnedActivity(mContext,
mActivityManager);
- if (topActivity != null && topActivity.getPackageName().equals(
- sourceComponent.getPackageName())) {
+ if (topActivity != null
+ && topActivity.getPackageName().equals(launchedFromPackage)) {
expandPipToFullscreen = false;
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
index 112fedb..376a0b6 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/tv/PipManager.java
@@ -695,7 +695,7 @@
}
@Override
- public void onPinnedActivityRestartAttempt(ComponentName sourceComponent) {
+ public void onPinnedActivityRestartAttempt(String launchedFromPackage) {
if (DEBUG) Log.d(TAG, "onPinnedActivityRestartAttempt()");
if (!checkCurrentUserId(DEBUG)) {
return;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
index eae1b81..cda902b 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/misc/SystemServicesProxy.java
@@ -153,7 +153,7 @@
public void onTaskStackChanged() { }
public void onTaskSnapshotChanged(int taskId, TaskSnapshot snapshot) { }
public void onActivityPinned() { }
- public void onPinnedActivityRestartAttempt(ComponentName sourceComponent) { }
+ public void onPinnedActivityRestartAttempt(String launchedFromPackage) { }
public void onPinnedStackAnimationEnded() { }
public void onActivityForcedResizable(String packageName, int taskId) { }
public void onActivityDismissingDockedStack() { }
@@ -198,10 +198,10 @@
}
@Override
- public void onPinnedActivityRestartAttempt(ComponentName sourceComponent)
+ public void onPinnedActivityRestartAttempt(String launchedFromPackage)
throws RemoteException{
mHandler.removeMessages(H.ON_PINNED_ACTIVITY_RESTART_ATTEMPT);
- mHandler.obtainMessage(H.ON_PINNED_ACTIVITY_RESTART_ATTEMPT, sourceComponent)
+ mHandler.obtainMessage(H.ON_PINNED_ACTIVITY_RESTART_ATTEMPT, launchedFromPackage)
.sendToTarget();
}
@@ -1244,8 +1244,7 @@
}
case ON_PINNED_ACTIVITY_RESTART_ATTEMPT: {
for (int i = mTaskStackListeners.size() - 1; i >= 0; i--) {
- mTaskStackListeners.get(i).onPinnedActivityRestartAttempt(
- (ComponentName) msg.obj);
+ mTaskStackListeners.get(i).onPinnedActivityRestartAttempt((String) msg.obj);
}
break;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
index 93f874d..aebc2c9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarPolicy.java
@@ -17,30 +17,57 @@
package com.android.systemui.statusbar.phone;
import android.app.ActivityManager;
+import android.app.ActivityManager.RunningAppProcessInfo;
+import android.app.ActivityManager.StackId;
+import android.app.ActivityManager.StackInfo;
import android.app.AlarmManager;
import android.app.AlarmManager.AlarmClockInfo;
+import android.app.AppGlobals;
+import android.app.Notification;
+import android.app.Notification.Action;
+import android.app.Notification.BigTextStyle;
+import android.app.Notification.Style;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
import android.app.SynchronousUserSwitchObserver;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.UserInfo;
+import android.graphics.drawable.Icon;
import android.media.AudioManager;
+import android.net.Uri;
+import android.os.Bundle;
import android.os.Handler;
import android.os.RemoteException;
import android.os.UserHandle;
import android.os.UserManager;
+import android.provider.Settings;
import android.provider.Settings.Global;
+import android.service.notification.StatusBarNotification;
import android.telecom.TelecomManager;
+import android.util.ArrayMap;
+import android.util.ArraySet;
import android.util.Log;
+import android.util.Pair;
+import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.internal.telephony.IccCardConstants;
import com.android.internal.telephony.TelephonyIntents;
import com.android.systemui.Dependency;
import com.android.systemui.R;
+import com.android.systemui.R.string;
import com.android.systemui.SysUiServiceProvider;
import com.android.systemui.qs.tiles.DndTile;
import com.android.systemui.qs.tiles.RotationLockTile;
+import com.android.systemui.recents.Recents;
+import com.android.systemui.recents.misc.SystemServicesProxy;
+import com.android.systemui.recents.misc.SystemServicesProxy.TaskStackListener;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.CommandQueue.Callbacks;
import com.android.systemui.statusbar.policy.BluetoothController;
@@ -58,6 +85,10 @@
import com.android.systemui.statusbar.policy.RotationLockController.RotationLockControllerCallback;
import com.android.systemui.statusbar.policy.UserInfoController;
import com.android.systemui.statusbar.policy.ZenModeController;
+import com.android.systemui.util.NotificationChannels;
+
+import java.util.ArrayList;
+import java.util.List;
/**
* This class contains all of the policy about which icons are installed in the status
@@ -96,6 +127,7 @@
private final ZenModeController mZenController;
private final DeviceProvisionedController mProvisionedController;
private final KeyguardMonitor mKeyguardMonitor;
+ private final ArraySet<Pair<String, Integer>> mCurrentNotifs = new ArraySet<>();
// Assume it's all good unless we hear otherwise. We don't always seem
// to get broadcasts that it *is* there.
@@ -163,7 +195,7 @@
}
// TTY status
- mIconController.setIcon(mSlotTty, R.drawable.stat_sys_tty_mode, null);
+ mIconController.setIcon(mSlotTty, R.drawable.stat_sys_tty_mode, null);
mIconController.setIconVisibility(mSlotTty, false);
// bluetooth status
@@ -212,6 +244,15 @@
mKeyguardMonitor.addCallback(this);
SysUiServiceProvider.getComponent(mContext, CommandQueue.class).addCallbacks(this);
+ SystemServicesProxy.getInstance(mContext).registerTaskStackListener(mTaskListener);
+
+ // Clear out all old notifications on startup (only present in the case where sysui dies)
+ NotificationManager noMan = mContext.getSystemService(NotificationManager.class);
+ for (StatusBarNotification notification : noMan.getActiveNotifications()) {
+ if (notification.getId() == SystemMessage.NOTE_INSTANT_APPS) {
+ noMan.cancel(notification.getTag(), notification.getId());
+ }
+ }
}
public void destroy() {
@@ -226,6 +267,10 @@
mKeyguardMonitor.removeCallback(this);
SysUiServiceProvider.getComponent(mContext, CommandQueue.class).removeCallbacks(this);
mContext.unregisterReceiver(mIntentReceiver);
+
+ NotificationManager noMan = mContext.getSystemService(NotificationManager.class);
+ mCurrentNotifs.forEach(v -> noMan.cancelAsUser(v.first, SystemMessage.NOTE_INSTANT_APPS,
+ new UserHandle(v.second)));
}
@Override
@@ -423,8 +468,10 @@
}
private void updateManagedProfile() {
- if (DEBUG) Log.v(TAG, "updateManagedProfile: mManagedProfileFocused: "
- + mManagedProfileFocused);
+ if (DEBUG) {
+ Log.v(TAG, "updateManagedProfile: mManagedProfileFocused: "
+ + mManagedProfileFocused);
+ }
final boolean showIcon;
if (mManagedProfileFocused && !mKeyguardMonitor.isShowing()) {
showIcon = true;
@@ -445,6 +492,76 @@
}
}
+ private void updateForegroundInstantApps() {
+ NotificationManager noMan = mContext.getSystemService(NotificationManager.class);
+ ArraySet<Pair<String, Integer>> notifs = new ArraySet<>(mCurrentNotifs);
+ IPackageManager pm = AppGlobals.getPackageManager();
+ mCurrentNotifs.clear();
+ try {
+ int[] STACKS_TO_CHECK = new int[]{
+ StackId.FULLSCREEN_WORKSPACE_STACK_ID,
+ StackId.DOCKED_STACK_ID,
+ };
+ for (int i = 0; i < STACKS_TO_CHECK.length; i++) {
+ StackInfo info = ActivityManager.getService().getStackInfo(STACKS_TO_CHECK[i]);
+ if (info == null || info.topActivity == null) continue;
+ String pkg = info.topActivity.getPackageName();
+ if (!hasNotif(notifs, pkg, info.userId)) {
+ // TODO: Optimize by not always needing to get application info.
+ // Maybe cache non-ephemeral packages?
+ ApplicationInfo appInfo = pm.getApplicationInfo(pkg, 0, info.userId);
+ if (appInfo.isInstantApp()) {
+ postEphemeralNotif(pkg, info.userId, appInfo, noMan);
+ }
+ }
+ }
+ } catch (RemoteException e) {
+ e.rethrowFromSystemServer();
+ }
+ // Cancel all the leftover notifications that don't have a foreground process anymore.
+ notifs.forEach(v -> noMan.cancelAsUser(v.first, SystemMessage.NOTE_INSTANT_APPS,
+ new UserHandle(v.second)));
+ }
+
+ private void postEphemeralNotif(String pkg, int userId, ApplicationInfo appInfo,
+ NotificationManager noMan) {
+ final Bundle extras = new Bundle();
+ extras.putString(Notification.EXTRA_SUBSTITUTE_APP_NAME,
+ mContext.getString(R.string.instant_apps));
+ mCurrentNotifs.add(new Pair<>(pkg, userId));
+ String message = mContext.getString(R.string.instant_apps_message);
+ PendingIntent appInfoAction = PendingIntent.getActivity(mContext, 0,
+ new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
+ .setData(Uri.fromParts("package", pkg, null)), 0);
+ // TODO: Add action for go to web as well.
+ Action action = new Notification.Action.Builder(null, mContext.getString(R.string.app_info),
+ appInfoAction).build();
+
+ noMan.notifyAsUser(pkg, SystemMessage.NOTE_INSTANT_APPS,
+ new Notification.Builder(mContext, NotificationChannels.GENERAL)
+ .addExtras(extras)
+ .addAction(action)
+ .setContentIntent(appInfoAction)
+ .setColor(mContext.getColor(R.color.instant_apps_color))
+ .setContentTitle(appInfo.loadLabel(mContext.getPackageManager()))
+ .setLargeIcon(Icon.createWithResource(pkg, appInfo.icon))
+ .setSmallIcon(Icon.createWithResource(mContext.getPackageName(),
+ R.drawable.instant_icon))
+ .setContentText(message)
+ .setOngoing(true)
+ .build(),
+ new UserHandle(userId));
+ }
+
+ private boolean hasNotif(ArraySet<Pair<String, Integer>> notifs, String pkg, int userId) {
+ Pair<String, Integer> key = new Pair<>(pkg, userId);
+ if (notifs.remove(key)) {
+ mCurrentNotifs.add(key);
+ return true;
+ }
+ return false;
+ }
+
private final SynchronousUserSwitchObserver mUserSwitchListener =
new SynchronousUserSwitchObserver() {
@Override
@@ -466,6 +583,7 @@
profileChanged(newUserId);
updateQuietState();
updateManagedProfile();
+ updateForegroundInstantApps();
}
});
}
@@ -497,20 +615,22 @@
private final NextAlarmController.NextAlarmChangeCallback mNextAlarmCallback =
new NextAlarmController.NextAlarmChangeCallback() {
- @Override
- public void onNextAlarmChanged(AlarmManager.AlarmClockInfo nextAlarm) {
- updateAlarm();
- }
- };
+ @Override
+ public void onNextAlarmChanged(AlarmManager.AlarmClockInfo nextAlarm) {
+ updateAlarm();
+ }
+ };
@Override
public void appTransitionStarting(long startTime, long duration, boolean forced) {
updateManagedProfile();
+ updateForegroundInstantApps();
}
@Override
public void onKeyguardShowingChanged() {
updateManagedProfile();
+ updateForegroundInstantApps();
}
@Override
@@ -524,6 +644,11 @@
}
@Override
+ public void preloadRecentApps() {
+ updateForegroundInstantApps();
+ }
+
+ @Override
public void onRotationLockStateChanged(boolean rotationLocked, boolean affordanceVisible) {
boolean portrait = RotationLockTile.isCurrentOrientationLockPortrait(
mRotationLockController, mContext);
@@ -561,6 +686,14 @@
mIconController.setIconVisibility(mSlotDataSaver, isDataSaving);
}
+ private final TaskStackListener mTaskListener = new TaskStackListener() {
+ @Override
+ public void onTaskStackChanged() {
+ // Listen for changes to stacks and then check which instant apps are foreground.
+ updateForegroundInstantApps();
+ }
+ };
+
private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index 8d2f0c3..c822652 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -3429,6 +3429,26 @@
// VALUE: true if the connection was successful, false if the connection failed
WIFI_NETWORK_RECOMMENDATION_CONNECTION_SUCCESS = 837;
+ // OPEN: Settings > Storage > Games
+ // CATEGORY: SETTINGS
+ // OS: O
+ APPLICATIONS_STORAGE_GAMES = 838;
+
+ // OPEN: Settings > Storage > Audio and Music
+ // CATEGORY: SETTINGS
+ // OS: O
+ APPLICATIONS_STORAGE_MUSIC = 839;
+
+ // ACTION: Settings > Storage > Free Up Space to launch Deletion Helper
+ // CATEGORY: SETTINGS
+ // OS: O
+ STORAGE_FREE_UP_SPACE_NOW = 840;
+
+ // ACTION: Settings > Storage > Files to open the File Manager
+ // CATEGORY: SETTINGS
+ // OS: O
+ STORAGE_FILES = 841;
+
// ---- End O Constants, all O constants go above this line ----
// Add new aosp constants above this line.
diff --git a/proto/src/system_messages.proto b/proto/src/system_messages.proto
index 5b91776..74f5cf5 100644
--- a/proto/src/system_messages.proto
+++ b/proto/src/system_messages.proto
@@ -52,6 +52,10 @@
// Package: com.android.systemui
NOTE_PLUGIN = 6;
+ // Notify the user that instant app is running.
+ // Package: com.android.systemui
+ NOTE_INSTANT_APPS = 7;
+
// Confirm that the user wants to remove the guest account.
// Package: com.android.systemui
NOTE_REMOVE_GUEST = 1010;
diff --git a/services/core/java/com/android/server/IntentResolver.java b/services/core/java/com/android/server/IntentResolver.java
index 14abb53..40499c9 100644
--- a/services/core/java/com/android/server/IntentResolver.java
+++ b/services/core/java/com/android/server/IntentResolver.java
@@ -351,7 +351,7 @@
}
public List<R> queryIntentFromList(Intent intent, String resolvedType, boolean defaultOnly,
- boolean visibleToEphemeral, boolean isEphemeral, ArrayList<F[]> listCut, int userId) {
+ ArrayList<F[]> listCut, int userId) {
ArrayList<R> resultList = new ArrayList<R>();
final boolean debug = localLOGV ||
@@ -361,8 +361,8 @@
final String scheme = intent.getScheme();
int N = listCut.size();
for (int i = 0; i < N; ++i) {
- buildResolveList(intent, categories, debug, defaultOnly, visibleToEphemeral,
- isEphemeral, resolvedType, scheme, listCut.get(i), resultList, userId);
+ buildResolveList(intent, categories, debug, defaultOnly, resolvedType, scheme,
+ listCut.get(i), resultList, userId);
}
filterResults(resultList);
sortResults(resultList);
@@ -370,7 +370,7 @@
}
public List<R> queryIntent(Intent intent, String resolvedType, boolean defaultOnly,
- boolean visibleToEphemeral, boolean isEphemeral, int userId) {
+ int userId) {
String scheme = intent.getScheme();
ArrayList<R> finalList = new ArrayList<R>();
@@ -443,20 +443,20 @@
FastImmutableArraySet<String> categories = getFastIntentCategories(intent);
if (firstTypeCut != null) {
- buildResolveList(intent, categories, debug, defaultOnly, visibleToEphemeral,
- isEphemeral, resolvedType, scheme, firstTypeCut, finalList, userId);
+ buildResolveList(intent, categories, debug, defaultOnly, resolvedType,
+ scheme, firstTypeCut, finalList, userId);
}
if (secondTypeCut != null) {
- buildResolveList(intent, categories, debug, defaultOnly, visibleToEphemeral,
- isEphemeral, resolvedType, scheme, secondTypeCut, finalList, userId);
+ buildResolveList(intent, categories, debug, defaultOnly, resolvedType,
+ scheme, secondTypeCut, finalList, userId);
}
if (thirdTypeCut != null) {
- buildResolveList(intent, categories, debug, defaultOnly, visibleToEphemeral,
- isEphemeral, resolvedType, scheme, thirdTypeCut, finalList, userId);
+ buildResolveList(intent, categories, debug, defaultOnly, resolvedType,
+ scheme, thirdTypeCut, finalList, userId);
}
if (schemeCut != null) {
- buildResolveList(intent, categories, debug, defaultOnly, visibleToEphemeral,
- isEphemeral, resolvedType, scheme, schemeCut, finalList, userId);
+ buildResolveList(intent, categories, debug, defaultOnly, resolvedType,
+ scheme, schemeCut, finalList, userId);
}
filterResults(finalList);
sortResults(finalList);
@@ -694,8 +694,8 @@
}
private void buildResolveList(Intent intent, FastImmutableArraySet<String> categories,
- boolean debug, boolean defaultOnly, boolean visibleToEphemeral, boolean isEphemeral,
- String resolvedType, String scheme, F[] src, List<R> dest, int userId) {
+ boolean debug, boolean defaultOnly, String resolvedType, String scheme,
+ F[] src, List<R> dest, int userId) {
final String action = intent.getAction();
final Uri data = intent.getData();
final String packageName = intent.getPackage();
@@ -735,15 +735,6 @@
continue;
}
- // throw out filters that aren't visible to ephemeral apps
- if (visibleToEphemeral && !filter.isVisibleToEphemeral()) {
- continue;
- }
- // throw out ephemeral filters if we're not explicitly requesting them
- if (!isEphemeral && filter.isEphemeral()) {
- continue;
- }
-
// Are we verified ?
if (filter.getAutoVerify()) {
if (localVerificationLOGV || debug) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 35c2462..aaed0e9 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -231,6 +231,7 @@
import android.content.pm.PermissionInfo;
import android.content.pm.ProviderInfo;
import android.content.pm.ResolveInfo;
+import android.content.pm.SELinuxUtil;
import android.content.pm.ServiceInfo;
import android.content.pm.UserInfo;
import android.content.res.CompatibilityInfo;
@@ -294,6 +295,7 @@
import android.service.voice.VoiceInteractionManagerInternal;
import android.service.voice.VoiceInteractionSession;
import android.telecom.TelecomManager;
+import android.text.TextUtils;
import android.text.format.DateUtils;
import android.text.format.Time;
import android.text.style.SuggestionSpan;
@@ -3506,6 +3508,7 @@
info.processName = processName;
info.className = entryPoint;
info.packageName = "android";
+ info.seInfoUser = SELinuxUtil.COMPLETE_STR;
ProcessRecord proc = startProcessLocked(processName, info /* info */,
false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */,
null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
@@ -3777,6 +3780,13 @@
app.requiredAbi = requiredAbi;
app.instructionSet = instructionSet;
+ // the per-user SELinux context must be set
+ if (TextUtils.isEmpty(app.info.seInfoUser)) {
+ Slog.wtf(TAG, "SELinux tag not defined",
+ new IllegalStateException("SELinux tag not defined"));
+ }
+ final String seInfo = app.info.seInfo
+ + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser);
// Start the process. It will either succeed and return a result containing
// the PID of the new process, or else throw a RuntimeException.
boolean isActivityProcess = (entryPoint == null);
@@ -3788,12 +3798,12 @@
if (hostingType.equals("webview_service")) {
startResult = Process.startWebView(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
- app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
+ app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, null, entryPointArgs);
} else {
startResult = Process.start(entryPoint,
app.processName, uid, uid, gids, debugFlags, mountExternal,
- app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
+ app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet,
app.info.dataDir, invokeWith, entryPointArgs);
}
checkTime(startTime, "startProcess: returned from zygote!");
@@ -3809,7 +3819,7 @@
try {
AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
- app.info.seinfo, app.info.sourceDir, startResult.pid);
+ seInfo, app.info.sourceDir, startResult.pid);
} catch (RemoteException ex) {
// Ignore
}
@@ -18777,8 +18787,7 @@
}
List<BroadcastFilter> registeredReceiversForUser =
mReceiverResolver.queryIntent(intent,
- resolvedType, false, false /*visibleToEphemeral*/,
- false /*isInstant*/, users[i]);
+ resolvedType, false /*defaultOnly*/, users[i]);
if (registeredReceivers == null) {
registeredReceivers = registeredReceiversForUser;
} else if (registeredReceiversForUser != null) {
@@ -18787,8 +18796,7 @@
}
} else {
registeredReceivers = mReceiverResolver.queryIntent(intent,
- resolvedType, false, false /*visibleToEphemeral*/,
- false /*isInstant*/, userId);
+ resolvedType, false /*defaultOnly*/, userId);
}
}
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 4b1dcca..3c109ac 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -1200,7 +1200,7 @@
ResolveInfo resolveIntent(Intent intent, String resolvedType, int userId, int flags) {
try {
return AppGlobals.getPackageManager().resolveIntent(intent, resolvedType,
- PackageManager.MATCH_DEFAULT_ONLY | flags
+ PackageManager.MATCH_INSTANT | PackageManager.MATCH_DEFAULT_ONLY | flags
| ActivityManagerService.STOCK_PM_FLAGS, userId);
} catch (RemoteException e) {
}
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 4b07af0..7605a1e 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -585,10 +585,8 @@
// The activity was already running in the pinned stack so it wasn't started, but either
// brought to the front or the new intent was delivered to it since it was already in
// front. Notify anyone interested in this piece of information.
- final ComponentName sourceComponent = sourceRecord == null ? null :
- sourceRecord.realActivity;
mService.mTaskChangeNotificationController.notifyPinnedActivityRestartAttempt(
- sourceComponent);
+ sourceRecord.launchedFromPackage);
return;
}
}
diff --git a/services/core/java/com/android/server/am/TaskChangeNotificationController.java b/services/core/java/com/android/server/am/TaskChangeNotificationController.java
index 2990dff..9dfc7cd 100644
--- a/services/core/java/com/android/server/am/TaskChangeNotificationController.java
+++ b/services/core/java/com/android/server/am/TaskChangeNotificationController.java
@@ -97,7 +97,7 @@
};
private final TaskStackConsumer mNotifyPinnedActivityRestartAttempt = (l, m) -> {
- l.onPinnedActivityRestartAttempt((ComponentName) m.obj);
+ l.onPinnedActivityRestartAttempt((String) m.obj);
};
private final TaskStackConsumer mNotifyPinnedStackAnimationEnded = (l, m) -> {
@@ -267,11 +267,11 @@
* running in the pinned stack and the activity was not actually started, but the task is
* either brought to the front or a new Intent is delivered to it.
*/
- void notifyPinnedActivityRestartAttempt(ComponentName sourceComponent) {
+ void notifyPinnedActivityRestartAttempt(String launchedFromPackage) {
mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
final Message msg =
mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG,
- sourceComponent);
+ launchedFromPackage);
forAllLocalListeners(mNotifyPinnedActivityRestartAttempt, msg);
msg.sendToTarget();
}
diff --git a/services/core/java/com/android/server/firewall/IntentFirewall.java b/services/core/java/com/android/server/firewall/IntentFirewall.java
index 93c14b9..376a864 100644
--- a/services/core/java/com/android/server/firewall/IntentFirewall.java
+++ b/services/core/java/com/android/server/firewall/IntentFirewall.java
@@ -151,8 +151,7 @@
// For the first pass, find all the rules that have at least one intent-filter or
// component-filter that matches this intent
List<Rule> candidateRules;
- candidateRules = resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/,
- false /*visibleToEphemeral*/, false /*isInstant*/, 0);
+ candidateRules = resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, 0);
if (candidateRules == null) {
candidateRules = new ArrayList<Rule>();
}
diff --git a/services/core/java/com/android/server/pm/EphemeralResolver.java b/services/core/java/com/android/server/pm/EphemeralResolver.java
index 3c55422..d99a1b6 100644
--- a/services/core/java/com/android/server/pm/EphemeralResolver.java
+++ b/services/core/java/com/android/server/pm/EphemeralResolver.java
@@ -234,8 +234,7 @@
}
}
List<EphemeralResponse> matchedResolveInfoList = ephemeralResolver.queryIntent(
- intent, resolvedType, false /*defaultOnly*/, false /*visibleToEphemeral*/,
- false /*isInstant*/, userId);
+ intent, resolvedType, false /*defaultOnly*/, userId);
if (!matchedResolveInfoList.isEmpty()) {
return matchedResolveInfoList.get(0);
}
diff --git a/services/core/java/com/android/server/pm/InstantAppRegistry.java b/services/core/java/com/android/server/pm/InstantAppRegistry.java
index 42934a4..23925ad 100644
--- a/services/core/java/com/android/server/pm/InstantAppRegistry.java
+++ b/services/core/java/com/android/server/pm/InstantAppRegistry.java
@@ -217,7 +217,7 @@
propagateInstantAppPermissionsIfNeeded(pkg.packageName, userId);
// Track instant apps
- if (pkg.applicationInfo.isInstantApp()) {
+ if (ps.getInstantApp(userId)) {
addInstantAppLPw(userId, ps.appId);
}
@@ -257,7 +257,7 @@
continue;
}
- if (pkg.applicationInfo.isInstantApp()) {
+ if (ps.getInstantApp(userId)) {
// Add a record for an uninstalled instant app
addUninstalledInstantAppLPw(pkg, userId);
removeInstantAppLPw(userId, ps.appId);
@@ -533,11 +533,12 @@
final int packageCount = mService.mPackages.size();
for (int i = 0; i < packageCount; i++) {
- PackageParser.Package pkg = mService.mPackages.valueAt(i);
- if (!pkg.applicationInfo.isInstantApp()) {
+ final PackageParser.Package pkg = mService.mPackages.valueAt(i);
+ final PackageSetting ps = (PackageSetting) pkg.mExtras;
+ if (ps == null || !ps.getInstantApp(userId)) {
continue;
}
- InstantAppInfo info = createInstantAppInfoForPackage(
+ final InstantAppInfo info = createInstantAppInfoForPackage(
pkg, userId, true);
if (info == null) {
continue;
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 8b4ef56..53765f2 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -683,9 +683,9 @@
File stageDir = null;
String stageCid = null;
if ((params.installFlags & PackageManager.INSTALL_INTERNAL) != 0) {
- final boolean isEphemeral =
- (params.installFlags & PackageManager.INSTALL_EPHEMERAL) != 0;
- stageDir = buildStageDir(params.volumeUuid, sessionId, isEphemeral);
+ final boolean isInstant =
+ (params.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
+ stageDir = buildStageDir(params.volumeUuid, sessionId, isInstant);
} else {
stageCid = buildExternalStageCid(sessionId);
}
@@ -787,9 +787,6 @@
}
private File buildStagingDir(String volumeUuid, boolean isEphemeral) {
- if (isEphemeral) {
- return Environment.getDataAppEphemeralDirectory(volumeUuid);
- }
return Environment.getDataAppDirectory(volumeUuid);
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 067a136..463cfac 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -704,7 +704,7 @@
final ApkLite apk;
try {
int flags = PackageParser.PARSE_COLLECT_CERTIFICATES;
- if ((params.installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) {
+ if ((params.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
flags |= PackageParser.PARSE_IS_EPHEMERAL;
}
apk = PackageParser.parseApkLite(addedFile, flags);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index f43e468..4b294b9 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -41,7 +41,7 @@
import static android.content.pm.PackageManager.INSTALL_FAILED_CONFLICTING_PROVIDER;
import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE;
import static android.content.pm.PackageManager.INSTALL_FAILED_DUPLICATE_PERMISSION;
-import static android.content.pm.PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID;
+import static android.content.pm.PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID;
import static android.content.pm.PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
@@ -164,6 +164,7 @@
import android.content.pm.PermissionInfo;
import android.content.pm.ProviderInfo;
import android.content.pm.ResolveInfo;
+import android.content.pm.SELinuxUtil;
import android.content.pm.ServiceInfo;
import android.content.pm.SharedLibraryInfo;
import android.content.pm.Signature;
@@ -257,6 +258,7 @@
import com.android.internal.util.XmlUtils;
import com.android.server.AttributeCache;
import com.android.server.BackgroundDexOptJobService;
+import com.android.server.DeviceIdleController;
import com.android.server.EventLogTags;
import com.android.server.FgThread;
import com.android.server.IntentResolver;
@@ -421,8 +423,11 @@
static final int SCAN_CHECK_ONLY = 1<<13;
static final int SCAN_DONT_KILL_APP = 1<<14;
static final int SCAN_IGNORE_FROZEN = 1<<15;
- static final int REMOVE_CHATTY = 1<<16;
- static final int SCAN_FIRST_BOOT_OR_UPGRADE = 1<<17;
+ static final int SCAN_FIRST_BOOT_OR_UPGRADE = 1<<16;
+ static final int SCAN_AS_INSTANT_APP = 1<<17;
+ static final int SCAN_AS_FULL_APP = 1<<18;
+ /** Should not be with the scan flags */
+ static final int FLAGS_REMOVE_CHATTY = 1<<31;
private static final String STATIC_SHARED_LIB_DELIMITER = "_";
@@ -623,7 +628,6 @@
/** Directory where installed third-party apps stored */
final File mAppInstallDir;
- final File mEphemeralInstallDir;
/**
* Directory to which applications installed internally have their
@@ -847,6 +851,8 @@
private UserManagerInternal mUserManagerInternal;
+ private DeviceIdleController.LocalService mDeviceIdleController;
+
private File mCacheDir;
private ArraySet<String> mPrivappPermissionsViolations;
@@ -1776,28 +1782,32 @@
// the first time vs. those who are seeing an update.
int[] firstUsers = EMPTY_INT_ARRAY;
int[] updateUsers = EMPTY_INT_ARRAY;
- if (res.origUsers == null || res.origUsers.length == 0) {
- firstUsers = res.newUsers;
- } else {
- for (int newUser : res.newUsers) {
- boolean isNew = true;
- for (int origUser : res.origUsers) {
- if (origUser == newUser) {
- isNew = false;
- break;
- }
+ final boolean allNewUsers = res.origUsers == null || res.origUsers.length == 0;
+ final PackageSetting ps = (PackageSetting) res.pkg.mExtras;
+ for (int newUser : res.newUsers) {
+ if (ps.getInstantApp(newUser)) {
+ continue;
+ }
+ if (allNewUsers) {
+ firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
+ continue;
+ }
+ boolean isNew = true;
+ for (int origUser : res.origUsers) {
+ if (origUser == newUser) {
+ isNew = false;
+ break;
}
- if (isNew) {
- firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
- } else {
- updateUsers = ArrayUtils.appendInt(updateUsers, newUser);
- }
+ }
+ if (isNew) {
+ firstUsers = ArrayUtils.appendInt(firstUsers, newUser);
+ } else {
+ updateUsers = ArrayUtils.appendInt(updateUsers, newUser);
}
}
- // Send installed broadcasts if the install/update is not ephemeral
- // and the package is not a static shared lib.
- if (!isEphemeral(res.pkg) && res.pkg.staticSharedLibName == null) {
+ // Send installed broadcasts if the package is not a static shared lib.
+ if (res.pkg.staticSharedLibName == null) {
mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath);
// Send added for users that see the package for the first time
@@ -1884,16 +1894,14 @@
}
}
- if (!isEphemeral(res.pkg)) {
- // Notify DexManager that the package was installed for new users.
- // The updated users should already be indexed and the package code paths
- // should not change.
- // Don't notify the manager for ephemeral apps as they are not expected to
- // survive long enough to benefit of background optimizations.
- for (int userId : firstUsers) {
- PackageInfo info = getPackageInfo(packageName, /*flags*/ 0, userId);
- mDexManager.notifyPackageInstalled(info, userId);
- }
+ // Notify DexManager that the package was installed for new users.
+ // The updated users should already be indexed and the package code paths
+ // should not change.
+ // Don't notify the manager for ephemeral apps as they are not expected to
+ // survive long enough to benefit of background optimizations.
+ for (int userId : firstUsers) {
+ PackageInfo info = getPackageInfo(packageName, /*flags*/ 0, userId);
+ mDexManager.notifyPackageInstalled(info, userId);
}
}
@@ -2282,7 +2290,6 @@
File dataDir = Environment.getDataDirectory();
mAppInstallDir = new File(dataDir, "app");
mAppLib32InstallDir = new File(dataDir, "app-lib");
- mEphemeralInstallDir = new File(dataDir, "app-ephemeral");
mAsecInternalPath = new File(dataDir, "app-asec").getPath();
mDrmAppPrivateInstallDir = new File(dataDir, "app-private");
sUserManager = new UserManagerService(context, this,
@@ -2586,10 +2593,6 @@
| PackageParser.PARSE_FORWARD_LOCK,
scanFlags | SCAN_REQUIRE_KNOWN, 0);
- scanDirLI(mEphemeralInstallDir, mDefParseFlags
- | PackageParser.PARSE_IS_EPHEMERAL,
- scanFlags | SCAN_REQUIRE_KNOWN, 0);
-
/**
* Remove disable package settings for any updated system
* apps that were removed via an OTA. If they're not a
@@ -3332,14 +3335,14 @@
&& callingAppId != Process.ROOT_UID
&& checkUidPermission(Manifest.permission.ACCESS_INSTANT_APPS,
Binder.getCallingUid()) != PackageManager.PERMISSION_GRANTED) {
- final String ephemeralPackageName = getEphemeralPackageName(Binder.getCallingUid());
- if (ephemeralPackageName != null) {
+ final String instantAppPackageName = getInstantAppPackageName(Binder.getCallingUid());
+ if (instantAppPackageName != null) {
// ephemeral apps can only get information on themselves
- if (!ephemeralPackageName.equals(p.packageName)) {
+ if (!instantAppPackageName.equals(p.packageName)) {
return null;
}
} else {
- if (p.applicationInfo.isInstantApp()) {
+ if (ps.getInstantApp(userId)) {
// only get access to the ephemeral app if we've been granted access
if (!mInstantAppRegistry.isInstantAccessGranted(
userId, callingAppId, ps.appId)) {
@@ -3855,6 +3858,14 @@
return mUserManagerInternal;
}
+ private DeviceIdleController.LocalService getDeviceIdleController() {
+ if (mDeviceIdleController == null) {
+ mDeviceIdleController =
+ LocalServices.getService(DeviceIdleController.LocalService.class);
+ }
+ return mDeviceIdleController;
+ }
+
/**
* Update given flags when being used to request {@link PackageInfo}.
*/
@@ -3950,17 +3961,17 @@
flags |= PackageManager.MATCH_SYSTEM_ONLY;
}
final int callingUid = Binder.getCallingUid();
- if (callingUid == Process.SYSTEM_UID || callingUid == 0) {
- // The system sees all components
- flags |= PackageManager.MATCH_EPHEMERAL;
- } else if (getEphemeralPackageName(callingUid) != null) {
+ if (getInstantAppPackageName(callingUid) != null) {
// But, ephemeral apps see both ephemeral and exposed, non-ephemeral components
- flags |= PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY;
- flags |= PackageManager.MATCH_EPHEMERAL;
+ flags |= PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY;
+ flags |= PackageManager.MATCH_INSTANT;
} else {
// Otherwise, prevent leaking ephemeral components
- flags &= ~PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY;
- flags &= ~PackageManager.MATCH_EPHEMERAL;
+ flags &= ~PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY;
+ if (callingUid != Process.SYSTEM_UID && callingUid != 0) {
+ // Unless called from the system process
+ flags &= ~PackageManager.MATCH_INSTANT;
+ }
}
return updateFlagsForComponent(flags, userId, cookie);
}
@@ -4689,7 +4700,8 @@
return;
}
- if (pkg.applicationInfo.isInstantApp() && !bp.isInstant()) {
+ final PackageSetting ps = mSettings.mPackages.get(packageName);
+ if (ps.getInstantApp(userId) && !bp.isInstant()) {
throw new SecurityException("Cannot grant non-ephemeral permission"
+ name + " for package " + packageName);
}
@@ -5738,8 +5750,7 @@
List<PersistentPreferredActivity> pprefs = ppir != null
? ppir.queryIntent(intent, resolvedType,
(flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
- (flags & PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY) != 0,
- (flags & PackageManager.MATCH_EPHEMERAL) != 0, userId)
+ userId)
: null;
if (pprefs != null && pprefs.size() > 0) {
final int M = pprefs.size();
@@ -5811,8 +5822,7 @@
List<PreferredActivity> prefs = pir != null
? pir.queryIntent(intent, resolvedType,
(flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
- (flags & PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY) != 0,
- (flags & PackageManager.MATCH_EPHEMERAL) != 0, userId)
+ userId)
: null;
if (prefs != null && prefs.size() > 0) {
boolean changed = false;
@@ -5983,8 +5993,7 @@
String resolvedType, int userId) {
CrossProfileIntentResolver resolver = mSettings.mCrossProfileIntentResolvers.get(userId);
if (resolver != null) {
- return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/,
- false /*visibleToEphemeral*/, false /*isInstant*/, userId);
+ return resolver.queryIntent(intent, resolvedType, false /*defaultOnly*/, userId);
}
return null;
}
@@ -6003,16 +6012,17 @@
}
/**
- * Returns the package name of the calling Uid if it's an ephemeral app. If it isn't
- * ephemeral, returns {@code null}.
+ * Returns the package name of the calling Uid if it's an instant app. If it isn't
+ * instant, returns {@code null}.
*/
- private String getEphemeralPackageName(int callingUid) {
+ private String getInstantAppPackageName(int callingUid) {
final int appId = UserHandle.getAppId(callingUid);
synchronized (mPackages) {
final Object obj = mSettings.getUserIdLPr(appId);
if (obj instanceof PackageSetting) {
final PackageSetting ps = (PackageSetting) obj;
- return ps.pkg.applicationInfo.isInstantApp() ? ps.pkg.packageName : null;
+ final boolean isInstantApp = ps.getInstantApp(UserHandle.getUserId(callingUid));
+ return isInstantApp ? ps.pkg.packageName : null;
}
}
return null;
@@ -6021,7 +6031,7 @@
private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,
String resolvedType, int flags, int userId) {
if (!sUserManager.exists(userId)) return Collections.emptyList();
- final String ephemeralPkgName = getEphemeralPackageName(Binder.getCallingUid());
+ final String instantAppPkgName = getInstantAppPackageName(Binder.getCallingUid());
flags = updateFlagsForResolve(flags, userId, intent);
enforceCrossUserPermission(Binder.getCallingUid(), userId,
false /* requireFullPermission */, false /* checkShell */,
@@ -6043,14 +6053,14 @@
// an ephemeral application or 2) the calling package is ephemeral and the
// activity is not visible to ephemeral applications.
boolean matchEphemeral =
- (flags & PackageManager.MATCH_EPHEMERAL) != 0;
+ (flags & PackageManager.MATCH_INSTANT) != 0;
boolean ephemeralVisibleOnly =
- (flags & PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY) != 0;
+ (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
boolean blockResolution =
- (!matchEphemeral && ephemeralPkgName == null
+ (!matchEphemeral && instantAppPkgName == null
&& (ai.applicationInfo.privateFlags
- & ApplicationInfo.PRIVATE_FLAG_EPHEMERAL) != 0)
- || (ephemeralVisibleOnly && ephemeralPkgName != null
+ & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0)
+ || (ephemeralVisibleOnly && instantAppPkgName != null
&& (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_EPHEMERAL) == 0);
if (!blockResolution) {
final ResolveInfo ri = new ResolveInfo();
@@ -6077,7 +6087,7 @@
List<ResolveInfo> xpResult = new ArrayList<ResolveInfo>(1);
xpResult.add(xpResolveInfo);
return filterForEphemeral(
- filterIfNotSystemUser(xpResult, userId), ephemeralPkgName);
+ filterIfNotSystemUser(xpResult, userId), instantAppPkgName);
}
// Check for results in the current profile.
@@ -6117,13 +6127,13 @@
// And we are not going to add emphemeral app, so we can return the
// result straight away.
result.add(xpDomainInfo.resolveInfo);
- return filterForEphemeral(result, ephemeralPkgName);
+ return filterForEphemeral(result, instantAppPkgName);
}
} else if (result.size() <= 1 && !addEphemeral) {
// No result in parent user and <= 1 result in current profile, and we
// are not going to add emphemeral app, so we can return the result without
// further processing.
- return filterForEphemeral(result, ephemeralPkgName);
+ return filterForEphemeral(result, instantAppPkgName);
}
// We have more than one candidate (combining results from current and parent
// profile), so we need filtering and sorting.
@@ -6137,7 +6147,7 @@
result = filterForEphemeral(filterIfNotSystemUser(
mActivities.queryIntentForPackage(
intent, resolvedType, flags, pkg.activities, userId),
- userId), ephemeralPkgName);
+ userId), instantAppPkgName);
} else {
// the caller wants to resolve for a particular package; however, there
// were no installed results, so, try to find an ephemeral result
@@ -6175,7 +6185,7 @@
if (sortResult) {
Collections.sort(result, mResolvePrioritySorter);
}
- return filterForEphemeral(result, ephemeralPkgName);
+ return filterForEphemeral(result, instantAppPkgName);
}
private static class CrossProfileDomainInfo {
@@ -7139,9 +7149,9 @@
return false;
}
synchronized (mPackages) {
- PackageParser.Package pkg = mPackages.get(packageName);
- if (pkg != null) {
- return pkg.applicationInfo.isInstantApp();
+ final PackageSetting ps = mSettings.mPackages.get(packageName);
+ if (ps != null) {
+ return ps.getInstantApp(userId);
}
}
return false;
@@ -7644,7 +7654,7 @@
* @throws PackageManagerException on a parse error.
*/
private PackageParser.Package scanPackageLI(PackageParser.Package pkg, File scanFile,
- final int policyFlags, int scanFlags, long currentTime, UserHandle user)
+ final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
throws PackageManagerException {
// If the package has children and this is the first dive in the function
// we scan the package with the SCAN_CHECK_ONLY flag set to see whether all
@@ -7684,7 +7694,7 @@
* @throws PackageManagerException on a parse error.
*/
private PackageParser.Package scanPackageInternalLI(PackageParser.Package pkg, File scanFile,
- int policyFlags, int scanFlags, long currentTime, UserHandle user)
+ int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
throws PackageManagerException {
PackageSetting ps = null;
PackageSetting updatedPkg;
@@ -7920,6 +7930,11 @@
pkg.setApplicationInfoBaseResourcePath(baseResourcePath);
pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
+ final int userId = ((user == null) ? 0 : user.getIdentifier());
+ if (ps != null && ps.getInstantApp(userId)) {
+ scanFlags |= SCAN_AS_INSTANT_APP;
+ }
+
// Note that we invoke the following method only if we are about to unpack an application
PackageParser.Package scannedPkg = scanPackageLI(pkg, policyFlags, scanFlags
| SCAN_UPDATE_SIGNATURE, currentTime, user);
@@ -8857,7 +8872,7 @@
}
private PackageParser.Package scanPackageTracedLI(PackageParser.Package pkg,
- final int policyFlags, int scanFlags, long currentTime, UserHandle user)
+ final int policyFlags, int scanFlags, long currentTime, @Nullable UserHandle user)
throws PackageManagerException {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
// If the package has children and this is the first dive in the function
@@ -8896,7 +8911,8 @@
}
private PackageParser.Package scanPackageLI(PackageParser.Package pkg, final int policyFlags,
- int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
+ int scanFlags, long currentTime, @Nullable UserHandle user)
+ throws PackageManagerException {
boolean success = false;
try {
final PackageParser.Package res = scanPackageDirtyLI(pkg, policyFlags, scanFlags,
@@ -8962,7 +8978,7 @@
}
private PackageParser.Package scanPackageDirtyLI(PackageParser.Package pkg,
- final int policyFlags, final int scanFlags, long currentTime, UserHandle user)
+ final int policyFlags, final int scanFlags, long currentTime, @Nullable UserHandle user)
throws PackageManagerException {
if (DEBUG_PACKAGE_SCANNING) {
if ((policyFlags & PackageParser.PARSE_CHATTY) != 0)
@@ -9100,16 +9116,16 @@
if (pkgSetting == null) {
final String parentPackageName = (pkg.parentPackage != null)
? pkg.parentPackage.packageName : null;
-
+ final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
// REMOVE SharedUserSetting from method; update in a separate call
pkgSetting = Settings.createNewSetting(pkg.packageName, origPackage,
disabledPkgSetting, realName, suid, destCodeFile, destResourceFile,
pkg.applicationInfo.nativeLibraryRootDir, pkg.applicationInfo.primaryCpuAbi,
pkg.applicationInfo.secondaryCpuAbi, pkg.mVersionCode,
pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags, user,
- true /*allowInstall*/, parentPackageName, pkg.getChildPackageNames(),
- UserManagerService.getInstance(), usesStaticLibraries,
- pkg.usesStaticLibrariesVersions);
+ true /*allowInstall*/, instantApp, parentPackageName,
+ pkg.getChildPackageNames(), UserManagerService.getInstance(),
+ usesStaticLibraries, pkg.usesStaticLibrariesVersions);
// SIDE EFFECTS; updates system state; move elsewhere
if (origPackage != null) {
mSettings.addRenamedPackageLPw(pkg.packageName, origPackage.name);
@@ -9176,9 +9192,8 @@
}
if (mFoundPolicyFile) {
- SELinuxMMAC.assignSeinfoValue(pkg);
+ SELinuxMMAC.assignSeInfoValue(pkg);
}
-
pkg.applicationInfo.uid = pkgSetting.appId;
pkg.mExtras = pkgSetting;
@@ -9413,11 +9428,11 @@
}
}
} else {
+ final int userId = user == null ? 0 : user.getIdentifier();
// Modify state for the given package setting
commitPackageSettings(pkg, pkgSetting, user, scanFlags,
(policyFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/);
- if (isEphemeral(pkg)) {
- final int userId = user == null ? 0 : user.getIdentifier();
+ if (pkgSetting.getInstantApp(userId)) {
mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId);
}
}
@@ -9532,10 +9547,10 @@
"Packages declaring static-shared libs must target O SDK or higher");
}
- // Package declaring static a shared lib cannot be ephemeral
- if (pkg.applicationInfo.isInstantApp()) {
+ // Package declaring static a shared lib cannot be instant apps
+ if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
throw new PackageManagerException(
- "Packages declaring static-shared libs cannot be ephemeral");
+ "Packages declaring static-shared libs cannot be instant apps");
}
// Package declaring static a shared lib cannot be renamed since the package
@@ -9778,7 +9793,6 @@
mPlatformPackage = pkg;
pkg.mVersionCode = mSdkVersion;
mAndroidApplication = pkg.applicationInfo;
-
if (!mResolverReplaced) {
mResolveActivity.applicationInfo = mAndroidApplication;
mResolveActivity.name = ResolverActivity.class.getName();
@@ -10067,10 +10081,10 @@
PackageParser.PermissionGroup cur = mPermissionGroups.get(pg.info.name);
final String curPackageName = cur == null ? null : cur.info.packageName;
// Dont allow ephemeral apps to define new permission groups.
- if (pkg.applicationInfo.isInstantApp()) {
+ if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
Slog.w(TAG, "Permission group " + pg.info.name + " from package "
+ pg.info.packageName
- + " ignored: ephemeral apps cannot define new permission groups.");
+ + " ignored: instant apps cannot define new permission groups.");
continue;
}
final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName);
@@ -10112,10 +10126,10 @@
PackageParser.Permission p = pkg.permissions.get(i);
// Dont allow ephemeral apps to define new permissions.
- if (pkg.applicationInfo.isInstantApp()) {
+ if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
Slog.w(TAG, "Permission " + p.info.name + " from package "
+ p.info.packageName
- + " ignored: ephemeral apps cannot define new permissions.");
+ + " ignored: instant apps cannot define new permissions.");
continue;
}
@@ -11737,13 +11751,10 @@
final class ActivityIntentResolver
extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
- boolean defaultOnly, boolean visibleToEphemeral, boolean isEphemeral, int userId) {
+ boolean defaultOnly, int userId) {
if (!sUserManager.exists(userId)) return null;
- mFlags = (defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0)
- | (visibleToEphemeral ? PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY : 0)
- | (isEphemeral ? PackageManager.MATCH_EPHEMERAL : 0);
- return super.queryIntent(intent, resolvedType, defaultOnly, visibleToEphemeral,
- isEphemeral, userId);
+ mFlags = (defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0);
+ return super.queryIntent(intent, resolvedType, defaultOnly, userId);
}
public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
@@ -11752,8 +11763,7 @@
mFlags = flags;
return super.queryIntent(intent, resolvedType,
(flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
- (flags & PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY) != 0,
- (flags & PackageManager.MATCH_EPHEMERAL) != 0, userId);
+ userId);
}
public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
@@ -11764,9 +11774,6 @@
}
mFlags = flags;
final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
- final boolean vislbleToEphemeral =
- (flags & PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY) != 0;
- final boolean isEphemeral = (flags & PackageManager.MATCH_EPHEMERAL) != 0;
final int N = packageActivities.size();
ArrayList<PackageParser.ActivityIntentInfo[]> listCut =
new ArrayList<PackageParser.ActivityIntentInfo[]>(N);
@@ -11781,8 +11788,7 @@
listCut.add(array);
}
}
- return super.queryIntentFromList(intent, resolvedType, defaultOnly,
- vislbleToEphemeral, isEphemeral, listCut, userId);
+ return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
}
/**
@@ -12194,11 +12200,24 @@
if (ps == null) {
return null;
}
+ final PackageUserState userState = ps.readUserState(userId);
ActivityInfo ai = PackageParser.generateActivityInfo(activity, mFlags,
- ps.readUserState(userId), userId);
+ userState, userId);
if (ai == null) {
return null;
}
+ final boolean matchVisibleToInstantApp =
+ (mFlags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;
+ final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
+ // throw out filters that aren't visible to ephemeral apps
+ if (matchVisibleToInstantApp
+ && !(info.isVisibleToInstantApp() || userState.instantApp)) {
+ return null;
+ }
+ // throw out ephemeral filters if we're not explicitly requesting them
+ if (!isInstantApp && userState.instantApp) {
+ return null;
+ }
final ResolveInfo res = new ResolveInfo();
res.activityInfo = ai;
if ((mFlags&PackageManager.GET_RESOLVED_FILTER) != 0) {
@@ -12267,10 +12286,9 @@
private final class ServiceIntentResolver
extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
- boolean defaultOnly, boolean visibleToEphemeral, boolean isEphemeral, int userId) {
+ boolean defaultOnly, int userId) {
mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
- return super.queryIntent(intent, resolvedType, defaultOnly, visibleToEphemeral,
- isEphemeral, userId);
+ return super.queryIntent(intent, resolvedType, defaultOnly, userId);
}
public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
@@ -12279,8 +12297,7 @@
mFlags = flags;
return super.queryIntent(intent, resolvedType,
(flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
- (flags & PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY) != 0,
- (flags & PackageManager.MATCH_EPHEMERAL) != 0, userId);
+ userId);
}
public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
@@ -12291,9 +12308,6 @@
}
mFlags = flags;
final boolean defaultOnly = (flags&PackageManager.MATCH_DEFAULT_ONLY) != 0;
- final boolean vislbleToEphemeral =
- (flags&PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY) != 0;
- final boolean isEphemeral = (flags&PackageManager.MATCH_EPHEMERAL) != 0;
final int N = packageServices.size();
ArrayList<PackageParser.ServiceIntentInfo[]> listCut =
new ArrayList<PackageParser.ServiceIntentInfo[]>(N);
@@ -12308,8 +12322,7 @@
listCut.add(array);
}
}
- return super.queryIntentFromList(intent, resolvedType, defaultOnly,
- vislbleToEphemeral, isEphemeral, listCut, userId);
+ return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
}
public final void addService(PackageParser.Service s) {
@@ -12484,10 +12497,9 @@
private final class ProviderIntentResolver
extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
- boolean defaultOnly, boolean visibleToEphemeral, boolean isEphemeral, int userId) {
+ boolean defaultOnly, int userId) {
mFlags = defaultOnly ? PackageManager.MATCH_DEFAULT_ONLY : 0;
- return super.queryIntent(intent, resolvedType, defaultOnly, visibleToEphemeral,
- isEphemeral, userId);
+ return super.queryIntent(intent, resolvedType, defaultOnly, userId);
}
public List<ResolveInfo> queryIntent(Intent intent, String resolvedType, int flags,
@@ -12497,8 +12509,7 @@
mFlags = flags;
return super.queryIntent(intent, resolvedType,
(flags & PackageManager.MATCH_DEFAULT_ONLY) != 0,
- (flags & PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY) != 0,
- (flags & PackageManager.MATCH_EPHEMERAL) != 0, userId);
+ userId);
}
public List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
@@ -12510,9 +12521,6 @@
}
mFlags = flags;
final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
- final boolean isEphemeral = (flags&PackageManager.MATCH_EPHEMERAL) != 0;
- final boolean vislbleToEphemeral =
- (flags&PackageManager.MATCH_VISIBLE_TO_EPHEMERAL_ONLY) != 0;
final int N = packageProviders.size();
ArrayList<PackageParser.ProviderIntentInfo[]> listCut =
new ArrayList<PackageParser.ProviderIntentInfo[]>(N);
@@ -12527,8 +12535,7 @@
listCut.add(array);
}
}
- return super.queryIntentFromList(intent, resolvedType, defaultOnly,
- vislbleToEphemeral, isEphemeral, listCut, userId);
+ return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
}
public final void addProvider(PackageParser.Provider p) {
@@ -13069,7 +13076,7 @@
String installerPackageName, int installerUid, UserHandle user,
Certificate[][] certificates) {
if (DEBUG_EPHEMERAL) {
- if ((sessionParams.installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) {
+ if ((sessionParams.installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
Slog.d(TAG, "Ephemeral install of " + packageName);
}
}
@@ -13284,7 +13291,8 @@
* @hide
*/
@Override
- public int installExistingPackageAsUser(String packageName, int userId, int installReason) {
+ public int installExistingPackageAsUser(String packageName, int userId, int installFlags,
+ int installReason) {
mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES,
null);
PackageSetting pkgSetting;
@@ -13299,6 +13307,10 @@
long callingId = Binder.clearCallingIdentity();
try {
boolean installed = false;
+ final boolean instantApp =
+ (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
+ final boolean fullApp =
+ (installFlags & PackageManager.INSTALL_FULL_APP) != 0;
// writer
synchronized (mPackages) {
@@ -13313,7 +13325,11 @@
mSettings.writePackageRestrictionsLPr(userId);
mSettings.writeKernelMappingLPr(pkgSetting);
installed = true;
+ } else if (fullApp && pkgSetting.getInstantApp(userId)) {
+ // upgrade app from instant to full; we don't allow app downgrade
+ installed = true;
}
+ setInstantAppForUser(pkgSetting, userId, instantApp, fullApp);
}
if (installed) {
@@ -13335,6 +13351,29 @@
return PackageManager.INSTALL_SUCCEEDED;
}
+ void setInstantAppForUser(PackageSetting pkgSetting, int userId,
+ boolean instantApp, boolean fullApp) {
+ // no state specified; do nothing
+ if (!instantApp && !fullApp) {
+ return;
+ }
+ if (userId != UserHandle.USER_ALL) {
+ if (instantApp && !pkgSetting.getInstantApp(userId)) {
+ pkgSetting.setInstantApp(true /*instantApp*/, userId);
+ } else if (fullApp && pkgSetting.getInstantApp(userId)) {
+ pkgSetting.setInstantApp(false /*instantApp*/, userId);
+ }
+ } else {
+ for (int currentUserId : sUserManager.getUserIds()) {
+ if (instantApp && !pkgSetting.getInstantApp(currentUserId)) {
+ pkgSetting.setInstantApp(true /*instantApp*/, currentUserId);
+ } else if (fullApp && pkgSetting.getInstantApp(currentUserId)) {
+ pkgSetting.setInstantApp(false /*instantApp*/, currentUserId);
+ }
+ }
+ }
+ }
+
boolean isUserRestricted(int userId, String restrictionKey) {
Bundle restrictions = sUserManager.getUserRestrictions(userId);
if (restrictions.getBoolean(restrictionKey, false)) {
@@ -13693,7 +13732,7 @@
return false;
}
// Ephemeral apps don't get the full verification treatment
- if ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0) {
+ if ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0) {
if (DEBUG_EPHEMERAL) {
Slog.d(TAG, "INSTALL_EPHEMERAL so skipping verification");
}
@@ -14485,7 +14524,7 @@
final boolean onSd = (installFlags & PackageManager.INSTALL_EXTERNAL) != 0;
final boolean onInt = (installFlags & PackageManager.INSTALL_INTERNAL) != 0;
- final boolean ephemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0;
+ final boolean ephemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
PackageInfoLite pkgLite = null;
if (onInt && onSd) {
@@ -14569,7 +14608,7 @@
if (DEBUG_EPHEMERAL) {
Slog.v(TAG, "...setting INSTALL_EPHEMERAL install flag");
}
- installFlags |= PackageManager.INSTALL_EPHEMERAL;
+ installFlags |= PackageManager.INSTALL_INSTANT_APP;
installFlags &= ~(PackageManager.INSTALL_EXTERNAL
|PackageManager.INSTALL_INTERNAL);
} else {
@@ -14662,6 +14701,9 @@
final List<ComponentName> sufficientVerifiers = matchVerifiers(pkgLite,
receivers, verificationState);
+ DeviceIdleController.LocalService idleController = getDeviceIdleController();
+ final long idleDuration = getVerificationTimeout();
+
/*
* If any sufficient verifiers were listed in the package
* manifest, attempt to ask them.
@@ -14674,6 +14716,9 @@
} 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);
@@ -14694,6 +14739,9 @@
* target BroadcastReceivers have run.
*/
verification.setComponent(requiredVerifierComponent);
+ idleController.addPowerSaveTempWhitelistApp(Process.myUid(),
+ requiredVerifierComponent.getPackageName(), idleDuration,
+ verifierUser.getIdentifier(), false, "package verifier");
mContext.sendOrderedBroadcastAsUser(verification, verifierUser,
android.Manifest.permission.PACKAGE_VERIFICATION_AGENT,
new BroadcastReceiver() {
@@ -14903,7 +14951,7 @@
}
protected boolean isEphemeral() {
- return (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0;
+ return (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
}
UserHandle getUser() {
@@ -14983,7 +15031,7 @@
}
try {
- final boolean isEphemeral = (installFlags & PackageManager.INSTALL_EPHEMERAL) != 0;
+ final boolean isEphemeral = (installFlags & PackageManager.INSTALL_INSTANT_APP) != 0;
final File tempDir =
mInstallerService.allocateStageDirLegacy(volumeUuid, isEphemeral);
codeFile = tempDir;
@@ -15810,7 +15858,7 @@
private void replacePackageLIF(PackageParser.Package pkg, final int policyFlags, int scanFlags,
UserHandle user, String installerPackageName, PackageInstalledInfo res,
int installReason) {
- final boolean isEphemeral = (policyFlags & PackageParser.PARSE_IS_EPHEMERAL) != 0;
+ final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
final PackageParser.Package oldPackage;
final String pkgName = pkg.packageName;
@@ -15834,17 +15882,17 @@
return;
}
+ final PackageSetting ps = mSettings.mPackages.get(pkgName);
+
// don't allow an upgrade from full to ephemeral
- final boolean oldIsEphemeral = oldPackage.applicationInfo.isInstantApp();
- if (isEphemeral && !oldIsEphemeral) {
- // can't downgrade from full to ephemeral
- Slog.w(TAG, "Can't replace app with ephemeral: " + pkgName);
- res.setReturnCode(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID);
+ if (isInstantApp && !ps.getInstantApp(user.getIdentifier())) {
+ // can't downgrade from full to instant
+ Slog.w(TAG, "Can't replace app with instant app: " + pkgName);
+ res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
return;
}
// verify signatures are valid
- final PackageSetting ps = mSettings.mPackages.get(pkgName);
if (shouldCheckUpgradeKeySetLP(ps, scanFlags)) {
if (!checkUpgradeKeySetLP(ps, pkg)) {
res.setError(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
@@ -16046,6 +16094,10 @@
childPs.oldCodePaths = ps.oldCodePaths;
}
}
+ // set instant app status, but, only if it's explicitly specified
+ final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
+ final boolean fullApp = (scanFlags & SCAN_AS_FULL_APP) != 0;
+ setInstantAppForUser(ps, user.getIdentifier(), instantApp, fullApp);
prepareAppDataAfterInstallLIF(newPackage);
addedPkg = true;
} catch (PackageManagerException e) {
@@ -16517,7 +16569,8 @@
final boolean forwardLocked = ((installFlags & PackageManager.INSTALL_FORWARD_LOCK) != 0);
final boolean onExternal = (((installFlags & PackageManager.INSTALL_EXTERNAL) != 0)
|| (args.volumeUuid != null));
- final boolean ephemeral = ((installFlags & PackageManager.INSTALL_EPHEMERAL) != 0);
+ final boolean instantApp = ((installFlags & PackageManager.INSTALL_INSTANT_APP) != 0);
+ final boolean fullApp = ((installFlags & PackageManager.INSTALL_FULL_APP) != 0);
final boolean forceSdk = ((installFlags & PackageManager.INSTALL_FORCE_SDK) != 0);
boolean replace = false;
int scanFlags = SCAN_NEW_INSTALL | SCAN_UPDATE_SIGNATURE;
@@ -16528,6 +16581,12 @@
if ((installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
scanFlags |= SCAN_DONT_KILL_APP;
}
+ if (instantApp) {
+ scanFlags |= SCAN_AS_INSTANT_APP;
+ }
+ if (fullApp) {
+ scanFlags |= SCAN_AS_FULL_APP;
+ }
// Result object to be returned
res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
@@ -16535,10 +16594,10 @@
if (DEBUG_INSTALL) Slog.d(TAG, "installPackageLI: path=" + tmpPackageFile);
// Sanity check
- if (ephemeral && (forwardLocked || onExternal)) {
+ if (instantApp && (forwardLocked || onExternal)) {
Slog.i(TAG, "Incompatible ephemeral install; fwdLocked=" + forwardLocked
+ " external=" + onExternal);
- res.setReturnCode(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID);
+ res.setReturnCode(PackageManager.INSTALL_FAILED_INSTANT_APP_INVALID);
return;
}
@@ -16547,7 +16606,7 @@
| PackageParser.PARSE_ENFORCE_CODE
| (forwardLocked ? PackageParser.PARSE_FORWARD_LOCK : 0)
| (onExternal ? PackageParser.PARSE_EXTERNAL_STORAGE : 0)
- | (ephemeral ? PackageParser.PARSE_IS_EPHEMERAL : 0)
+ | (instantApp ? PackageParser.PARSE_IS_EPHEMERAL : 0)
| (forceSdk ? PackageParser.PARSE_FORCE_SDK : 0);
PackageParser pp = new PackageParser();
pp.setSeparateProcesses(mSeparateProcesses);
@@ -16566,7 +16625,7 @@
// // Ephemeral apps must have target SDK >= O.
// // TODO: Update conditional and error message when O gets locked down
-// if (ephemeral && pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {
+// if (instantApp && pkg.applicationInfo.targetSdkVersion <= Build.VERSION_CODES.N_MR1) {
// res.setError(PackageManager.INSTALL_FAILED_EPHEMERAL_INVALID,
// "Ephemeral apps must have target SDK version of at least O");
// return;
@@ -16809,10 +16868,10 @@
res.setError(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
"Cannot install updates to system apps on sdcard");
return;
- } else if (ephemeral) {
- // Abort update; system app can't be replaced with an ephemeral app
- res.setError(INSTALL_FAILED_EPHEMERAL_INVALID,
- "Cannot update a system app with an ephemeral app");
+ } else if (instantApp) {
+ // Abort update; system app can't be replaced with an instant app
+ res.setError(INSTALL_FAILED_INSTANT_APP_INVALID,
+ "Cannot update a system app with an instant app");
return;
}
}
@@ -17059,14 +17118,6 @@
return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
}
- private static boolean isEphemeral(PackageParser.Package pkg) {
- return pkg.applicationInfo.isInstantApp();
- }
-
- private static boolean isEphemeral(PackageSetting ps) {
- return ps.pkg != null && isEphemeral(ps.pkg);
- }
-
private static boolean isSystemApp(PackageParser.Package pkg) {
return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
}
@@ -17089,9 +17140,6 @@
private int packageFlagsToInstallFlags(PackageSetting ps) {
int installFlags = 0;
- if (isEphemeral(ps)) {
- installFlags |= PackageManager.INSTALL_EPHEMERAL;
- }
if (isExternal(ps) && TextUtils.isEmpty(ps.volumeUuid)) {
// This existing package was an external ASEC install when we have
// the external flag without a UUID
@@ -17493,7 +17541,7 @@
try (PackageFreezer freezer = freezePackageForDelete(packageName, freezeUser,
deleteFlags, "deletePackageX")) {
res = deletePackageLIF(packageName, UserHandle.of(removeUser), true, allUsers,
- deleteFlags | REMOVE_CHATTY, info, true, null);
+ deleteFlags | FLAGS_REMOVE_CHATTY, info, true, null);
}
synchronized (mPackages) {
if (res) {
@@ -17643,7 +17691,7 @@
}
}
- removePackageLI(ps, (flags & REMOVE_CHATTY) != 0);
+ removePackageLI(ps, (flags & FLAGS_REMOVE_CHATTY) != 0);
if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
final PackageParser.Package resolvedPkg;
@@ -18202,11 +18250,18 @@
Slog.d(TAG, "Marking package:" + ps.name + " uninstalled for user:" + nextUserId);
}
ps.setUserState(nextUserId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
- false /*installed*/, true /*stopped*/, true /*notLaunched*/,
- false /*hidden*/, false /*suspended*/, null, null, null,
+ false /*installed*/,
+ true /*stopped*/,
+ true /*notLaunched*/,
+ false /*hidden*/,
+ false /*suspended*/,
+ false /*instantApp*/,
+ null /*lastDisableAppCaller*/,
+ null /*enabledComponents*/,
+ null /*disabledComponents*/,
false /*blockUninstall*/,
- ps.readUserState(nextUserId).domainVerificationStatus, 0,
- PackageManager.INSTALL_REASON_UNKNOWN);
+ ps.readUserState(nextUserId).domainVerificationStatus,
+ 0, PackageManager.INSTALL_REASON_UNKNOWN);
}
mSettings.writeKernelMappingLPr(ps);
}
@@ -21688,12 +21743,12 @@
final ApplicationInfo app = pkg.applicationInfo;
final int appId = UserHandle.getAppId(app.uid);
- Preconditions.checkNotNull(app.seinfo);
+ Preconditions.checkNotNull(app.seInfo);
long ceDataInode = -1;
try {
ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
- appId, app.seinfo, app.targetSdkVersion);
+ appId, app.seInfo, app.targetSdkVersion);
} catch (InstallerException e) {
if (app.isSystemApp()) {
logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
@@ -21701,7 +21756,7 @@
destroyAppDataLeafLIF(pkg, userId, flags);
try {
ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
- appId, app.seinfo, app.targetSdkVersion);
+ appId, app.seInfo, app.targetSdkVersion);
logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
} catch (InstallerException e2) {
logCriticalInfo(Log.DEBUG, "Recovery failed!");
@@ -22003,7 +22058,7 @@
installerPackageName = ps.installerPackageName;
packageAbiOverride = ps.cpuAbiOverrideString;
appId = UserHandle.getAppId(pkg.applicationInfo.uid);
- seinfo = pkg.applicationInfo.seinfo;
+ seinfo = pkg.applicationInfo.seInfo;
label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
freezer = freezePackage(packageName, "movePackageInternal");
@@ -22812,8 +22867,8 @@
@Override
public boolean isPackageEphemeral(int userId, String packageName) {
synchronized (mPackages) {
- PackageParser.Package p = mPackages.get(packageName);
- return p != null ? p.applicationInfo.isInstantApp() : false;
+ final PackageSetting ps = mSettings.mPackages.get(packageName);
+ return ps != null ? ps.getInstantApp(userId) : false;
}
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 1203e4d..a7349fc 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -39,6 +39,7 @@
import android.content.pm.PermissionInfo;
import android.content.pm.PackageInstaller.SessionInfo;
import android.content.pm.PackageInstaller.SessionParams;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.content.pm.VersionedPackage;
import android.content.res.AssetManager;
@@ -116,6 +117,8 @@
return runInstallRemove();
case "install-write":
return runInstallWrite();
+ case "install-existing":
+ return runInstallExisting();
case "compile":
return runCompile();
case "reconcile-secondary-dex-files":
@@ -301,6 +304,51 @@
return doRemoveSplit(sessionId, splitName, true /*logSuccess*/);
}
+ private int runInstallExisting() throws RemoteException {
+ final PrintWriter pw = getOutPrintWriter();
+ int userId = UserHandle.USER_SYSTEM;
+ int installFlags = 0;
+ String opt;
+ while ((opt = getNextOption()) != null) {
+ switch (opt) {
+ case "--user":
+ userId = UserHandle.parseUserArg(getNextArgRequired());
+ break;
+ case "--ephemeral":
+ case "--instant":
+ installFlags |= PackageManager.INSTALL_INSTANT_APP;
+ installFlags &= ~PackageManager.INSTALL_FULL_APP;
+ break;
+ case "--full":
+ installFlags &= ~PackageManager.INSTALL_INSTANT_APP;
+ installFlags |= PackageManager.INSTALL_FULL_APP;
+ break;
+ default:
+ pw.println("Error: Unknown option: " + opt);
+ return 1;
+ }
+ }
+
+ final String packageName = getNextArg();
+ if (packageName == null) {
+ pw.println("Error: package name not specified");
+ return 1;
+ }
+
+ try {
+ final int res = mInterface.installExistingPackageAsUser(packageName, userId,
+ installFlags, PackageManager.INSTALL_REASON_UNKNOWN);
+ if (res == PackageManager.INSTALL_FAILED_INVALID_URI) {
+ throw new NameNotFoundException("Package " + packageName + " doesn't exist");
+ }
+ pw.println("Package " + packageName + " installed for user: " + userId);
+ return 0;
+ } catch (RemoteException | NameNotFoundException e) {
+ pw.println(e.toString());
+ return 1;
+ }
+ }
+
private int runCompile() throws RemoteException {
final PrintWriter pw = getOutPrintWriter();
boolean checkProfiles = SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false);
@@ -1145,8 +1193,12 @@
sessionParams.abiOverride = checkAbiArgument(getNextArg());
break;
case "--ephemeral":
+ case "--instantapp":
sessionParams.setInstallAsInstantApp(true /*isInstantApp*/);
break;
+ case "--full":
+ sessionParams.setInstallAsInstantApp(false /*isInstantApp*/);
+ break;
case "--user":
params.userId = UserHandle.parseUserArg(getNextArgRequired());
break;
diff --git a/services/core/java/com/android/server/pm/PackageSettingBase.java b/services/core/java/com/android/server/pm/PackageSettingBase.java
index 0e11b0c..601377d6 100644
--- a/services/core/java/com/android/server/pm/PackageSettingBase.java
+++ b/services/core/java/com/android/server/pm/PackageSettingBase.java
@@ -397,11 +397,19 @@
modifyUserState(userId).blockUninstall = blockUninstall;
}
+ boolean getInstantApp(int userId) {
+ return readUserState(userId).instantApp;
+ }
+
+ void setInstantApp(boolean instantApp, int userId) {
+ modifyUserState(userId).instantApp = instantApp;
+ }
+
void setUserState(int userId, long ceDataInode, int enabled, boolean installed, boolean stopped,
- boolean notLaunched, boolean hidden, boolean suspended,
+ boolean notLaunched, boolean hidden, boolean suspended, boolean instantApp,
String lastDisableAppCaller, ArraySet<String> enabledComponents,
- ArraySet<String> disabledComponents, boolean blockUninstall, int domainVerifState,
- int linkGeneration, int installReason) {
+ ArraySet<String> disabledComponents, boolean blockUninstall,
+ int domainVerifState, int linkGeneration, int installReason) {
PackageUserState state = modifyUserState(userId);
state.ceDataInode = ceDataInode;
state.enabled = enabled;
@@ -417,6 +425,7 @@
state.domainVerificationStatus = domainVerifState;
state.appLinkGeneration = linkGeneration;
state.installReason = installReason;
+ state.instantApp = instantApp;
}
ArraySet<String> getEnabledComponents(int userId) {
diff --git a/services/core/java/com/android/server/pm/SELinuxMMAC.java b/services/core/java/com/android/server/pm/SELinuxMMAC.java
index 7e7de21..188e66f 100644
--- a/services/core/java/com/android/server/pm/SELinuxMMAC.java
+++ b/services/core/java/com/android/server/pm/SELinuxMMAC.java
@@ -17,6 +17,8 @@
package com.android.server.pm;
import android.content.pm.PackageParser;
+import android.content.pm.PackageUserState;
+import android.content.pm.SELinuxUtil;
import android.content.pm.Signature;
import android.os.Environment;
import android.util.Slog;
@@ -69,9 +71,6 @@
// Append v2 to existing seinfo label
private static final String SANDBOX_V2_STR = ":v2";
- // Append ephemeral to existing seinfo label
- private static final String EPHEMERAL_APP_STR = ":ephemeralapp";
-
// Append targetSdkVersion=n to existing seinfo label where n is the app's targetSdkVersion
private static final String TARGETSDKVERSION_STR = ":targetSdkVersion=";
@@ -279,31 +278,28 @@
*
* @param pkg object representing the package to be labeled.
*/
- public static void assignSeinfoValue(PackageParser.Package pkg) {
+ public static void assignSeInfoValue(PackageParser.Package pkg) {
synchronized (sPolicies) {
for (Policy policy : sPolicies) {
- String seinfo = policy.getMatchedSeinfo(pkg);
- if (seinfo != null) {
- pkg.applicationInfo.seinfo = seinfo;
+ String seInfo = policy.getMatchedSeInfo(pkg);
+ if (seInfo != null) {
+ pkg.applicationInfo.seInfo = seInfo;
break;
}
}
}
- if (pkg.applicationInfo.isInstantApp())
- pkg.applicationInfo.seinfo += EPHEMERAL_APP_STR;
-
if (pkg.applicationInfo.targetSandboxVersion == 2)
- pkg.applicationInfo.seinfo += SANDBOX_V2_STR;
+ pkg.applicationInfo.seInfo += SANDBOX_V2_STR;
if (pkg.applicationInfo.isPrivilegedApp())
- pkg.applicationInfo.seinfo += PRIVILEGED_APP_STR;
+ pkg.applicationInfo.seInfo += PRIVILEGED_APP_STR;
- pkg.applicationInfo.seinfo += TARGETSDKVERSION_STR + pkg.applicationInfo.targetSdkVersion;
+ pkg.applicationInfo.seInfo += TARGETSDKVERSION_STR + pkg.applicationInfo.targetSdkVersion;
if (DEBUG_POLICY_INSTALL) {
Slog.i(TAG, "package (" + pkg.packageName + ") labeled with " +
- "seinfo=" + pkg.applicationInfo.seinfo);
+ "seinfo=" + pkg.applicationInfo.seInfo);
}
}
}
@@ -438,7 +434,7 @@
* @return A string representing the seinfo matched during policy lookup.
* A value of null can also be returned if no match occured.
*/
- public String getMatchedSeinfo(PackageParser.Package pkg) {
+ public String getMatchedSeInfo(PackageParser.Package pkg) {
// Check for exact signature matches across all certs.
Signature[] certs = mCerts.toArray(new Signature[0]);
if (!Signature.areExactMatch(certs, pkg.mSignatures)) {
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 6156802..a8a5ff0 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -219,6 +219,7 @@
private static final String ATTR_DOMAIN_VERIFICATON_STATE = "domainVerificationStatus";
private static final String ATTR_APP_LINK_GENERATION = "app-link-generation";
private static final String ATTR_INSTALL_REASON = "install-reason";
+ private static final String ATTR_INSTANT_APP = "instant-app";
private static final String ATTR_PACKAGE_NAME = "packageName";
private static final String ATTR_FINGERPRINT = "fingerprint";
@@ -687,7 +688,7 @@
PackageSetting disabledPkg, String realPkgName, SharedUserSetting sharedUser,
File codePath, File resourcePath, String legacyNativeLibraryPath, String primaryCpuAbi,
String secondaryCpuAbi, int versionCode, int pkgFlags, int pkgPrivateFlags,
- UserHandle installUser, boolean allowInstall, String parentPkgName,
+ UserHandle installUser, boolean allowInstall, boolean instantApp, String parentPkgName,
List<String> childPkgNames, UserManagerService userManager,
String[] usesStaticLibraries, int[] usesStaticLibrariesVersions) {
final PackageSetting pkgSetting;
@@ -745,14 +746,17 @@
|| installUserId == user.id;
pkgSetting.setUserState(user.id, 0, COMPONENT_ENABLED_STATE_DEFAULT,
installed,
- true, // stopped,
- true, // notLaunched
- false, // hidden
- false, // suspended
- null, null, null,
- false, // blockUninstall
- INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED, 0,
- PackageManager.INSTALL_REASON_UNKNOWN);
+ true /*stopped*/,
+ true /*notLaunched*/,
+ false /*hidden*/,
+ false /*suspended*/,
+ instantApp,
+ null /*lastDisableAppCaller*/,
+ null /*enabledComponents*/,
+ null /*disabledComponents*/,
+ false /*blockUninstall*/,
+ INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED,
+ 0, PackageManager.INSTALL_REASON_UNKNOWN);
}
}
}
@@ -1643,15 +1647,18 @@
// consider all applications to be installed.
for (PackageSetting pkg : mPackages.values()) {
pkg.setUserState(userId, 0, COMPONENT_ENABLED_STATE_DEFAULT,
- true, // installed
- false, // stopped
- false, // notLaunched
- false, // hidden
- false, // suspended
- null, null, null,
- false, // blockUninstall
- INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED, 0,
- PackageManager.INSTALL_REASON_UNKNOWN);
+ true /*installed*/,
+ false /*stopped*/,
+ false /*notLaunched*/,
+ false /*hidden*/,
+ false /*suspended*/,
+ false /*instantApp*/,
+ null /*lastDisableAppCaller*/,
+ null /*enabledComponents*/,
+ null /*disabledComponents*/,
+ false /*blockUninstall*/,
+ INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED,
+ 0, PackageManager.INSTALL_REASON_UNKNOWN);
}
return;
}
@@ -1718,6 +1725,8 @@
false);
final boolean blockUninstall = XmlUtils.readBooleanAttribute(parser,
ATTR_BLOCK_UNINSTALL, false);
+ final boolean instantApp = XmlUtils.readBooleanAttribute(parser,
+ ATTR_INSTANT_APP, false);
final int enabled = XmlUtils.readIntAttribute(parser, ATTR_ENABLED,
COMPONENT_ENABLED_STATE_DEFAULT);
final String enabledCaller = parser.getAttributeValue(null,
@@ -1754,8 +1763,9 @@
}
ps.setUserState(userId, ceDataInode, enabled, installed, stopped, notLaunched,
- hidden, suspended, enabledCaller, enabledComponents, disabledComponents,
- blockUninstall, verifState, linkGeneration, installReason);
+ hidden, suspended, instantApp, enabledCaller, enabledComponents,
+ disabledComponents, blockUninstall, verifState, linkGeneration,
+ installReason);
} else if (tagName.equals("preferred-activities")) {
readPreferredActivitiesLPw(parser, userId);
} else if (tagName.equals(TAG_PERSISTENT_PREFERRED_ACTIVITIES)) {
@@ -2025,6 +2035,9 @@
if (ustate.blockUninstall) {
serializer.attribute(null, ATTR_BLOCK_UNINSTALL, "true");
}
+ if (ustate.instantApp) {
+ serializer.attribute(null, ATTR_INSTANT_APP, "true");
+ }
if (ustate.enabled != COMPONENT_ENABLED_STATE_DEFAULT) {
serializer.attribute(null, ATTR_ENABLED,
Integer.toString(ustate.enabled));
@@ -2682,7 +2695,7 @@
sb.append(isDebug ? " 1 " : " 0 ");
sb.append(dataPath);
sb.append(" ");
- sb.append(ai.seinfo);
+ sb.append(ai.seInfo);
sb.append(" ");
if (gids != null && gids.length > 0) {
sb.append(gids[0]);
@@ -4140,7 +4153,7 @@
volumeUuids[i] = ps.volumeUuid;
names[i] = ps.name;
appIds[i] = ps.appId;
- seinfos[i] = ps.pkg.applicationInfo.seinfo;
+ seinfos[i] = ps.pkg.applicationInfo.seInfo;
targetSdkVersions[i] = ps.pkg.applicationInfo.targetSdkVersion;
}
}
@@ -4429,7 +4442,7 @@
ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE, "DEFAULT_TO_DEVICE_PROTECTED_STORAGE",
ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE, "DIRECT_BOOT_AWARE",
ApplicationInfo.PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE, "PARTIALLY_DIRECT_BOOT_AWARE",
- ApplicationInfo.PRIVATE_FLAG_EPHEMERAL, "EPHEMERAL",
+ ApplicationInfo.PRIVATE_FLAG_INSTANT, "EPHEMERAL",
ApplicationInfo.PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER, "REQUIRED_FOR_SYSTEM_USER",
ApplicationInfo.PRIVATE_FLAG_RESIZEABLE_ACTIVITIES_EXPLICITLY_SET, "RESIZEABLE_ACTIVITIES_EXPLICITLY_SET",
ApplicationInfo.PRIVATE_FLAG_RESIZEABLE_ACTIVITIES_VIA_SDK_VERSION, "RESIZEABLE_ACTIVITIES_VIA_SDK_VERSION",
@@ -4502,6 +4515,7 @@
pw.print(ps.getSuspended(user.id) ? "SU" : "su");
pw.print(ps.getStopped(user.id) ? "S" : "s");
pw.print(ps.getNotLaunched(user.id) ? "l" : "L");
+ pw.print(ps.getInstantApp(user.id) ? "IA" : "ia");
pw.print(",");
pw.print(ps.getEnabled(user.id));
String lastDisabledAppCaller = ps.getLastDisabledAppCaller(user.id);
@@ -4755,6 +4769,8 @@
pw.print(ps.getNotLaunched(user.id));
pw.print(" enabled=");
pw.println(ps.getEnabled(user.id));
+ pw.print(" instant=");
+ pw.println(ps.getInstantApp(user.id));
String lastDisabledAppCaller = ps.getLastDisabledAppCaller(user.id);
if (lastDisabledAppCaller != null) {
pw.print(prefix); pw.print(" lastDisabledCaller: ");
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index d250827..0d6cd80 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -236,6 +236,7 @@
import com.android.server.statusbar.StatusBarManagerInternal;
import com.android.server.wm.AppTransition;
import com.android.server.vr.VrManagerInternal;
+import com.android.server.vr.PersistentVrStateListener;
import java.io.File;
import java.io.FileReader;
@@ -416,6 +417,9 @@
AppOpsManager mAppOpsManager;
private boolean mHasFeatureWatch;
+ // Assigned on main thread, accessed on UI thread
+ volatile VrManagerInternal mVrManagerInternal;
+
// Vibrator pattern for haptic feedback of a long press.
long[] mLongPressVibePattern;
@@ -503,6 +507,8 @@
volatile boolean mGoingToSleep;
volatile boolean mRecentsVisible;
volatile boolean mTvPictureInPictureVisible;
+ // Written by vr manager thread, only read in this class
+ volatile boolean mPersistentVrModeEnabled;
// Used to hold the last user key used to wake the device. This helps us prevent up events
// from being passed to the foregrounded app without a corresponding down event
@@ -982,6 +988,14 @@
}
MyOrientationListener mOrientationListener;
+ final PersistentVrStateListener mPersistentVrModeListener =
+ new PersistentVrStateListener() {
+ @Override
+ public void onPersistentVrStateChanged(boolean enabled) {
+ mPersistentVrModeEnabled = enabled;
+ }
+ };
+
private final StatusBarController mStatusBarController = new StatusBarController();
private final BarController mNavigationBarController = new BarController("NavigationBar",
@@ -1914,24 +1928,36 @@
if (mStatusBar != null) {
requestTransientBars(mStatusBar);
}
+ if (mPersistentVrModeEnabled) {
+ exitPersistentVrMode();
+ }
}
@Override
public void onSwipeFromBottom() {
if (mNavigationBar != null && mNavigationBarPosition == NAV_BAR_BOTTOM) {
requestTransientBars(mNavigationBar);
}
+ if (mPersistentVrModeEnabled) {
+ exitPersistentVrMode();
+ }
}
@Override
public void onSwipeFromRight() {
if (mNavigationBar != null && mNavigationBarPosition == NAV_BAR_RIGHT) {
requestTransientBars(mNavigationBar);
}
+ if (mPersistentVrModeEnabled) {
+ exitPersistentVrMode();
+ }
}
@Override
public void onSwipeFromLeft() {
if (mNavigationBar != null && mNavigationBarPosition == NAV_BAR_LEFT) {
requestTransientBars(mNavigationBar);
}
+ if (mPersistentVrModeEnabled) {
+ exitPersistentVrMode();
+ }
}
@Override
public void onFling(int duration) {
@@ -6489,11 +6515,17 @@
}
private void reportScreenStateToVrManager(boolean isScreenOn) {
- VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
- if (vrService == null) {
+ if (mVrManagerInternal == null) {
return;
}
- vrService.onScreenStateChanged(isScreenOn);
+ mVrManagerInternal.onScreenStateChanged(isScreenOn);
+ }
+
+ private void exitPersistentVrMode() {
+ if (mVrManagerInternal == null) {
+ return;
+ }
+ mVrManagerInternal.setPersistentVrModeEnabled(false);
}
private void finishWindowsDrawn() {
@@ -6982,6 +7014,11 @@
});
mKeyguardDelegate.onSystemReady();
+ mVrManagerInternal = LocalServices.getService(VrManagerInternal.class);
+ if (mVrManagerInternal != null) {
+ mVrManagerInternal.addPersistentVrModeStateListener(mPersistentVrModeListener);
+ }
+
readCameraLensCoverState();
updateUiMode();
boolean bindKeyguardNow;
diff --git a/services/core/java/com/android/server/vr/PersistentVrStateListener.java b/services/core/java/com/android/server/vr/PersistentVrStateListener.java
new file mode 100644
index 0000000..bccd5f1
--- /dev/null
+++ b/services/core/java/com/android/server/vr/PersistentVrStateListener.java
@@ -0,0 +1,31 @@
+/**
+ * Copyright (C) 2017 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.vr;
+
+/**
+ * Listener for state changes to persistent VR mode.
+ *
+ * @hide Only for use within system server.
+ */
+public abstract class PersistentVrStateListener {
+
+ /**
+ * Called when the Persistent VR mode state changes.
+ *
+ * @param enabled {@code true} if persistent VR mode is enabled.
+ */
+ public abstract void onPersistentVrStateChanged(boolean enabled);
+}
diff --git a/services/core/java/com/android/server/vr/VrManagerInternal.java b/services/core/java/com/android/server/vr/VrManagerInternal.java
index 45b7baf..58e4bdc 100644
--- a/services/core/java/com/android/server/vr/VrManagerInternal.java
+++ b/services/core/java/com/android/server/vr/VrManagerInternal.java
@@ -88,4 +88,9 @@
* @param enabled true if the device should be placed in persistent VR mode.
*/
public abstract void setPersistentVrModeEnabled(boolean enabled);
+
+ /**
+ * Adds listener that reports state changes to persistent VR mode.
+ */
+ public abstract void addPersistentVrModeStateListener(PersistentVrStateListener listener);
}
diff --git a/services/core/java/com/android/server/vr/VrManagerService.java b/services/core/java/com/android/server/vr/VrManagerService.java
index f0ea527..21a4f74 100644
--- a/services/core/java/com/android/server/vr/VrManagerService.java
+++ b/services/core/java/com/android/server/vr/VrManagerService.java
@@ -122,6 +122,8 @@
private boolean mGuard;
private final RemoteCallbackList<IVrStateCallbacks> mRemoteCallbacks =
new RemoteCallbackList<>();
+ private final ArrayList<PersistentVrStateListener> mPersistentVrStateListeners =
+ new ArrayList<>();
private int mPreviousCoarseLocationMode = INVALID_APPOPS_MODE;
private int mPreviousManageOverlayMode = INVALID_APPOPS_MODE;
private VrState mPendingState;
@@ -132,6 +134,7 @@
private static final int MSG_VR_STATE_CHANGE = 0;
private static final int MSG_PENDING_VR_STATE_CHANGE = 1;
+ private static final int MSG_PERSISTENT_VR_MODE_STATE_CHANGE = 2;
/**
* Set whether VR mode may be enabled.
@@ -151,7 +154,7 @@
} else {
// Disable persistent mode when VR mode isn't allowed, allows an escape hatch to
// exit persistent VR mode when screen is turned off.
- mPersistentVrModeEnabled = false;
+ setPersistentModeAndNotifyListenersLocked(false);
// Set pending state to current state.
mPendingState = (mVrModeEnabled && mCurrentVrService != null)
@@ -213,6 +216,13 @@
}
}
} break;
+ case MSG_PERSISTENT_VR_MODE_STATE_CHANGE : {
+ boolean state = (msg.arg1 == 1);
+ for (int i = 0; i < mPersistentVrStateListeners.size(); i++) {
+ mPersistentVrStateListeners.get(i).onPersistentVrStateChanged(
+ state);
+ }
+ } break;
default :
throw new IllegalStateException("Unknown message type: " + msg.what);
}
@@ -424,6 +434,16 @@
pw.println(n.flattenToString());
}
}
+ pw.println("Attached persistent mode listeners:");
+ if (mPersistentVrStateListeners == null ||
+ mPersistentVrStateListeners.size() == 0) {
+ pw.println("None");
+ } else {
+ for (PersistentVrStateListener l : mPersistentVrStateListeners) {
+ pw.print(tab);
+ pw.println("listener: " + l);
+ }
+ }
pw.println("\n");
pw.println("********* End of VrManagerService Dump *********");
}
@@ -471,6 +491,11 @@
public void setPersistentVrModeEnabled(boolean enabled) {
VrManagerService.this.setPersistentVrModeEnabled(enabled);
}
+
+ @Override
+ public void addPersistentVrModeStateListener(PersistentVrStateListener listener) {
+ VrManagerService.this.addPersistentVrModeStateListener(listener);
+ }
}
public VrManagerService(Context context) {
@@ -1013,9 +1038,8 @@
}
private void setPersistentVrModeEnabled(boolean enabled) {
- synchronized (mLock) {
- mPersistentVrModeEnabled = enabled;
-
+ synchronized(mLock) {
+ setPersistentModeAndNotifyListenersLocked(enabled);
// Disabling persistent mode when not showing a VR should disable the overall vr mode.
if (!enabled && mCurrentVrModeComponent == null) {
setVrMode(false, null, 0, null);
@@ -1023,6 +1047,22 @@
}
}
+ private void setPersistentModeAndNotifyListenersLocked(boolean enabled) {
+ if (mPersistentVrModeEnabled == enabled) {
+ return;
+ }
+ mPersistentVrModeEnabled = enabled;
+
+ mHandler.sendMessage(mHandler.obtainMessage(MSG_PERSISTENT_VR_MODE_STATE_CHANGE,
+ (mPersistentVrModeEnabled) ? 1 : 0, 0));
+ }
+
+ private void addPersistentVrModeStateListener(PersistentVrStateListener listener) {
+ synchronized (mLock) {
+ mPersistentVrStateListeners.add(listener);
+ }
+ }
+
private int hasVrPackage(@NonNull ComponentName targetPackageName, int userId) {
synchronized (mLock) {
return mComponentObserver.isValid(targetPackageName, userId);
diff --git a/services/core/java/com/android/server/wm/PinnedStackController.java b/services/core/java/com/android/server/wm/PinnedStackController.java
index 6a8417dc..cfeb198 100644
--- a/services/core/java/com/android/server/wm/PinnedStackController.java
+++ b/services/core/java/com/android/server/wm/PinnedStackController.java
@@ -233,7 +233,7 @@
* @return the movement bounds for the given {@param stackBounds} and the current state of the
* controller.
*/
- Rect getMovementBounds(Rect stackBounds) {
+ private Rect getMovementBounds(Rect stackBounds) {
return getMovementBounds(stackBounds, true /* adjustForIme */);
}
@@ -241,7 +241,7 @@
* @return the movement bounds for the given {@param stackBounds} and the current state of the
* controller.
*/
- Rect getMovementBounds(Rect stackBounds, boolean adjustForIme) {
+ private Rect getMovementBounds(Rect stackBounds, boolean adjustForIme) {
final Rect movementBounds = new Rect();
getInsetBounds(movementBounds);
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index e496666..7da6809 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -194,6 +194,7 @@
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.text.DateFormat;
+import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -2911,11 +2912,41 @@
}
}
+ private void ensureUnknownSourcesRestrictionForProfileOwners() {
+ synchronized (this) {
+ for (int userId : mOwners.getProfileOwnerKeys().toArray(new Integer[0])) {
+ if (!mUserManager.isManagedProfile(userId) ||
+ Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.UNKNOWN_SOURCES_DEFAULT_REVERSED, 0, userId) == 0) {
+ continue;
+ }
+ setUserRestrictionOnBehalfOfProfileOwnerLocked(
+ UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userId);
+ Settings.Secure.putIntForUser(mContext.getContentResolver(),
+ Settings.Secure.UNKNOWN_SOURCES_DEFAULT_REVERSED, 0, userId);
+ }
+ }
+ }
+
+ private void setUserRestrictionOnBehalfOfProfileOwnerLocked(String userRestrictionKey,
+ int userId) {
+ if (UserRestrictionsUtils.isValidRestriction(userRestrictionKey) &&
+ UserRestrictionsUtils.canProfileOwnerChange(userRestrictionKey, userId)) {
+ ActiveAdmin profileOwner = getProfileOwnerAdminLocked(userId);
+ if (profileOwner == null) {
+ return;
+ }
+ Bundle restrictions = profileOwner.ensureUserRestrictions();
+ restrictions.putBoolean(userRestrictionKey, true);
+ saveUserRestrictionsLocked(userId);
+ }
+ }
+
private void onLockSettingsReady() {
getUserData(UserHandle.USER_SYSTEM);
loadOwners();
cleanUpOldUsers();
-
+ ensureUnknownSourcesRestrictionForProfileOwners();
onStartUser(UserHandle.USER_SYSTEM);
// Register an observer for watching for user setup complete and settings changes.
@@ -6638,6 +6669,12 @@
mOwners.writeProfileOwner(userHandle);
Slog.i(LOG_TAG, "Profile owner set: " + who + " on user " + userHandle);
+ if (mUserManager.isManagedProfile(userHandle)) {
+ setUserRestrictionOnBehalfOfProfileOwnerLocked(
+ UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, userHandle);
+ Settings.Secure.putIntForUser(mContext.getContentResolver(),
+ Settings.Secure.UNKNOWN_SOURCES_DEFAULT_REVERSED, 0, userHandle);
+ }
return true;
}
}
@@ -7919,7 +7956,7 @@
// Install the profile owner if not present.
if (!mIPackageManager.isPackageAvailable(adminPkg, userHandle)) {
mIPackageManager.installExistingPackageAsUser(adminPkg, userHandle,
- PackageManager.INSTALL_REASON_POLICY);
+ 0 /*installFlags*/, PackageManager.INSTALL_REASON_POLICY);
}
} catch (RemoteException e) {
Slog.e(LOG_TAG, "Failed to make remote calls for createAndManageUser, "
@@ -8238,7 +8275,7 @@
// Install the app.
mIPackageManager.installExistingPackageAsUser(packageName, userId,
- PackageManager.INSTALL_REASON_POLICY);
+ 0 /*installFlags*/, PackageManager.INSTALL_REASON_POLICY);
} catch (RemoteException re) {
// shouldn't happen
@@ -8280,7 +8317,7 @@
if (isSystemApp(mIPackageManager, packageName, parentUserId)) {
numberOfAppsInstalled++;
mIPackageManager.installExistingPackageAsUser(packageName, userId,
- PackageManager.INSTALL_REASON_POLICY);
+ 0 /*installFlags*/, PackageManager.INSTALL_REASON_POLICY);
} else {
Slog.d(LOG_TAG, "Not enabling " + packageName + " since is not a"
+ " system app");
@@ -8724,7 +8761,27 @@
throw new SecurityException(String.format(
"Permission denial: Profile owners cannot update %1$s", setting));
}
-
+ if (setting.equals(Settings.Secure.INSTALL_NON_MARKET_APPS)) {
+ if (getTargetSdk(who.getPackageName(), callingUserId) >= Build.VERSION_CODES.O) {
+ throw new UnsupportedOperationException(Settings.Secure.INSTALL_NON_MARKET_APPS
+ + " is deprecated. Please use the user restriction "
+ + UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES + " instead.");
+ }
+ if (!mUserManager.isManagedProfile(callingUserId)) {
+ Slog.e(LOG_TAG, "Ignoring setSecureSetting request for "
+ + setting + ". User restriction "
+ + UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES
+ + " should be used instead.");
+ } else {
+ try {
+ setUserRestriction(who, UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES,
+ (Integer.parseInt(value) == 0) ? true : false);
+ } catch (NumberFormatException exc) {
+ Slog.e(LOG_TAG, "Invalid value: " + value + " for setting " + setting);
+ }
+ }
+ return;
+ }
long id = mInjector.binderClearCallingIdentity();
try {
if (Settings.Secure.DEFAULT_INPUT_METHOD.equals(setting)) {
diff --git a/services/retaildemo/java/com/android/server/retaildemo/PreloadAppsInstaller.java b/services/retaildemo/java/com/android/server/retaildemo/PreloadAppsInstaller.java
index 3fa72dc..90c58d0 100644
--- a/services/retaildemo/java/com/android/server/retaildemo/PreloadAppsInstaller.java
+++ b/services/retaildemo/java/com/android/server/retaildemo/PreloadAppsInstaller.java
@@ -104,7 +104,7 @@
}
try {
mPackageManager.installExistingPackageAsUser(packageName, userId,
- PackageManager.INSTALL_REASON_UNKNOWN);
+ 0 /*installFlags*/, PackageManager.INSTALL_REASON_UNKNOWN);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
} finally {
@@ -175,4 +175,4 @@
}
}
}
-}
\ No newline at end of file
+}
diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
index e2e1844..100338e 100644
--- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
@@ -1053,7 +1053,7 @@
ret.applicationInfo.flags &= ~ApplicationInfo.FLAG_INSTALLED;
}
if (mEphemeralPackages.contains(PackageWithUser.of(userId, packageName))) {
- ret.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_EPHEMERAL;
+ ret.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_INSTANT;
}
if (mSystemPackages.contains(packageName)) {
ret.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
index baf60c5..325d99a 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
@@ -388,6 +388,7 @@
ApplicationInfo.PRIVATE_FLAG_PRIVILEGED /*pkgPrivateFlags*/,
null /*installUser*/,
false /*allowInstall*/,
+ false /*instantApp*/,
null /*parentPkgName*/,
null /*childPkgNames*/,
UserManagerService.getInstance(),
@@ -428,6 +429,7 @@
0 /*pkgPrivateFlags*/,
UserHandle.SYSTEM /*installUser*/,
true /*allowInstall*/,
+ false /*instantApp*/,
null /*parentPkgName*/,
null /*childPkgNames*/,
UserManagerService.getInstance(),
@@ -471,6 +473,7 @@
0 /*pkgPrivateFlags*/,
null /*installUser*/,
false /*allowInstall*/,
+ false /*instantApp*/,
null /*parentPkgName*/,
null /*childPkgNames*/,
UserManagerService.getInstance(),
@@ -514,6 +517,7 @@
0 /*pkgPrivateFlags*/,
null /*installUser*/,
false /*allowInstall*/,
+ false /*instantApp*/,
null /*parentPkgName*/,
null /*childPkgNames*/,
UserManagerService.getInstance(),
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
index e5640c7..5591029 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
@@ -380,7 +380,7 @@
assertTrue(Arrays.equals(a.splitSourceDirs, that.splitSourceDirs));
assertTrue(Arrays.equals(a.splitPublicSourceDirs, that.splitPublicSourceDirs));
assertTrue(Arrays.equals(a.resourceDirs, that.resourceDirs));
- assertEquals(a.seinfo, that.seinfo);
+ assertEquals(a.seInfo, that.seInfo);
assertTrue(Arrays.equals(a.sharedLibraryFiles, that.sharedLibraryFiles));
assertEquals(a.dataDir, that.dataDir);
assertEquals(a.deviceProtectedDataDir, that.deviceProtectedDataDir);
diff --git a/services/tests/servicestests/src/com/android/server/retaildemo/PreloadAppsInstallerTest.java b/services/tests/servicestests/src/com/android/server/retaildemo/PreloadAppsInstallerTest.java
index 346dc42..a8c39c4 100644
--- a/services/tests/servicestests/src/com/android/server/retaildemo/PreloadAppsInstallerTest.java
+++ b/services/tests/servicestests/src/com/android/server/retaildemo/PreloadAppsInstallerTest.java
@@ -104,7 +104,7 @@
null, null);
// Verify that we try to install the package in system user.
verify(mIpm).installExistingPackageAsUser(path, UserHandle.USER_SYSTEM,
- PackageManager.INSTALL_REASON_UNKNOWN);
+ 0 /*installFlags*/, PackageManager.INSTALL_REASON_UNKNOWN);
}
assertEquals("DEMO_USER_SETUP should be set to 1 after preloaded apps are installed",
"1",
@@ -141,7 +141,7 @@
null, null);
// Verify that we try to install the package in system user.
verify(mIpm).installExistingPackageAsUser(path, UserHandle.USER_SYSTEM,
- PackageManager.INSTALL_REASON_UNKNOWN);
+ 0 /*installFlags*/, PackageManager.INSTALL_REASON_UNKNOWN);
}
assertEquals("DEMO_USER_SETUP should be set to 1 after preloaded apps are installed",
"1",
diff --git a/test-runner/src/android/test/mock/MockContext.java b/test-runner/src/android/test/mock/MockContext.java
index 6bcd08a..3f5ca84 100644
--- a/test-runner/src/android/test/mock/MockContext.java
+++ b/test-runner/src/android/test/mock/MockContext.java
@@ -765,6 +765,10 @@
throw new UnsupportedOperationException();
}
+ /** @hide **/
+ @Override
+ public File getPreloadsFileCache() { throw new UnsupportedOperationException(); }
+
@Override
public Context createDeviceProtectedStorageContext() {
throw new UnsupportedOperationException();
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
index 852ab94..2c9fe29 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeContext.java
@@ -1412,6 +1412,12 @@
}
@Override
+ public File getPreloadsFileCache() {
+ // pass
+ return null;
+ }
+
+ @Override
public ContentResolver getContentResolver() {
if (mContentResolver == null) {
mContentResolver = new BridgeContentResolver(this);
diff --git a/wifi/java/android/net/wifi/WifiConfiguration.java b/wifi/java/android/net/wifi/WifiConfiguration.java
index 97a15e4..3eb9934 100644
--- a/wifi/java/android/net/wifi/WifiConfiguration.java
+++ b/wifi/java/android/net/wifi/WifiConfiguration.java
@@ -855,6 +855,7 @@
* This network is disabled because EAP-TLS failure
*/
public static final int DISABLED_TLS_VERSION_MISMATCH = 7;
+ // Values above are for temporary disablement; values below are for permanent disablement.
/**
* This network is disabled due to absence of user credentials
*/
@@ -979,6 +980,28 @@
private boolean mHasEverConnected;
/**
+ * Boolean indicating whether {@link com.android.server.wifi.RecommendedNetworkEvaluator}
+ * chose not to connect to this network in the last qualified network selection process.
+ */
+ private boolean mNotRecommended;
+
+ /**
+ * Set whether {@link com.android.server.wifi.RecommendedNetworkEvaluator} does not
+ * recommend connecting to this network.
+ */
+ public void setNotRecommended(boolean notRecommended) {
+ mNotRecommended = notRecommended;
+ }
+
+ /**
+ * Returns whether {@link com.android.server.wifi.RecommendedNetworkEvaluator} does not
+ * recommend connecting to this network.
+ */
+ public boolean isNotRecommended() {
+ return mNotRecommended;
+ }
+
+ /**
* set whether this network is visible in latest Qualified Network Selection
* @param seen value set to candidate
*/
@@ -1301,6 +1324,7 @@
dest.writeInt(CONNECT_CHOICE_NOT_EXISTS);
}
dest.writeInt(getHasEverConnected() ? 1 : 0);
+ dest.writeInt(isNotRecommended() ? 1 : 0);
}
public void readFromParcel(Parcel in) {
@@ -1320,6 +1344,7 @@
setConnectChoiceTimestamp(INVALID_NETWORK_SELECTION_DISABLE_TIMESTAMP);
}
setHasEverConnected(in.readInt() != 0);
+ setNotRecommended(in.readInt() != 0);
}
}
diff --git a/wifi/java/android/net/wifi/aware/ConfigRequest.java b/wifi/java/android/net/wifi/aware/ConfigRequest.java
index 6a5957b..cc14ab2 100644
--- a/wifi/java/android/net/wifi/aware/ConfigRequest.java
+++ b/wifi/java/android/net/wifi/aware/ConfigRequest.java
@@ -19,6 +19,8 @@
import android.os.Parcel;
import android.os.Parcelable;
+import java.util.Arrays;
+
/**
* Defines a request object to configure a Wi-Fi Aware network. Built using
* {@link ConfigRequest.Builder}. Configuration is requested using
@@ -41,6 +43,18 @@
public static final int CLUSTER_ID_MAX = 0xFFFF;
/**
+ * Indices for configuration variables which are specified per band.
+ */
+ public static final int NAN_BAND_24GHZ = 0;
+ public static final int NAN_BAND_5GHZ = 1;
+
+ /**
+ * Magic values for Discovery Window (DW) interval configuration
+ */
+ public static final int DW_INTERVAL_NOT_INIT = -1;
+ public static final int DW_DISABLE = 0; // only valid for 5GHz
+
+ /**
* Indicates whether 5G band support is requested.
*/
public final boolean mSupport5gBand;
@@ -62,19 +76,26 @@
*/
public final int mClusterHigh;
+ /**
+ * Specifies the discovery window interval for the device on NAN_BAND_*.
+ */
+ public final int mDiscoveryWindowInterval[];
+
private ConfigRequest(boolean support5gBand, int masterPreference, int clusterLow,
- int clusterHigh) {
+ int clusterHigh, int discoveryWindowInterval[]) {
mSupport5gBand = support5gBand;
mMasterPreference = masterPreference;
mClusterLow = clusterLow;
mClusterHigh = clusterHigh;
+ mDiscoveryWindowInterval = discoveryWindowInterval;
}
@Override
public String toString() {
return "ConfigRequest [mSupport5gBand=" + mSupport5gBand + ", mMasterPreference="
+ mMasterPreference + ", mClusterLow=" + mClusterLow + ", mClusterHigh="
- + mClusterHigh + "]";
+ + mClusterHigh + ", mDiscoveryWindowInterval="
+ + Arrays.toString(mDiscoveryWindowInterval) + "]";
}
@Override
@@ -88,6 +109,7 @@
dest.writeInt(mMasterPreference);
dest.writeInt(mClusterLow);
dest.writeInt(mClusterHigh);
+ dest.writeIntArray(mDiscoveryWindowInterval);
}
public static final Creator<ConfigRequest> CREATOR = new Creator<ConfigRequest>() {
@@ -102,7 +124,10 @@
int masterPreference = in.readInt();
int clusterLow = in.readInt();
int clusterHigh = in.readInt();
- return new ConfigRequest(support5gBand, masterPreference, clusterLow, clusterHigh);
+ int discoveryWindowInterval[] = in.createIntArray();
+
+ return new ConfigRequest(support5gBand, masterPreference, clusterLow, clusterHigh,
+ discoveryWindowInterval);
}
};
@@ -119,17 +144,8 @@
ConfigRequest lhs = (ConfigRequest) o;
return mSupport5gBand == lhs.mSupport5gBand && mMasterPreference == lhs.mMasterPreference
- && mClusterLow == lhs.mClusterLow && mClusterHigh == lhs.mClusterHigh;
- }
-
- /**
- * Checks whether the configuration's settings are non-default.
- *
- * @return true if any of the settings are non-default.
- */
- public boolean isNonDefault() {
- return mSupport5gBand || mMasterPreference != 0 || mClusterLow != CLUSTER_ID_MIN
- || mClusterHigh != CLUSTER_ID_MAX;
+ && mClusterLow == lhs.mClusterLow && mClusterHigh == lhs.mClusterHigh
+ && Arrays.equals(mDiscoveryWindowInterval, lhs.mDiscoveryWindowInterval);
}
@Override
@@ -140,6 +156,7 @@
result = 31 * result + mMasterPreference;
result = 31 * result + mClusterLow;
result = 31 * result + mClusterHigh;
+ result = 31 * result + Arrays.hashCode(mDiscoveryWindowInterval);
return result;
}
@@ -173,6 +190,23 @@
throw new IllegalArgumentException(
"Invalid argument combination - must have Cluster Low <= Cluster High");
}
+ if (mDiscoveryWindowInterval.length != 2) {
+ throw new IllegalArgumentException(
+ "Invalid discovery window interval: must have 2 elements (2.4 & 5");
+ }
+ if (mDiscoveryWindowInterval[NAN_BAND_24GHZ] != DW_INTERVAL_NOT_INIT &&
+ (mDiscoveryWindowInterval[NAN_BAND_24GHZ] < 1 // valid for 2.4GHz: [1-5]
+ || mDiscoveryWindowInterval[NAN_BAND_24GHZ] > 5)) {
+ throw new IllegalArgumentException(
+ "Invalid discovery window interval for 2.4GHz: valid is UNSET or [1,5]");
+ }
+ if (mDiscoveryWindowInterval[NAN_BAND_5GHZ] != DW_INTERVAL_NOT_INIT &&
+ (mDiscoveryWindowInterval[NAN_BAND_5GHZ] < 0 // valid for 5GHz: [0-5]
+ || mDiscoveryWindowInterval[NAN_BAND_5GHZ] > 5)) {
+ throw new IllegalArgumentException(
+ "Invalid discovery window interval for 5GHz: valid is UNSET or [0,5]");
+ }
+
}
/**
@@ -183,6 +217,7 @@
private int mMasterPreference = 0;
private int mClusterLow = CLUSTER_ID_MIN;
private int mClusterHigh = CLUSTER_ID_MAX;
+ private int mDiscoveryWindowInterval[] = {DW_INTERVAL_NOT_INIT, DW_INTERVAL_NOT_INIT};
/**
* Specify whether 5G band support is required in this request. Disabled by default.
@@ -271,6 +306,33 @@
}
/**
+ * The discovery window interval specifies the discovery windows in which the device will be
+ * awake. The configuration enables trading off latency vs. power (higher interval means
+ * higher discovery latency but lower power).
+ *
+ * @param band Either {@link #NAN_BAND_24GHZ} or {@link #NAN_BAND_5GHZ}.
+ * @param interval A value of 1, 2, 3, 4, or 5 indicating an interval of 2^(interval-1). For
+ * the 5GHz band a value of 0 indicates that the device will not be awake
+ * for any discovery windows.
+ *
+ * @return The builder itself to facilitate chaining operations
+ * {@code builder.setDiscoveryWindowInterval(...).setMasterPreference(...)}.
+ */
+ public Builder setDiscoveryWindowInterval(int band, int interval) {
+ if (band != NAN_BAND_24GHZ && band != NAN_BAND_5GHZ) {
+ throw new IllegalArgumentException("Invalid band value");
+ }
+ if ((band == NAN_BAND_24GHZ && (interval < 1 || interval > 5))
+ || (band == NAN_BAND_5GHZ && (interval < 0 || interval > 5))) {
+ throw new IllegalArgumentException(
+ "Invalid interval value: 2.4 GHz [1,5] or 5GHz [0,5]");
+ }
+
+ mDiscoveryWindowInterval[band] = interval;
+ return this;
+ }
+
+ /**
* Build {@link ConfigRequest} given the current requests made on the
* builder.
*/
@@ -280,7 +342,8 @@
"Invalid argument combination - must have Cluster Low <= Cluster High");
}
- return new ConfigRequest(mSupport5gBand, mMasterPreference, mClusterLow, mClusterHigh);
+ return new ConfigRequest(mSupport5gBand, mMasterPreference, mClusterLow, mClusterHigh,
+ mDiscoveryWindowInterval);
}
}
}
diff --git a/wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl b/wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl
index 794c142..0f4910f 100644
--- a/wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl
+++ b/wifi/java/android/net/wifi/aware/IWifiAwareManager.aidl
@@ -34,8 +34,6 @@
interface IWifiAwareManager
{
// Aware API
- void enableUsage();
- void disableUsage();
boolean isUsageEnabled();
Characteristics getCharacteristics();
diff --git a/wifi/java/android/net/wifi/aware/WifiAwareManager.java b/wifi/java/android/net/wifi/aware/WifiAwareManager.java
index a9e38ce..0eb6a3d 100644
--- a/wifi/java/android/net/wifi/aware/WifiAwareManager.java
+++ b/wifi/java/android/net/wifi/aware/WifiAwareManager.java
@@ -253,36 +253,6 @@
}
/**
- * Enable the usage of the Aware API. Doesn't actually turn on Aware cluster formation - that
- * only happens when an attach is attempted. {@link #ACTION_WIFI_AWARE_STATE_CHANGED} broadcast
- * will be triggered.
- *
- * @hide
- */
- public void enableUsage() {
- try {
- mService.enableUsage();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Disable the usage of the Aware API. All attempts to attach() will be rejected. All open
- * connections and sessions will be terminated. {@link #ACTION_WIFI_AWARE_STATE_CHANGED}
- * broadcast will be triggered.
- *
- * @hide
- */
- public void disableUsage() {
- try {
- mService.disableUsage();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
* Returns the current status of Aware API: whether or not Aware is available. To track
* changes in the state of Aware API register for the
* {@link #ACTION_WIFI_AWARE_STATE_CHANGED} broadcast.
diff --git a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
index a396d87..7f68f6f 100644
--- a/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/aware/WifiAwareManagerTest.java
@@ -100,26 +100,6 @@
*/
/**
- * Validate pass-through of enableUsage() API.
- */
- @Test
- public void testEnableUsage() throws Exception {
- mDut.enableUsage();
-
- verify(mockAwareService).enableUsage();
- }
-
- /**
- * Validate pass-through of disableUsage() API.
- */
- @Test
- public void testDisableUsage() throws Exception {
- mDut.disableUsage();
-
- verify(mockAwareService).disableUsage();
- }
-
- /**
* Validate pass-through of isUsageEnabled() API.
*/
@Test
@@ -566,6 +546,12 @@
collector.checkThat("mMasterPreference", 0,
equalTo(configRequest.mMasterPreference));
collector.checkThat("mSupport5gBand", false, equalTo(configRequest.mSupport5gBand));
+ collector.checkThat("mDiscoveryWindowInterval.length", 2,
+ equalTo(configRequest.mDiscoveryWindowInterval.length));
+ collector.checkThat("mDiscoveryWindowInterval[2.4GHz]", ConfigRequest.DW_INTERVAL_NOT_INIT,
+ equalTo(configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_24GHZ]));
+ collector.checkThat("mDiscoveryWindowInterval[5Hz]", ConfigRequest.DW_INTERVAL_NOT_INIT,
+ equalTo(configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_5GHZ]));
}
@Test
@@ -574,10 +560,12 @@
final int clusterLow = 5;
final int masterPreference = 55;
final boolean supportBand5g = true;
+ final int dwWindow5GHz = 3;
ConfigRequest configRequest = new ConfigRequest.Builder().setClusterHigh(clusterHigh)
.setClusterLow(clusterLow).setMasterPreference(masterPreference)
.setSupport5gBand(supportBand5g)
+ .setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_5GHZ, dwWindow5GHz)
.build();
collector.checkThat("mClusterHigh", clusterHigh, equalTo(configRequest.mClusterHigh));
@@ -585,6 +573,12 @@
collector.checkThat("mMasterPreference", masterPreference,
equalTo(configRequest.mMasterPreference));
collector.checkThat("mSupport5gBand", supportBand5g, equalTo(configRequest.mSupport5gBand));
+ collector.checkThat("mDiscoveryWindowInterval.length", 2,
+ equalTo(configRequest.mDiscoveryWindowInterval.length));
+ collector.checkThat("mDiscoveryWindowInterval[2.4GHz]", ConfigRequest.DW_INTERVAL_NOT_INIT,
+ equalTo(configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_24GHZ]));
+ collector.checkThat("mDiscoveryWindowInterval[5GHz]", dwWindow5GHz,
+ equalTo(configRequest.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_5GHZ]));
}
@Test(expected = IllegalArgumentException.class)
@@ -633,16 +627,44 @@
new ConfigRequest.Builder().setClusterLow(100).setClusterHigh(5).build();
}
+ @Test(expected = IllegalArgumentException.class)
+ public void testConfigRequestBuilderDwIntervalInvalidBand() {
+ new ConfigRequest.Builder().setDiscoveryWindowInterval(5, 1).build();
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testConfigRequestBuilderDwIntervalInvalidValueZero() {
+ new ConfigRequest.Builder().setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_24GHZ,
+ 0).build();
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testConfigRequestBuilderDwIntervalInvalidValueLarge() {
+ new ConfigRequest.Builder().setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_5GHZ,
+ 6).build();
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testConfigRequestBuilderDwIntervalInvalidValueLargeValidate() {
+ ConfigRequest cr = new ConfigRequest.Builder().build();
+ cr.mDiscoveryWindowInterval[ConfigRequest.NAN_BAND_5GHZ] = 6;
+ cr.validate();
+ }
+
@Test
public void testConfigRequestParcel() {
final int clusterHigh = 189;
final int clusterLow = 25;
final int masterPreference = 177;
final boolean supportBand5g = true;
+ final int dwWindow24GHz = 1;
+ final int dwWindow5GHz = 5;
ConfigRequest configRequest = new ConfigRequest.Builder().setClusterHigh(clusterHigh)
.setClusterLow(clusterLow).setMasterPreference(masterPreference)
.setSupport5gBand(supportBand5g)
+ .setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_24GHZ, dwWindow24GHz)
+ .setDiscoveryWindowInterval(ConfigRequest.NAN_BAND_5GHZ, dwWindow5GHz)
.build();
Parcel parcelW = Parcel.obtain();