Merge "Fix issue with force resizing activity when app level doesn't want to" into oc-dev
diff --git a/Android.mk b/Android.mk
index 8daab8f..eb649c9 100644
--- a/Android.mk
+++ b/Android.mk
@@ -1460,7 +1460,8 @@
LOCAL_SRC_FILES := \
$(call all-proto-files-under, core/proto) \
$(call all-proto-files-under, libs/incident/proto)
-include $(BUILD_STATIC_LIBRARY)
+LOCAL_SHARED_LIBRARIES := libprotobuf-cpp-full
+include $(BUILD_SHARED_LIBRARY)
# ==== c++ proto host library ==============================
include $(CLEAR_VARS)
diff --git a/api/current.txt b/api/current.txt
index 5287984..00202b6 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5586,7 +5586,7 @@
method public boolean removeAutomaticZenRule(java.lang.String);
method public final void setInterruptionFilter(int);
method public void setNotificationPolicy(android.app.NotificationManager.Policy);
- method public android.content.ComponentName startServiceInForeground(android.content.Intent, int, android.app.Notification);
+ method public deprecated android.content.ComponentName startServiceInForeground(android.content.Intent, int, android.app.Notification);
method public boolean updateAutomaticZenRule(java.lang.String, android.app.AutomaticZenRule);
field public static final java.lang.String ACTION_INTERRUPTION_FILTER_CHANGED = "android.app.action.INTERRUPTION_FILTER_CHANGED";
field public static final java.lang.String ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED = "android.app.action.NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED";
@@ -5641,6 +5641,7 @@
method public java.lang.String getCreatorPackage();
method public int getCreatorUid();
method public android.os.UserHandle getCreatorUserHandle();
+ method public static android.app.PendingIntent getForegroundService(android.content.Context, int, android.content.Intent, int);
method public android.content.IntentSender getIntentSender();
method public static android.app.PendingIntent getService(android.content.Context, int, android.content.Intent, int);
method public deprecated java.lang.String getTargetPackage();
@@ -8858,6 +8859,7 @@
method public abstract void startActivities(android.content.Intent[], android.os.Bundle);
method public abstract void startActivity(android.content.Intent);
method public abstract void startActivity(android.content.Intent, android.os.Bundle);
+ method public abstract android.content.ComponentName startForegroundService(android.content.Intent);
method public abstract boolean startInstrumentation(android.content.ComponentName, java.lang.String, android.os.Bundle);
method public abstract void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException;
method public abstract void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
@@ -9049,6 +9051,7 @@
method public void startActivities(android.content.Intent[], android.os.Bundle);
method public void startActivity(android.content.Intent);
method public void startActivity(android.content.Intent, android.os.Bundle);
+ method public android.content.ComponentName startForegroundService(android.content.Intent);
method public boolean startInstrumentation(android.content.ComponentName, java.lang.String, android.os.Bundle);
method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException;
method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
@@ -24504,26 +24507,26 @@
}
public final class TvContract {
- method public static final android.net.Uri buildChannelLogoUri(long);
- method public static final android.net.Uri buildChannelLogoUri(android.net.Uri);
- method public static final android.net.Uri buildChannelUri(long);
- method public static final android.net.Uri buildChannelUriForPassthroughInput(java.lang.String);
- method public static final android.net.Uri buildChannelsUriForInput(java.lang.String);
- method public static final java.lang.String buildInputId(android.content.ComponentName);
- method public static final android.net.Uri buildPreviewProgramUri(long);
- method public static final android.net.Uri buildPreviewProgramsUriForChannel(long);
- method public static final android.net.Uri buildPreviewProgramsUriForChannel(android.net.Uri);
- method public static final android.net.Uri buildProgramUri(long);
- method public static final android.net.Uri buildProgramsUriForChannel(long);
- method public static final android.net.Uri buildProgramsUriForChannel(android.net.Uri);
- method public static final android.net.Uri buildProgramsUriForChannel(long, long, long);
- method public static final android.net.Uri buildProgramsUriForChannel(android.net.Uri, long, long);
- method public static final android.net.Uri buildRecordedProgramUri(long);
- method public static final android.net.Uri buildWatchNextProgramUri(long);
- method public static final boolean isChannelUri(android.net.Uri);
- method public static final boolean isChannelUriForPassthroughInput(android.net.Uri);
- method public static final boolean isChannelUriForTunerInput(android.net.Uri);
- method public static final boolean isProgramUri(android.net.Uri);
+ method public static android.net.Uri buildChannelLogoUri(long);
+ method public static android.net.Uri buildChannelLogoUri(android.net.Uri);
+ method public static android.net.Uri buildChannelUri(long);
+ method public static android.net.Uri buildChannelUriForPassthroughInput(java.lang.String);
+ method public static android.net.Uri buildChannelsUriForInput(java.lang.String);
+ method public static java.lang.String buildInputId(android.content.ComponentName);
+ method public static android.net.Uri buildPreviewProgramUri(long);
+ method public static android.net.Uri buildPreviewProgramsUriForChannel(long);
+ method public static android.net.Uri buildPreviewProgramsUriForChannel(android.net.Uri);
+ method public static android.net.Uri buildProgramUri(long);
+ method public static android.net.Uri buildProgramsUriForChannel(long);
+ method public static android.net.Uri buildProgramsUriForChannel(android.net.Uri);
+ method public static android.net.Uri buildProgramsUriForChannel(long, long, long);
+ method public static android.net.Uri buildProgramsUriForChannel(android.net.Uri, long, long);
+ method public static android.net.Uri buildRecordedProgramUri(long);
+ method public static android.net.Uri buildWatchNextProgramUri(long);
+ method public static boolean isChannelUri(android.net.Uri);
+ method public static boolean isChannelUriForPassthroughInput(android.net.Uri);
+ method public static boolean isChannelUriForTunerInput(android.net.Uri);
+ method public static boolean isProgramUri(android.net.Uri);
field public static final java.lang.String ACTION_MAKE_CHANNEL_BROWSABLE = "android.media.tv.action.MAKE_CHANNEL_BROWSABLE";
field public static final java.lang.String ACTION_PREVIEW_PROGRAM_ADDED_TO_WATCH_NEXT = "android.media.tv.action.PREVIEW_PROGRAM_ADDED_TO_WATCH_NEXT";
field public static final java.lang.String ACTION_PREVIEW_PROGRAM_BROWSABLE_DISABLED = "android.media.tv.action.PREVIEW_PROGRAM_BROWSABLE_DISABLED";
@@ -40679,6 +40682,7 @@
method public void startActivities(android.content.Intent[], android.os.Bundle);
method public void startActivity(android.content.Intent);
method public void startActivity(android.content.Intent, android.os.Bundle);
+ method public android.content.ComponentName startForegroundService(android.content.Intent);
method public boolean startInstrumentation(android.content.ComponentName, java.lang.String, android.os.Bundle);
method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException;
method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
@@ -45161,8 +45165,8 @@
method public void addTouchables(java.util.ArrayList<android.view.View>);
method public android.view.ViewPropertyAnimator animate();
method public void announceForAccessibility(java.lang.CharSequence);
- method public boolean autofill(android.view.autofill.AutofillValue);
- method public boolean autofill(android.util.SparseArray<android.view.autofill.AutofillValue>);
+ method public void autofill(android.view.autofill.AutofillValue);
+ method public void autofill(android.util.SparseArray<android.view.autofill.AutofillValue>);
method protected boolean awakenScrollBars();
method protected boolean awakenScrollBars(int);
method protected boolean awakenScrollBars(int, boolean);
@@ -47670,6 +47674,7 @@
method public void unregisterCallback(android.view.autofill.AutofillManager.AutofillCallback);
field public static final java.lang.String EXTRA_ASSIST_STRUCTURE = "android.view.autofill.extra.ASSIST_STRUCTURE";
field public static final java.lang.String EXTRA_AUTHENTICATION_RESULT = "android.view.autofill.extra.AUTHENTICATION_RESULT";
+ field public static final java.lang.String EXTRA_DATA_EXTRAS = "android.view.autofill.extra.DATA_EXTRAS";
field public static final int FLAG_MANUAL_REQUEST = 1; // 0x1
}
@@ -48110,7 +48115,8 @@
public final class TextClassificationManager {
method public java.util.List<android.view.textclassifier.TextLanguage> detectLanguages(java.lang.CharSequence);
- method public android.view.textclassifier.TextClassifier getDefaultTextClassifier();
+ method public android.view.textclassifier.TextClassifier getTextClassifier();
+ method public void setTextClassifier(android.view.textclassifier.TextClassifier);
}
public final class TextClassificationResult {
@@ -48147,9 +48153,6 @@
field public static final java.lang.String TYPE_URL = "url";
}
- public static abstract class TextClassifier.EntityType implements java.lang.annotation.Annotation {
- }
-
public final class TextLanguage {
method public float getConfidenceScore(java.util.Locale);
method public int getEndIndex();
diff --git a/api/removed.txt b/api/removed.txt
index 75da976..af429b8 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -380,6 +380,14 @@
}
+package android.view.textclassifier {
+
+ public final class TextClassificationManager {
+ method public android.view.textclassifier.TextClassifier getDefaultTextClassifier();
+ }
+
+}
+
package android.webkit {
public class WebViewClient {
diff --git a/api/system-current.txt b/api/system-current.txt
index bec8d25..f9e4545 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -5312,6 +5312,7 @@
field public static final int DEFAULT_LIGHTS = 4; // 0x4
field public static final int DEFAULT_SOUND = 1; // 0x1
field public static final int DEFAULT_VIBRATE = 2; // 0x2
+ field public static final java.lang.String EXTRA_ALLOW_DURING_SETUP = "android.allowDuringSetup";
field public static final java.lang.String EXTRA_AUDIO_CONTENTS_URI = "android.audioContents";
field public static final java.lang.String EXTRA_BACKGROUND_IMAGE_URI = "android.backgroundImageUri";
field public static final java.lang.String EXTRA_BIG_TEXT = "android.bigText";
@@ -5779,7 +5780,7 @@
method public boolean removeAutomaticZenRule(java.lang.String);
method public final void setInterruptionFilter(int);
method public void setNotificationPolicy(android.app.NotificationManager.Policy);
- method public android.content.ComponentName startServiceInForeground(android.content.Intent, int, android.app.Notification);
+ method public deprecated android.content.ComponentName startServiceInForeground(android.content.Intent, int, android.app.Notification);
method public boolean updateAutomaticZenRule(java.lang.String, android.app.AutomaticZenRule);
field public static final java.lang.String ACTION_INTERRUPTION_FILTER_CHANGED = "android.app.action.INTERRUPTION_FILTER_CHANGED";
field public static final java.lang.String ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED = "android.app.action.NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED";
@@ -5834,6 +5835,7 @@
method public java.lang.String getCreatorPackage();
method public int getCreatorUid();
method public android.os.UserHandle getCreatorUserHandle();
+ method public static android.app.PendingIntent getForegroundService(android.content.Context, int, android.content.Intent, int);
method public android.content.IntentSender getIntentSender();
method public static android.app.PendingIntent getService(android.content.Context, int, android.content.Intent, int);
method public deprecated java.lang.String getTargetPackage();
@@ -9352,6 +9354,7 @@
method public abstract void startActivities(android.content.Intent[], android.os.Bundle);
method public abstract void startActivity(android.content.Intent);
method public abstract void startActivity(android.content.Intent, android.os.Bundle);
+ method public abstract android.content.ComponentName startForegroundService(android.content.Intent);
method public abstract boolean startInstrumentation(android.content.ComponentName, java.lang.String, android.os.Bundle);
method public abstract void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException;
method public abstract void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
@@ -9557,6 +9560,7 @@
method public void startActivities(android.content.Intent[], android.os.Bundle);
method public void startActivity(android.content.Intent);
method public void startActivity(android.content.Intent, android.os.Bundle);
+ method public android.content.ComponentName startForegroundService(android.content.Intent);
method public boolean startInstrumentation(android.content.ComponentName, java.lang.String, android.os.Bundle);
method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException;
method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
@@ -26433,28 +26437,28 @@
}
public final class TvContract {
- method public static final android.net.Uri buildChannelLogoUri(long);
- method public static final android.net.Uri buildChannelLogoUri(android.net.Uri);
- method public static final android.net.Uri buildChannelUri(long);
- method public static final android.net.Uri buildChannelUriForPassthroughInput(java.lang.String);
- method public static final android.net.Uri buildChannelsUriForInput(java.lang.String);
- method public static final android.net.Uri buildChannelsUriForInput(java.lang.String, boolean);
- method public static final android.net.Uri buildChannelsUriForInput(java.lang.String, java.lang.String, boolean);
- method public static final java.lang.String buildInputId(android.content.ComponentName);
- method public static final android.net.Uri buildPreviewProgramUri(long);
- method public static final android.net.Uri buildPreviewProgramsUriForChannel(long);
- method public static final android.net.Uri buildPreviewProgramsUriForChannel(android.net.Uri);
- method public static final android.net.Uri buildProgramUri(long);
- method public static final android.net.Uri buildProgramsUriForChannel(long);
- method public static final android.net.Uri buildProgramsUriForChannel(android.net.Uri);
- method public static final android.net.Uri buildProgramsUriForChannel(long, long, long);
- method public static final android.net.Uri buildProgramsUriForChannel(android.net.Uri, long, long);
- method public static final android.net.Uri buildRecordedProgramUri(long);
- method public static final android.net.Uri buildWatchNextProgramUri(long);
- method public static final boolean isChannelUri(android.net.Uri);
- method public static final boolean isChannelUriForPassthroughInput(android.net.Uri);
- method public static final boolean isChannelUriForTunerInput(android.net.Uri);
- method public static final boolean isProgramUri(android.net.Uri);
+ method public static android.net.Uri buildChannelLogoUri(long);
+ method public static android.net.Uri buildChannelLogoUri(android.net.Uri);
+ method public static android.net.Uri buildChannelUri(long);
+ method public static android.net.Uri buildChannelUriForPassthroughInput(java.lang.String);
+ method public static android.net.Uri buildChannelsUriForInput(java.lang.String);
+ method public static android.net.Uri buildChannelsUriForInput(java.lang.String, boolean);
+ method public static android.net.Uri buildChannelsUriForInput(java.lang.String, java.lang.String, boolean);
+ method public static java.lang.String buildInputId(android.content.ComponentName);
+ method public static android.net.Uri buildPreviewProgramUri(long);
+ method public static android.net.Uri buildPreviewProgramsUriForChannel(long);
+ method public static android.net.Uri buildPreviewProgramsUriForChannel(android.net.Uri);
+ method public static android.net.Uri buildProgramUri(long);
+ method public static android.net.Uri buildProgramsUriForChannel(long);
+ method public static android.net.Uri buildProgramsUriForChannel(android.net.Uri);
+ method public static android.net.Uri buildProgramsUriForChannel(long, long, long);
+ method public static android.net.Uri buildProgramsUriForChannel(android.net.Uri, long, long);
+ method public static android.net.Uri buildRecordedProgramUri(long);
+ method public static android.net.Uri buildWatchNextProgramUri(long);
+ method public static boolean isChannelUri(android.net.Uri);
+ method public static boolean isChannelUriForPassthroughInput(android.net.Uri);
+ method public static boolean isChannelUriForTunerInput(android.net.Uri);
+ method public static boolean isProgramUri(android.net.Uri);
field public static final java.lang.String ACTION_MAKE_CHANNEL_BROWSABLE = "android.media.tv.action.MAKE_CHANNEL_BROWSABLE";
field public static final java.lang.String ACTION_PREVIEW_PROGRAM_ADDED_TO_WATCH_NEXT = "android.media.tv.action.PREVIEW_PROGRAM_ADDED_TO_WATCH_NEXT";
field public static final java.lang.String ACTION_PREVIEW_PROGRAM_BROWSABLE_DISABLED = "android.media.tv.action.PREVIEW_PROGRAM_BROWSABLE_DISABLED";
@@ -44116,6 +44120,7 @@
method public void startActivities(android.content.Intent[], android.os.Bundle);
method public void startActivity(android.content.Intent);
method public void startActivity(android.content.Intent, android.os.Bundle);
+ method public android.content.ComponentName startForegroundService(android.content.Intent);
method public boolean startInstrumentation(android.content.ComponentName, java.lang.String, android.os.Bundle);
method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException;
method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
@@ -48616,8 +48621,8 @@
method public void addTouchables(java.util.ArrayList<android.view.View>);
method public android.view.ViewPropertyAnimator animate();
method public void announceForAccessibility(java.lang.CharSequence);
- method public boolean autofill(android.view.autofill.AutofillValue);
- method public boolean autofill(android.util.SparseArray<android.view.autofill.AutofillValue>);
+ method public void autofill(android.view.autofill.AutofillValue);
+ method public void autofill(android.util.SparseArray<android.view.autofill.AutofillValue>);
method protected boolean awakenScrollBars();
method protected boolean awakenScrollBars(int);
method protected boolean awakenScrollBars(int, boolean);
@@ -51128,6 +51133,7 @@
method public void unregisterCallback(android.view.autofill.AutofillManager.AutofillCallback);
field public static final java.lang.String EXTRA_ASSIST_STRUCTURE = "android.view.autofill.extra.ASSIST_STRUCTURE";
field public static final java.lang.String EXTRA_AUTHENTICATION_RESULT = "android.view.autofill.extra.AUTHENTICATION_RESULT";
+ field public static final java.lang.String EXTRA_DATA_EXTRAS = "android.view.autofill.extra.DATA_EXTRAS";
field public static final int FLAG_MANUAL_REQUEST = 1; // 0x1
}
@@ -51568,7 +51574,8 @@
public final class TextClassificationManager {
method public java.util.List<android.view.textclassifier.TextLanguage> detectLanguages(java.lang.CharSequence);
- method public android.view.textclassifier.TextClassifier getDefaultTextClassifier();
+ method public android.view.textclassifier.TextClassifier getTextClassifier();
+ method public void setTextClassifier(android.view.textclassifier.TextClassifier);
}
public final class TextClassificationResult {
@@ -51605,9 +51612,6 @@
field public static final java.lang.String TYPE_URL = "url";
}
- public static abstract class TextClassifier.EntityType implements java.lang.annotation.Annotation {
- }
-
public final class TextLanguage {
method public float getConfidenceScore(java.util.Locale);
method public int getEndIndex();
diff --git a/api/system-removed.txt b/api/system-removed.txt
index 3aa9398..272ae77 100644
--- a/api/system-removed.txt
+++ b/api/system-removed.txt
@@ -374,6 +374,14 @@
}
+package android.view.textclassifier {
+
+ public final class TextClassificationManager {
+ method public android.view.textclassifier.TextClassifier getDefaultTextClassifier();
+ }
+
+}
+
package android.webkit {
public class WebViewClient {
diff --git a/api/test-current.txt b/api/test-current.txt
index e9f94d9..f800461 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -5599,7 +5599,7 @@
method public boolean removeAutomaticZenRule(java.lang.String);
method public final void setInterruptionFilter(int);
method public void setNotificationPolicy(android.app.NotificationManager.Policy);
- method public android.content.ComponentName startServiceInForeground(android.content.Intent, int, android.app.Notification);
+ method public deprecated android.content.ComponentName startServiceInForeground(android.content.Intent, int, android.app.Notification);
method public boolean updateAutomaticZenRule(java.lang.String, android.app.AutomaticZenRule);
field public static final java.lang.String ACTION_INTERRUPTION_FILTER_CHANGED = "android.app.action.INTERRUPTION_FILTER_CHANGED";
field public static final java.lang.String ACTION_NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED = "android.app.action.NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED";
@@ -5654,6 +5654,7 @@
method public java.lang.String getCreatorPackage();
method public int getCreatorUid();
method public android.os.UserHandle getCreatorUserHandle();
+ method public static android.app.PendingIntent getForegroundService(android.content.Context, int, android.content.Intent, int);
method public android.content.IntentSender getIntentSender();
method public static android.app.PendingIntent getService(android.content.Context, int, android.content.Intent, int);
method public deprecated java.lang.String getTargetPackage();
@@ -8890,6 +8891,7 @@
method public abstract void startActivities(android.content.Intent[], android.os.Bundle);
method public abstract void startActivity(android.content.Intent);
method public abstract void startActivity(android.content.Intent, android.os.Bundle);
+ method public abstract android.content.ComponentName startForegroundService(android.content.Intent);
method public abstract boolean startInstrumentation(android.content.ComponentName, java.lang.String, android.os.Bundle);
method public abstract void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException;
method public abstract void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
@@ -9082,6 +9084,7 @@
method public void startActivities(android.content.Intent[], android.os.Bundle);
method public void startActivity(android.content.Intent);
method public void startActivity(android.content.Intent, android.os.Bundle);
+ method public android.content.ComponentName startForegroundService(android.content.Intent);
method public boolean startInstrumentation(android.content.ComponentName, java.lang.String, android.os.Bundle);
method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException;
method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
@@ -24617,26 +24620,26 @@
}
public final class TvContract {
- method public static final android.net.Uri buildChannelLogoUri(long);
- method public static final android.net.Uri buildChannelLogoUri(android.net.Uri);
- method public static final android.net.Uri buildChannelUri(long);
- method public static final android.net.Uri buildChannelUriForPassthroughInput(java.lang.String);
- method public static final android.net.Uri buildChannelsUriForInput(java.lang.String);
- method public static final java.lang.String buildInputId(android.content.ComponentName);
- method public static final android.net.Uri buildPreviewProgramUri(long);
- method public static final android.net.Uri buildPreviewProgramsUriForChannel(long);
- method public static final android.net.Uri buildPreviewProgramsUriForChannel(android.net.Uri);
- method public static final android.net.Uri buildProgramUri(long);
- method public static final android.net.Uri buildProgramsUriForChannel(long);
- method public static final android.net.Uri buildProgramsUriForChannel(android.net.Uri);
- method public static final android.net.Uri buildProgramsUriForChannel(long, long, long);
- method public static final android.net.Uri buildProgramsUriForChannel(android.net.Uri, long, long);
- method public static final android.net.Uri buildRecordedProgramUri(long);
- method public static final android.net.Uri buildWatchNextProgramUri(long);
- method public static final boolean isChannelUri(android.net.Uri);
- method public static final boolean isChannelUriForPassthroughInput(android.net.Uri);
- method public static final boolean isChannelUriForTunerInput(android.net.Uri);
- method public static final boolean isProgramUri(android.net.Uri);
+ method public static android.net.Uri buildChannelLogoUri(long);
+ method public static android.net.Uri buildChannelLogoUri(android.net.Uri);
+ method public static android.net.Uri buildChannelUri(long);
+ method public static android.net.Uri buildChannelUriForPassthroughInput(java.lang.String);
+ method public static android.net.Uri buildChannelsUriForInput(java.lang.String);
+ method public static java.lang.String buildInputId(android.content.ComponentName);
+ method public static android.net.Uri buildPreviewProgramUri(long);
+ method public static android.net.Uri buildPreviewProgramsUriForChannel(long);
+ method public static android.net.Uri buildPreviewProgramsUriForChannel(android.net.Uri);
+ method public static android.net.Uri buildProgramUri(long);
+ method public static android.net.Uri buildProgramsUriForChannel(long);
+ method public static android.net.Uri buildProgramsUriForChannel(android.net.Uri);
+ method public static android.net.Uri buildProgramsUriForChannel(long, long, long);
+ method public static android.net.Uri buildProgramsUriForChannel(android.net.Uri, long, long);
+ method public static android.net.Uri buildRecordedProgramUri(long);
+ method public static android.net.Uri buildWatchNextProgramUri(long);
+ method public static boolean isChannelUri(android.net.Uri);
+ method public static boolean isChannelUriForPassthroughInput(android.net.Uri);
+ method public static boolean isChannelUriForTunerInput(android.net.Uri);
+ method public static boolean isProgramUri(android.net.Uri);
field public static final java.lang.String ACTION_MAKE_CHANNEL_BROWSABLE = "android.media.tv.action.MAKE_CHANNEL_BROWSABLE";
field public static final java.lang.String ACTION_PREVIEW_PROGRAM_ADDED_TO_WATCH_NEXT = "android.media.tv.action.PREVIEW_PROGRAM_ADDED_TO_WATCH_NEXT";
field public static final java.lang.String ACTION_PREVIEW_PROGRAM_BROWSABLE_DISABLED = "android.media.tv.action.PREVIEW_PROGRAM_BROWSABLE_DISABLED";
@@ -40883,6 +40886,7 @@
method public void startActivities(android.content.Intent[], android.os.Bundle);
method public void startActivity(android.content.Intent);
method public void startActivity(android.content.Intent, android.os.Bundle);
+ method public android.content.ComponentName startForegroundService(android.content.Intent);
method public boolean startInstrumentation(android.content.ComponentName, java.lang.String, android.os.Bundle);
method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int) throws android.content.IntentSender.SendIntentException;
method public void startIntentSender(android.content.IntentSender, android.content.Intent, int, int, int, android.os.Bundle) throws android.content.IntentSender.SendIntentException;
@@ -45535,8 +45539,8 @@
method public void addTouchables(java.util.ArrayList<android.view.View>);
method public android.view.ViewPropertyAnimator animate();
method public void announceForAccessibility(java.lang.CharSequence);
- method public boolean autofill(android.view.autofill.AutofillValue);
- method public boolean autofill(android.util.SparseArray<android.view.autofill.AutofillValue>);
+ method public void autofill(android.view.autofill.AutofillValue);
+ method public void autofill(android.util.SparseArray<android.view.autofill.AutofillValue>);
method protected boolean awakenScrollBars();
method protected boolean awakenScrollBars(int);
method protected boolean awakenScrollBars(int, boolean);
@@ -48053,6 +48057,7 @@
method public void unregisterCallback(android.view.autofill.AutofillManager.AutofillCallback);
field public static final java.lang.String EXTRA_ASSIST_STRUCTURE = "android.view.autofill.extra.ASSIST_STRUCTURE";
field public static final java.lang.String EXTRA_AUTHENTICATION_RESULT = "android.view.autofill.extra.AUTHENTICATION_RESULT";
+ field public static final java.lang.String EXTRA_DATA_EXTRAS = "android.view.autofill.extra.DATA_EXTRAS";
field public static final int FLAG_MANUAL_REQUEST = 1; // 0x1
}
@@ -48493,7 +48498,8 @@
public final class TextClassificationManager {
method public java.util.List<android.view.textclassifier.TextLanguage> detectLanguages(java.lang.CharSequence);
- method public android.view.textclassifier.TextClassifier getDefaultTextClassifier();
+ method public android.view.textclassifier.TextClassifier getTextClassifier();
+ method public void setTextClassifier(android.view.textclassifier.TextClassifier);
}
public final class TextClassificationResult {
@@ -48530,9 +48536,6 @@
field public static final java.lang.String TYPE_URL = "url";
}
- public static abstract class TextClassifier.EntityType implements java.lang.annotation.Annotation {
- }
-
public final class TextLanguage {
method public float getConfidenceScore(java.util.Locale);
method public int getEndIndex();
diff --git a/api/test-removed.txt b/api/test-removed.txt
index 75da976..af429b8 100644
--- a/api/test-removed.txt
+++ b/api/test-removed.txt
@@ -380,6 +380,14 @@
}
+package android.view.textclassifier {
+
+ public final class TextClassificationManager {
+ method public android.view.textclassifier.TextClassifier getDefaultTextClassifier();
+ }
+
+}
+
package android.webkit {
public class WebViewClient {
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index bace226..147b5d0 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -2740,6 +2740,10 @@
return true;
}
return false;
+ } else if (keyCode == KeyEvent.KEYCODE_TAB) {
+ // Don't consume TAB here since it's used for navigation. Arrow keys
+ // aren't considered "typing keys" so they already won't get consumed.
+ return false;
} else {
// Common code for DEFAULT_KEYS_DIALER & DEFAULT_KEYS_SEARCH_*
boolean clearSpannable = false;
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 9f2f669..4004bd6 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -405,6 +405,13 @@
*/
public static final int INTENT_SENDER_SERVICE = 4;
+ /**
+ * Type for IActivityManaqer.getIntentSender: this PendingIntent is
+ * for a startForegroundService operation.
+ * @hide
+ */
+ public static final int INTENT_SENDER_FOREGROUND_SERVICE = 5;
+
/** @hide User operation call: success! */
public static final int USER_OP_SUCCESS = 0;
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 4c080c9..467ba99 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -1447,14 +1447,21 @@
@Override
public ComponentName startService(Intent service) {
warnIfCallingFromSystemProcess();
- return startServiceCommon(service, -1, null, mUser);
+ return startServiceCommon(service, -1, null, false, mUser);
}
@Override
+ public ComponentName startForegroundService(Intent service) {
+ warnIfCallingFromSystemProcess();
+ return startServiceCommon(service, -1, null, true, mUser);
+ }
+
+ // STOPSHIP: remove when NotificationManager.startServiceInForeground() is retired
+ @Override
public ComponentName startServiceInForeground(Intent service,
int id, Notification notification) {
warnIfCallingFromSystemProcess();
- return startServiceCommon(service, id, notification, mUser);
+ return startServiceCommon(service, id, notification, false, mUser);
}
@Override
@@ -1465,24 +1472,30 @@
@Override
public ComponentName startServiceAsUser(Intent service, UserHandle user) {
- return startServiceCommon(service, -1, null, user);
+ return startServiceCommon(service, -1, null, false, user);
}
@Override
+ public ComponentName startForegroundServiceAsUser(Intent service, UserHandle user) {
+ return startServiceCommon(service, -1, null, true, user);
+ }
+
+ // STOPSHIP: remove when NotificationManager.startServiceInForeground() is retired
+ @Override
public ComponentName startServiceInForegroundAsUser(Intent service,
int id, Notification notification, UserHandle user) {
- return startServiceCommon(service, id, notification, user);
+ return startServiceCommon(service, id, notification, false, user);
}
private ComponentName startServiceCommon(Intent service, int id, Notification notification,
- UserHandle user) {
+ boolean requireForeground, UserHandle user) {
try {
validateServiceIntent(service);
service.prepareToLeaveProcess(this);
ComponentName cn = ActivityManager.getService().startService(
mMainThread.getApplicationThread(), service, service.resolveTypeIfNeeded(
- getContentResolver()), id, notification, getOpPackageName(),
- user.getIdentifier());
+ getContentResolver()), id, notification, requireForeground,
+ getOpPackageName(), user.getIdentifier());
if (cn != null) {
if (cn.getPackageName().equals("!")) {
throw new SecurityException(
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index 5d025d9..0c1be07 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -2725,7 +2725,15 @@
for (int i = 0; i < count; i++) {
Fragment f = nonConfigFragments.get(i);
if (DEBUG) Log.v(TAG, "restoreAllState: re-attaching retained " + f);
- FragmentState fs = fms.mActive[f.mIndex];
+ int index = 0; // index of f in fms.mActive
+ while (index < fms.mActive.length && fms.mActive[index].mIndex != f.mIndex) {
+ index++;
+ }
+ if (index == fms.mActive.length) {
+ throwException(new IllegalStateException("Could not find active fragment "
+ + "with index " + f.mIndex));
+ }
+ FragmentState fs = fms.mActive[index];
fs.mInstance = f;
f.mSavedViewState = null;
f.mBackStackNesting = 0;
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index b9d1d91..0a5e4be 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -130,7 +130,7 @@
PendingIntent getRunningServiceControlPanel(in ComponentName service);
ComponentName startService(in IApplicationThread caller, in Intent service,
in String resolvedType, int id, in Notification notification,
- in String callingPackage, int userId);
+ boolean requireForeground, in String callingPackage, int userId);
int stopService(in IApplicationThread caller, in Intent service,
in String resolvedType, int userId);
int bindService(in IApplicationThread caller, in IBinder token, in Intent service,
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index c78b3cd..4bbc003 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -971,6 +971,7 @@
* Only available to notifications coming from the android package.
* @hide
*/
+ @SystemApi
public static final String EXTRA_ALLOW_DURING_SETUP = "android.allowDuringSetup";
/**
diff --git a/core/java/android/app/NotificationManager.java b/core/java/android/app/NotificationManager.java
index 75998f2..72c5978 100644
--- a/core/java/android/app/NotificationManager.java
+++ b/core/java/android/app/NotificationManager.java
@@ -1171,8 +1171,11 @@
* @return If the service is being started or is already running, the
* {@link ComponentName} of the actual service that was started is
* returned; else if the service does not exist null is returned.
+ *
+ * @deprecated STOPSHIP transition away from this for O
*/
@Nullable
+ @Deprecated
public ComponentName startServiceInForeground(Intent service,
int id, Notification notification) {
return mContext.startServiceInForeground(service, id, notification);
diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java
index 7d1a16a..dc432af 100644
--- a/core/java/android/app/PendingIntent.java
+++ b/core/java/android/app/PendingIntent.java
@@ -596,6 +596,42 @@
*/
public static PendingIntent getService(Context context, int requestCode,
@NonNull Intent intent, @Flags int flags) {
+ return buildServicePendingIntent(context, requestCode, intent, flags,
+ ActivityManager.INTENT_SENDER_SERVICE);
+ }
+
+ /**
+ * Retrieve a PendingIntent that will start a foreground service, like calling
+ * {@link Context#startService Context.startForegroundService()}. The start
+ * arguments given to the service will come from the extras of the Intent.
+ *
+ * <p class="note">For security reasons, the {@link android.content.Intent}
+ * you supply here should almost always be an <em>explicit intent</em>,
+ * that is specify an explicit component to be delivered to through
+ * {@link Intent#setClass(android.content.Context, Class) Intent.setClass}</p>
+ *
+ * @param context The Context in which this PendingIntent should start
+ * the service.
+ * @param requestCode Private request code for the sender
+ * @param intent An Intent describing the service to be started.
+ * @param flags May be {@link #FLAG_ONE_SHOT}, {@link #FLAG_NO_CREATE},
+ * {@link #FLAG_CANCEL_CURRENT}, {@link #FLAG_UPDATE_CURRENT},
+ * {@link #FLAG_IMMUTABLE} or any of the flags as supported by
+ * {@link Intent#fillIn Intent.fillIn()} to control which unspecified parts
+ * of the intent that can be supplied when the actual send happens.
+ *
+ * @return Returns an existing or new PendingIntent matching the given
+ * parameters. May return null only if {@link #FLAG_NO_CREATE} has been
+ * supplied.
+ */
+ public static PendingIntent getForegroundService(Context context, int requestCode,
+ @NonNull Intent intent, @Flags int flags) {
+ return buildServicePendingIntent(context, requestCode, intent, flags,
+ ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE);
+ }
+
+ private static PendingIntent buildServicePendingIntent(Context context, int requestCode,
+ Intent intent, int flags, int serviceKind) {
String packageName = context.getPackageName();
String resolvedType = intent != null ? intent.resolveTypeIfNeeded(
context.getContentResolver()) : null;
@@ -603,7 +639,7 @@
intent.prepareToLeaveProcess(context);
IIntentSender target =
ActivityManager.getService().getIntentSender(
- ActivityManager.INTENT_SENDER_SERVICE, packageName,
+ serviceKind, packageName,
null, null, requestCode, new Intent[] { intent },
resolvedType != null ? new String[] { resolvedType } : null,
flags, null, UserHandle.myUserId());
diff --git a/core/java/android/app/job/JobInfo.java b/core/java/android/app/job/JobInfo.java
index 78e4c0d..f9094c0 100644
--- a/core/java/android/app/job/JobInfo.java
+++ b/core/java/android/app/job/JobInfo.java
@@ -83,6 +83,9 @@
/* Minimum flex for a periodic job, in milliseconds. */
private static final long MIN_FLEX_MILLIS = 5 * 60 * 1000L; // 5 minutes
+ /* Minimum backoff interval for a job, in milliseconds */
+ private static final long MIN_BACKOFF_MILLIS = 10 * 1000L; // 10 seconds
+
/**
* Query the minimum interval allowed for periodic scheduled jobs. Attempting
* to declare a smaller period that this when scheduling a job will result in a
@@ -106,6 +109,14 @@
}
/**
+ * Query the minimum automatic-reschedule backoff interval permitted for jobs.
+ * @hide
+ */
+ public static final long getMinBackoffMillis() {
+ return MIN_BACKOFF_MILLIS;
+ }
+
+ /**
* Default type of backoff.
* @hide
*/
@@ -361,7 +372,8 @@
* job does not recur periodically.
*/
public long getIntervalMillis() {
- return intervalMillis >= getMinPeriodMillis() ? intervalMillis : getMinPeriodMillis();
+ final long minInterval = getMinPeriodMillis();
+ return intervalMillis >= minInterval ? intervalMillis : minInterval;
}
/**
@@ -381,7 +393,8 @@
* to 5 seconds.
*/
public long getInitialBackoffMillis() {
- return initialBackoffMillis;
+ final long minBackoff = getMinBackoffMillis();
+ return initialBackoffMillis >= minBackoff ? initialBackoffMillis : minBackoff;
}
/**
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 3a8a420..1803bbe 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -2576,7 +2576,7 @@
* {@link ComponentName} of the actual service that was started is
* returned; else if the service does not exist null is returned.
*
- * @throws SecurityException If the caller does not permission to access the service
+ * @throws SecurityException If the caller does not have permission to access the service
* or the service can not be found.
* @throws IllegalStateException If the application is in a state where the service
* can not be started (such as not in the foreground in a state when services are allowed).
@@ -2588,11 +2588,47 @@
public abstract ComponentName startService(Intent service);
/**
+ * Similar to {@link #startService(Intent)}, but with an implicit promise that the
+ * Service will call {@link android.app.Service#startForeground(int, Notification)
+ * startForeground(int, Notification)} once it begins running. The service is given
+ * an amount of time comparable to the ANR interval to do this, otherwise the system
+ * will automatically stop the service and declare the app ANR.
+ *
+ * <p>Unlike the ordinary {@link #startService(Intent)}, this method can be used
+ * at any time, regardless of whether the app hosting the service is in a foreground
+ * state.
+ *
+ * @param service Identifies the service to be started. The Intent must be
+ * fully explicit (supplying a component name). Additional values
+ * may be included in the Intent extras to supply arguments along with
+ * this specific start call.
+ *
+ * @return If the service is being started or is already running, the
+ * {@link ComponentName} of the actual service that was started is
+ * returned; else if the service does not exist null is returned.
+ *
+ * @throws SecurityException If the caller does not have permission to access the service
+ * or the service can not be found.
+ *
+ * @see #stopService
+ * @see android.app.Service#startForeground(int, Notification)
+ */
+ @Nullable
+ public abstract ComponentName startForegroundService(Intent service);
+
+ /**
+ * @hide like {@link #startForegroundService(Intent)} but for a specific user.
+ */
+ @Nullable
+ public abstract ComponentName startForegroundServiceAsUser(Intent service, UserHandle user);
+
+ /**
* Start a service directly into the "foreground service" state. Unlike {@link #startService},
* this method can be used from within background operations like broadcast receivers
* or scheduled jobs. The API entry point for this is in NotificationManager in order to
* preserve appropriate public package layering.
* @hide
+ * @deprecated STOPSHIP remove in favor of two-step startForegroundService() + startForeground()
*/
@Nullable
public abstract ComponentName startServiceInForeground(Intent service,
@@ -2620,7 +2656,7 @@
* @return If there is a service matching the given Intent that is already
* running, then it is stopped and {@code true} is returned; else {@code false} is returned.
*
- * @throws SecurityException If the caller does not permission to access the service
+ * @throws SecurityException If the caller does not have permission to access the service
* or the service can not be found.
* @throws IllegalStateException If the application is in a state where the service
* can not be started (such as not in the foreground in a state when services are allowed).
@@ -2638,7 +2674,9 @@
/**
* @hide like {@link #startServiceInForeground(Intent, int, Notification)}
* but for a specific user.
+ * @deprecated STOPSHIP remove when trial API is turned off
*/
+ @Deprecated
@Nullable
public abstract ComponentName startServiceInForegroundAsUser(Intent service,
int id, Notification notification, UserHandle user);
@@ -2685,7 +2723,7 @@
* {@code false} is returned if the connection is not made so you will not
* receive the service object.
*
- * @throws SecurityException If the caller does not permission to access the service
+ * @throws SecurityException If the caller does not have permission to access the service
* or the service can not be found.
*
* @see #unbindService
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index 6b0bbfa..75784a6 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -644,7 +644,12 @@
return mBase.startService(service);
}
- /** @hide */
+ @Override
+ public ComponentName startForegroundService(Intent service) {
+ return mBase.startForegroundService(service);
+ }
+
+ /** @hide STOPSHIP remove when trial API is turned down */
@Override
public ComponentName startServiceInForeground(Intent service,
int id, Notification notification) {
@@ -664,6 +669,12 @@
/** @hide */
@Override
+ public ComponentName startForegroundServiceAsUser(Intent service, UserHandle user) {
+ return mBase.startForegroundServiceAsUser(service, user);
+ }
+
+ /** @hide STOPSHIP removed when trial API is turned down */
+ @Override
public ComponentName startServiceInForegroundAsUser(Intent service,
int id, Notification notification, UserHandle user) {
return mBase.startServiceInForegroundAsUser(service, id, notification, user);
diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java
index 370af17..16d582ef 100644
--- a/core/java/android/content/pm/PackageManagerInternal.java
+++ b/core/java/android/content/pm/PackageManagerInternal.java
@@ -314,4 +314,17 @@
*/
public abstract ResolveInfo resolveIntent(Intent intent, String resolvedType,
int flags, int userId);
+
+ /**
+ * Track the creator of a new isolated uid.
+ * @param isolatedUid The newly created isolated uid.
+ * @param ownerUid The uid of the app that created the isolated process.
+ */
+ public abstract void addIsolatedUid(int isolatedUid, int ownerUid);
+
+ /**
+ * Track removal of an isolated uid.
+ * @param isolatedUid isolated uid that is no longer being used.
+ */
+ public abstract void removeIsolatedUid(int isolatedUid);
}
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index 5fa2461..5f66abd 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -741,6 +741,10 @@
int timeTotal = -1;
int uncryptTime = -1;
int sourceVersion = -1;
+ int temperature_start = -1;
+ int temperature_end = -1;
+ int temperature_max = -1;
+
while ((line = in.readLine()) != null) {
// Here is an example of lines in last_install:
// ...
@@ -785,6 +789,12 @@
} else if (line.startsWith("bytes_stashed")) {
bytesStashedInMiB = (bytesStashedInMiB == -1) ? scaled :
bytesStashedInMiB + scaled;
+ } else if (line.startsWith("temperature_start")) {
+ temperature_start = scaled;
+ } else if (line.startsWith("temperature_end")) {
+ temperature_end = scaled;
+ } else if (line.startsWith("temperature_max")) {
+ temperature_max = scaled;
}
}
@@ -804,6 +814,15 @@
if (bytesStashedInMiB != -1) {
MetricsLogger.histogram(context, "ota_stashed_in_MiBs", bytesStashedInMiB);
}
+ if (temperature_start != -1) {
+ MetricsLogger.histogram(context, "ota_temperature_start", temperature_start);
+ }
+ if (temperature_end != -1) {
+ MetricsLogger.histogram(context, "ota_temperature_end", temperature_end);
+ }
+ if (temperature_max != -1) {
+ MetricsLogger.histogram(context, "ota_temperature_max", temperature_max);
+ }
} catch (IOException e) {
Log.e(TAG, "Failed to read lines in last_install", e);
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 42575b6..a6bf2d2 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -369,8 +369,10 @@
public static final String DISALLOW_ADD_MANAGED_PROFILE = "no_add_managed_profile";
/**
- * Specifies if a user is disallowed from disabling application
- * verification. The default value is <code>false</code>.
+ * Specifies if a user is disallowed from disabling application verification.
+ * Starting from {@link android.os.Build.VERSION_CODES#O}, application verification
+ * is enforced across all users on the device if a profile owner or device owner sets
+ * this restriction to <code>true</code>. The default value is <code>false</code>.
*
* <p>Key for user restrictions.
* <p>Type: Boolean
diff --git a/core/java/android/view/ContextThemeWrapper.java b/core/java/android/view/ContextThemeWrapper.java
index 86318e9..d3cc175 100644
--- a/core/java/android/view/ContextThemeWrapper.java
+++ b/core/java/android/view/ContextThemeWrapper.java
@@ -36,8 +36,8 @@
/**
* Creates a new context wrapper with no theme and no base context.
- * <p>
- * <stong>Note:</strong> A base context <strong>must</strong> be attached
+ * <p class="note">
+ * <strong>Note:</strong> A base context <strong>must</strong> be attached
* using {@link #attachBaseContext(Context)} before calling any other
* method on the newly constructed context wrapper.
*/
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java
index 519c1e2..1cb563f 100644
--- a/core/java/android/view/SurfaceControl.java
+++ b/core/java/android/view/SurfaceControl.java
@@ -451,10 +451,6 @@
return nativeGetHandle(mNativeObject);
}
- public boolean getTransformToDisplayInverse() {
- return nativeGetTransformToDisplayInverse(mNativeObject);
- }
-
/** flag the transaction as an animation */
public static void setAnimationTransaction() {
nativeSetAnimationTransaction();
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index e924f77..23fcb55 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -7447,11 +7447,8 @@
* </pre>
*
* @param value value to be autofilled.
- *
- * @return {@code true} if the view was successfully autofilled, {@code false} otherwise
*/
- public boolean autofill(@SuppressWarnings("unused") AutofillValue value) {
- return false;
+ public void autofill(@SuppressWarnings("unused") AutofillValue value) {
}
/**
@@ -7461,12 +7458,8 @@
* {@link #onProvideAutofillVirtualStructure(ViewStructure, int)} for more info.
*
* @param values map of values to be autofilled, keyed by virtual child id.
- *
- * @return {@code true} if the view was successfully autofilled, {@code false} otherwise
*/
- public boolean autofill(
- @NonNull @SuppressWarnings("unused") SparseArray<AutofillValue>values) {
- return false;
+ public void autofill(@NonNull @SuppressWarnings("unused") SparseArray<AutofillValue> values) {
}
/**
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index a43b13e..2e201bf 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -6386,7 +6386,7 @@
args.arg2 = sameProcessCall ? new Rect(contentInsets) : contentInsets;
args.arg3 = sameProcessCall ? new Rect(visibleInsets) : visibleInsets;
args.arg4 = sameProcessCall && mergedConfiguration != null
- ? new MergedConfiguration(mergedConfiguration) : null;
+ ? new MergedConfiguration(mergedConfiguration) : mergedConfiguration;
args.arg5 = sameProcessCall ? new Rect(overscanInsets) : overscanInsets;
args.arg6 = sameProcessCall ? new Rect(stableInsets) : stableInsets;
args.arg7 = sameProcessCall ? new Rect(outsets) : outsets;
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index b4d2c6b..19980fb 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -56,9 +56,9 @@
/**
* Intent extra: The assist structure which captures the filled screen.
+ *
* <p>
* Type: {@link android.app.assist.AssistStructure}
- * </p>
*/
public static final String EXTRA_ASSIST_STRUCTURE =
"android.view.autofill.extra.ASSIST_STRUCTURE";
@@ -72,11 +72,25 @@
* <p>
* Type: {@link android.service.autofill.FillResponse} or a
* {@link android.service.autofill.Dataset}
- * </p>
*/
public static final String EXTRA_AUTHENTICATION_RESULT =
"android.view.autofill.extra.AUTHENTICATION_RESULT";
+ /**
+ * Intent extra: The optional extras provided by the
+ * {@link android.service.autofill.AutofillService}.
+ *
+ * <p>For example, when the service responds to a {@link
+ * android.service.autofill.FillCallback#onSuccess(android.service.autofill.FillResponse)} with
+ * a {@code FillResponse} that requires authentication, the Intent that launches the
+ * service authentication will contain the Bundle set by
+ * {@link android.service.autofill.FillResponse.Builder#setExtras(Bundle)} on this extra.
+ *
+ * <p>
+ * Type: {@link android.os.Bundle}
+ */
+ public static final String EXTRA_DATA_EXTRAS = "android.view.autofill.extra.DATA_EXTRAS";
+
// Public flags start from the lowest bit
/**
* Indicates autofill was explicitly requested by the user.
@@ -554,9 +568,8 @@
}
valuesByParent.put(id.getVirtualChildId(), value);
} else {
- if (view.autofill(value)) {
- numApplied++;
- }
+ view.autofill(value);
+ numApplied++;
}
}
@@ -564,9 +577,8 @@
for (int i = 0; i < virtualValues.size(); i++) {
final View parent = virtualValues.keyAt(i);
final SparseArray<AutofillValue> childrenValues = virtualValues.valueAt(i);
- if (parent.autofill(childrenValues)) {
- numApplied += childrenValues.size();
- }
+ parent.autofill(childrenValues);
+ numApplied += childrenValues.size();
}
}
diff --git a/core/java/android/view/textclassifier/TextClassificationManager.java b/core/java/android/view/textclassifier/TextClassificationManager.java
index 5487965..0b6021a 100644
--- a/core/java/android/view/textclassifier/TextClassificationManager.java
+++ b/core/java/android/view/textclassifier/TextClassificationManager.java
@@ -17,6 +17,7 @@
package android.view.textclassifier;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.Context;
import android.os.ParcelFileDescriptor;
import android.util.Log;
@@ -45,7 +46,7 @@
private final Context mContext;
private ParcelFileDescriptor mLangIdFd;
- private TextClassifier mDefault;
+ private TextClassifier mTextClassifier;
private LangId mLangId;
/** @hide */
@@ -53,15 +54,32 @@
mContext = Preconditions.checkNotNull(context);
}
- /**
- * Returns the default text classifier.
- */
+ // TODO: Remove.
+ /** @removed */
public TextClassifier getDefaultTextClassifier() {
+ return getTextClassifier();
+ }
+
+ /**
+ * Returns the text classifier.
+ */
+ public TextClassifier getTextClassifier() {
synchronized (mTextClassifierLock) {
- if (mDefault == null) {
- mDefault = new TextClassifierImpl(mContext);
+ if (mTextClassifier == null) {
+ mTextClassifier = new TextClassifierImpl(mContext);
}
- return mDefault;
+ return mTextClassifier;
+ }
+ }
+
+ /**
+ * Sets the text classifier.
+ * Set to null to use the system default text classifier.
+ * Set to {@link TextClassifier#NO_OP} to disable text classifier features.
+ */
+ public void setTextClassifier(@Nullable TextClassifier textClassifier) {
+ synchronized (mTextClassifierLock) {
+ mTextClassifier = textClassifier;
}
}
diff --git a/core/java/android/view/textclassifier/TextClassifier.java b/core/java/android/view/textclassifier/TextClassifier.java
index dabbf31..0831e20 100644
--- a/core/java/android/view/textclassifier/TextClassifier.java
+++ b/core/java/android/view/textclassifier/TextClassifier.java
@@ -39,9 +39,10 @@
String TYPE_ADDRESS = "address";
String TYPE_URL = "url";
+ /** @hide */
@Retention(RetentionPolicy.SOURCE)
@StringDef({
- TYPE_OTHER, TYPE_EMAIL, TYPE_PHONE, TYPE_ADDRESS
+ TYPE_OTHER, TYPE_EMAIL, TYPE_PHONE, TYPE_ADDRESS, TYPE_URL
})
@interface EntityType {}
diff --git a/core/java/android/widget/AbsSpinner.java b/core/java/android/widget/AbsSpinner.java
index 8f662ba..352e7de 100644
--- a/core/java/android/widget/AbsSpinner.java
+++ b/core/java/android/widget/AbsSpinner.java
@@ -526,15 +526,15 @@
}
@Override
- public boolean autofill(AutofillValue value) {
- if (!isEnabled()) return false;
+ public void autofill(AutofillValue value) {
+ if (!isEnabled()) return;
- if (value.isList()) {
- setSelection(value.getListValue());
- } else {
+ if (!value.isList()) {
Log.w(LOG_TAG, value + " could not be autofilled into " + this);
+ return;
}
- return true;
+
+ setSelection(value.getListValue());
}
@Override
diff --git a/core/java/android/widget/CompoundButton.java b/core/java/android/widget/CompoundButton.java
index 9dc61ab..c7ba7b5 100644
--- a/core/java/android/widget/CompoundButton.java
+++ b/core/java/android/widget/CompoundButton.java
@@ -584,16 +584,15 @@
}
@Override
- public boolean autofill(AutofillValue value) {
- if (!isEnabled()) return false;
+ public void autofill(AutofillValue value) {
+ if (!isEnabled()) return;
- if (value.isToggle()) {
- setChecked(value.getToggleValue());
- } else {
+ if (!value.isToggle()) {
Log.w(LOG_TAG, value + " could not be autofilled into " + this);
+ return;
}
- return true;
+ setChecked(value.getToggleValue());
}
@Override
diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java
index 7d04f35..463ff58 100644
--- a/core/java/android/widget/DatePicker.java
+++ b/core/java/android/widget/DatePicker.java
@@ -775,16 +775,15 @@
}
@Override
- public boolean autofill(AutofillValue value) {
- if (!isEnabled()) return false;
+ public void autofill(AutofillValue value) {
+ if (!isEnabled()) return;
- if (value.isDate()) {
- mDelegate.updateDate(value.getDateValue());
- } else {
+ if (!value.isDate()) {
Log.w(LOG_TAG, value + " could not be autofilled into " + this);
+ return;
}
- return true;
+ mDelegate.updateDate(value.getDateValue());
}
@Override
diff --git a/core/java/android/widget/RadioGroup.java b/core/java/android/widget/RadioGroup.java
index a7574c7..08e6575 100644
--- a/core/java/android/widget/RadioGroup.java
+++ b/core/java/android/widget/RadioGroup.java
@@ -426,24 +426,22 @@
}
@Override
- public boolean autofill(AutofillValue value) {
- if (!isEnabled()) return false;
+ public void autofill(AutofillValue value) {
+ if (!isEnabled()) return;
- int index;
- if (value.isList()) {
- index = value.getListValue();
- } else {
+ if (!value.isList()) {
Log.w(LOG_TAG, value + " could not be autofilled into " + this);
- return false;
+ return;
}
+ final int index = value.getListValue();
final View child = getChildAt(index);
if (child == null) {
Log.w(VIEW_LOG_TAG, "RadioGroup.autoFill(): no child with index " + index);
- return false;
+ return;
}
+
check(child.getId());
- return true;
}
@Override
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index bc7c79d..3d5e81b 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -10050,17 +10050,13 @@
}
@Override
- public boolean autofill(AutofillValue value) {
- if (value.isText()) {
- if (isTextEditable()) {
- setText(value.getTextValue(), mBufferType, true, 0);
- return true;
- }
- } else {
+ public void autofill(AutofillValue value) {
+ if (!value.isText() || !isTextEditable()) {
Log.w(LOG_TAG, value + " could not be autofilled into " + this);
+ return;
}
- return false;
+ setText(value.getTextValue(), mBufferType, true, 0);
}
@Override
@@ -10769,7 +10765,7 @@
TextClassificationManager tcm =
mContext.getSystemService(TextClassificationManager.class);
if (tcm != null) {
- mTextClassifier = tcm.getDefaultTextClassifier();
+ mTextClassifier = tcm.getTextClassifier();
} else {
mTextClassifier = TextClassifier.NO_OP;
}
diff --git a/core/java/android/widget/TimePicker.java b/core/java/android/widget/TimePicker.java
index 1e97e3b..0289dad 100644
--- a/core/java/android/widget/TimePicker.java
+++ b/core/java/android/widget/TimePicker.java
@@ -530,16 +530,14 @@
}
@Override
- public boolean autofill(AutofillValue value) {
- if (!isEnabled()) return false;
+ public void autofill(AutofillValue value) {
+ if (!isEnabled()) return;
- if (value.isDate()) {
- mDelegate.setDate(value.getDateValue());
- } else {
+ if (!value.isDate()) {
Log.w(LOG_TAG, value + " could not be autofilled into " + this);
}
- return true;
+ mDelegate.setDate(value.getDateValue());
}
@Override
diff --git a/core/java/com/android/internal/app/ToolbarActionBar.java b/core/java/com/android/internal/app/ToolbarActionBar.java
index 7ce5fc3..b3904f4 100644
--- a/core/java/com/android/internal/app/ToolbarActionBar.java
+++ b/core/java/com/android/internal/app/ToolbarActionBar.java
@@ -477,12 +477,9 @@
final KeyCharacterMap kmap = KeyCharacterMap.load(
event != null ? event.getDeviceId() : KeyCharacterMap.VIRTUAL_KEYBOARD);
menu.setQwertyMode(kmap.getKeyboardType() != KeyCharacterMap.NUMERIC);
- menu.performShortcut(keyCode, event, 0);
+ return menu.performShortcut(keyCode, event, 0);
}
- // This action bar always returns true for handling keyboard shortcuts.
- // This will block the window from preparing a temporary panel to handle
- // keyboard shortcuts.
- return true;
+ return false;
}
@Override
@@ -525,6 +522,17 @@
}
return result;
}
+
+ @Override
+ public View onCreatePanelView(int featureId) {
+ if (featureId == Window.FEATURE_OPTIONS_PANEL) {
+ // This gets called by PhoneWindow.preparePanel. Since this already manages
+ // its own panel, we return a dummy view here to prevent PhoneWindow from
+ // preparing a default one.
+ return new View(mDecorToolbar.getContext());
+ }
+ return super.onCreatePanelView(featureId);
+ }
}
private final class ActionMenuPresenterCallback implements MenuPresenter.Callback {
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 3d0d6bf..b263657 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -114,7 +114,7 @@
private static final int MAGIC = 0xBA757475; // 'BATSTATS'
// Current on-disk Parcel version
- private static final int VERSION = 151 + (USE_OLD_HISTORY ? 1000 : 0);
+ private static final int VERSION = 152 + (USE_OLD_HISTORY ? 1000 : 0);
// Maximum number of items we will record in the history.
private static final int MAX_HISTORY_ITEMS = 2000;
@@ -10057,6 +10057,9 @@
public void setBatteryStateLocked(int status, int health, int plugType, int level,
int temp, int volt, int chargeUAh, int chargeFullUAh) {
+ // Temperature is encoded without the signed bit, so clamp any negative temperatures to 0.
+ temp = Math.max(0, temp);
+
final boolean onBattery = plugType == BATTERY_PLUGGED_NONE;
final long uptime = mClocks.uptimeMillis();
final long elapsedRealtime = mClocks.elapsedRealtime();
diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp
index 6fbf49b..e2443bb 100644
--- a/core/jni/android_view_SurfaceControl.cpp
+++ b/core/jni/android_view_SurfaceControl.cpp
@@ -735,16 +735,6 @@
return javaObjectForIBinder(env, ctrl->getHandle());
}
-static jboolean nativeGetTransformToDisplayInverse(JNIEnv* env, jclass clazz, jlong nativeObject) {
- bool out = false;
- auto ctrl = reinterpret_cast<SurfaceControl *>(nativeObject);
- status_t status = ctrl->getTransformToDisplayInverse(&out);
- if (status != NO_ERROR) {
- return false;
- }
- return out;
-}
-
static jobject nativeGetHdrCapabilities(JNIEnv* env, jclass clazz, jobject tokenObject) {
sp<IBinder> token(ibinderForJavaObject(env, tokenObject));
if (token == NULL) return NULL;
@@ -854,8 +844,6 @@
(void*)nativeSetOverrideScalingMode },
{"nativeGetHandle", "(J)Landroid/os/IBinder;",
(void*)nativeGetHandle },
- {"nativeGetTransformToDisplayInverse", "(J)Z",
- (void*)nativeGetTransformToDisplayInverse },
{"nativeScreenshotToBuffer",
"(Landroid/os/IBinder;Landroid/graphics/Rect;IIIIZZI)Landroid/graphics/GraphicBuffer;",
(void*)nativeScreenshotToBuffer },
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index db234e7..cda2369 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -784,9 +784,14 @@
-->
<integer name="config_defaultNightMode">1</integer>
+ <!-- Boolean indicating whether the HWC setColorTransform function can be performed efficiently
+ in hardware. -->
+ <bool name="config_setColorTransformAccelerated">false</bool>
+
<!-- Control whether Night display is available. This should only be enabled on devices
- with HWC 2.0 or higher. -->
- <bool name="config_nightDisplayAvailable">false</bool>
+ that have a HWC implementation that can apply the matrix passed to setColorTransform
+ without impacting power, performance, and app compatibility (e.g. protected content). -->
+ <bool name="config_nightDisplayAvailable">@bool/config_setColorTransformAccelerated</bool>
<!-- Default mode to control how Night display is automatically activated.
One of the following values (see NightDisplayController.java):
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 92436f4..db5fade 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -2774,6 +2774,7 @@
<java-symbol type="drawable" name="ic_doc_video" />
<java-symbol type="drawable" name="ic_doc_generic" />
+ <java-symbol type="bool" name="config_setColorTransformAccelerated" />
<java-symbol type="bool" name="config_nightDisplayAvailable" />
<java-symbol type="bool" name="config_allowDisablingAssistDisclosure" />
<java-symbol type="integer" name="config_defaultNightDisplayAutoMode" />
diff --git a/libs/hwui/hwui_static_deps.mk b/libs/hwui/hwui_static_deps.mk
index 8826cfc..7f06421 100644
--- a/libs/hwui/hwui_static_deps.mk
+++ b/libs/hwui/hwui_static_deps.mk
@@ -27,7 +27,5 @@
libft2 \
libminikin \
libandroidfw \
- libRScpp
-
-LOCAL_STATIC_LIBRARIES += \
+ libRScpp \
libplatformprotos
diff --git a/media/java/android/media/tv/TvContract.java b/media/java/android/media/tv/TvContract.java
index 7bf69c0..9739319 100644
--- a/media/java/android/media/tv/TvContract.java
+++ b/media/java/android/media/tv/TvContract.java
@@ -283,7 +283,7 @@
* @param name The {@link ComponentName} of the TV input service to build ID for.
* @return the ID for the given TV input service.
*/
- public static final String buildInputId(ComponentName name) {
+ public static String buildInputId(ComponentName name) {
return name.flattenToShortString();
}
@@ -292,7 +292,7 @@
*
* @param channelId The ID of the channel to point to.
*/
- public static final Uri buildChannelUri(long channelId) {
+ public static Uri buildChannelUri(long channelId) {
return ContentUris.withAppendedId(Channels.CONTENT_URI, channelId);
}
@@ -302,7 +302,7 @@
* @param inputId The ID of the pass-through input to build a channels URI for.
* @see TvInputInfo#isPassthroughInput()
*/
- public static final Uri buildChannelUriForPassthroughInput(String inputId) {
+ public static Uri buildChannelUriForPassthroughInput(String inputId) {
return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT).authority(AUTHORITY)
.appendPath(PATH_PASSTHROUGH).appendPath(inputId).build();
}
@@ -312,7 +312,7 @@
*
* @param channelId The ID of the channel whose logo is pointed to.
*/
- public static final Uri buildChannelLogoUri(long channelId) {
+ public static Uri buildChannelLogoUri(long channelId) {
return buildChannelLogoUri(buildChannelUri(channelId));
}
@@ -321,7 +321,7 @@
*
* @param channelUri The URI of the channel whose logo is pointed to.
*/
- public static final Uri buildChannelLogoUri(Uri channelUri) {
+ public static Uri buildChannelLogoUri(Uri channelUri) {
if (!isChannelUriForTunerInput(channelUri)) {
throw new IllegalArgumentException("Not a channel: " + channelUri);
}
@@ -334,7 +334,7 @@
* @param inputId The ID of the TV input to build a channels URI for. If {@code null}, builds a
* URI for all the TV inputs.
*/
- public static final Uri buildChannelsUriForInput(@Nullable String inputId) {
+ public static Uri buildChannelsUriForInput(@Nullable String inputId) {
return buildChannelsUriForInput(inputId, false);
}
@@ -349,7 +349,7 @@
* @hide
*/
@SystemApi
- public static final Uri buildChannelsUriForInput(@Nullable String inputId,
+ public static Uri buildChannelsUriForInput(@Nullable String inputId,
boolean browsableOnly) {
Uri.Builder builder = Channels.CONTENT_URI.buildUpon();
if (inputId != null) {
@@ -372,7 +372,7 @@
* @hide
*/
@SystemApi
- public static final Uri buildChannelsUriForInput(@Nullable String inputId,
+ public static Uri buildChannelsUriForInput(@Nullable String inputId,
@Nullable String genre, boolean browsableOnly) {
if (genre == null) {
return buildChannelsUriForInput(inputId, browsableOnly);
@@ -389,7 +389,7 @@
*
* @param programId The ID of the program to point to.
*/
- public static final Uri buildProgramUri(long programId) {
+ public static Uri buildProgramUri(long programId) {
return ContentUris.withAppendedId(Programs.CONTENT_URI, programId);
}
@@ -398,7 +398,7 @@
*
* @param channelId The ID of the channel to return programs for.
*/
- public static final Uri buildProgramsUriForChannel(long channelId) {
+ public static Uri buildProgramsUriForChannel(long channelId) {
return Programs.CONTENT_URI.buildUpon()
.appendQueryParameter(PARAM_CHANNEL, String.valueOf(channelId)).build();
}
@@ -408,7 +408,7 @@
*
* @param channelUri The URI of the channel to return programs for.
*/
- public static final Uri buildProgramsUriForChannel(Uri channelUri) {
+ public static Uri buildProgramsUriForChannel(Uri channelUri) {
if (!isChannelUriForTunerInput(channelUri)) {
throw new IllegalArgumentException("Not a channel: " + channelUri);
}
@@ -425,7 +425,7 @@
* @param endTime The end time used to filter programs. The returned programs should have
* {@link Programs#COLUMN_START_TIME_UTC_MILLIS} that is less than this time.
*/
- public static final Uri buildProgramsUriForChannel(long channelId, long startTime,
+ public static Uri buildProgramsUriForChannel(long channelId, long startTime,
long endTime) {
Uri uri = buildProgramsUriForChannel(channelId);
return uri.buildUpon().appendQueryParameter(PARAM_START_TIME, String.valueOf(startTime))
@@ -442,7 +442,7 @@
* @param endTime The end time used to filter programs. The returned programs should have
* {@link Programs#COLUMN_START_TIME_UTC_MILLIS} that is less than this time.
*/
- public static final Uri buildProgramsUriForChannel(Uri channelUri, long startTime,
+ public static Uri buildProgramsUriForChannel(Uri channelUri, long startTime,
long endTime) {
if (!isChannelUriForTunerInput(channelUri)) {
throw new IllegalArgumentException("Not a channel: " + channelUri);
@@ -455,7 +455,7 @@
*
* @param recordedProgramId The ID of the recorded program to point to.
*/
- public static final Uri buildRecordedProgramUri(long recordedProgramId) {
+ public static Uri buildRecordedProgramUri(long recordedProgramId) {
return ContentUris.withAppendedId(RecordedPrograms.CONTENT_URI, recordedProgramId);
}
@@ -464,7 +464,7 @@
*
* @param previewProgramId The ID of the preview program to point to.
*/
- public static final Uri buildPreviewProgramUri(long previewProgramId) {
+ public static Uri buildPreviewProgramUri(long previewProgramId) {
return ContentUris.withAppendedId(PreviewPrograms.CONTENT_URI, previewProgramId);
}
@@ -473,7 +473,7 @@
*
* @param channelId The ID of the channel to return preview programs for.
*/
- public static final Uri buildPreviewProgramsUriForChannel(long channelId) {
+ public static Uri buildPreviewProgramsUriForChannel(long channelId) {
return PreviewPrograms.CONTENT_URI.buildUpon()
.appendQueryParameter(PARAM_CHANNEL, String.valueOf(channelId)).build();
}
@@ -483,7 +483,7 @@
*
* @param channelUri The URI of the channel to return preview programs for.
*/
- public static final Uri buildPreviewProgramsUriForChannel(Uri channelUri) {
+ public static Uri buildPreviewProgramsUriForChannel(Uri channelUri) {
if (!isChannelUriForTunerInput(channelUri)) {
throw new IllegalArgumentException("Not a channel: " + channelUri);
}
@@ -495,7 +495,7 @@
*
* @param watchNextProgramId The ID of the watch next program to point to.
*/
- public static final Uri buildWatchNextProgramUri(long watchNextProgramId) {
+ public static Uri buildWatchNextProgramUri(long watchNextProgramId) {
return ContentUris.withAppendedId(WatchNextPrograms.CONTENT_URI, watchNextProgramId);
}
@@ -505,7 +505,7 @@
* @param watchedProgramId The ID of the watched program to point to.
* @hide
*/
- public static final Uri buildWatchedProgramUri(long watchedProgramId) {
+ public static Uri buildWatchedProgramUri(long watchedProgramId) {
return ContentUris.withAppendedId(WatchedPrograms.CONTENT_URI, watchedProgramId);
}
@@ -522,28 +522,28 @@
/**
* Returns {@code true}, if {@code uri} is a channel URI.
*/
- public static final boolean isChannelUri(Uri uri) {
+ public static boolean isChannelUri(Uri uri) {
return isChannelUriForTunerInput(uri) || isChannelUriForPassthroughInput(uri);
}
/**
* Returns {@code true}, if {@code uri} is a channel URI for a tuner input.
*/
- public static final boolean isChannelUriForTunerInput(Uri uri) {
+ public static boolean isChannelUriForTunerInput(Uri uri) {
return isTvUri(uri) && isTwoSegmentUriStartingWith(uri, PATH_CHANNEL);
}
/**
* Returns {@code true}, if {@code uri} is a channel URI for a pass-through input.
*/
- public static final boolean isChannelUriForPassthroughInput(Uri uri) {
+ public static boolean isChannelUriForPassthroughInput(Uri uri) {
return isTvUri(uri) && isTwoSegmentUriStartingWith(uri, PATH_PASSTHROUGH);
}
/**
* Returns {@code true}, if {@code uri} is a program URI.
*/
- public static final boolean isProgramUri(Uri uri) {
+ public static boolean isProgramUri(Uri uri) {
return isTvUri(uri) && isTwoSegmentUriStartingWith(uri, PATH_PROGRAM);
}
@@ -580,7 +580,7 @@
*
* <p>Type: TEXT
*/
- public static final String COLUMN_TITLE = "title";
+ String COLUMN_TITLE = "title";
/**
* The season display number of this TV program for episodic TV shows.
@@ -592,7 +592,7 @@
*
* <p>Type: TEXT
*/
- public static final String COLUMN_SEASON_DISPLAY_NUMBER = "season_display_number";
+ String COLUMN_SEASON_DISPLAY_NUMBER = "season_display_number";
/**
* The title of the season for this TV program for episodic TV shows.
@@ -608,7 +608,7 @@
*
* <p>Type: TEXT
*/
- public static final String COLUMN_SEASON_TITLE = "season_title";
+ String COLUMN_SEASON_TITLE = "season_title";
/**
* The episode display number of this TV program for episodic TV shows.
@@ -620,7 +620,7 @@
*
* <p>Type: TEXT
*/
- public static final String COLUMN_EPISODE_DISPLAY_NUMBER = "episode_display_number";
+ String COLUMN_EPISODE_DISPLAY_NUMBER = "episode_display_number";
/**
* The episode title of this TV program for episodic TV shows.
@@ -629,7 +629,7 @@
*
* <p>Type: TEXT
*/
- public static final String COLUMN_EPISODE_TITLE = "episode_title";
+ String COLUMN_EPISODE_TITLE = "episode_title";
/**
* The comma-separated canonical genre string of this TV program.
@@ -643,7 +643,7 @@
* @see Genres#encode
* @see Genres#decode
*/
- public static final String COLUMN_CANONICAL_GENRE = "canonical_genre";
+ String COLUMN_CANONICAL_GENRE = "canonical_genre";
/**
* The short description of this TV program that is displayed to the user by default.
@@ -652,7 +652,7 @@
*
* <p>Type: TEXT
*/
- public static final String COLUMN_SHORT_DESCRIPTION = "short_description";
+ String COLUMN_SHORT_DESCRIPTION = "short_description";
/**
* The detailed, lengthy description of this TV program that is displayed only when the user
@@ -663,7 +663,7 @@
*
* <p>Type: TEXT
*/
- public static final String COLUMN_LONG_DESCRIPTION = "long_description";
+ String COLUMN_LONG_DESCRIPTION = "long_description";
/**
* The width of the video for this TV program, in the unit of pixels.
@@ -675,7 +675,7 @@
*
* <p>Type: INTEGER
*/
- public static final String COLUMN_VIDEO_WIDTH = "video_width";
+ String COLUMN_VIDEO_WIDTH = "video_width";
/**
* The height of the video for this TV program, in the unit of pixels.
@@ -687,7 +687,7 @@
*
* <p>Type: INTEGER
*/
- public static final String COLUMN_VIDEO_HEIGHT = "video_height";
+ String COLUMN_VIDEO_HEIGHT = "video_height";
/**
* The comma-separated audio languages of this TV program.
@@ -697,7 +697,7 @@
*
* <p>Type: TEXT
*/
- public static final String COLUMN_AUDIO_LANGUAGE = "audio_language";
+ String COLUMN_AUDIO_LANGUAGE = "audio_language";
/**
* The comma-separated content ratings of this TV program.
@@ -714,7 +714,7 @@
*
* <p>Type: TEXT
*/
- public static final String COLUMN_CONTENT_RATING = "content_rating";
+ String COLUMN_CONTENT_RATING = "content_rating";
/**
* The URI for the poster art of this TV program.
@@ -732,7 +732,7 @@
*
* <p>Type: TEXT
*/
- public static final String COLUMN_POSTER_ART_URI = "poster_art_uri";
+ String COLUMN_POSTER_ART_URI = "poster_art_uri";
/**
* The URI for the thumbnail of this TV program.
@@ -754,7 +754,7 @@
*
* <p>Type: TEXT
*/
- public static final String COLUMN_THUMBNAIL_URI = "thumbnail_uri";
+ String COLUMN_THUMBNAIL_URI = "thumbnail_uri";
/**
* The flag indicating whether this TV program is searchable or not.
@@ -769,7 +769,7 @@
*
* <p>Type: INTEGER (boolean)
*/
- public static final String COLUMN_SEARCHABLE = "searchable";
+ String COLUMN_SEARCHABLE = "searchable";
/**
* Internal data used by individual TV input services.
@@ -779,7 +779,7 @@
*
* <p>Type: BLOB
*/
- public static final String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";
+ String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";
/**
* Internal integer flag used by individual TV input services.
@@ -789,7 +789,7 @@
*
* <p>Type: INTEGER
*/
- public static final String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1";
+ String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1";
/**
* Internal integer flag used by individual TV input services.
@@ -799,7 +799,7 @@
*
* <p>Type: INTEGER
*/
- public static final String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2";
+ String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2";
/**
* Internal integer flag used by individual TV input services.
@@ -809,7 +809,7 @@
*
* <p>Type: INTEGER
*/
- public static final String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3";
+ String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3";
/**
* Internal integer flag used by individual TV input services.
@@ -819,7 +819,7 @@
*
* <p>Type: INTEGER
*/
- public static final String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
+ String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
/**
* The version number of this row entry used by TV input services.
@@ -831,7 +831,7 @@
*
* <p>Type: INTEGER
*/
- public static final String COLUMN_VERSION_NUMBER = "version_number";
+ String COLUMN_VERSION_NUMBER = "version_number";
}
/**
@@ -862,84 +862,84 @@
*
* @see #COLUMN_TYPE
*/
- public static final String TYPE_MOVIE = "TYPE_MOVIE";
+ String TYPE_MOVIE = "TYPE_MOVIE";
/**
* The program type for TV series.
*
* @see #COLUMN_TYPE
*/
- public static final String TYPE_TV_SERIES = "TYPE_TV_SERIES";
+ String TYPE_TV_SERIES = "TYPE_TV_SERIES";
/**
* The program type for TV season.
*
* @see #COLUMN_TYPE
*/
- public static final String TYPE_TV_SEASON = "TYPE_TV_SEASON";
+ String TYPE_TV_SEASON = "TYPE_TV_SEASON";
/**
* The program type for TV episode.
*
* @see #COLUMN_TYPE
*/
- public static final String TYPE_TV_EPISODE = "TYPE_TV_EPISODE";
+ String TYPE_TV_EPISODE = "TYPE_TV_EPISODE";
/**
* The program type for clip.
*
* @see #COLUMN_TYPE
*/
- public static final String TYPE_CLIP = "TYPE_CLIP";
+ String TYPE_CLIP = "TYPE_CLIP";
/**
* The program type for event.
*
* @see #COLUMN_TYPE
*/
- public static final String TYPE_EVENT = "TYPE_EVENT";
+ String TYPE_EVENT = "TYPE_EVENT";
/**
* The program type for channel.
*
* @see #COLUMN_TYPE
*/
- public static final String TYPE_CHANNEL = "TYPE_CHANNEL";
+ String TYPE_CHANNEL = "TYPE_CHANNEL";
/**
* The program type for track.
*
* @see #COLUMN_TYPE
*/
- public static final String TYPE_TRACK = "TYPE_TRACK";
+ String TYPE_TRACK = "TYPE_TRACK";
/**
* The program type for album.
*
* @see #COLUMN_TYPE
*/
- public static final String TYPE_ALBUM = "TYPE_ALBUM";
+ String TYPE_ALBUM = "TYPE_ALBUM";
/**
* The program type for artist.
*
* @see #COLUMN_TYPE
*/
- public static final String TYPE_ARTIST = "TYPE_ARTIST";
+ String TYPE_ARTIST = "TYPE_ARTIST";
/**
* The program type for playlist.
*
* @see #COLUMN_TYPE
*/
- public static final String TYPE_PLAYLIST = "TYPE_PLAYLIST";
+ String TYPE_PLAYLIST = "TYPE_PLAYLIST";
/**
* The program type for station.
*
* @see #COLUMN_TYPE
*/
- public static final String TYPE_STATION = "TYPE_STATION";
+ String TYPE_STATION = "TYPE_STATION";
/** @hide */
@StringDef({
@@ -957,7 +957,7 @@
* @see #COLUMN_POSTER_ART_ASPECT_RATIO
* @see #COLUMN_THUMBNAIL_ASPECT_RATIO
*/
- public static final String ASPECT_RATIO_16_9 = "ASPECT_RATIO_16_9";
+ String ASPECT_RATIO_16_9 = "ASPECT_RATIO_16_9";
/**
* The aspect ratio for 3:2.
@@ -965,7 +965,7 @@
* @see #COLUMN_POSTER_ART_ASPECT_RATIO
* @see #COLUMN_THUMBNAIL_ASPECT_RATIO
*/
- public static final String ASPECT_RATIO_3_2 = "ASPECT_RATIO_3_2";
+ String ASPECT_RATIO_3_2 = "ASPECT_RATIO_3_2";
/**
* The aspect ratio for 1:1.
@@ -973,7 +973,7 @@
* @see #COLUMN_POSTER_ART_ASPECT_RATIO
* @see #COLUMN_THUMBNAIL_ASPECT_RATIO
*/
- public static final String ASPECT_RATIO_1_1 = "ASPECT_RATIO_1_1";
+ String ASPECT_RATIO_1_1 = "ASPECT_RATIO_1_1";
/**
* The aspect ratio for 2:3.
@@ -981,7 +981,7 @@
* @see #COLUMN_POSTER_ART_ASPECT_RATIO
* @see #COLUMN_THUMBNAIL_ASPECT_RATIO
*/
- public static final String ASPECT_RATIO_2_3 = "ASPECT_RATIO_2_3";
+ String ASPECT_RATIO_2_3 = "ASPECT_RATIO_2_3";
/** @hide */
@StringDef({
@@ -997,14 +997,14 @@
*
* @see #COLUMN_AVAILABILITY
*/
- public static final String AVAILABILITY_AVAILABLE = "AVAILABILITY_AVAILABLE";
+ String AVAILABILITY_AVAILABLE = "AVAILABILITY_AVAILABLE";
/**
* The availability for "free with subscription".
*
* @see #COLUMN_AVAILABILITY
*/
- public static final String AVAILABILITY_FREE_WITH_SUBSCRIPTION =
+ String AVAILABILITY_FREE_WITH_SUBSCRIPTION =
"AVAILABILITY_FREE_WITH_SUBSCRIPTION";
/**
@@ -1013,7 +1013,7 @@
*
* @see #COLUMN_AVAILABILITY
*/
- public static final String AVAILABILITY_PAID_CONTENT = "AVAILABILITY_PAID_CONTENT";
+ String AVAILABILITY_PAID_CONTENT = "AVAILABILITY_PAID_CONTENT";
/** @hide */
@StringDef({
@@ -1033,49 +1033,49 @@
*
* @see #COLUMN_INTERACTION_TYPE
*/
- public static final String INTERACTION_TYPE_LISTENS = "INTERACTION_TYPE_LISTENS";
+ String INTERACTION_TYPE_LISTENS = "INTERACTION_TYPE_LISTENS";
/**
* The interaction type for "followers".
*
* @see #COLUMN_INTERACTION_TYPE
*/
- public static final String INTERACTION_TYPE_FOLLOWERS = "INTERACTION_TYPE_FOLLOWERS";
+ String INTERACTION_TYPE_FOLLOWERS = "INTERACTION_TYPE_FOLLOWERS";
/**
* The interaction type for "fans".
*
* @see #COLUMN_INTERACTION_TYPE
*/
- public static final String INTERACTION_TYPE_FANS = "INTERACTION_TYPE_FANS";
+ String INTERACTION_TYPE_FANS = "INTERACTION_TYPE_FANS";
/**
* The interaction type for "likes".
*
* @see #COLUMN_INTERACTION_TYPE
*/
- public static final String INTERACTION_TYPE_LIKES = "INTERACTION_TYPE_LIKES";
+ String INTERACTION_TYPE_LIKES = "INTERACTION_TYPE_LIKES";
/**
* The interaction type for "thumbs".
*
* @see #COLUMN_INTERACTION_TYPE
*/
- public static final String INTERACTION_TYPE_THUMBS = "INTERACTION_TYPE_THUMBS";
+ String INTERACTION_TYPE_THUMBS = "INTERACTION_TYPE_THUMBS";
/**
* The interaction type for "views".
*
* @see #COLUMN_INTERACTION_TYPE
*/
- public static final String INTERACTION_TYPE_VIEWS = "INTERACTION_TYPE_VIEWS";
+ String INTERACTION_TYPE_VIEWS = "INTERACTION_TYPE_VIEWS";
/**
* The interaction type for "viewers".
*
* @see #COLUMN_INTERACTION_TYPE
*/
- public static final String INTERACTION_TYPE_VIEWERS = "INTERACTION_TYPE_VIEWERS";
+ String INTERACTION_TYPE_VIEWERS = "INTERACTION_TYPE_VIEWERS";
/** @hide */
@StringDef({
@@ -1091,14 +1091,14 @@
*
* @see #COLUMN_REVIEW_RATING_STYLE
*/
- public static final String REVIEW_RATING_STYLE_STARS = "REVIEW_RATING_STYLE_STARS";
+ String REVIEW_RATING_STYLE_STARS = "REVIEW_RATING_STYLE_STARS";
/**
* The review rating style for thumbs-up and thumbs-down rating.
*
* @see #COLUMN_REVIEW_RATING_STYLE
*/
- public static final String REVIEW_RATING_STYLE_THUMBS_UP_DOWN =
+ String REVIEW_RATING_STYLE_THUMBS_UP_DOWN =
"REVIEW_RATING_STYLE_THUMBS_UP_DOWN";
/**
@@ -1106,7 +1106,7 @@
*
* @see #COLUMN_REVIEW_RATING_STYLE
*/
- public static final String REVIEW_RATING_STYLE_PERCENTAGE =
+ String REVIEW_RATING_STYLE_PERCENTAGE =
"REVIEW_RATING_STYLE_PERCENTAGE";
/**
@@ -1131,7 +1131,7 @@
*
* <p>Type: TEXT
*/
- public static final String COLUMN_TYPE = "type";
+ String COLUMN_TYPE = "type";
/**
* The aspect ratio of the poster art for this TV program.
@@ -1144,7 +1144,7 @@
*
* <p>Type: TEXT
*/
- public static final String COLUMN_POSTER_ART_ASPECT_RATIO = "poster_art_aspect_ratio";
+ String COLUMN_POSTER_ART_ASPECT_RATIO = "poster_art_aspect_ratio";
/**
* The aspect ratio of the thumbnail for this TV program.
@@ -1157,7 +1157,7 @@
*
* <p>Type: TEXT
*/
- public static final String COLUMN_THUMBNAIL_ASPECT_RATIO = "poster_thumbnail_aspect_ratio";
+ String COLUMN_THUMBNAIL_ASPECT_RATIO = "poster_thumbnail_aspect_ratio";
/**
* The URI for the logo of this TV program.
@@ -1178,7 +1178,7 @@
*
* <p>Type: TEXT
*/
- public static final String COLUMN_LOGO_URI = "logo_uri";
+ String COLUMN_LOGO_URI = "logo_uri";
/**
* The availability of this TV program.
@@ -1190,7 +1190,7 @@
*
* <p>Type: TEXT
*/
- public static final String COLUMN_AVAILABILITY = "availability";
+ String COLUMN_AVAILABILITY = "availability";
/**
* The starting price of this TV program.
@@ -1201,7 +1201,7 @@
* <p>Type: TEXT
* @see #COLUMN_OFFER_PRICE
*/
- public static final String COLUMN_STARTING_PRICE = "starting_price";
+ String COLUMN_STARTING_PRICE = "starting_price";
/**
* The offer price of this TV program.
@@ -1212,7 +1212,7 @@
* <p>Type: TEXT
* @see #COLUMN_STARTING_PRICE
*/
- public static final String COLUMN_OFFER_PRICE = "offer_price";
+ String COLUMN_OFFER_PRICE = "offer_price";
/**
* The release date of this TV program.
@@ -1221,7 +1221,7 @@
*
* <p>Type: TEXT
*/
- public static final String COLUMN_RELEASE_DATE = "release_date";
+ String COLUMN_RELEASE_DATE = "release_date";
/**
* The count of the items included in this TV program.
@@ -1231,7 +1231,7 @@
*
* <p>Type: INTEGER
*/
- public static final String COLUMN_ITEM_COUNT = "item_count";
+ String COLUMN_ITEM_COUNT = "item_count";
/**
* The flag indicating whether this TV program is live or not.
@@ -1242,7 +1242,7 @@
*
* <p>Type: INTEGER (boolean)
*/
- public static final String COLUMN_LIVE = "live";
+ String COLUMN_LIVE = "live";
/**
* The internal ID used by individual TV input services.
@@ -1254,7 +1254,7 @@
*
* <p>Type: TEXT
*/
- public static final String COLUMN_INTERNAL_PROVIDER_ID = "internal_provider_id";
+ String COLUMN_INTERNAL_PROVIDER_ID = "internal_provider_id";
/**
* The URI for the preview video.
@@ -1273,7 +1273,7 @@
*
* <p>Type: TEXT
*/
- public static final String COLUMN_PREVIEW_VIDEO_URI = "preview_video_uri";
+ String COLUMN_PREVIEW_VIDEO_URI = "preview_video_uri";
/**
* The last playback position (in milliseconds) of the preview video.
@@ -1284,7 +1284,7 @@
*
* <p>Type: INTEGER
*/
- public static final String COLUMN_LAST_PLAYBACK_POSITION_MILLIS =
+ String COLUMN_LAST_PLAYBACK_POSITION_MILLIS =
"last_playback_position_millis";
/**
@@ -1296,7 +1296,7 @@
*
* <p>Type: INTEGER
*/
- public static final String COLUMN_DURATION_MILLIS = "duration_millis";
+ String COLUMN_DURATION_MILLIS = "duration_millis";
/**
* The intent URI which is launched when the preview video is selected.
@@ -1309,7 +1309,7 @@
*
* <p>Type: TEXT
*/
- public static final String COLUMN_APP_LINK_INTENT_URI =
+ String COLUMN_APP_LINK_INTENT_URI =
"app_link_intent_uri";
/**
@@ -1322,7 +1322,7 @@
* <p>Type: INTEGER (boolean)
* @see Channels#COLUMN_TRANSIENT
*/
- public static final String COLUMN_TRANSIENT = "transient";
+ String COLUMN_TRANSIENT = "transient";
/**
* The type of interaction for this TV program.
@@ -1339,7 +1339,7 @@
* <p>Type: TEXT
* @see #COLUMN_INTERACTION_COUNT
*/
- public static final String COLUMN_INTERACTION_TYPE = "interaction_type";
+ String COLUMN_INTERACTION_TYPE = "interaction_type";
/**
* The interaction count for this program.
@@ -1349,14 +1349,14 @@
* <p>Type: INTEGER (long)
* @see #COLUMN_INTERACTION_TYPE
*/
- public static final String COLUMN_INTERACTION_COUNT = "interaction_count";
+ String COLUMN_INTERACTION_COUNT = "interaction_count";
/**
* The author or artist of this content.
*
* <p>Type: TEXT
*/
- public static final String COLUMN_AUTHOR = "author";
+ String COLUMN_AUTHOR = "author";
/**
* The review rating score style used for {@link #COLUMN_REVIEW_RATING}.
@@ -1367,7 +1367,7 @@
* <p>Type: TEXT
* @see #COLUMN_REVIEW_RATING
*/
- public static final String COLUMN_REVIEW_RATING_STYLE = "review_rating_style";
+ String COLUMN_REVIEW_RATING_STYLE = "review_rating_style";
/**
* The review rating score for this program.
@@ -1383,7 +1383,7 @@
* <p>Type: TEXT
* @see #COLUMN_REVIEW_RATING_STYLE
*/
- public static final String COLUMN_REVIEW_RATING = "review_rating";
+ String COLUMN_REVIEW_RATING = "review_rating";
/**
* The flag indicating whether this TV program is browsable or not.
@@ -1401,7 +1401,7 @@
*
* <p>Type: INTEGER (boolean)
*/
- public static final String COLUMN_BROWSABLE = "browsable";
+ String COLUMN_BROWSABLE = "browsable";
/**
* The content ID of this TV program.
@@ -1413,7 +1413,7 @@
*
* <p>Type: TEXT
*/
- public static final String COLUMN_CONTENT_ID = "content_id";
+ String COLUMN_CONTENT_ID = "content_id";
}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
index ec80745..297fe67 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivity.java
@@ -17,6 +17,7 @@
package com.android.systemui.pip.phone;
import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_ACTIONS;
+import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_ALLOW_TIMEOUT;
import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_CONTROLLER_MESSENGER;
import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_DISMISS_FRACTION;
import static com.android.systemui.pip.phone.PipMenuActivityController.EXTRA_MOVEMENT_BOUNDS;
@@ -75,8 +76,8 @@
public static final int MESSAGE_UPDATE_ACTIONS = 4;
public static final int MESSAGE_UPDATE_DISMISS_FRACTION = 5;
- private static final long INITIAL_DISMISS_DELAY = 2000;
- private static final long POST_INTERACTION_DISMISS_DELAY = 1500;
+ private static final long INITIAL_DISMISS_DELAY = 3500;
+ private static final long POST_INTERACTION_DISMISS_DELAY = 2000;
private static final long MENU_FADE_DURATION = 125;
private static final float MENU_BACKGROUND_ALPHA = 0.3f;
@@ -116,7 +117,8 @@
case MESSAGE_SHOW_MENU: {
final Bundle data = (Bundle) msg.obj;
showMenu(data.getParcelable(EXTRA_STACK_BOUNDS),
- data.getParcelable(EXTRA_MOVEMENT_BOUNDS));
+ data.getParcelable(EXTRA_MOVEMENT_BOUNDS),
+ data.getBoolean(EXTRA_ALLOW_TIMEOUT));
break;
}
case MESSAGE_POKE_MENU:
@@ -252,7 +254,7 @@
// Do nothing
}
- private void showMenu(Rect stackBounds, Rect movementBounds) {
+ private void showMenu(Rect stackBounds, Rect movementBounds, boolean allowMenuTimeout) {
if (!mMenuVisible) {
updateActionViews(stackBounds);
if (mMenuContainerAnimator != null) {
@@ -265,18 +267,22 @@
mMenuContainer.getAlpha(), 1f);
mMenuContainerAnimator.setInterpolator(Interpolators.ALPHA_IN);
mMenuContainerAnimator.setDuration(MENU_FADE_DURATION);
- mMenuContainerAnimator.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- repostDelayedFinish(INITIAL_DISMISS_DELAY);
- }
- });
+ if (allowMenuTimeout) {
+ mMenuContainerAnimator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ repostDelayedFinish(INITIAL_DISMISS_DELAY);
+ }
+ });
+ }
mMenuContainerAnimator.addUpdateListener(mMenuBgUpdateListener);
mMenuContainerAnimator.start();
} else {
// If we are already visible, then just start the delayed dismiss and unregister any
// existing input consumers from the previous drag
- repostDelayedFinish(POST_INTERACTION_DISMISS_DELAY);
+ if (allowMenuTimeout) {
+ repostDelayedFinish(POST_INTERACTION_DISMISS_DELAY);
+ }
notifyUnregisterInputConsumer();
}
}
@@ -320,7 +326,8 @@
if (intent.getBooleanExtra(EXTRA_SHOW_MENU, false)) {
Rect stackBounds = intent.getParcelableExtra(EXTRA_STACK_BOUNDS);
Rect movementBounds = intent.getParcelableExtra(EXTRA_MOVEMENT_BOUNDS);
- showMenu(stackBounds, movementBounds);
+ boolean allowMenuTimeout = intent.getBooleanExtra(EXTRA_ALLOW_TIMEOUT, true);
+ showMenu(stackBounds, movementBounds, allowMenuTimeout);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
index e2069e2..bcaa395 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipMenuActivityController.java
@@ -33,7 +33,6 @@
import android.os.RemoteException;
import android.os.UserHandle;
import android.util.Log;
-import android.util.Pair;
import android.view.IWindowManager;
import com.android.systemui.pip.phone.PipMediaController.ActionListener;
@@ -56,6 +55,7 @@
public static final String EXTRA_ACTIONS = "actions";
public static final String EXTRA_STACK_BOUNDS = "stack_bounds";
public static final String EXTRA_MOVEMENT_BOUNDS = "movement_bounds";
+ public static final String EXTRA_ALLOW_TIMEOUT = "allow_timeout";
public static final String EXTRA_SHOW_MENU = "show_menu";
public static final String EXTRA_DISMISS_FRACTION = "dismiss_fraction";
@@ -105,7 +105,8 @@
private ParceledListSlice mMediaActions;
private boolean mMenuVisible;
- private Bundle mTmpData = new Bundle();
+ // The dismiss fraction update is sent frequently, so use a temporary bundle for the message
+ private Bundle mTmpDismissFractionData = new Bundle();
private boolean mStartActivityRequested;
private Messenger mToActivityMessenger;
@@ -195,11 +196,11 @@
*/
public void setDismissFraction(float fraction) {
if (mToActivityMessenger != null) {
- mTmpData.clear();
- mTmpData.putFloat(EXTRA_DISMISS_FRACTION, fraction);
+ mTmpDismissFractionData.clear();
+ mTmpDismissFractionData.putFloat(EXTRA_DISMISS_FRACTION, fraction);
Message m = Message.obtain();
m.what = PipMenuActivity.MESSAGE_UPDATE_DISMISS_FRACTION;
- m.obj = mTmpData;
+ m.obj = mTmpDismissFractionData;
try {
mToActivityMessenger.send(m);
} catch (RemoteException e) {
@@ -207,28 +208,29 @@
}
} else if (!mStartActivityRequested) {
startMenuActivity(null /* stackBounds */, null /* movementBounds */,
- false /* showMenu */);
+ false /* showMenu */, false /* allowMenuTimeout */);
}
}
/**
* Shows the menu activity.
*/
- public void showMenu(Rect stackBounds, Rect movementBounds) {
+ public void showMenu(Rect stackBounds, Rect movementBounds, boolean allowMenuTimeout) {
if (mToActivityMessenger != null) {
- mTmpData.clear();
- mTmpData.putParcelable(EXTRA_STACK_BOUNDS, stackBounds);
- mTmpData.putParcelable(EXTRA_MOVEMENT_BOUNDS, movementBounds);
+ Bundle data = new Bundle();
+ data.putParcelable(EXTRA_STACK_BOUNDS, stackBounds);
+ data.putParcelable(EXTRA_MOVEMENT_BOUNDS, movementBounds);
+ data.putBoolean(EXTRA_ALLOW_TIMEOUT, allowMenuTimeout);
Message m = Message.obtain();
m.what = PipMenuActivity.MESSAGE_SHOW_MENU;
- m.obj = mTmpData;
+ m.obj = data;
try {
mToActivityMessenger.send(m);
} catch (RemoteException e) {
Log.e(TAG, "Could not notify menu to show", e);
}
} else if (!mStartActivityRequested) {
- startMenuActivity(stackBounds, movementBounds, true /* showMenu */);
+ startMenuActivity(stackBounds, movementBounds, true /* showMenu */, allowMenuTimeout);
}
}
@@ -290,7 +292,8 @@
/**
* Starts the menu activity on the top task of the pinned stack.
*/
- private void startMenuActivity(Rect stackBounds, Rect movementBounds, boolean showMenu) {
+ private void startMenuActivity(Rect stackBounds, Rect movementBounds, boolean showMenu,
+ boolean allowMenuTimeout) {
try {
StackInfo pinnedStackInfo = mActivityManager.getStackInfo(PINNED_STACK_ID);
if (pinnedStackInfo != null && pinnedStackInfo.taskIds != null &&
@@ -305,6 +308,7 @@
intent.putExtra(EXTRA_MOVEMENT_BOUNDS, movementBounds);
}
intent.putExtra(EXTRA_SHOW_MENU, showMenu);
+ intent.putExtra(EXTRA_ALLOW_TIMEOUT, allowMenuTimeout);
ActivityOptions options = ActivityOptions.makeCustomAnimation(mContext, 0, 0);
options.setLaunchTaskId(
pinnedStackInfo.taskIds[pinnedStackInfo.taskIds.length - 1]);
@@ -336,12 +340,12 @@
Log.e(TAG, "Error showing PIP menu activity", e);
}
- mTmpData.clear();
- mTmpData.putParcelable(EXTRA_STACK_BOUNDS, stackBounds);
- mTmpData.putParcelable(EXTRA_ACTIONS, resolveMenuActions());
+ Bundle data = new Bundle();
+ data.putParcelable(EXTRA_STACK_BOUNDS, stackBounds);
+ data.putParcelable(EXTRA_ACTIONS, resolveMenuActions());
Message m = Message.obtain();
m.what = PipMenuActivity.MESSAGE_UPDATE_ACTIONS;
- m.obj = mTmpData;
+ m.obj = data;
try {
mToActivityMessenger.send(m);
} catch (RemoteException e) {
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
index a0f491f..0ce3210 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -288,7 +288,8 @@
}
private void onAccessibilityShowMenu() {
- mMenuController.showMenu(mMotionHelper.getBounds(), mMovementBounds);
+ mMenuController.showMenu(mMotionHelper.getBounds(), mMovementBounds,
+ false /* allowMenuTimeout */);
}
private boolean handleTouchEvent(MotionEvent ev) {
@@ -617,7 +618,8 @@
// If the menu is still visible, and we aren't minimized, then just poke the menu
// so that it will timeout after the user stops touching it
if (mMenuController.isMenuVisible()) {
- mMenuController.showMenu(mMotionHelper.getBounds(), mMovementBounds);
+ mMenuController.showMenu(mMotionHelper.getBounds(), mMovementBounds,
+ true /* allowMenuTimeout */);
}
if (isFling) {
@@ -631,7 +633,8 @@
mMotionHelper.animateToClosestSnapTarget(mMovementBounds, null /* listener */);
setMinimizedStateInternal(false);
} else if (!mIsMenuVisible) {
- mMenuController.showMenu(mMotionHelper.getBounds(), mMovementBounds);
+ mMenuController.showMenu(mMotionHelper.getBounds(), mMovementBounds,
+ true /* allowMenuTimeout */);
} else {
mMotionHelper.expandPip();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
index 0398f7b..21a0dc9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInfo.java
@@ -76,6 +76,7 @@
private TextView mNumChannelsView;
private View mChannelDisabledView;
private Switch mChannelEnabledSwitch;
+ private CheckSaveListener mCheckSaveListener;
private NotificationGuts mGutsContainer;
@@ -83,6 +84,13 @@
super(context, attrs);
}
+ // Specify a CheckSaveListener to override when/if the user's changes are committed.
+ public interface CheckSaveListener {
+ // Invoked when importance has changed and the NotificationInfo wants to try to save it.
+ // Listener should run saveImportance unless the change should be canceled.
+ void checkSave(Runnable saveImportance);
+ }
+
public interface OnSettingsClickListener {
void onClick(View v, NotificationChannel channel, int appUid);
}
@@ -92,11 +100,14 @@
final String pkg,
final List<NotificationChannel> notificationChannels,
OnSettingsClickListener onSettingsClick,
- OnClickListener onDoneClick, final Set<String> nonBlockablePkgs)
+ OnClickListener onDoneClick,
+ CheckSaveListener checkSaveListener,
+ final Set<String> nonBlockablePkgs)
throws RemoteException {
mINotificationManager = iNotificationManager;
mPkg = pkg;
mNotificationChannels = notificationChannels;
+ mCheckSaveListener = checkSaveListener;
boolean isSingleDefaultChannel = false;
if (mNotificationChannels.isEmpty()) {
throw new IllegalArgumentException("bindNotification requires at least one channel");
@@ -238,7 +249,7 @@
doneButton.setOnClickListener(onDoneClick);
}
- public boolean hasImportanceChanged() {
+ private boolean hasImportanceChanged() {
return mSingleNotificationChannel != null &&
mStartingUserImportance != getSelectedImportance();
}
@@ -316,8 +327,12 @@
@Override
public boolean handleCloseControls(boolean save) {
- if (save) {
- saveImportance();
+ if (save && hasImportanceChanged()) {
+ if (mCheckSaveListener != null) {
+ mCheckSaveListener.checkSave(() -> { saveImportance(); });
+ } else {
+ saveImportance();
+ }
}
return false;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
index 5370ceb..e1fceb6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBar.java
@@ -5778,21 +5778,19 @@
startAppNotificationSettingsActivity(pkg, appUid, channel);
};
final View.OnClickListener onDoneClick = (View v) -> {
+ saveAndCloseNotificationMenu(info, row, guts, v);
+ };
+ final NotificationInfo.CheckSaveListener checkSaveListener = (Runnable saveImportance) -> {
// If the user has security enabled, show challenge if the setting is changed.
- if (info.hasImportanceChanged()
- && isLockscreenPublicMode(userHandle.getIdentifier())
+ if (isLockscreenPublicMode(userHandle.getIdentifier())
&& (mState == StatusBarState.KEYGUARD
|| mState == StatusBarState.SHADE_LOCKED)) {
- OnDismissAction dismissAction = new OnDismissAction() {
- @Override
- public boolean onDismiss() {
- saveAndCloseNotificationMenu(info, row, guts, v);
- return true;
- }
- };
- onLockedNotificationImportanceChange(dismissAction);
+ onLockedNotificationImportanceChange(() -> {
+ saveImportance.run();
+ return true;
+ });
} else {
- saveAndCloseNotificationMenu(info, row, guts, v);
+ saveImportance.run();
}
};
@@ -5815,7 +5813,7 @@
}
try {
info.bindNotification(pmUser, iNotificationManager, pkg, new ArrayList(channels),
- onSettingsClick, onDoneClick, mNonBlockablePkgs);
+ onSettingsClick, onDoneClick, checkSaveListener, mNonBlockablePkgs);
} catch (RemoteException e) {
Log.e(TAG, e.toString());
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
index 5632b71..21930a3 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationInfoTest.java
@@ -135,7 +135,7 @@
public void testBindNotification_SetsTextApplicationName() throws Exception {
when(mMockPackageManager.getApplicationLabel(any())).thenReturn("App Name");
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
final TextView textView = (TextView) mNotificationInfo.findViewById(R.id.pkgname);
assertTrue(textView.getText().toString().contains("App Name"));
}
@@ -146,7 +146,7 @@
when(mMockPackageManager.getApplicationIcon(any(ApplicationInfo.class)))
.thenReturn(iconDrawable);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
final ImageView iconView = (ImageView) mNotificationInfo.findViewById(R.id.pkgicon);
assertEquals(iconDrawable, iconView.getDrawable());
}
@@ -154,7 +154,7 @@
@Test
public void testBindNotification_GroupNameHiddenIfNoGroup() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
final TextView groupNameView = (TextView) mNotificationInfo.findViewById(R.id.group_name);
assertEquals(View.GONE, groupNameView.getVisibility());
final TextView groupDividerView =
@@ -171,7 +171,7 @@
eq("test_group_id"), eq(TEST_PACKAGE_NAME), anyInt()))
.thenReturn(notificationChannelGroup);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
final TextView groupNameView = (TextView) mNotificationInfo.findViewById(R.id.group_name);
assertEquals(View.VISIBLE, groupNameView.getVisibility());
assertEquals("Test Group Name", groupNameView.getText());
@@ -183,7 +183,7 @@
@Test
public void testBindNotification_SetsTextChannelName() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
final TextView textView = (TextView) mNotificationInfo.findViewById(R.id.channel_name);
assertEquals(TEST_CHANNEL_NAME, textView.getText());
}
@@ -196,7 +196,7 @@
(View v, NotificationChannel c, int appUid) -> {
assertEquals(mNotificationChannel, c);
latch.countDown();
- }, null, null);
+ }, null, null, null);
final TextView settingsButton =
(TextView) mNotificationInfo.findViewById(R.id.more_settings);
@@ -214,7 +214,7 @@
(View v, NotificationChannel c, int appUid) -> {
assertEquals(null, c);
latch.countDown();
- }, null, null);
+ }, null, null, null);
final TextView settingsButton =
(TextView) mNotificationInfo.findViewById(R.id.more_settings);
@@ -227,7 +227,7 @@
public void testBindNotification_SettingsTextWithOneChannel() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- (View v, NotificationChannel c, int appUid) -> {}, null, null);
+ (View v, NotificationChannel c, int appUid) -> {}, null, null, null);
final TextView settingsButton =
(TextView) mNotificationInfo.findViewById(R.id.more_settings);
assertEquals(getStringById(R.string.notification_more_settings), settingsButton.getText());
@@ -239,7 +239,7 @@
eq(TEST_PACKAGE_NAME), anyInt(), anyBoolean())).thenReturn(2);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel),
- (View v, NotificationChannel c, int appUid) -> {}, null, null);
+ (View v, NotificationChannel c, int appUid) -> {}, null, null, null);
final TextView settingsButton =
(TextView) mNotificationInfo.findViewById(R.id.more_settings);
assertEquals(getStringById(R.string.notification_all_categories), settingsButton.getText());
@@ -251,7 +251,7 @@
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null,
(View v) -> { latch.countDown(); },
- null);
+ null, null);
final TextView doneButton = (TextView) mNotificationInfo.findViewById(R.id.done);
doneButton.performClick();
@@ -262,7 +262,8 @@
@Test
public void testBindNotification_NumChannelsTextUniqueWhenDefaultChannel() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mDefaultNotificationChannel), null, null, null);
+ TEST_PACKAGE_NAME, Arrays.asList(mDefaultNotificationChannel),
+ null, null, null, null);
final TextView numChannelsView =
(TextView) mNotificationInfo.findViewById(R.id.num_channels_desc);
assertEquals(View.VISIBLE, numChannelsView.getVisibility());
@@ -274,7 +275,7 @@
public void testBindNotification_NumChannelsTextDisplaysWhenNotDefaultChannel()
throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
final TextView numChannelsView =
(TextView) mNotificationInfo.findViewById(R.id.num_channels_desc);
assertEquals(numChannelsView.getVisibility(), View.VISIBLE);
@@ -287,7 +288,7 @@
when(mMockINotificationManager.getNumNotificationChannelsForPackage(
eq(TEST_PACKAGE_NAME), anyInt(), anyBoolean())).thenReturn(2);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
final TextView numChannelsView =
(TextView) mNotificationInfo.findViewById(R.id.num_channels_desc);
assertEquals(getNumChannelsDescString(2), numChannelsView.getText());
@@ -299,7 +300,7 @@
throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel, mDefaultNotificationChannel),
- null, null, null);
+ null, null, null, null);
final TextView numChannelsView =
(TextView) mNotificationInfo.findViewById(R.id.num_channels_desc);
assertEquals(getChannelsListDescString(mNotificationChannel, mDefaultNotificationChannel),
@@ -315,7 +316,7 @@
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME,
Arrays.asList(mNotificationChannel, mDefaultNotificationChannel, thirdChannel),
- null, null, null);
+ null, null, null, null);
final TextView numChannelsView =
(TextView) mNotificationInfo.findViewById(R.id.num_channels_desc);
assertEquals(
@@ -336,7 +337,7 @@
TEST_PACKAGE_NAME,
Arrays.asList(mNotificationChannel, mDefaultNotificationChannel, thirdChannel,
fourthChannel),
- null, null, null);
+ null, null, null, null);
final TextView numChannelsView =
(TextView) mNotificationInfo.findViewById(R.id.num_channels_desc);
assertEquals(
@@ -351,7 +352,7 @@
throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel, mDefaultNotificationChannel),
- null, null, null);
+ null, null, null, null);
final TextView channelNameView =
(TextView) mNotificationInfo.findViewById(R.id.channel_name);
assertEquals(getNumChannelsString(2), channelNameView.getText());
@@ -362,7 +363,7 @@
public void testEnabledSwitchInvisibleIfBundleFromDifferentChannels() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel, mDefaultNotificationChannel),
- null, null, null);
+ null, null, null, null);
Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
assertEquals(View.INVISIBLE, enabledSwitch.getVisibility());
}
@@ -370,7 +371,7 @@
@Test
public void testbindNotification_ChannelDisabledTextGoneWhenNotDisabled() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
final TextView channelDisabledView =
(TextView) mNotificationInfo.findViewById(R.id.channel_disabled);
assertEquals(channelDisabledView.getVisibility(), View.GONE);
@@ -380,7 +381,7 @@
public void testbindNotification_ChannelDisabledTextVisibleWhenDisabled() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_NONE);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
final TextView channelDisabledView =
(TextView) mNotificationInfo.findViewById(R.id.channel_disabled);
assertEquals(channelDisabledView.getVisibility(), View.VISIBLE);
@@ -396,35 +397,17 @@
throws Exception {
mDefaultNotificationChannel.setImportance(NotificationManager.IMPORTANCE_NONE);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mDefaultNotificationChannel), null, null, null);
+ TEST_PACKAGE_NAME, Arrays.asList(mDefaultNotificationChannel),
+ null, null, null, null);
final TextView channelDisabledView =
(TextView) mNotificationInfo.findViewById(R.id.channel_disabled);
assertEquals(View.VISIBLE, channelDisabledView.getVisibility());
}
@Test
- @UiThreadTest
- public void testHasImportanceChanged_DefaultsToFalse() throws Exception {
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
- assertFalse(mNotificationInfo.hasImportanceChanged());
- }
-
- @Test
- public void testHasImportanceChanged_ReturnsTrueAfterChannelDisabled() throws Exception {
- mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
- mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
- // Find the high button and check it.
- Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
- enabledSwitch.setChecked(false);
- assertTrue(mNotificationInfo.hasImportanceChanged());
- }
-
- @Test
public void testBindNotification_DoesNotUpdateNotificationChannel() throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
anyString(), anyInt(), any());
}
@@ -433,7 +416,7 @@
public void testDoesNotUpdateNotificationChannelAfterImportanceChanged() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
enabledSwitch.setChecked(false);
@@ -445,7 +428,7 @@
public void testHandleCloseControls_DoesNotUpdateNotificationChannelIfUnchanged()
throws Exception {
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
mNotificationInfo.handleCloseControls(true);
verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
@@ -457,7 +440,7 @@
throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_UNSPECIFIED);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
mNotificationInfo.handleCloseControls(true);
verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
@@ -468,7 +451,7 @@
public void testEnabledSwitchOnByDefault() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
assertTrue(enabledSwitch.isChecked());
@@ -478,7 +461,7 @@
public void testEnabledButtonOffWhenAlreadyBanned() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_NONE);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
assertFalse(enabledSwitch.isChecked());
@@ -488,7 +471,7 @@
public void testEnabledSwitchVisibleByDefault() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null);
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null, null);
Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
assertEquals(View.VISIBLE, enabledSwitch.getVisibility());
@@ -498,7 +481,7 @@
public void testEnabledSwitchInvisibleIfNonBlockable() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null,
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null,
Collections.singleton(TEST_PACKAGE_NAME));
Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
@@ -509,7 +492,7 @@
public void testNonBlockableAppDoesNotBecomeBlocked() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null,
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null,
Collections.singleton(TEST_PACKAGE_NAME));
mNotificationInfo.handleCloseControls(true);
verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
@@ -520,7 +503,7 @@
public void testEnabledSwitchChangedCallsUpdateNotificationChannel() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null,
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null,
Collections.singleton(TEST_PACKAGE_NAME));
Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
@@ -534,7 +517,7 @@
public void testCloseControlsDoesNotUpdateIfSaveIsFalse() throws Exception {
mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
- TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null,
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null, null,
Collections.singleton(TEST_PACKAGE_NAME));
Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
@@ -543,4 +526,34 @@
verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
eq(TEST_PACKAGE_NAME), anyInt(), eq(mNotificationChannel));
}
+
+ @Test
+ public void testCloseControlsDoesNotUpdateIfCheckSaveListenerIsNoOp() throws Exception {
+ mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
+ mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null,
+ (Runnable saveImportance) -> {},
+ Collections.singleton(TEST_PACKAGE_NAME));
+
+ Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
+ enabledSwitch.setChecked(false);
+ mNotificationInfo.handleCloseControls(true);
+ verify(mMockINotificationManager, never()).updateNotificationChannelForPackage(
+ eq(TEST_PACKAGE_NAME), anyInt(), eq(mNotificationChannel));
+ }
+
+ @Test
+ public void testCloseControlsUpdatesWhenCheckSaveListenerUsesCallback() throws Exception {
+ mNotificationChannel.setImportance(NotificationManager.IMPORTANCE_LOW);
+ mNotificationInfo.bindNotification(mMockPackageManager, mMockINotificationManager,
+ TEST_PACKAGE_NAME, Arrays.asList(mNotificationChannel), null, null,
+ (Runnable saveImportance) -> { saveImportance.run(); },
+ Collections.singleton(TEST_PACKAGE_NAME));
+
+ Switch enabledSwitch = (Switch) mNotificationInfo.findViewById(R.id.channel_enabled_switch);
+ enabledSwitch.setChecked(false);
+ mNotificationInfo.handleCloseControls(true);
+ verify(mMockINotificationManager, times(1)).updateNotificationChannelForPackage(
+ eq(TEST_PACKAGE_NAME), anyInt(), eq(mNotificationChannel));
+ }
}
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 1093e9e..9285027 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -244,10 +244,10 @@
// FillServiceCallbacks
@Override
- public void authenticate(IntentSender intent) {
+ public void authenticate(IntentSender intent, Bundle extras) {
final Intent fillInIntent;
synchronized (mLock) {
- fillInIntent = createAuthFillInIntent(mStructure);
+ fillInIntent = createAuthFillInIntent(mStructure, extras);
}
mHandlerCaller.getHandler().post(() -> startAuthentication(intent, fillInIntent));
}
@@ -313,7 +313,7 @@
if (mCurrentResponse == null || data == null) {
removeSelf();
} else {
- Parcelable result = data.getParcelable(
+ final Parcelable result = data.getParcelable(
AutofillManager.EXTRA_AUTHENTICATION_RESULT);
if (result instanceof FillResponse) {
mMetricsLogger.action(MetricsEvent.AUTOFILL_AUTHENTICATED, mPackageName);
@@ -321,7 +321,7 @@
mCurrentResponse = (FillResponse) result;
processResponseLocked(mCurrentResponse);
} else if (result instanceof Dataset) {
- Dataset dataset = (Dataset) result;
+ final Dataset dataset = (Dataset) result;
final int index = mCurrentResponse.getDatasets().indexOf(mAutoFilledDataset);
if (index >= 0) {
mCurrentResponse.getDatasets().set(index, dataset);
@@ -614,7 +614,8 @@
if (mCurrentResponse.getAuthentication() != null) {
// Handle authentication.
- final Intent fillInIntent = createAuthFillInIntent(mStructure);
+ final Intent fillInIntent = createAuthFillInIntent(mStructure,
+ mCurrentResponse.getExtras());
mCurrentViewState.setResponse(mCurrentResponse, fillInIntent);
return;
}
@@ -640,7 +641,7 @@
}
// ...or handle authentication.
- Intent fillInIntent = createAuthFillInIntent(mStructure);
+ final Intent fillInIntent = createAuthFillInIntent(mStructure, null);
startAuthentication(dataset.getAuthentication(), fillInIntent);
}
}
@@ -649,9 +650,12 @@
return mService.getServiceName();
}
- private Intent createAuthFillInIntent(AssistStructure structure) {
- Intent fillInIntent = new Intent();
+ private Intent createAuthFillInIntent(AssistStructure structure, Bundle extras) {
+ final Intent fillInIntent = new Intent();
fillInIntent.putExtra(AutofillManager.EXTRA_ASSIST_STRUCTURE, structure);
+ if (extras != null) {
+ fillInIntent.putExtra(AutofillManager.EXTRA_DATA_EXTRAS, extras);
+ }
return fillInIntent;
}
diff --git a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
index 2555cee..832ff9a 100644
--- a/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
+++ b/services/autofill/java/com/android/server/autofill/ui/AutoFillUI.java
@@ -22,6 +22,7 @@
import android.content.Context;
import android.content.IntentSender;
import android.metrics.LogMaker;
+import android.os.Bundle;
import android.os.Handler;
import android.service.autofill.Dataset;
import android.service.autofill.FillResponse;
@@ -63,7 +64,7 @@
private final MetricsLogger mMetricsLogger = new MetricsLogger();
public interface AutoFillUiCallback {
- void authenticate(@NonNull IntentSender intent);
+ void authenticate(@NonNull IntentSender intent, @Nullable Bundle extras);
void fill(@NonNull Dataset dataset);
void save();
void cancelSave();
@@ -156,7 +157,7 @@
log.setType(MetricsProto.MetricsEvent.TYPE_DETAIL);
hideFillUiUiThread();
if (mCallback != null) {
- mCallback.authenticate(response.getAuthentication());
+ mCallback.authenticate(response.getAuthentication(), response.getExtras());
}
}
diff --git a/services/core/java/com/android/server/BatteryService.java b/services/core/java/com/android/server/BatteryService.java
index 98242f9..fd44794 100644
--- a/services/core/java/com/android/server/BatteryService.java
+++ b/services/core/java/com/android/server/BatteryService.java
@@ -679,7 +679,7 @@
pw.println("Battery service (battery) commands:");
pw.println(" help");
pw.println(" Print this help text.");
- pw.println(" set [-f] [ac|usb|wireless|status|level|present|invalid] <value>");
+ pw.println(" set [-f] [ac|usb|wireless|status|level|temp|present|invalid] <value>");
pw.println(" Force a battery property value, freezing battery state.");
pw.println(" -f: force a battery change broadcast be sent, prints new sequence.");
pw.println(" unplug [-f]");
@@ -767,6 +767,9 @@
case "level":
mBatteryProps.batteryLevel = Integer.parseInt(value);
break;
+ case "temp":
+ mBatteryProps.batteryTemperature = Integer.parseInt(value);
+ break;
case "invalid":
mInvalidCharger = Integer.parseInt(value);
break;
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 0ccaf8e..015603b 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -1407,14 +1407,10 @@
long identityToken = clearCallingIdentity();
try {
UserAccounts accounts = getUserAccounts(userId);
- synchronized (accounts.dbLock) {
- synchronized (accounts.cacheLock) {
- if (!accountExistsCacheLocked(accounts, account)) {
- return null;
- }
- return readUserDataInternalLocked(accounts, account, key);
- }
+ if (!accountExistsCache(accounts, account)) {
+ return null;
}
+ return readUserDataInternal(accounts, account, key);
} finally {
restoreCallingIdentity(identityToken);
}
@@ -1597,17 +1593,11 @@
@Override
public void run() throws RemoteException {
// Confirm that the owner's account still exists before this step.
- UserAccounts owner = getUserAccounts(parentUserId);
- synchronized (owner.dbLock) {
- synchronized (owner.cacheLock) {
- for (Account acc : getAccounts(parentUserId,
- mContext.getOpPackageName())) {
- if (acc.equals(account)) {
- mAuthenticator.addAccountFromCredentials(
- this, account, accountCredentials);
- break;
- }
- }
+ for (Account acc : getAccounts(parentUserId, mContext.getOpPackageName())) {
+ if (acc.equals(account)) {
+ mAuthenticator.addAccountFromCredentials(
+ this, account, accountCredentials);
+ break;
}
}
}
@@ -2509,54 +2499,53 @@
long identityToken = clearCallingIdentity();
try {
UserAccounts accounts = getUserAccounts(userId);
- synchronized (accounts.dbLock) {
- synchronized (accounts.cacheLock) {
- if (!accountExistsCacheLocked(accounts, account)) {
- return;
- }
- setUserdataInternalLocked(accounts, account, key, value);
- }
+ if (!accountExistsCache(accounts, account)) {
+ return;
}
+ setUserdataInternal(accounts, account, key, value);
} finally {
restoreCallingIdentity(identityToken);
}
}
- private boolean accountExistsCacheLocked(UserAccounts accounts, Account account) {
- if (accounts.accountCache.containsKey(account.type)) {
- for (Account acc : accounts.accountCache.get(account.type)) {
- if (acc.name.equals(account.name)) {
- return true;
+ private boolean accountExistsCache(UserAccounts accounts, Account account) {
+ synchronized (accounts.cacheLock) {
+ if (accounts.accountCache.containsKey(account.type)) {
+ for (Account acc : accounts.accountCache.get(account.type)) {
+ if (acc.name.equals(account.name)) {
+ return true;
+ }
}
}
}
return false;
}
- private void setUserdataInternalLocked(UserAccounts accounts, Account account, String key,
+ private void setUserdataInternal(UserAccounts accounts, Account account, String key,
String value) {
- if (account == null || key == null) {
- return;
- }
- accounts.accountsDb.beginTransaction();
- try {
- long accountId = accounts.accountsDb.findDeAccountId(account);
- if (accountId < 0) {
- return;
- }
- long extrasId = accounts.accountsDb.findExtrasIdByAccountId(accountId, key);
- if (extrasId < 0) {
- extrasId = accounts.accountsDb.insertExtra(accountId, key, value);
- if (extrasId < 0) {
+ synchronized (accounts.dbLock) {
+ accounts.accountsDb.beginTransaction();
+ try {
+ long accountId = accounts.accountsDb.findDeAccountId(account);
+ if (accountId < 0) {
return;
}
- } else if (!accounts.accountsDb.updateExtra(extrasId, value)) {
- return;
+ long extrasId = accounts.accountsDb.findExtrasIdByAccountId(accountId, key);
+ if (extrasId < 0) {
+ extrasId = accounts.accountsDb.insertExtra(accountId, key, value);
+ if (extrasId < 0) {
+ return;
+ }
+ } else if (!accounts.accountsDb.updateExtra(extrasId, value)) {
+ return;
+ }
+ accounts.accountsDb.setTransactionSuccessful();
+ } finally {
+ accounts.accountsDb.endTransaction();
}
- writeUserDataIntoCacheLocked(accounts, account, key, value);
- accounts.accountsDb.setTransactionSuccessful();
- } finally {
- accounts.accountsDb.endTransaction();
+ synchronized (accounts.cacheLock) {
+ writeUserDataIntoCacheLocked(accounts, account, key, value);
+ }
}
}
@@ -5628,6 +5617,7 @@
}
}
+ /** protected by the {@code dbLock}, {@code cacheLock} */
protected void writeUserDataIntoCacheLocked(UserAccounts accounts,
Account account, String key, String value) {
Map<String, String> userDataForAccount = accounts.userDataCache.get(account);
@@ -5694,13 +5684,24 @@
}
}
- protected String readUserDataInternalLocked(
- UserAccounts accounts, Account account, String key) {
- Map<String, String> userDataForAccount = accounts.userDataCache.get(account);
+ private String readUserDataInternal(UserAccounts accounts, Account account, String key) {
+ Map<String, String> userDataForAccount;
+ // Fast path - check if data is already cached
+ synchronized (accounts.cacheLock) {
+ userDataForAccount = accounts.userDataCache.get(account);
+ }
+ // If not cached yet - do slow path and sync with db if necessary
if (userDataForAccount == null) {
- // need to populate the cache for this account
- userDataForAccount = accounts.accountsDb.findUserExtrasForAccount(account);
- accounts.userDataCache.put(account, userDataForAccount);
+ synchronized (accounts.dbLock) {
+ synchronized (accounts.cacheLock) {
+ userDataForAccount = accounts.userDataCache.get(account);
+ if (userDataForAccount == null) {
+ // need to populate the cache for this account
+ userDataForAccount = accounts.accountsDb.findUserExtrasForAccount(account);
+ accounts.userDataCache.put(account, userDataForAccount);
+ }
+ }
+ }
}
return userDataForAccount.get(key);
}
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index b4f8f61..8b0665c 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -17,7 +17,6 @@
package com.android.server.am;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
-import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
import static com.android.server.am.ActivityManagerDebugConfig.*;
import java.io.FileDescriptor;
@@ -96,6 +95,10 @@
// How long we wait for a service to finish executing.
static final int SERVICE_BACKGROUND_TIMEOUT = SERVICE_TIMEOUT * 10;
+ // How long the startForegroundService() grace period is to get around to
+ // calling startForeground() before we ANR + stop it.
+ static final int SERVICE_START_FOREGROUND_TIMEOUT = 5*1000;
+
// How long a service needs to be running until restarting its process
// is no longer considered to be a relaunch of the service.
static final int SERVICE_RESTART_DURATION = 1*1000;
@@ -307,8 +310,8 @@
}
ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
- int id, Notification notification,
- int callingPid, int callingUid, String callingPackage, final int userId)
+ int id, Notification notification, int callingPid, int callingUid,
+ boolean fgRequired, String callingPackage, final int userId)
throws TransactionTooLargeException {
if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "startService: " + service
+ " type=" + resolvedType + " args=" + service.getExtras());
@@ -345,8 +348,9 @@
return null;
}
- // Non-null notification means this is a start directly into the foreground
- if (!r.startRequested && notification == null) {
+ // If this isn't a direct-to-foreground start, check our ability to kick off an
+ // arbitrary service
+ if (!r.startRequested && !fgRequired) {
final long token = Binder.clearCallingIdentity();
try {
// Before going further -- if this app is not allowed to start services in the
@@ -392,12 +396,13 @@
r.lastActivity = SystemClock.uptimeMillis();
r.startRequested = true;
r.delayedStop = false;
+ r.fgRequired = fgRequired;
r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
service, neededGrants));
final ServiceMap smap = getServiceMapLocked(r.userId);
boolean addToStarting = false;
- if (!callerFg && r.app == null
+ if (!callerFg && !fgRequired && r.app == null
&& mAm.mUserController.hasStartedUserState(r.userId)) {
ProcessRecord proc = mAm.getProcessRecordLocked(r.processName, r.appInfo.uid, false);
if (proc == null || proc.curProcState > ActivityManager.PROCESS_STATE_RECEIVER) {
@@ -449,9 +454,9 @@
Slog.v(TAG_SERVICE, sb.toString());
}
} else if (DEBUG_DELAYED_STARTS) {
- if (callerFg) {
+ if (callerFg || fgRequired) {
Slog.v(TAG_SERVICE, "Not potential delay (callerFg=" + callerFg + " uid="
- + callingUid + " pid=" + callingPid + "): " + r);
+ + callingUid + " pid=" + callingPid + " fgRequired=" + fgRequired + "): " + r);
} else if (r.app != null) {
Slog.v(TAG_SERVICE, "Not potential delay (cur app=" + r.app + "): " + r);
} else {
@@ -461,6 +466,7 @@
}
ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
+ // STOPSHIP deprecated; remove when NotificationManager.startServiceInForeground is retired
if (notification != null) {
setServiceForegroundInnerLocked(r, id, notification, 0);
}
@@ -540,7 +546,7 @@
if (first) {
smap.rescheduleDelayedStartsLocked();
}
- } else if (callerFg) {
+ } else if (callerFg || r.fgRequired) {
smap.ensureNotStartingBackgroundLocked(r);
}
@@ -756,8 +762,17 @@
}
}
}
+ if (r.fgRequired) {
+ if (DEBUG_BACKGROUND_CHECK) {
+ Slog.i(TAG, "Service called startForeground() as required: " + r);
+ }
+ r.fgRequired = false;
+ r.fgWaiting = false;
+ mAm.mHandler.removeMessages(
+ ActivityManagerService.SERVICE_FOREGROUND_TIMEOUT_MSG, r);
+ }
if (r.foregroundId != id) {
- cancelForegroudNotificationLocked(r);
+ cancelForegroundNotificationLocked(r);
r.foregroundId = id;
}
notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
@@ -779,7 +794,7 @@
}
}
if ((flags & Service.STOP_FOREGROUND_REMOVE) != 0) {
- cancelForegroudNotificationLocked(r);
+ cancelForegroundNotificationLocked(r);
r.foregroundId = 0;
r.foregroundNoti = null;
} else if (r.appInfo.targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP) {
@@ -792,7 +807,7 @@
}
}
- private void cancelForegroudNotificationLocked(ServiceRecord r) {
+ private void cancelForegroundNotificationLocked(ServiceRecord r) {
if (r.foregroundId != 0) {
// First check to see if this app has any other active foreground services
// with the same notification ID. If so, we shouldn't actually cancel it,
@@ -1631,7 +1646,7 @@
r.makeRestarting(mAm.mProcessStats.getMemFactorLocked(), now);
}
- cancelForegroudNotificationLocked(r);
+ cancelForegroundNotificationLocked(r);
mAm.mHandler.removeCallbacks(r.restarter);
mAm.mHandler.postAtTime(r.restarter, r.nextRestartTime);
@@ -1718,7 +1733,9 @@
return null;
}
- if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Bringing up " + r + " " + r.intent);
+ if (DEBUG_SERVICE) {
+ Slog.v(TAG_SERVICE, "Bringing up " + r + " " + r.intent + " fg=" + r.fgRequired);
+ }
// We are now bringing the service up, so no longer in the
// restarting state.
@@ -1944,8 +1961,10 @@
ServiceRecord.StartItem si = null;
try {
si = r.pendingStarts.remove(0);
- if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Sending arguments to: "
- + r + " " + r.intent + " args=" + si.intent);
+ if (DEBUG_SERVICE) {
+ Slog.v(TAG_SERVICE, "Sending arguments to: "
+ + r + " " + r.intent + " args=" + si.intent);
+ }
if (si.intent == null && N > 1) {
// If somehow we got a dummy null intent in the middle,
// then skip it. DO NOT skip a null intent when it is
@@ -1966,6 +1985,19 @@
oomAdjusted = true;
mAm.updateOomAdjLocked(r.app);
}
+ if (r.fgRequired && !r.fgWaiting) {
+ if (!r.isForeground) {
+ if (DEBUG_BACKGROUND_CHECK) {
+ Slog.i(TAG, "Launched service must call startForeground() within timeout: " + r);
+ }
+ scheduleServiceForegroundTransitionTimeoutLocked(r);
+ } else {
+ if (DEBUG_BACKGROUND_CHECK) {
+ Slog.i(TAG, "Service already foreground; no new timeout: " + r);
+ }
+ r.fgRequired = false;
+ }
+ }
int flags = 0;
if (si.deliveryCount > 1) {
flags |= Service.START_FLAG_RETRY;
@@ -2101,7 +2133,7 @@
}
}
- cancelForegroudNotificationLocked(r);
+ cancelForegroundNotificationLocked(r);
r.isForeground = false;
r.foregroundId = 0;
r.foregroundNoti = null;
@@ -2925,23 +2957,53 @@
}
}
+ void serviceForegroundTimeout(ServiceRecord r) {
+ ProcessRecord app;
+ synchronized (mAm) {
+ if (!r.fgRequired) {
+ return;
+ }
+
+ if (DEBUG_BACKGROUND_CHECK) {
+ Slog.i(TAG, "Service foreground-required timeout for " + r);
+ }
+ app = r.app;
+ r.fgWaiting = false;
+ stopServiceLocked(r);
+ }
+
+ if (app != null) {
+ mAm.mAppErrors.appNotResponding(app, null, null, false,
+ "Context.startForegroundService() did not then call Service.startForeground()");
+ }
+ }
+
void scheduleServiceTimeoutLocked(ProcessRecord proc) {
if (proc.executingServices.size() == 0 || proc.thread == null) {
return;
}
- long now = SystemClock.uptimeMillis();
Message msg = mAm.mHandler.obtainMessage(
ActivityManagerService.SERVICE_TIMEOUT_MSG);
msg.obj = proc;
- mAm.mHandler.sendMessageAtTime(msg,
- proc.execServicesFg ? (now+SERVICE_TIMEOUT) : (now+ SERVICE_BACKGROUND_TIMEOUT));
+ mAm.mHandler.sendMessageDelayed(msg,
+ proc.execServicesFg ? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT);
+ }
+
+ void scheduleServiceForegroundTransitionTimeoutLocked(ServiceRecord r) {
+ if (r.app.executingServices.size() == 0 || r.app.thread == null) {
+ return;
+ }
+ Message msg = mAm.mHandler.obtainMessage(
+ ActivityManagerService.SERVICE_FOREGROUND_TIMEOUT_MSG);
+ msg.obj = r;
+ r.fgWaiting = true;
+ mAm.mHandler.sendMessageDelayed(msg, SERVICE_START_FOREGROUND_TIMEOUT);
}
final class ServiceDumper {
private final FileDescriptor fd;
private final PrintWriter pw;
private final String[] args;
- private final int opti;
private final boolean dumpAll;
private final String dumpPackage;
private final ItemMatcher matcher;
@@ -2962,7 +3024,6 @@
this.fd = fd;
this.pw = pw;
this.args = args;
- this.opti = opti;
this.dumpAll = dumpAll;
this.dumpPackage = dumpPackage;
matcher = new ItemMatcher();
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 8cb0eee..487f383 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1726,6 +1726,7 @@
static final int HANDLE_TRUST_STORAGE_UPDATE_MSG = 63;
static final int REPORT_LOCKED_BOOT_COMPLETE_MSG = 64;
static final int NOTIFY_VR_SLEEPING_MSG = 65;
+ static final int SERVICE_FOREGROUND_TIMEOUT_MSG = 66;
static final int START_USER_SWITCH_FG_MSG = 712;
static final int FIRST_ACTIVITY_STACK_MSG = 100;
@@ -1991,6 +1992,9 @@
}
mServices.serviceTimeout((ProcessRecord)msg.obj);
} break;
+ case SERVICE_FOREGROUND_TIMEOUT_MSG: {
+ mServices.serviceForegroundTimeout((ServiceRecord)msg.obj);
+ } break;
case UPDATE_TIME_ZONE: {
synchronized (ActivityManagerService.this) {
for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
@@ -6552,6 +6556,7 @@
if (Arrays.binarySearch(mDeviceIdleTempWhitelist, UserHandle.getAppId(proc.uid)) >= 0) {
uidRec.setWhitelist = uidRec.curWhitelist = true;
}
+ uidRec.updateHasInternetPermission();
mActiveUids.put(proc.uid, uidRec);
noteUidProcessState(uidRec.uid, uidRec.curProcState);
enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
@@ -6596,6 +6601,7 @@
mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
if (app.isolated) {
mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
+ getPackageManagerInternalLocked().removeIsolatedUid(app.uid);
}
boolean willRestart = false;
if (app.persistent && !app.isolated) {
@@ -12089,6 +12095,7 @@
// the uid of the isolated process is specified by the caller.
uid = isolatedUid;
}
+ getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid);
// Register the isolated UID with this application so BatteryStats knows to
// attribute resource usage to the application.
@@ -17896,7 +17903,7 @@
@Override
public ComponentName startService(IApplicationThread caller, Intent service,
- String resolvedType, int id, Notification notification,
+ String resolvedType, int id, Notification notification, boolean requireForeground,
String callingPackage, int userId)
throws TransactionTooLargeException {
enforceNotIsolatedCaller("startService");
@@ -17910,28 +17917,28 @@
}
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
- "startService: " + service + " type=" + resolvedType);
+ "*** startService: " + service + " type=" + resolvedType + " fg=" + requireForeground);
synchronized(this) {
final int callingPid = Binder.getCallingPid();
final int callingUid = Binder.getCallingUid();
final long origId = Binder.clearCallingIdentity();
ComponentName res = mServices.startServiceLocked(caller, service,
- resolvedType, id, notification,
- callingPid, callingUid, callingPackage, userId);
+ resolvedType, id, notification, callingPid, callingUid,
+ requireForeground, callingPackage, userId);
Binder.restoreCallingIdentity(origId);
return res;
}
}
ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
- String callingPackage, int userId)
+ boolean fgRequired, String callingPackage, int userId)
throws TransactionTooLargeException {
synchronized(this) {
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
"startServiceInPackage: " + service + " type=" + resolvedType);
final long origId = Binder.clearCallingIdentity();
ComponentName res = mServices.startServiceLocked(null, service,
- resolvedType, 0, null, -1, uid, callingPackage, userId);
+ resolvedType, 0, null, -1, uid, fgRequired, callingPackage, userId);
Binder.restoreCallingIdentity(origId);
return res;
}
@@ -18865,9 +18872,7 @@
}
switch (action) {
case Intent.ACTION_UID_REMOVED:
- final Bundle intentExtras = intent.getExtras();
- final int uid = intentExtras != null
- ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
+ final int uid = getUidFromIntent(intent);
if (uid >= 0) {
mBatteryStatsService.removeUid(uid);
mAppOpsService.uidRemoved(uid);
@@ -19063,6 +19068,18 @@
mHandler.sendEmptyMessage(HANDLE_TRUST_STORAGE_UPDATE_MSG);
break;
}
+
+ if (Intent.ACTION_PACKAGE_ADDED.equals(action) ||
+ Intent.ACTION_PACKAGE_REMOVED.equals(action) ||
+ Intent.ACTION_PACKAGE_REPLACED.equals(action)) {
+ final int uid = getUidFromIntent(intent);
+ if (uid != -1) {
+ final UidRecord uidRec = mActiveUids.get(uid);
+ if (uidRec != null) {
+ uidRec.updateHasInternetPermission();
+ }
+ }
+ }
}
// Add to the sticky list if requested.
@@ -19329,6 +19346,18 @@
return ActivityManager.BROADCAST_SUCCESS;
}
+ /**
+ * @return uid from the extra field {@link Intent#EXTRA_UID} if present, Otherwise -1
+ */
+ private int getUidFromIntent(Intent intent) {
+ if (intent == null) {
+ return -1;
+ }
+ final Bundle intentExtras = intent.getExtras();
+ return intent.hasExtra(Intent.EXTRA_UID)
+ ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
+ }
+
final void rotateBroadcastStatsIfNeededLocked() {
final long now = SystemClock.elapsedRealtime();
if (mCurBroadcastStats == null ||
@@ -22547,6 +22576,9 @@
if (!mInjector.isNetworkRestrictedForUid(uidRec.uid)) {
continue;
}
+ if (!UserHandle.isApp(uidRec.uid) || !uidRec.hasInternetPermission) {
+ continue;
+ }
// If process state is not changed, then there's nothing to do.
if (uidRec.setProcState == uidRec.curProcState) {
continue;
@@ -22557,7 +22589,7 @@
if (blockState == NETWORK_STATE_NO_CHANGE) {
continue;
}
- synchronized (uidRec.lock) {
+ synchronized (uidRec.networkStateLock) {
uidRec.curProcStateSeq = ++mProcStateSeqCounter;
if (blockState == NETWORK_STATE_BLOCK) {
if (blockingUids == null) {
@@ -22570,7 +22602,7 @@
+ " threads for uid: " + uidRec);
}
if (uidRec.waitingForNetwork) {
- uidRec.lock.notifyAll();
+ uidRec.networkStateLock.notifyAll();
}
}
}
@@ -23500,7 +23532,7 @@
return;
}
}
- synchronized (record.lock) {
+ synchronized (record.networkStateLock) {
if (record.lastNetworkUpdatedProcStateSeq >= procStateSeq) {
if (DEBUG_NETWORK) {
Slog.d(TAG_NETWORK, "procStateSeq: " + procStateSeq + " has already"
@@ -23522,7 +23554,7 @@
Slog.d(TAG_NETWORK, "Notifying all blocking threads for uid: " + uid
+ ", procStateSeq: " + procStateSeq);
}
- record.lock.notifyAll();
+ record.networkStateLock.notifyAll();
}
}
}
@@ -23547,7 +23579,7 @@
return;
}
}
- synchronized (record.lock) {
+ synchronized (record.networkStateLock) {
if (record.lastDispatchedProcStateSeq < procStateSeq) {
if (DEBUG_NETWORK) {
Slog.d(TAG_NETWORK, "Uid state change for seq no. " + procStateSeq + " is not "
@@ -23581,7 +23613,7 @@
}
final long startTime = SystemClock.uptimeMillis();
record.waitingForNetwork = true;
- record.lock.wait(mWaitForNetworkTimeoutMs);
+ record.networkStateLock.wait(mWaitForNetworkTimeoutMs);
record.waitingForNetwork = false;
final long totalTime = SystemClock.uptimeMillis() - startTime;
if (totalTime >= mWaitForNetworkTimeoutMs) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
index 9b6d13a..a9bd872 100644
--- a/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
+++ b/services/core/java/com/android/server/am/ActivityManagerShellCommand.java
@@ -519,7 +519,7 @@
pw.println("Starting service: " + intent);
pw.flush();
ComponentName cn = mInterface.startService(null, intent, intent.getType(),
- -1, null, SHELL_PACKAGE_NAME, mUserId);
+ -1, null, false, SHELL_PACKAGE_NAME, mUserId);
if (cn == null) {
err.println("Error: Not found; no service started.");
return -1;
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 1712d48..d3935d1 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -149,9 +149,11 @@
case MSG_WRITE_TO_DISK:
updateExternalStatsSync("write", UPDATE_ALL);
+ Slog.d(TAG, "begin writeAsyncLocked");
synchronized (mStats) {
mStats.writeAsyncLocked();
}
+ Slog.d(TAG, "end writeAsyncLocked");
break;
}
}
@@ -191,19 +193,24 @@
@Override
public String getPlatformLowPowerStats() {
- mUtf8BufferStat.clear();
- mUtf16BufferStat.clear();
- mDecoderStat.reset();
- int bytesWritten = getPlatformLowPowerStats(mUtf8BufferStat);
- if (bytesWritten < 0) {
- return null;
- } else if (bytesWritten == 0) {
- return "Empty";
+ Slog.d(TAG, "begin getPlatformLowPowerStats");
+ try {
+ mUtf8BufferStat.clear();
+ mUtf16BufferStat.clear();
+ mDecoderStat.reset();
+ int bytesWritten = getPlatformLowPowerStats(mUtf8BufferStat);
+ if (bytesWritten < 0) {
+ return null;
+ } else if (bytesWritten == 0) {
+ return "Empty";
+ }
+ mUtf8BufferStat.limit(bytesWritten);
+ mDecoderStat.decode(mUtf8BufferStat, mUtf16BufferStat, true);
+ mUtf16BufferStat.flip();
+ return mUtf16BufferStat.toString();
+ } finally {
+ Slog.d(TAG, "end getPlatformLowPowerStats");
}
- mUtf8BufferStat.limit(bytesWritten);
- mDecoderStat.decode(mUtf8BufferStat, mUtf16BufferStat, true);
- mUtf16BufferStat.flip();
- return mUtf16BufferStat.toString();
}
BatteryStatsService(File systemDir, Handler handler) {
@@ -551,9 +558,11 @@
public void noteScreenState(int state) {
enforceCallingPermission();
+ Slog.d(TAG, "begin noteScreenState");
synchronized (mStats) {
mStats.noteScreenStateLocked(state);
}
+ Slog.d(TAG, "end noteScreenState");
}
public void noteScreenBrightness(int brightness) {
@@ -706,9 +715,11 @@
public void noteStartCamera(int uid) {
enforceCallingPermission();
+ Slog.d(TAG, "begin noteStartCamera");
synchronized (mStats) {
mStats.noteCameraOnLocked(uid);
}
+ Slog.d(TAG, "end noteStartCamera");
}
public void noteStopCamera(int uid) {
@@ -1009,24 +1020,32 @@
mHandler.post(new Runnable() {
@Override
public void run() {
- synchronized (mStats) {
- final boolean onBattery = plugType == BatteryStatsImpl.BATTERY_PLUGGED_NONE;
- if (mStats.isOnBattery() == onBattery) {
- // The battery state has not changed, so we don't need to sync external
- // stats immediately.
- mStats.setBatteryStateLocked(status, health, plugType, level, temp, volt,
- chargeUAh, chargeFullUAh);
- return;
+ Slog.d(TAG, "begin setBatteryStateLocked");
+ try {
+ synchronized (mStats) {
+ final boolean onBattery = plugType == BatteryStatsImpl.BATTERY_PLUGGED_NONE;
+ if (mStats.isOnBattery() == onBattery) {
+ // The battery state has not changed, so we don't need to sync external
+ // stats immediately.
+ mStats.setBatteryStateLocked(status, health, plugType, level, temp,
+ volt,
+ chargeUAh, chargeFullUAh);
+ return;
+ }
}
+ } finally {
+ Slog.d(TAG, "end setBatteryStateLocked");
}
// Sync external stats first as the battery has changed states. If we don't sync
// immediately here, we may not collect the relevant data later.
updateExternalStatsSync("battery-state", BatteryStatsImpl.ExternalStatsSync.UPDATE_ALL);
+ Slog.d(TAG, "begin setBatteryStateLocked");
synchronized (mStats) {
mStats.setBatteryStateLocked(status, health, plugType, level, temp, volt,
chargeUAh, chargeFullUAh);
}
+ Slog.d(TAG, "end setBatteryStateLocked");
}
});
}
@@ -1326,19 +1345,23 @@
}
}
}
+ Slog.d(TAG, "begin dumpCheckinLocked from UID " + Binder.getCallingUid());
synchronized (mStats) {
mStats.dumpCheckinLocked(mContext, pw, apps, flags, historyStart);
if (writeData) {
mStats.writeAsyncLocked();
}
}
+ Slog.d(TAG, "end dumpCheckinLocked");
} else {
+ Slog.d(TAG, "begin dumpLocked from UID " + Binder.getCallingUid());
synchronized (mStats) {
mStats.dumpLocked(mContext, pw, flags, reqUid, historyStart);
if (writeData) {
mStats.writeAsyncLocked();
}
}
+ Slog.d(TAG, "end dumpLocked");
}
}
@@ -1460,9 +1483,11 @@
SynchronousResultReceiver bluetoothReceiver = null;
SynchronousResultReceiver modemReceiver = null;
+ Slog.d(TAG, "begin updateExternalStatsSync reason=" + reason);
synchronized (mExternalStatsLock) {
if (mContext == null) {
// Don't do any work yet.
+ Slog.d(TAG, "end updateExternalStatsSync");
return;
}
@@ -1559,6 +1584,7 @@
}
}
}
+ Slog.d(TAG, "end updateExternalStatsSync");
}
/**
diff --git a/services/core/java/com/android/server/am/PendingIntentRecord.java b/services/core/java/com/android/server/am/PendingIntentRecord.java
index c494171..f05bfb6 100644
--- a/services/core/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/core/java/com/android/server/am/PendingIntentRecord.java
@@ -175,6 +175,8 @@
return "broadcastIntent";
case ActivityManager.INTENT_SENDER_SERVICE:
return "startService";
+ case ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE:
+ return "startForegroundService";
case ActivityManager.INTENT_SENDER_ACTIVITY_RESULT:
return "activityResult";
}
@@ -318,9 +320,11 @@
}
break;
case ActivityManager.INTENT_SENDER_SERVICE:
+ case ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE:
try {
- owner.startServiceInPackage(uid, finalIntent,
- resolvedType, key.packageName, userId);
+ owner.startServiceInPackage(uid, finalIntent, resolvedType,
+ key.type == ActivityManager.INTENT_SENDER_FOREGROUND_SERVICE,
+ key.packageName, userId);
} catch (RuntimeException e) {
Slog.w(TAG, "Unable to send startService intent", e);
} catch (TransactionTooLargeException e) {
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index dfbe59f..44ebf50 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -92,6 +92,8 @@
ServiceState restartTracker; // tracking service restart
boolean whitelistManager; // any bindings to this service have BIND_ALLOW_WHITELIST_MANAGEMENT?
boolean delayed; // are we waiting to start this service in the background?
+ boolean fgRequired; // is the service required to go foreground after starting?
+ boolean fgWaiting; // is a timeout for going foreground already scheduled?
boolean isForeground; // is service currently in foreground mode?
int foregroundId; // Notification ID of last foreground req.
Notification foregroundNoti; // Notification record of foreground state.
diff --git a/services/core/java/com/android/server/am/UidRecord.java b/services/core/java/com/android/server/am/UidRecord.java
index 67b80f6..c0fb77f 100644
--- a/services/core/java/com/android/server/am/UidRecord.java
+++ b/services/core/java/com/android/server/am/UidRecord.java
@@ -16,7 +16,9 @@
package com.android.server.am;
+import android.Manifest;
import android.app.ActivityManager;
+import android.content.pm.PackageManager;
import android.os.SystemClock;
import android.os.UserHandle;
import android.util.TimeUtils;
@@ -43,30 +45,37 @@
* {@link ActivityManagerService#mProcStateSeqCounter}
* when {@link #curProcState} changes from background to foreground or vice versa.
*/
- @GuardedBy("lock")
+ @GuardedBy("networkStateUpdate")
long curProcStateSeq;
/**
* Last seq number for which NetworkPolicyManagerService notified ActivityManagerService that
* network policies rules were updated.
*/
- @GuardedBy("lock")
+ @GuardedBy("networkStateUpdate")
long lastNetworkUpdatedProcStateSeq;
/**
* Last seq number for which AcitivityManagerService dispatched uid state change to
* NetworkPolicyManagerService.
*/
- @GuardedBy("lock")
+ @GuardedBy("networkStateUpdate")
long lastDispatchedProcStateSeq;
/**
* Indicates if any thread is waiting for network rules to get updated for {@link #uid}.
*/
- @GuardedBy("lock")
- boolean waitingForNetwork;
+ volatile boolean waitingForNetwork;
- final Object lock = new Object();
+ /**
+ * Indicates whether this uid has internet permission or not.
+ */
+ volatile boolean hasInternetPermission;
+
+ /**
+ * This object is used for waiting for the network state to get updated.
+ */
+ final Object networkStateLock = new Object();
static final int CHANGE_PROCSTATE = 0;
static final int CHANGE_GONE = 1;
@@ -95,6 +104,11 @@
curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
}
+ public void updateHasInternetPermission() {
+ hasInternetPermission = ActivityManager.checkUidPermission(Manifest.permission.INTERNET,
+ uid) == PackageManager.PERMISSION_GRANTED;
+ }
+
/**
* If the change being dispatched is neither CHANGE_GONE nor CHANGE_GONE_IDLE (not interested in
* these changes), then update the {@link #lastDispatchedProcStateSeq} with
diff --git a/services/core/java/com/android/server/am/UserState.java b/services/core/java/com/android/server/am/UserState.java
index 6710bdc..9970c82 100644
--- a/services/core/java/com/android/server/am/UserState.java
+++ b/services/core/java/com/android/server/am/UserState.java
@@ -88,7 +88,7 @@
state = newState;
}
- static String stateToString(int state) {
+ public static String stateToString(int state) {
switch (state) {
case STATE_BOOTING: return "BOOTING";
case STATE_RUNNING_LOCKED: return "RUNNING_LOCKED";
diff --git a/services/core/java/com/android/server/job/JobServiceContext.java b/services/core/java/com/android/server/job/JobServiceContext.java
index 1337046..618feb1 100644
--- a/services/core/java/com/android/server/job/JobServiceContext.java
+++ b/services/core/java/com/android/server/job/JobServiceContext.java
@@ -597,7 +597,8 @@
service.stopJob(mParams);
} catch (RemoteException e) {
Slog.e(TAG, "Error sending onStopJob to client.", e);
- closeAndCleanupJobH(false /* reschedule */);
+ // The job's host app apparently crashed during the job, so we should reschedule.
+ closeAndCleanupJobH(true /* reschedule */);
}
}
diff --git a/services/core/java/com/android/server/job/controllers/ConnectivityController.java b/services/core/java/com/android/server/job/controllers/ConnectivityController.java
index 94ca24c..b458d8b 100644
--- a/services/core/java/com/android/server/job/controllers/ConnectivityController.java
+++ b/services/core/java/com/android/server/job/controllers/ConnectivityController.java
@@ -17,18 +17,18 @@
package com.android.server.job.controllers;
import android.app.job.JobInfo;
-import android.content.BroadcastReceiver;
import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
import android.net.ConnectivityManager;
+import android.net.ConnectivityManager.NetworkCallback;
import android.net.INetworkPolicyListener;
+import android.net.Network;
+import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.NetworkPolicyManager;
+import android.os.Process;
import android.os.UserHandle;
import android.util.Slog;
-import com.android.internal.os.BackgroundThread;
import com.android.internal.annotations.GuardedBy;
import com.android.server.job.JobSchedulerService;
import com.android.server.job.StateChangedListener;
@@ -46,9 +46,12 @@
public class ConnectivityController extends StateController implements
ConnectivityManager.OnNetworkActiveListener {
private static final String TAG = "JobScheduler.Conn";
+ private static final boolean DEBUG = false;
private final ConnectivityManager mConnManager;
private final NetworkPolicyManager mNetPolicyManager;
+ private boolean mConnected;
+ private boolean mValidated;
@GuardedBy("mLock")
private final ArrayList<JobStatus> mTrackedJobs = new ArrayList<JobStatus>();
@@ -73,10 +76,9 @@
mConnManager = mContext.getSystemService(ConnectivityManager.class);
mNetPolicyManager = mContext.getSystemService(NetworkPolicyManager.class);
- final IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
- mContext.registerReceiverAsUser(
- mConnectivityReceiver, UserHandle.SYSTEM, intentFilter, null, null);
+ mConnected = mValidated = false;
+ mConnManager.registerDefaultNetworkCallback(mNetworkCallback);
mNetPolicyManager.registerListener(mNetPolicyListener);
}
@@ -84,7 +86,7 @@
public void maybeStartTrackingJobLocked(JobStatus jobStatus, JobStatus lastJob) {
if (jobStatus.hasConnectivityConstraint() || jobStatus.hasUnmeteredConstraint()
|| jobStatus.hasNotRoamingConstraint()) {
- updateConstraintsSatisfied(jobStatus);
+ updateConstraintsSatisfied(jobStatus, null);
mTrackedJobs.add(jobStatus);
}
}
@@ -98,18 +100,43 @@
}
}
- private boolean updateConstraintsSatisfied(JobStatus jobStatus) {
+ private boolean updateConstraintsSatisfied(JobStatus jobStatus,
+ NetworkCapabilities capabilities) {
+ final int jobUid = jobStatus.getSourceUid();
final boolean ignoreBlocked = (jobStatus.getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) != 0;
- final NetworkInfo info = mConnManager.getActiveNetworkInfoForUid(jobStatus.getSourceUid(),
- ignoreBlocked);
- final boolean connected = (info != null) && info.isConnected();
+ final NetworkInfo info = mConnManager.getActiveNetworkInfoForUid(jobUid, ignoreBlocked);
+ if (capabilities == null) {
+ final Network network = mConnManager.getActiveNetworkForUid(jobUid, ignoreBlocked);
+ capabilities = mConnManager.getNetworkCapabilities(network);
+ }
+
+ final boolean validated = capabilities != null
+ && capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
+ final boolean connected = info != null && info.isConnected();
+ final boolean connectionUsable = connected && validated;
final boolean unmetered = connected && !info.isMetered();
final boolean notRoaming = connected && !info.isRoaming();
boolean changed = false;
- changed |= jobStatus.setConnectivityConstraintSatisfied(connected);
+ changed |= jobStatus.setConnectivityConstraintSatisfied(connectionUsable);
changed |= jobStatus.setUnmeteredConstraintSatisfied(unmetered);
changed |= jobStatus.setNotRoamingConstraintSatisfied(notRoaming);
+
+ // Track system-uid connected/validated as a general reportable proxy for the
+ // overall state of connectivity constraint satisfiability.
+ if (jobUid == Process.SYSTEM_UID) {
+ mConnected = connected;
+ mValidated = validated;
+ }
+
+ if (DEBUG) {
+ Slog.i(TAG, "Connectivity " + (changed ? "CHANGED" : "unchanged")
+ + " for " + jobStatus + ": usable=" + connectionUsable
+ + " connected=" + connected
+ + " validated=" + validated
+ + " unmetered=" + unmetered
+ + " notRoaming=" + notRoaming);
+ }
return changed;
}
@@ -119,13 +146,13 @@
* @param uid only update jobs belonging to this UID, or {@code -1} to
* update all tracked jobs.
*/
- private void updateTrackedJobs(int uid) {
+ private void updateTrackedJobs(int uid, NetworkCapabilities capabilities) {
synchronized (mLock) {
boolean changed = false;
for (int i = 0; i < mTrackedJobs.size(); i++) {
final JobStatus js = mTrackedJobs.get(i);
if (uid == -1 || uid == js.getSourceUid()) {
- changed |= updateConstraintsSatisfied(js);
+ changed |= updateConstraintsSatisfied(js, capabilities);
}
}
if (changed) {
@@ -152,38 +179,61 @@
}
}
- private BroadcastReceiver mConnectivityReceiver = new BroadcastReceiver() {
+ private final NetworkCallback mNetworkCallback = new NetworkCallback() {
@Override
- public void onReceive(Context context, Intent intent) {
- updateTrackedJobs(-1);
+ public void onCapabilitiesChanged(Network network, NetworkCapabilities networkCapabilities) {
+ if (DEBUG) {
+ Slog.v(TAG, "onCapabilitiesChanged() : " + networkCapabilities);
+ }
+ updateTrackedJobs(-1, networkCapabilities);
+ }
+
+ @Override
+ public void onLost(Network network) {
+ if (DEBUG) {
+ Slog.v(TAG, "Network lost");
+ }
+ updateTrackedJobs(-1, null);
}
};
- private INetworkPolicyListener mNetPolicyListener = new INetworkPolicyListener.Stub() {
+ private final INetworkPolicyListener mNetPolicyListener = new INetworkPolicyListener.Stub() {
@Override
public void onUidRulesChanged(int uid, int uidRules) {
- updateTrackedJobs(uid);
+ if (DEBUG) {
+ Slog.v(TAG, "Uid rules changed for " + uid);
+ }
+ updateTrackedJobs(uid, null);
}
@Override
public void onMeteredIfacesChanged(String[] meteredIfaces) {
- updateTrackedJobs(-1);
+ // We track this via our NetworkCallback
}
@Override
public void onRestrictBackgroundChanged(boolean restrictBackground) {
- updateTrackedJobs(-1);
+ if (DEBUG) {
+ Slog.v(TAG, "Background restriction change to " + restrictBackground);
+ }
+ updateTrackedJobs(-1, null);
}
@Override
public void onUidPoliciesChanged(int uid, int uidPolicies) {
- updateTrackedJobs(uid);
+ if (DEBUG) {
+ Slog.v(TAG, "Uid policy changed for " + uid);
+ }
+ updateTrackedJobs(uid, null);
}
};
@Override
public void dumpControllerStateLocked(PrintWriter pw, int filterUid) {
- pw.println("Connectivity.");
+ pw.print("Connectivity: connected=");
+ pw.print(mConnected);
+ pw.print(" validated=");
+ pw.println(mValidated);
pw.print("Tracking ");
pw.print(mTrackedJobs.size());
pw.println(":");
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 7468b95..ede5a5e 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -90,7 +90,6 @@
import android.media.IRingtonePlayer;
import android.net.Uri;
import android.os.Binder;
-import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
@@ -3127,9 +3126,8 @@
+ ", incomingUserId=" + incomingUserId
+ ", notificationUid=" + notificationUid
+ ", notification=" + notification;
- if (Build.IS_DEBUGGABLE) {
- throw new IllegalArgumentException(noChannelStr);
- }
+ // STOPSHIP TODO: should throw instead of logging.
+ // throw new IllegalArgumentException(noChannelStr);
Log.e(TAG, noChannelStr);
return;
}
diff --git a/services/core/java/com/android/server/pm/OtaDexoptService.java b/services/core/java/com/android/server/pm/OtaDexoptService.java
index 126f8c4..6245ffc 100644
--- a/services/core/java/com/android/server/pm/OtaDexoptService.java
+++ b/services/core/java/com/android/server/pm/OtaDexoptService.java
@@ -135,16 +135,7 @@
}
for (PackageParser.Package p : important) {
- // Make sure that core apps are optimized according to their own "reason".
- // If the core apps are not preopted in the B OTA, and REASON_AB_OTA is not speed
- // (by default is speed-profile) they will be interepreted/JITed. This in itself is
- // not a problem as we will end up doing profile guided compilation. However, some
- // core apps may be loaded by system server which doesn't JIT and we need to make
- // sure we don't interpret-only
- int compilationReason = p.coreApp
- ? PackageManagerService.REASON_CORE_APP
- : PackageManagerService.REASON_AB_OTA;
- mDexoptCommands.addAll(generatePackageDexopts(p, compilationReason));
+ mDexoptCommands.addAll(generatePackageDexopts(p, PackageManagerService.REASON_AB_OTA));
}
for (PackageParser.Package p : others) {
// We assume here that there are no core apps left.
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 621e37b..2115f31 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -537,12 +537,9 @@
public static final int REASON_INSTALL = 2;
public static final int REASON_BACKGROUND_DEXOPT = 3;
public static final int REASON_AB_OTA = 4;
- public static final int REASON_NON_SYSTEM_LIBRARY = 5;
- public static final int REASON_SHARED_APK = 6;
- public static final int REASON_FORCED_DEXOPT = 7;
- public static final int REASON_CORE_APP = 8;
+ public static final int REASON_FORCED_DEXOPT = 5;
- public static final int REASON_LAST = REASON_CORE_APP;
+ public static final int REASON_LAST = REASON_FORCED_DEXOPT;
/** All dangerous permission names in the same order as the events in MetricsEvent */
private static final List<String> ALL_DANGEROUS_PERMISSIONS = Arrays.asList(
@@ -653,6 +650,11 @@
final ArrayMap<String, Set<String>> mKnownCodebase =
new ArrayMap<String, Set<String>>();
+ // Keys are isolated uids and values are the uid of the application
+ // that created the isolated proccess.
+ @GuardedBy("mPackages")
+ final SparseIntArray mIsolatedOwners = new SparseIntArray();
+
// List of APK paths to load for each user and package. This data is never
// persisted by the package manager. Instead, the overlay manager will
// ensure the data is up-to-date in runtime.
@@ -1179,6 +1181,7 @@
// Stores a list of users whose package restrictions file needs to be updated
private ArraySet<Integer> mDirtyUsers = new ArraySet<Integer>();
+ static final long DEFAULT_CONTAINER_WHITELIST_DURATION = 10 * 60 * 1000;
final private DefaultContainerConnection mDefContainerConn =
new DefaultContainerConnection();
class DefaultContainerConnection implements ServiceConnection {
@@ -2378,59 +2381,6 @@
Slog.w(TAG, "No SYSTEMSERVERCLASSPATH found!");
}
- final List<String> allInstructionSets = InstructionSets.getAllInstructionSets();
- final String[] dexCodeInstructionSets =
- getDexCodeInstructionSets(
- allInstructionSets.toArray(new String[allInstructionSets.size()]));
-
- /**
- * Ensure all external libraries have had dexopt run on them.
- */
- if (mSharedLibraries.size() > 0) {
- Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
- // NOTE: For now, we're compiling these system "shared libraries"
- // (and framework jars) into all available architectures. It's possible
- // to compile them only when we come across an app that uses them (there's
- // already logic for that in scanPackageLI) but that adds some complexity.
- for (String dexCodeInstructionSet : dexCodeInstructionSets) {
- final int libCount = mSharedLibraries.size();
- for (int i = 0; i < libCount; i++) {
- SparseArray<SharedLibraryEntry> versionedLib = mSharedLibraries.valueAt(i);
- final int versionCount = versionedLib.size();
- for (int j = 0; j < versionCount; j++) {
- SharedLibraryEntry libEntry = versionedLib.valueAt(j);
- final String libPath = libEntry.path != null
- ? libEntry.path : libEntry.apk;
- if (libPath == null) {
- continue;
- }
- try {
- // Shared libraries do not have profiles so we perform a full
- // AOT compilation (if needed).
- int dexoptNeeded = DexFile.getDexOptNeeded(
- libPath, dexCodeInstructionSet,
- getCompilerFilterForReason(REASON_SHARED_APK),
- false /* newProfile */);
- if (dexoptNeeded != DexFile.NO_DEXOPT_NEEDED) {
- mInstaller.dexopt(libPath, Process.SYSTEM_UID, "*",
- dexCodeInstructionSet, dexoptNeeded, null,
- DEXOPT_PUBLIC,
- getCompilerFilterForReason(REASON_SHARED_APK),
- StorageManager.UUID_PRIVATE_INTERNAL,
- PackageDexOptimizer.SKIP_SHARED_LIBRARY_CHECK);
- }
- } catch (FileNotFoundException e) {
- Slog.w(TAG, "Library not found: " + libPath);
- } catch (IOException | InstallerException e) {
- Slog.w(TAG, "Cannot dexopt " + libPath + "; is it an APK or JAR? "
- + e.getMessage());
- }
- }
- }
- }
- Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
- }
-
File frameworkDir = new File(Environment.getRootDirectory(), "framework");
final VersionInfo ver = mSettings.getInternalVersion();
@@ -2819,41 +2769,6 @@
mSettings.writeLPr();
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
- // Perform dexopt on all apps that mark themselves as coreApps. We do this pretty
- // early on (before the package manager declares itself as early) because other
- // components in the system server might ask for package contexts for these apps.
- //
- // Note that "onlyCore" in this context means the system is encrypted or encrypting
- // (i.e, that the data partition is unavailable).
- if ((isFirstBoot() || isUpgrade() || VMRuntime.didPruneDalvikCache()) && !onlyCore) {
- long start = System.nanoTime();
- List<PackageParser.Package> coreApps = new ArrayList<>();
- for (PackageParser.Package pkg : mPackages.values()) {
- if (pkg.coreApp) {
- coreApps.add(pkg);
- }
- }
-
- int[] stats = performDexOptUpgrade(coreApps, false,
- getCompilerFilterForReason(REASON_CORE_APP));
-
- final int elapsedTimeSeconds =
- (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - start);
- MetricsLogger.histogram(mContext, "opt_coreapps_time_s", elapsedTimeSeconds);
-
- if (DEBUG_DEXOPT) {
- Slog.i(TAG, "Dex-opt core apps took : " + elapsedTimeSeconds + " seconds (" +
- stats[0] + ", " + stats[1] + ", " + stats[2] + ")");
- }
-
-
- // TODO: Should we log these stats to tron too ?
- // MetricsLogger.histogram(mContext, "opt_coreapps_num_dexopted", stats[0]);
- // MetricsLogger.histogram(mContext, "opt_coreapps_num_skipped", stats[1]);
- // MetricsLogger.histogram(mContext, "opt_coreapps_num_failed", stats[2]);
- // MetricsLogger.histogram(mContext, "opt_coreapps_num_total", coreApps.size());
- }
-
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_PMS_READY,
SystemClock.uptimeMillis());
@@ -6212,6 +6127,10 @@
* instant, returns {@code null}.
*/
private String getInstantAppPackageName(int callingUid) {
+ // If the caller is an isolated app use the owner's uid for the lookup.
+ if (Process.isIsolated(callingUid)) {
+ callingUid = mIsolatedOwners.get(callingUid);
+ }
final int appId = UserHandle.getAppId(callingUid);
synchronized (mPackages) {
final Object obj = mSettings.getUserIdLPr(appId);
@@ -7384,17 +7303,22 @@
if (HIDE_EPHEMERAL_APIS || isEphemeralDisabled()) {
return false;
}
+ int uid = Binder.getCallingUid();
+ if (Process.isIsolated(uid)) {
+ uid = mIsolatedOwners.get(uid);
+ }
synchronized (mPackages) {
final PackageSetting ps = mSettings.mPackages.get(packageName);
+ PackageParser.Package pkg = mPackages.get(packageName);
final boolean returnAllowed =
ps != null
- && (isCallerSameApp(packageName)
+ && (isCallerSameApp(packageName, uid)
|| mContext.checkCallingOrSelfPermission(
android.Manifest.permission.ACCESS_INSTANT_APPS)
== PERMISSION_GRANTED
|| mInstantAppRegistry.isInstantAccessGranted(
- userId, UserHandle.getAppId(Binder.getCallingUid()), ps.appId));
+ userId, UserHandle.getAppId(uid), ps.appId));
if (returnAllowed) {
return ps.getInstantApp(userId);
}
@@ -7411,7 +7335,7 @@
enforceCrossUserPermission(Binder.getCallingUid(), userId,
true /* requireFullPermission */, false /* checkShell */,
"getInstantAppCookie");
- if (!isCallerSameApp(packageName)) {
+ if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
return null;
}
synchronized (mPackages) {
@@ -7429,7 +7353,7 @@
enforceCrossUserPermission(Binder.getCallingUid(), userId,
true /* requireFullPermission */, true /* checkShell */,
"setInstantAppCookie");
- if (!isCallerSameApp(packageName)) {
+ if (!isCallerSameApp(packageName, Binder.getCallingUid())) {
return false;
}
synchronized (mPackages) {
@@ -7457,10 +7381,10 @@
}
}
- private boolean isCallerSameApp(String packageName) {
+ private boolean isCallerSameApp(String packageName, int uid) {
PackageParser.Package pkg = mPackages.get(packageName);
return pkg != null
- && UserHandle.getAppId(Binder.getCallingUid()) == pkg.applicationInfo.uid;
+ && UserHandle.getAppId(uid) == pkg.applicationInfo.uid;
}
@Override
@@ -8497,19 +8421,23 @@
? new PackageDexOptimizer.ForcedUpdatePackageDexOptimizer(mPackageDexOptimizer)
: mPackageDexOptimizer;
- // Optimize all dependencies first. Note: we ignore the return value and march on
+ // Dexopt all dependencies first. Note: we ignore the return value and march on
// on errors.
+ // Note that we are going to call performDexOpt on those libraries as many times as
+ // they are referenced in packages. When we do a batch of performDexOpt (for example
+ // at boot, or background job), the passed 'targetCompilerFilter' stays the same,
+ // and the first package that uses the library will dexopt it. The
+ // others will see that the compiled code for the library is up to date.
Collection<PackageParser.Package> deps = findSharedNonSystemLibraries(p);
final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo);
if (!deps.isEmpty()) {
for (PackageParser.Package depPackage : deps) {
// TODO: Analyze and investigate if we (should) profile libraries.
- // Currently this will do a full compilation of the library by default.
pdo.performDexOpt(depPackage, null /* sharedLibraries */, instructionSets,
false /* checkProfiles */,
- getCompilerFilterForReason(REASON_NON_SYSTEM_LIBRARY),
+ targetCompilerFilter,
getOrCreateCompilerPackageStats(depPackage),
- mDexManager.isUsedByOtherApps(p.packageName));
+ true /* isUsedByOtherApps */);
}
}
return pdo.performDexOpt(p, p.usesLibraryFiles, instructionSets, checkProfiles,
@@ -12987,7 +12915,10 @@
IActivityManager am = ActivityManager.getService();
if (am != null) {
try {
- am.startService(null, intent, null, -1, null, mContext.getOpPackageName(),
+ getDeviceIdleController().addPowerSaveTempWhitelistApp(Process.SYSTEM_UID,
+ DEFAULT_CONTAINER_PACKAGE, DEFAULT_CONTAINER_WHITELIST_DURATION,
+ UserHandle.USER_SYSTEM, false, "cleaning packages");
+ am.startService(null, intent, null, -1, null, false, mContext.getOpPackageName(),
UserHandle.USER_SYSTEM);
} catch (RemoteException e) {
}
@@ -23220,6 +23151,21 @@
return resolveIntentInternal(
intent, resolvedType, flags, userId, true /*includeInstantApp*/);
}
+
+
+ @Override
+ public void addIsolatedUid(int isolatedUid, int ownerUid) {
+ synchronized (mPackages) {
+ mIsolatedOwners.put(isolatedUid, ownerUid);
+ }
+ }
+
+ @Override
+ public void removeIsolatedUid(int isolatedUid) {
+ synchronized (mPackages) {
+ mIsolatedOwners.delete(isolatedUid);
+ }
+ }
}
@Override
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java b/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java
index 0634dac..f6872e4 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java
@@ -26,8 +26,7 @@
public class PackageManagerServiceCompilerMapping {
// Names for compilation reasons.
static final String REASON_STRINGS[] = {
- "first-boot", "boot", "install", "bg-dexopt", "ab-ota", "nsys-library", "shared-apk",
- "forced-dexopt", "core-app"
+ "first-boot", "boot", "install", "bg-dexopt", "ab-ota", "forced-dexopt"
};
// Static block to ensure the strings array is of the right length.
@@ -57,7 +56,6 @@
// Ensure that some reasons are not mapped to profile-guided filters.
switch (reason) {
- case PackageManagerService.REASON_SHARED_APK:
case PackageManagerService.REASON_FORCED_DEXOPT:
if (DexFile.isProfileGuidedCompilerFilter(sysPropValue)) {
throw new IllegalStateException("\"" + sysPropValue + "\" is profile-guided, "
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index a31258c3..8ecf6f7 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -3389,6 +3389,12 @@
pw.print(" <partial>");
}
pw.println();
+ pw.print(" State: ");
+ final int state;
+ synchronized (mUserStates) {
+ state = mUserStates.get(userId, -1);
+ }
+ pw.println(UserState.stateToString(state));
pw.print(" Created: ");
if (userInfo.creationTime == 0) {
pw.println("<unknown>");
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index aa85574..ae413e5 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -894,9 +894,10 @@
final int lastOrientation = mLastOrientation;
final boolean oldAltOrientation = mAltOrientation;
int rotation = mService.mPolicy.rotationForOrientationLw(lastOrientation, oldRotation);
- final boolean rotateSeamlessly;
+ final boolean rotateSeamlessly = mService.mPolicy.shouldRotateSeamlessly(oldRotation,
+ rotation);
- if (mService.mPolicy.shouldRotateSeamlessly(oldRotation, rotation)) {
+ if (rotateSeamlessly) {
final WindowState seamlessRotated = getWindow((w) -> w.mSeamlesslyRotated);
if (seamlessRotated != null) {
// We can't rotate (seamlessly or not) while waiting for the last seamless rotation
@@ -905,27 +906,6 @@
// window-removal.
return false;
}
-
- final WindowState cantSeamlesslyRotate = getWindow((w) ->
- w.isChildWindow() && w.isVisibleNow()
- && !w.mWinAnimator.mSurfaceController.getTransformToDisplayInverse());
- if (cantSeamlesslyRotate != null) {
- // In what can only be called an unfortunate workaround we require seamlessly
- // rotated child windows to have the TRANSFORM_TO_DISPLAY_INVERSE flag. Due to
- // limitations in the client API, there is no way for the client to set this flag in
- // a race free fashion. If we seamlessly rotate a window which does not have this
- // flag, but then gains it, we will get an incorrect visual result
- // (rotated viewfinder). This means if we want to support seamlessly rotating
- // windows which could gain this flag, we can't rotate windows without it. This
- // limits seamless rotation in N to camera framework users, windows without
- // children, and native code. This is unfortunate but having the camera work is our
- // primary goal.
- rotateSeamlessly = false;
- } else {
- rotateSeamlessly = true;
- }
- } else {
- rotateSeamlessly = false;
}
// TODO: Implement forced rotation changes.
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 826fb45..a7f6db1 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -591,6 +591,17 @@
}
}
+ private int getLayerStack() {
+ return mWin.getDisplayContent().getDisplay().getLayerStack();
+ }
+
+ void updateLayerStackInTransaction() {
+ if (mSurfaceController != null) {
+ mSurfaceController.setLayerStackInTransaction(
+ getLayerStack());
+ }
+ }
+
WindowSurfaceController createSurfaceLocked(int windowType, int ownerUid) {
final WindowState w = mWin;
if (w.restoreSavedSurface()) {
@@ -703,8 +714,7 @@
}
// Start a new transaction and apply position & offset.
- final int layerStack = w.getDisplayContent().getDisplay().getLayerStack();
- mSurfaceController.setPositionAndLayer(mTmpSize.left, mTmpSize.top, layerStack, mAnimLayer);
+ mSurfaceController.setPositionAndLayer(mTmpSize.left, mTmpSize.top, getLayerStack(), mAnimLayer);
mLastHidden = true;
if (WindowManagerService.localLOGV) Slog.v(TAG, "Created surface " + this);
@@ -1435,7 +1445,6 @@
WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER);
w.applyDimLayerIfNeeded();
}
-
}
void prepareSurfaceLocked(final boolean recoveringMemory) {
@@ -1926,57 +1935,26 @@
DisplayContent.createRotationMatrix(deltaRotation, x, y, displayWidth, displayHeight,
transform);
- // We have two cases:
- // 1. Windows with NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY:
- // These windows never change buffer size when rotating. Rather the window manager
- // just updates the scaling factors to fit in the new coordinate system,
- // and SurfaceFlinger takes care of updating the buffer contents. So in this case
- // we just need we just need to update the scaling factors and things are seamless
- // already.
- // 2. Other windows:
- // In this case, we need to apply a rotation matrix to the window. For example
- // if we have a portrait window and rotate to landscape, the window is still portrait
- // and now extends off the bottom of the screen (and only halfway across). Essentially we
- // apply a transform to display the current buffer at it's old position
- // (in the new coordinate space). We then freeze layer updates until the resize
- // occurs, at which point we undo, them.
- if (w.isChildWindow() && mSurfaceController.getTransformToDisplayInverse()) {
- frameRect.set(x, y, x + width, y + height);
- transform.mapRect(frameRect);
+ // We just need to apply a rotation matrix to the window. For example
+ // if we have a portrait window and rotate to landscape, the window is still portrait
+ // and now extends off the bottom of the screen (and only halfway across). Essentially we
+ // apply a transform to display the current buffer at it's old position
+ // (in the new coordinate space). We then freeze layer updates until the resize
+ // occurs, at which point we undo, them.
+ mService.markForSeamlessRotation(w, true);
+ transform.getValues(mService.mTmpFloats);
- final Rect parentWindowFrame = w.getParentWindow().mFrame;
- w.mAttrs.x = (int) frameRect.left - parentWindowFrame.left;
- w.mAttrs.y = (int) frameRect.top - parentWindowFrame.top;
- w.mAttrs.width = (int) Math.ceil(frameRect.width());
- w.mAttrs.height = (int) Math.ceil(frameRect.height());
-
- w.setWindowScale(w.mRequestedWidth, w.mRequestedHeight);
-
- w.applyGravityAndUpdateFrame(w.mContainingFrame, w.mDisplayFrame);
- computeShownFrameLocked();
- setSurfaceBoundariesLocked(false);
-
- // The stack bounds will not yet be rotated at this point so setSurfaceBoundaries locked
- // will crop us incorrectly. Overwrite the crop, exposing the full surface. By the next
- // transaction this will be corrected.
- cropRect.set(0, 0, w.mRequestedWidth, w.mRequestedWidth + w.mRequestedHeight);
- mSurfaceController.setCropInTransaction(cropRect, false);
- } else {
- mService.markForSeamlessRotation(w, true);
- transform.getValues(mService.mTmpFloats);
-
- float DsDx = mService.mTmpFloats[Matrix.MSCALE_X];
- float DtDx = mService.mTmpFloats[Matrix.MSKEW_Y];
- float DtDy = mService.mTmpFloats[Matrix.MSKEW_X];
- float DsDy = mService.mTmpFloats[Matrix.MSCALE_Y];
- float nx = mService.mTmpFloats[Matrix.MTRANS_X];
- float ny = mService.mTmpFloats[Matrix.MTRANS_Y];
- mSurfaceController.setPositionInTransaction(nx, ny, false);
- mSurfaceController.setMatrixInTransaction(DsDx * w.mHScale,
- DtDx * w.mVScale,
- DtDy * w.mHScale,
- DsDy * w.mVScale, false);
- }
+ float DsDx = mService.mTmpFloats[Matrix.MSCALE_X];
+ float DtDx = mService.mTmpFloats[Matrix.MSKEW_Y];
+ float DtDy = mService.mTmpFloats[Matrix.MSKEW_X];
+ float DsDy = mService.mTmpFloats[Matrix.MSCALE_Y];
+ float nx = mService.mTmpFloats[Matrix.MTRANS_X];
+ float ny = mService.mTmpFloats[Matrix.MTRANS_Y];
+ mSurfaceController.setPositionInTransaction(nx, ny, false);
+ mSurfaceController.setMatrixInTransaction(DsDx * w.mHScale,
+ DtDx * w.mVScale,
+ DtDy * w.mHScale,
+ DsDy * w.mVScale, false);
}
void enableSurfaceTrace(FileDescriptor fd) {
diff --git a/services/core/java/com/android/server/wm/WindowSurfaceController.java b/services/core/java/com/android/server/wm/WindowSurfaceController.java
index b08bb70..adf4501 100644
--- a/services/core/java/com/android/server/wm/WindowSurfaceController.java
+++ b/services/core/java/com/android/server/wm/WindowSurfaceController.java
@@ -276,6 +276,12 @@
}
}
+ void setLayerStackInTransaction(int layerStack) {
+ if (mSurfaceControl != null) {
+ mSurfaceControl.setLayerStack(layerStack);
+ }
+ }
+
void setPositionInTransaction(float left, float top, boolean recoveringMemory) {
final boolean surfaceMoved = mSurfaceX != left || mSurfaceY != top;
if (surfaceMoved) {
@@ -357,7 +363,8 @@
return false;
}
- boolean prepareToShowInTransaction(float alpha, int layer, float dsdx, float dtdx, float dsdy,
+ boolean prepareToShowInTransaction(float alpha, int layer,
+ float dsdx, float dtdx, float dsdy,
float dtdy, boolean recoveringMemory) {
if (mSurfaceControl != null) {
try {
@@ -371,7 +378,6 @@
mLastDtdy = dtdy;
mSurfaceControl.setMatrix(
dsdx, dtdx, dsdy, dtdy);
-
} catch (RuntimeException e) {
Slog.w(TAG, "Error updating surface in " + title, e);
if (!recoveringMemory) {
@@ -509,10 +515,6 @@
return mSurfaceControl.getHandle();
}
- boolean getTransformToDisplayInverse() {
- return mSurfaceControl.getTransformToDisplayInverse();
- }
-
void getSurface(Surface outSurface) {
outSurface.copyFrom(mSurfaceControl);
}
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index fab59d6..e3033c9 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -30,6 +30,7 @@
import android.os.Debug;
import android.os.IBinder;
import android.util.Slog;
+import android.view.SurfaceControl;
import java.io.PrintWriter;
@@ -245,6 +246,18 @@
void onDisplayChanged(DisplayContent dc) {
dc.reParentWindowToken(this);
mDisplayContent = dc;
+
+ // TODO(b/36740756): One day this should perhaps be hooked
+ // up with goodToGo, so we don't move a window
+ // to another display before the window behind
+ // it is ready.
+ SurfaceControl.openTransaction();
+ for (int i = mChildren.size() - 1; i >= 0; --i) {
+ final WindowState win = mChildren.get(i);
+ win.mWinAnimator.updateLayerStackInTransaction();
+ }
+ SurfaceControl.closeTransaction();
+
super.onDisplayChanged(dc);
}
diff --git a/services/core/jni/com_android_server_am_BatteryStatsService.cpp b/services/core/jni/com_android_server_am_BatteryStatsService.cpp
index ec36df1..57bb9fe 100644
--- a/services/core/jni/com_android_server_am_BatteryStatsService.cpp
+++ b/services/core/jni/com_android_server_am_BatteryStatsService.cpp
@@ -57,6 +57,8 @@
static bool wakeup_init = false;
static sem_t wakeup_sem;
extern sp<IPower> gPowerHal;
+extern std::mutex gPowerHalMutex;
+extern bool getPowerHal();
static void wakeup_callback(bool success)
{
@@ -191,41 +193,26 @@
return -1;
}
- if (gPowerHal == nullptr) {
- ALOGE("gPowerHal not loaded");
- return -1;
- }
+ {
+ std::lock_guard<std::mutex> lock(gPowerHalMutex);
+ if (!getPowerHal()) {
+ ALOGE("Power Hal not loaded");
+ return -1;
+ }
- gPowerHal->getPlatformLowPowerStats(
- [&offset, &remaining, &total_added](hidl_vec<PowerStatePlatformSleepState> states,
- Status status) {
- if (status != Status::SUCCESS)
- return;
- for (size_t i = 0; i < states.size(); i++) {
- int added;
- const PowerStatePlatformSleepState& state = states[i];
+ Return<void> ret = gPowerHal->getPlatformLowPowerStats(
+ [&offset, &remaining, &total_added](hidl_vec<PowerStatePlatformSleepState> states,
+ Status status) {
+ if (status != Status::SUCCESS)
+ return;
+ for (size_t i = 0; i < states.size(); i++) {
+ int added;
+ const PowerStatePlatformSleepState& state = states[i];
- added = snprintf(offset, remaining,
- "state_%zu name=%s time=%" PRIu64 " count=%" PRIu64 " ",
- i + 1, state.name.c_str(), state.residencyInMsecSinceBoot,
- state.totalTransitions);
- if (added < 0) {
- break;
- }
- if (added > remaining) {
- added = remaining;
- }
- offset += added;
- remaining -= added;
- total_added += added;
-
- for (size_t j = 0; j < state.voters.size(); j++) {
- const PowerStateVoter& voter = state.voters[j];
added = snprintf(offset, remaining,
- "voter_%zu name=%s time=%" PRIu64 " count=%" PRIu64 " ",
- j + 1, voter.name.c_str(),
- voter.totalTimeInMsecVotedForSinceBoot,
- voter.totalNumberOfTimesVotedSinceBoot);
+ "state_%zu name=%s time=%" PRIu64 " count=%" PRIu64 " ",
+ i + 1, state.name.c_str(), state.residencyInMsecSinceBoot,
+ state.totalTransitions);
if (added < 0) {
break;
}
@@ -235,18 +222,42 @@
offset += added;
remaining -= added;
total_added += added;
- }
- if (remaining <= 0) {
- /* rewrite NULL character*/
- offset--;
- total_added--;
- ALOGE("PowerHal: buffer not enough");
- break;
+ for (size_t j = 0; j < state.voters.size(); j++) {
+ const PowerStateVoter& voter = state.voters[j];
+ added = snprintf(offset, remaining,
+ "voter_%zu name=%s time=%" PRIu64 " count=%" PRIu64 " ",
+ j + 1, voter.name.c_str(),
+ voter.totalTimeInMsecVotedForSinceBoot,
+ voter.totalNumberOfTimesVotedSinceBoot);
+ if (added < 0) {
+ break;
+ }
+ if (added > remaining) {
+ added = remaining;
+ }
+ offset += added;
+ remaining -= added;
+ total_added += added;
+ }
+
+ if (remaining <= 0) {
+ /* rewrite NULL character*/
+ offset--;
+ total_added--;
+ ALOGE("PowerHal: buffer not enough");
+ break;
+ }
}
}
+ );
+
+ if (!ret.isOk()) {
+ ALOGE("getPlatformLowPowerStats() failed: power HAL service not available");
+ gPowerHal = nullptr;
+ return -1;
}
- );
+ }
*offset = 0;
total_added += 1;
return total_added;
diff --git a/services/core/jni/com_android_server_power_PowerManagerService.cpp b/services/core/jni/com_android_server_power_PowerManagerService.cpp
index fab309b..1bdcd7a 100644
--- a/services/core/jni/com_android_server_power_PowerManagerService.cpp
+++ b/services/core/jni/com_android_server_power_PowerManagerService.cpp
@@ -43,7 +43,7 @@
using android::hardware::power::V1_0::IPower;
using android::hardware::power::V1_0::PowerHint;
using android::hardware::power::V1_0::Feature;
-using android::hardware::hidl_vec;
+using android::String8;
namespace android {
@@ -56,7 +56,8 @@
// ----------------------------------------------------------------------------
static jobject gPowerManagerServiceObj;
-sp<IPower> gPowerHal;
+sp<IPower> gPowerHal = nullptr;
+std::mutex gPowerHalMutex;
static nsecs_t gLastEventTime[USER_ACTIVITY_EVENT_LAST + 1];
// Throttling interval for user activity calls.
@@ -74,11 +75,37 @@
return false;
}
+// Check validity of current handle to the power HAL service, and call getService() if necessary.
+// The caller must be holding gPowerHalMutex.
+bool getPowerHal() {
+ if (gPowerHal == nullptr) {
+ gPowerHal = IPower::getService();
+ if (gPowerHal != nullptr) {
+ ALOGI("Loaded power HAL service");
+ } else {
+ ALOGI("Couldn't load power HAL service");
+ }
+ }
+ return gPowerHal != nullptr;
+}
+
+// Check if a call to a power HAL function failed; if so, log the failure and invalidate the
+// current handle to the power HAL service. The caller must be holding gPowerHalMutex.
+static void processReturn(const Return<void> &ret, const char* functionName) {
+ if (!ret.isOk()) {
+ ALOGE("%s() failed: power HAL service not available.", functionName);
+ gPowerHal = nullptr;
+ }
+}
+
void android_server_PowerManagerService_userActivity(nsecs_t eventTime, int32_t eventType) {
// Tell the power HAL when user activity occurs.
- if (gPowerHal != nullptr) {
- gPowerHal->powerHint(PowerHint::INTERACTION, 0);
+ gPowerHalMutex.lock();
+ if (getPowerHal()) {
+ Return<void> ret = gPowerHal->powerHint(PowerHint::INTERACTION, 0);
+ processReturn(ret, "powerHint");
}
+ gPowerHalMutex.unlock();
if (gPowerManagerServiceObj) {
// Throttle calls into user activity by event type.
@@ -106,14 +133,13 @@
}
// ----------------------------------------------------------------------------
-//TODO(b/31632518)
+
static void nativeInit(JNIEnv* env, jobject obj) {
gPowerManagerServiceObj = env->NewGlobalRef(obj);
- gPowerHal = IPower::getService();
- if (gPowerHal == nullptr) {
- ALOGE("Couldn't load PowerHAL module");
- }
+ gPowerHalMutex.lock();
+ getPowerHal();
+ gPowerHalMutex.unlock();
}
static void nativeAcquireSuspendBlocker(JNIEnv *env, jclass /* clazz */, jstring nameStr) {
@@ -127,14 +153,12 @@
}
static void nativeSetInteractive(JNIEnv* /* env */, jclass /* clazz */, jboolean enable) {
- if (gPowerHal != nullptr) {
- if (enable) {
- ALOGD_IF_SLOW(20, "Excessive delay in setInteractive(true) while turning screen on");
- gPowerHal->setInteractive(true);
- } else {
- ALOGD_IF_SLOW(20, "Excessive delay in setInteractive(false) while turning screen off");
- gPowerHal->setInteractive(false);
- }
+ std::lock_guard<std::mutex> lock(gPowerHalMutex);
+ if (getPowerHal()) {
+ String8 err("Excessive delay in setInteractive(%s) while turning screen %s");
+ ALOGD_IF_SLOW(20, String8::format(err, enable ? "true" : "false", enable ? "on" : "off"));
+ Return<void> ret = gPowerHal->setInteractive(enable);
+ processReturn(ret, "setInteractive");
}
}
@@ -149,20 +173,18 @@
}
static void nativeSendPowerHint(JNIEnv *env, jclass clazz, jint hintId, jint data) {
- if (gPowerHal != nullptr) {
- if(data)
- gPowerHal->powerHint((PowerHint)hintId, data);
- else {
- gPowerHal->powerHint((PowerHint)hintId, 0);
- }
+ std::lock_guard<std::mutex> lock(gPowerHalMutex);
+ if (getPowerHal()) {
+ Return<void> ret = gPowerHal->powerHint((PowerHint)hintId, data);
+ processReturn(ret, "powerHint");
}
}
static void nativeSetFeature(JNIEnv *env, jclass clazz, jint featureId, jint data) {
- int data_param = data;
-
- if (gPowerHal != nullptr) {
- gPowerHal->setFeature((Feature)featureId, data_param ? true : false);
+ std::lock_guard<std::mutex> lock(gPowerHalMutex);
+ if (getPowerHal()) {
+ Return<void> ret = gPowerHal->setFeature((Feature)featureId, static_cast<bool>(data));
+ processReturn(ret, "setFeature");
}
}
@@ -217,7 +239,6 @@
gLastEventTime[i] = LLONG_MIN;
}
gPowerManagerServiceObj = NULL;
- gPowerHal = NULL;
return 0;
}
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityManagerInternalTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityManagerInternalTest.java
index e7c91c0..bce87dc 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityManagerInternalTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerInternalTest.java
@@ -105,9 +105,9 @@
final UidRecord record2 = addActiveUidRecord(TEST_UID2, curProcStateSeq,
lastNetworkUpdatedProcStateSeq);
- final CustomThread thread1 = new CustomThread(record1.lock);
+ final CustomThread thread1 = new CustomThread(record1.networkStateLock);
thread1.startAndWait("Unexpected state for " + record1);
- final CustomThread thread2 = new CustomThread(record2.lock);
+ final CustomThread thread2 = new CustomThread(record2.networkStateLock);
thread2.startAndWait("Unexpected state for " + record2);
mAmi.notifyNetworkPolicyRulesUpdated(TEST_UID1, expectedProcStateSeq);
diff --git a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
index 1e038df..092c60b 100644
--- a/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/am/ActivityManagerServiceTest.java
@@ -105,7 +105,7 @@
public class ActivityManagerServiceTest {
private static final String TAG = ActivityManagerServiceTest.class.getSimpleName();
- private static final int TEST_UID = 111;
+ private static final int TEST_UID = 11111;
private static final long TEST_PROC_STATE_SEQ1 = 555;
private static final long TEST_PROC_STATE_SEQ2 = 556;
@@ -121,6 +121,7 @@
@Mock private Context mContext;
@Mock private AppOpsService mAppOpsService;
@Mock private PackageManager mPackageManager;
+ @Mock private BatteryStatsImpl mBatteryStatsImpl;
private TestInjector mInjector;
private ActivityManagerService mAms;
@@ -149,20 +150,9 @@
@MediumTest
@Test
public void incrementProcStateSeqAndNotifyAppsLocked() throws Exception {
- final UidRecord uidRec = new UidRecord(TEST_UID);
- uidRec.waitingForNetwork = true;
- mAms.mActiveUids.put(TEST_UID, uidRec);
- final BatteryStatsImpl batteryStats = Mockito.mock(BatteryStatsImpl.class);
- final ProcessRecord appRec = new ProcessRecord(batteryStats,
- new ApplicationInfo(), TAG, TEST_UID);
- appRec.thread = Mockito.mock(IApplicationThread.class);
- mAms.mLruProcesses.add(appRec);
-
- final ProcessRecord appRec2 = new ProcessRecord(batteryStats,
- new ApplicationInfo(), TAG, TEST_UID + 1);
- appRec2.thread = Mockito.mock(IApplicationThread.class);
- mAms.mLruProcesses.add(appRec2);
+ final UidRecord uidRec = addUidRecord(TEST_UID);
+ addUidRecord(TEST_UID + 1);
// Uid state is not moving from background to foreground or vice versa.
verifySeqCounterAndInteractions(uidRec,
@@ -235,12 +225,51 @@
44, // exptectedCurProcStateSeq
-1, // expectedBlockState, -1 to verify there are no interactions with main thread.
false); // expectNotify
+
+ // Verify when the uid doesn't have internet permission, then procStateSeq is not
+ // incremented.
+ uidRec.hasInternetPermission = false;
+ mAms.mWaitForNetworkTimeoutMs = 111;
+ mInjector.setNetworkRestrictedForUid(true);
+ verifySeqCounterAndInteractions(uidRec,
+ PROCESS_STATE_CACHED_ACTIVITY, // prevState
+ PROCESS_STATE_FOREGROUND_SERVICE, // curState
+ 44, // expectedGlobalCounter
+ 44, // exptectedCurProcStateSeq
+ -1, // expectedBlockState, -1 to verify there are no interactions with main thread.
+ false); // expectNotify
+
+ // Verify procStateSeq is not incremented when the uid is not an application, regardless
+ // of the process state.
+ final int notAppUid = 111;
+ final UidRecord uidRec2 = addUidRecord(notAppUid);
+ verifySeqCounterAndInteractions(uidRec2,
+ PROCESS_STATE_CACHED_EMPTY, // prevState
+ PROCESS_STATE_TOP, // curState
+ 44, // expectedGlobalCounter
+ 0, // exptectedCurProcStateSeq
+ -1, // expectedBlockState, -1 to verify there are no interactions with main thread.
+ false); // expectNotify
+ }
+
+ private UidRecord addUidRecord(int uid) {
+ final UidRecord uidRec = new UidRecord(uid);
+ uidRec.waitingForNetwork = true;
+ uidRec.hasInternetPermission = true;
+ mAms.mActiveUids.put(uid, uidRec);
+
+ final ProcessRecord appRec = new ProcessRecord(mBatteryStatsImpl,
+ new ApplicationInfo(), TAG, uid);
+ appRec.thread = Mockito.mock(IApplicationThread.class);
+ mAms.mLruProcesses.add(appRec);
+
+ return uidRec;
}
private void verifySeqCounterAndInteractions(UidRecord uidRec, int prevState, int curState,
int expectedGlobalCounter, int expectedCurProcStateSeq, int expectedBlockState,
boolean expectNotify) throws Exception {
- CustomThread thread = new CustomThread(uidRec.lock);
+ CustomThread thread = new CustomThread(uidRec.networkStateLock);
thread.startAndWait("Unexpected state for " + uidRec);
uidRec.setProcState = prevState;
@@ -720,7 +749,7 @@
record.lastNetworkUpdatedProcStateSeq = lastNetworkUpdatedProcStateSeq;
mAms.mActiveUids.put(Process.myUid(), record);
- CustomThread thread = new CustomThread(record.lock, new Runnable() {
+ CustomThread thread = new CustomThread(record.networkStateLock, new Runnable() {
@Override
public void run() {
mAms.waitForNetworkStateUpdate(procStateSeqToWait);
@@ -730,8 +759,8 @@
if (expectWait) {
thread.startAndWait(errMsg, true);
thread.assertTimedWaiting(errMsg);
- synchronized (record.lock) {
- record.lock.notifyAll();
+ synchronized (record.networkStateLock) {
+ record.networkStateLock.notifyAll();
}
thread.assertTerminated(errMsg);
assertTrue(thread.mNotified);
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 b410400..7c37027 100644
--- a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
@@ -15,6 +15,8 @@
*/
package com.android.server.pm;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.anyOrNull;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.anyStringOrNull;
import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.cloneShortcutList;
import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.hashSet;
import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.list;
@@ -884,7 +886,7 @@
entryName = ShortcutInfo.getResourceEntryName(entryName);
}
return Integer.parseInt(entryName.substring(1)) + ressIdOffset;
- }).when(res).getIdentifier(anyString(), anyString(), anyString());
+ }).when(res).getIdentifier(anyStringOrNull(), anyStringOrNull(), anyStringOrNull());
return res;
}).when(mMockPackageManager).getResourcesForApplicationAsUser(anyString(), anyInt());
}
@@ -1612,7 +1614,7 @@
eq(packageName),
eq(userId),
intentsCaptor.capture(),
- any(Bundle.class));
+ anyOrNull(Bundle.class));
return intentsCaptor.getValue();
}
@@ -1671,7 +1673,7 @@
anyString(),
anyInt(),
any(Intent[].class),
- any(Bundle.class));
+ anyOrNull(Bundle.class));
}
protected void assertStartShortcutThrowsException(@NonNull String packageName,
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
index 4b3c2f8..796cc16 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
@@ -15,6 +15,8 @@
*/
package com.android.server.pm;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.anyOrNull;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.anyStringOrNull;
import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllChooser;
import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllDisabled;
import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertAllDynamic;
@@ -2832,7 +2834,8 @@
// Not launchable.
doReturn(ActivityManager.START_CLASS_NOT_FOUND)
.when(mMockActivityManagerInternal).startActivitiesAsPackage(
- anyString(), anyInt(), any(Intent[].class), any(Bundle.class));
+ anyStringOrNull(), anyInt(),
+ anyOrNull(Intent[].class), anyOrNull(Bundle.class));
assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_0,
ActivityNotFoundException.class);
@@ -2840,7 +2843,8 @@
doReturn(ActivityManager.START_CLASS_NOT_FOUND)
.when(mMockActivityManagerInternal)
.startActivitiesAsPackage(
- anyString(), anyInt(), any(Intent[].class), any(Bundle.class));
+ anyStringOrNull(), anyInt(),
+ anyOrNull(Intent[].class), anyOrNull(Bundle.class));
assertStartShortcutThrowsException(CALLING_PACKAGE_1, "s1", USER_0,
ActivityNotFoundException.class);
});
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest8.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest8.java
index 0310e16..e9a329c 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest8.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest8.java
@@ -15,6 +15,7 @@
*/
package com.android.server.pm;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.anyOrNull;
import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertExpectException;
import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertForLauncherCallbackNoThrow;
import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertWith;
@@ -775,7 +776,7 @@
/* resultIntent=*/ null));
// The intent should be sent right away.
- verify(mServiceContext, times(1)).sendIntentSender(any(IntentSender.class));
+ verify(mServiceContext, times(1)).sendIntentSender(anyOrNull(IntentSender.class));
});
}
diff --git a/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java b/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
index f2bae4c..132ed98 100644
--- a/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
+++ b/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
@@ -58,6 +58,8 @@
import org.json.JSONException;
import org.json.JSONObject;
import org.mockito.ArgumentCaptor;
+import org.mockito.ArgumentMatcher;
+import org.mockito.ArgumentMatchers;
import org.mockito.Mockito;
import org.mockito.hamcrest.MockitoHamcrest;
@@ -733,6 +735,14 @@
fail("Timed out for: " + message);
}
+ public static final <T> T anyOrNull(Class<T> clazz) {
+ return ArgumentMatchers.argThat(value -> true);
+ }
+
+ public static final String anyStringOrNull() {
+ return ArgumentMatchers.argThat(value -> true);
+ }
+
public static ShortcutListAsserter assertWith(List<ShortcutInfo> list) {
return new ShortcutListAsserter(list);
}
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 7a226a0..bb83633 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -1390,6 +1390,13 @@
public static final String KEY_BOOSTED_LTE_EARFCNS_STRING_ARRAY =
"boosted_lte_earfcns_string_array";
+ /**
+ * Key identifying if voice call barring notification is required to be shown to the user.
+ * @hide
+ */
+ public static final String KEY_DISABLE_VOICE_BARRING_NOTIFICATION_BOOL =
+ "disable_voice_barring_notification_bool";
+
/** The default value for every variable. */
private final static PersistableBundle sDefaults;
@@ -1625,6 +1632,7 @@
null);
sDefaults.putInt(KEY_LTE_EARFCNS_RSRP_BOOST_INT, 0);
sDefaults.putStringArray(KEY_BOOSTED_LTE_EARFCNS_STRING_ARRAY, null);
+ sDefaults.putBoolean(KEY_DISABLE_VOICE_BARRING_NOTIFICATION_BOOL, false);
}
/**
diff --git a/test-runner/src/android/test/mock/MockContext.java b/test-runner/src/android/test/mock/MockContext.java
index da1d998..dca74ff 100644
--- a/test-runner/src/android/test/mock/MockContext.java
+++ b/test-runner/src/android/test/mock/MockContext.java
@@ -526,6 +526,12 @@
}
@Override
+ public ComponentName startForegroundService(Intent service) {
+ throw new UnsupportedOperationException();
+ }
+
+ /** STOPSHIP remove when trial API is turned down */
+ @Override
public ComponentName startServiceInForeground(Intent service,
int id, Notification notification) {
throw new UnsupportedOperationException();
@@ -544,6 +550,12 @@
/** @hide */
@Override
+ public ComponentName startForegroundServiceAsUser(Intent service, UserHandle user) {
+ throw new UnsupportedOperationException();
+ }
+
+ /** @hide STOPSHIP removed when trial API is turned down */
+ @Override
public ComponentName startServiceInForegroundAsUser(Intent service,
int id, Notification notification, UserHandle user) {
throw new UnsupportedOperationException();
diff --git a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
index e118889..80e3bad 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Typeface_Delegate.java
@@ -233,7 +233,8 @@
Map<String, ByteBuffer> bufferForPath) {
FontFamily fontFamily = new FontFamily(family.getLanguage(), family.getVariant());
for (FontConfig.Font font : family.getFonts()) {
- FontFamily_Delegate.addFont(fontFamily.mBuilderPtr, font.getFontName(),
+ String fullPathName = "/system/fonts/" + font.getFontName();
+ FontFamily_Delegate.addFont(fontFamily.mBuilderPtr, fullPathName,
font.getWeight(), font.isItalic());
}
fontFamily.freeze();
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 5c28150..06272c8 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
@@ -1853,6 +1853,18 @@
}
@Override
+ public ComponentName startForegroundService(Intent service) {
+ // pass
+ return null;
+ }
+
+ @Override
+ public ComponentName startForegroundServiceAsUser(Intent service, UserHandle user) {
+ // pass
+ return null;
+ }
+
+ @Override
public ComponentName startServiceInForeground(Intent service,
int id, Notification notification) {
// pass