Merge "Fix crashes seen when checking for carrierConfig certificates" into qt-qpr1-dev
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 41c3da3..414cc39 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -852,11 +852,16 @@
* to any callers for the same name, meaning they will see each other's
* edits as soon as they are made.
*
- * This method is thead-safe.
+ * <p>This method is thread-safe.
*
- * @param name Desired preferences file. If a preferences file by this name
- * does not exist, it will be created when you retrieve an
- * editor (SharedPreferences.edit()) and then commit changes (Editor.commit()).
+ * <p>If the preferences directory does not already exist, it will be created when this method
+ * is called.
+ *
+ * <p>If a preferences file by this name does not exist, it will be created when you retrieve an
+ * editor ({@link SharedPreferences#edit()}) and then commit changes ({@link
+ * SharedPreferences.Editor#commit()} or {@link SharedPreferences.Editor#apply()}).
+ *
+ * @param name Desired preferences file.
* @param mode Operating mode.
*
* @return The single {@link SharedPreferences} instance that can be used
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index 037a149..c74daa8 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -503,9 +503,38 @@
}
/**
- * Retrieves a list of launchable activities that match {@link Intent#ACTION_MAIN} and
- * {@link Intent#CATEGORY_LAUNCHER}, for a specified user. Result may include
- * synthesized activities like app details Activity injected by system.
+ * Retrieves a list of activities that specify {@link Intent#ACTION_MAIN} and
+ * {@link Intent#CATEGORY_LAUNCHER}, across all apps, for a specified user. If an app doesn't
+ * have any activities that specify <code>ACTION_MAIN</code> or <code>CATEGORY_LAUNCHER</code>,
+ * the system adds a synthesized activity to the list. This synthesized activity represents the
+ * app's details page within system settings.
+ *
+ * <p class="note"><b>Note: </b>It's possible for system apps, such as app stores, to prevent
+ * the system from adding synthesized activities to the returned list.</p>
+ *
+ * <p>As of <a href="/reference/android/os/Build.VERSION_CODES.html#Q">Android Q</a>, at least
+ * one of the app's activities or synthesized activities appears in the returned list unless the
+ * app satisfies at least one of the following conditions:</p>
+ * <ul>
+ * <li>The app is a system app.</li>
+ * <li>The app doesn't request any <a href="/guide/topics/permissions/overview">permissions</a>.
+ * </li>
+ * <li>The <code><application></code> tag in the app's manifest doesn't contain any child
+ * elements that represent
+ * <a href="/guide/components/fundamentals#DeclaringComponents">app components</a>.</li>
+ * </ul>
+ *
+ * <p>Additionally, the system hides synthesized activities for some or all apps in the
+ * following enterprise-related cases:</p>
+ * <ul>
+ * <li>If the device is a
+ * <a href="https://developers.google.com/android/work/overview#company-owned-devices-for-knowledge-workers">fully
+ * managed device</a>, no synthesized activities for any app appear in the returned list.</li>
+ * <li>If the current user has a
+ * <a href="https://developers.google.com/android/work/overview#employee-owned-devices-byod">work
+ * profile</a>, no synthesized activities for the user's work apps appear in the returned
+ * list.</li>
+ * </ul>
*
* @param packageName The specific package to query. If null, it checks all installed packages
* in the profile.
diff --git a/core/java/android/os/VibrationEffect.java b/core/java/android/os/VibrationEffect.java
index 702b41b..26da0a0 100644
--- a/core/java/android/os/VibrationEffect.java
+++ b/core/java/android/os/VibrationEffect.java
@@ -53,7 +53,7 @@
public static final int MAX_AMPLITUDE = 255;
/**
- * A click effect.
+ * A click effect. Use this effect as a baseline, as it's the most common type of click effect.
*
* @see #get(int)
*/
@@ -67,7 +67,7 @@
public static final int EFFECT_DOUBLE_CLICK = Effect.DOUBLE_CLICK;
/**
- * A tick effect.
+ * A tick effect. This effect is less strong compared to {@link #EFFECT_CLICK}.
* @see #get(int)
*/
public static final int EFFECT_TICK = Effect.TICK;
@@ -89,7 +89,7 @@
public static final int EFFECT_POP = Effect.POP;
/**
- * A heavy click effect.
+ * A heavy click effect. This effect is stronger than {@link #EFFECT_CLICK}.
* @see #get(int)
*/
public static final int EFFECT_HEAVY_CLICK = Effect.HEAVY_CLICK;
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index f92be19..cf2fc47 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -3477,6 +3477,14 @@
};
/**
+ * The user selected min refresh rate in frames per second.
+ *
+ * If this isn't set, 0 will be used.
+ * @hide
+ */
+ public static final String MIN_REFRESH_RATE = "min_refresh_rate";
+
+ /**
* The user selected peak refresh rate in frames per second.
*
* If this isn't set, the system falls back to a device specific default.
diff --git a/core/java/android/view/GestureExclusionTracker.java b/core/java/android/view/GestureExclusionTracker.java
index 6fcdd71..fcc14c1 100644
--- a/core/java/android/view/GestureExclusionTracker.java
+++ b/core/java/android/view/GestureExclusionTracker.java
@@ -44,7 +44,7 @@
while (i.hasNext()) {
final GestureExclusionViewInfo info = i.next();
final View v = info.getView();
- if (v == null || !v.isAttachedToWindow()) {
+ if (v == null || !v.isAttachedToWindow() || !v.isShown()) {
mGestureExclusionViewsChanged = true;
i.remove();
continue;
@@ -122,7 +122,8 @@
public int update() {
final View excludedView = getView();
- if (excludedView == null || !excludedView.isAttachedToWindow()) return GONE;
+ if (excludedView == null || !excludedView.isAttachedToWindow()
+ || !excludedView.isShown()) return GONE;
final List<Rect> localRects = excludedView.getSystemGestureExclusionRects();
final List<Rect> newRects = new ArrayList<>(localRects.size());
for (Rect src : localRects) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 4e86e60..9c55bb0 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -14423,6 +14423,7 @@
}
notifyAppearedOrDisappearedForContentCaptureIfNeeded(isVisible);
+ updateSystemGestureExclusionRects();
}
/**
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 95fca00..721ac2d 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -1843,8 +1843,8 @@
/**
* Injects the supplied Java object into this WebView. The object is
- * injected into the JavaScript context of the main frame, using the
- * supplied name. This allows the Java object's methods to be
+ * injected into all frames of the web page, including all the iframes,
+ * using the supplied name. This allows the Java object's methods to be
* accessed from JavaScript. For applications targeted to API
* level {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}
* and above, only public methods that are annotated with
@@ -1883,6 +1883,11 @@
* thread of this WebView. Care is therefore required to maintain thread
* safety.
* </li>
+ * <li> Because the object is exposed to all the frames, any frame could
+ * obtain the object name and call methods on it. There is no way to tell the
+ * calling frame's origin from the app side, so the app must not assume that
+ * the caller is trustworthy unless the app can guarantee that no third party
+ * content is ever loaded into the WebView even inside an iframe.</li>
* <li> The Java object's fields are not accessible.</li>
* <li> For applications targeted to API level {@link android.os.Build.VERSION_CODES#LOLLIPOP}
* and above, methods of injected Java objects are enumerable from
diff --git a/core/java/android/widget/ImageView.java b/core/java/android/widget/ImageView.java
index be5d221..d62b979 100644
--- a/core/java/android/widget/ImageView.java
+++ b/core/java/android/widget/ImageView.java
@@ -62,8 +62,9 @@
/**
* Displays image resources, for example {@link android.graphics.Bitmap}
* or {@link android.graphics.drawable.Drawable} resources.
- * ImageView is also commonly used to {@link #setImageTintMode(PorterDuff.Mode)
- * apply tints to an image} and handle {@link #setScaleType(ScaleType) image scaling}.
+ * ImageView is also commonly used to
+ * <a href="#setImageTintMode(android.graphics.PorterDuff.Mode)">apply tints to an image</a> and
+ * handle <a href="#setScaleType(android.widget.ImageView.ScaleType)">image scaling</a>.
*
* <p>
* The following XML snippet is a common example of using an ImageView to display an image resource:
@@ -76,7 +77,8 @@
* <ImageView
* android:layout_width="wrap_content"
* android:layout_height="wrap_content"
- * android:src="@mipmap/ic_launcher"
+ * android:src="@drawable/my_image"
+ * android:contentDescription="@string/my_image_description"
* />
* </LinearLayout>
* </pre>
diff --git a/core/jni/android_hardware_input_InputWindowHandle.cpp b/core/jni/android_hardware_input_InputWindowHandle.cpp
index a1d1d4f..57d1649 100644
--- a/core/jni/android_hardware_input_InputWindowHandle.cpp
+++ b/core/jni/android_hardware_input_InputWindowHandle.cpp
@@ -28,6 +28,7 @@
#include "android_hardware_input_InputWindowHandle.h"
#include "android_hardware_input_InputApplicationHandle.h"
#include "android_util_Binder.h"
+#include <binder/IPCThreadState.h>
namespace android {
@@ -78,6 +79,12 @@
NativeInputWindowHandle::~NativeInputWindowHandle() {
JNIEnv* env = AndroidRuntime::getJNIEnv();
env->DeleteWeakGlobalRef(mObjWeak);
+
+ // Clear the weak reference to the layer handle and flush any binder ref count operations so we
+ // do not hold on to any binder references.
+ // TODO(b/139697085) remove this after it can be flushed automatically
+ mInfo.touchableRegionCropHandle.clear();
+ IPCThreadState::self()->flushCommands();
}
jobject NativeInputWindowHandle::getInputWindowHandleObjLocalRef(JNIEnv* env) {
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index aee178a..0060741 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -93,6 +93,7 @@
Settings.System.VOLUME_VOICE, // deprecated since API 2?
Settings.System.WHEN_TO_MAKE_WIFI_CALLS, // bug?
Settings.System.WINDOW_ORIENTATION_LISTENER_LOG, // used for debugging only
+ Settings.System.MIN_REFRESH_RATE, // depends on hardware capabilities
Settings.System.PEAK_REFRESH_RATE // depends on hardware capabilities
);
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index b9945cc..e6eaa696 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -207,7 +207,7 @@
}
public GradientDrawable() {
- this(new GradientState(Orientation.TOP_BOTTOM, null), null);
+ this(new GradientState(Orientation.LEFT_RIGHT, null), null);
}
/**
diff --git a/packages/SystemUI/res/drawable/ic_5g_e_mobiledata.xml b/packages/SystemUI/res/drawable/ic_5g_e_mobiledata.xml
index fe1bb26..7c7c8c1 100644
--- a/packages/SystemUI/res/drawable/ic_5g_e_mobiledata.xml
+++ b/packages/SystemUI/res/drawable/ic_5g_e_mobiledata.xml
@@ -16,16 +16,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:viewportWidth="22"
android:viewportHeight="17"
- android:width="22dp"
- android:height="17dp">
+ android:width="19.41dp"
+ android:height="15dp">
<path
android:fillColor="#FFFFFFFF"
- android:pathData="M1.22,8.49l0.43-4.96h4.33v1.17H2.67L2.44,7.41c0.41-0.29,0.85-0.43,1.33-0.43c0.77,0,1.38,0.3,1.83,0.9 s0.66,1.41,0.66,2.43c0,1.03-0.24,1.84-0.72,2.43s-1.14,0.88-1.98,0.88c-0.75,0-1.36-0.24-1.83-0.73s-0.74-1.16-0.81-2.02h1.13 c0.07,0.57,0.23,1,0.49,1.29c0.26,0.29,0.59,0.43,1.01,0.43c0.47,0,0.84-0.2,1.1-0.61c0.26-0.41,0.4-0.96,0.4-1.65 c0-0.65-0.14-1.18-0.43-1.59S3.96,8.11,3.47,8.11c-0.4,0-0.72,0.1-0.96,0.31L2.19,8.75L1.22,8.49z" />
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M14.14,12.24l-0.22,0.27c-0.63,0.73-1.55,1.1-2.76,1.1c-1.08,0-1.92-0.36-2.53-1.07c-0.61-0.71-0.93-1.72-0.94-3.02V7.56 c0-1.39,0.28-2.44,0.84-3.13c0.56-0.7,1.39-1.04,2.51-1.04c0.95,0,1.69,0.26,2.23,0.79c0.54,0.53,0.83,1.28,0.89,2.26h-1.25 c-0.05-0.62-0.22-1.1-0.52-1.45c-0.29-0.35-0.74-0.52-1.34-0.52c-0.72,0-1.24,0.23-1.57,0.7C9.14,5.63,8.96,6.37,8.95,7.4v2.03 c0,1,0.19,1.77,0.57,2.31c0.38,0.54,0.93,0.8,1.65,0.8c0.67,0,1.19-0.16,1.54-0.49l0.18-0.17V9.59h-1.82V8.52h3.07V12.24z" />
- <path
- android:fillColor="#FFFFFFFF"
- android:pathData="M20.96,8.88h-3.52v3.53h4.1v1.07h-5.35V3.52h5.28V4.6h-4.03V7.8h3.52V8.88z" />
-
+ android:pathData="M 6.72 3.52 L 6.54 4.69 L 3.34 4.69 L 2.63 7.41 C 3.011 7.143 3.465 7 3.93 7 C 4.5 6.986 5.041 7.251 5.38 7.71 C 5.756 8.249 5.952 8.893 5.94 9.55 C 5.98 10.276 5.864 11.002 5.6 11.68 C 5.385 12.267 5.007 12.78 4.51 13.16 C 4.043 13.499 3.476 13.671 2.9 13.65 C 2.271 13.653 1.675 13.369 1.28 12.88 C 0.854 12.302 0.636 11.597 0.66 10.88 L 1.76 10.88 C 1.81 12 2.21 12.57 3 12.58 C 3.592 12.589 4.132 12.243 4.37 11.7 C 4.708 11.044 4.85 10.305 4.78 9.57 C 4.767 9.209 4.645 8.86 4.43 8.57 C 4.239 8.309 3.934 8.156 3.61 8.16 C 3.404 8.138 3.196 8.162 3 8.23 C 2.748 8.358 2.518 8.527 2.32 8.73 L 1.31 8.46 L 2.51 3.52 L 6.72 3.52 Z M 11.7 3.39 C 12.459 3.353 13.195 3.662 13.7 4.23 C 14.185 4.864 14.42 5.654 14.36 6.45 L 13.1 6.45 C 13.131 5.938 12.998 5.43 12.72 5 C 12.455 4.679 12.056 4.498 11.64 4.51 C 11.025 4.456 10.42 4.688 10 5.14 C 9.491 5.811 9.179 6.611 9.1 7.45 L 8.75 9.54 L 8.75 10.57 C 8.82 11.86 9.36 12.52 10.36 12.57 C 10.701 12.593 11.043 12.538 11.36 12.41 C 11.661 12.281 11.943 12.113 12.2 11.91 L 12.62 9.62 L 10.77 9.62 L 11 8.52 L 14 8.52 L 13.36 12.23 C 13.176 12.483 12.953 12.706 12.7 12.89 C 11.995 13.398 11.138 13.652 10.27 13.61 C 9.507 13.634 8.773 13.315 8.27 12.74 C 7.748 12.085 7.475 11.267 7.5 10.43 C 7.47 10.097 7.47 9.763 7.5 9.43 L 7.8 7.43 C 7.927 6.332 8.36 5.293 9.05 4.43 C 9.725 3.692 10.703 3.308 11.7 3.39 Z M 20.81 7.21 L 20.62 8.29 L 18.32 8.29 L 18.06 9.8 L 20.06 9.8 L 19.83 10.84 L 17.88 10.84 L 17.59 12.54 L 19.9 12.54 L 19.71 13.61 L 16.14 13.61 L 17.25 7.21 L 20.81 7.21 Z" />
+ <path android:pathData="M 0 0 H 14 V 17 H 0 V 0 Z"/>
</vector>
diff --git a/services/appprediction/java/com/android/server/appprediction/AppPredictionManagerService.java b/services/appprediction/java/com/android/server/appprediction/AppPredictionManagerService.java
index d7e68f8..5844f98 100644
--- a/services/appprediction/java/com/android/server/appprediction/AppPredictionManagerService.java
+++ b/services/appprediction/java/com/android/server/appprediction/AppPredictionManagerService.java
@@ -23,6 +23,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UserIdInt;
import android.app.prediction.AppPredictionContext;
import android.app.prediction.AppPredictionSessionId;
import android.app.prediction.AppTargetEvent;
@@ -61,7 +62,8 @@
public AppPredictionManagerService(Context context) {
super(context, new FrameworkResourcesServiceNameResolver(context,
- com.android.internal.R.string.config_defaultAppPredictionService), null);
+ com.android.internal.R.string.config_defaultAppPredictionService), null,
+ PACKAGE_UPDATE_POLICY_NO_REFRESH | PACKAGE_RESTART_POLICY_NO_REFRESH);
mActivityTaskManagerInternal = LocalServices.getService(ActivityTaskManagerInternal.class);
}
@@ -80,6 +82,22 @@
getContext().enforceCallingPermission(MANAGE_APP_PREDICTIONS, TAG);
}
+ @Override // from AbstractMasterSystemService
+ protected void onServicePackageUpdatedLocked(@UserIdInt int userId) {
+ final AppPredictionPerUserService service = peekServiceForUserLocked(userId);
+ if (service != null) {
+ service.onPackageUpdatedLocked();
+ }
+ }
+
+ @Override // from AbstractMasterSystemService
+ protected void onServicePackageRestartedLocked(@UserIdInt int userId) {
+ final AppPredictionPerUserService service = peekServiceForUserLocked(userId);
+ if (service != null) {
+ service.onPackageRestartedLocked();
+ }
+ }
+
@Override
protected int getMaximumTemporaryServiceDurationMs() {
return MAX_TEMP_SERVICE_DURATION_MS;
diff --git a/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java b/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java
index 03c4542..4f49fb7 100644
--- a/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java
+++ b/services/appprediction/java/com/android/server/appprediction/AppPredictionPerUserService.java
@@ -251,6 +251,40 @@
// Do nothing, eventually the system will bind to the remote service again...
}
+ void onPackageUpdatedLocked() {
+ if (isDebug()) {
+ Slog.v(TAG, "onPackageUpdatedLocked()");
+ }
+ destroyAndRebindRemoteService();
+ }
+
+ void onPackageRestartedLocked() {
+ if (isDebug()) {
+ Slog.v(TAG, "onPackageRestartedLocked()");
+ }
+ destroyAndRebindRemoteService();
+ }
+
+ private void destroyAndRebindRemoteService() {
+ if (mRemoteService == null) {
+ return;
+ }
+
+ if (isDebug()) {
+ Slog.d(TAG, "Destroying the old remote service.");
+ }
+ mRemoteService.destroy();
+ mRemoteService = null;
+
+ mRemoteService = getRemoteServiceLocked();
+ if (mRemoteService != null) {
+ if (isDebug()) {
+ Slog.d(TAG, "Rebinding to the new remote service.");
+ }
+ mRemoteService.reconnect();
+ }
+ }
+
/**
* Called after the remote service connected, it's used to restore state from a 'zombie'
* service (i.e., after it died).
diff --git a/services/appprediction/java/com/android/server/appprediction/RemoteAppPredictionService.java b/services/appprediction/java/com/android/server/appprediction/RemoteAppPredictionService.java
index c82e7a0..04e0e7f 100644
--- a/services/appprediction/java/com/android/server/appprediction/RemoteAppPredictionService.java
+++ b/services/appprediction/java/com/android/server/appprediction/RemoteAppPredictionService.java
@@ -135,6 +135,13 @@
}
/**
+ * Schedules a request to bind to the remote service.
+ */
+ public void reconnect() {
+ super.scheduleBind();
+ }
+
+ /**
* Failure callback
*/
public interface RemoteAppPredictionServiceCallbacks
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index d442ea9..bb455cd 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -5259,7 +5259,7 @@
storageManager.commitChanges();
} catch (Exception e) {
PowerManager pm = (PowerManager)
- mInjector.getContext().getSystemService(Context.POWER_SERVICE);
+ mContext.getSystemService(Context.POWER_SERVICE);
pm.reboot("Checkpoint commit failed");
}
diff --git a/services/core/java/com/android/server/display/DisplayModeDirector.java b/services/core/java/com/android/server/display/DisplayModeDirector.java
index 7648636..58aadd1 100644
--- a/services/core/java/com/android/server/display/DisplayModeDirector.java
+++ b/services/core/java/com/android/server/display/DisplayModeDirector.java
@@ -38,13 +38,16 @@
import android.os.UserHandle;
import android.os.PowerManager;
import android.os.SystemClock;
+import android.provider.DeviceConfig;
import android.provider.Settings;
import android.text.TextUtils;
+import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
import android.view.Display;
import android.view.DisplayInfo;
+import com.android.internal.os.BackgroundThread;
import com.android.internal.R;
import com.android.server.display.whitebalance.DisplayWhiteBalanceFactory;
import com.android.server.display.whitebalance.AmbientFilter;
@@ -64,6 +67,8 @@
private static final boolean DEBUG = false;
private static final int MSG_ALLOWED_MODES_CHANGED = 1;
+ private static final int MSG_BRIGHTNESS_THRESHOLDS_CHANGED = 2;
+ private static final int MSG_DEFAULT_PEAK_REFRESH_RATE_CHANGED = 3;
// Special ID used to indicate that given vote is to be applied globally, rather than to a
// specific display.
@@ -91,6 +96,7 @@
private final DisplayObserver mDisplayObserver;
private final BrightnessObserver mBrightnessObserver;
+ private final DeviceConfigDisplaySettings mDeviceConfigDisplaySettings;
private Listener mListener;
public DisplayModeDirector(@NonNull Context context, @NonNull Handler handler) {
@@ -103,7 +109,7 @@
mSettingsObserver = new SettingsObserver(context, handler);
mDisplayObserver = new DisplayObserver(context, handler);
mBrightnessObserver = new BrightnessObserver(context, handler);
-
+ mDeviceConfigDisplaySettings = new DeviceConfigDisplaySettings();
}
/**
@@ -405,7 +411,7 @@
void onAllowedDisplayModesChanged();
}
- private static final class DisplayModeDirectorHandler extends Handler {
+ private final class DisplayModeDirectorHandler extends Handler {
DisplayModeDirectorHandler(Looper looper) {
super(looper, null, true /*async*/);
}
@@ -417,6 +423,23 @@
Listener listener = (Listener) msg.obj;
listener.onAllowedDisplayModesChanged();
break;
+
+ case MSG_BRIGHTNESS_THRESHOLDS_CHANGED:
+ Pair<int[], int[]> thresholds = (Pair<int[], int[]>) msg.obj;
+
+ if (thresholds != null) {
+ mBrightnessObserver.onDeviceConfigThresholdsChanged(
+ thresholds.first, thresholds.second);
+ } else {
+ mBrightnessObserver.onDeviceConfigThresholdsChanged(null, null);
+ }
+ break;
+
+ case MSG_DEFAULT_PEAK_REFRESH_RATE_CHANGED:
+ Float defaultPeakRefreshRate = (Float) msg.obj;
+ mSettingsObserver.onDeviceConfigDefaultPeakRefreshRateChanged(
+ defaultPeakRefreshRate);
+ break;
}
}
}
@@ -502,13 +525,15 @@
}
private final class SettingsObserver extends ContentObserver {
- private final Uri mRefreshRateSetting =
+ private final Uri mPeakRefreshRateSetting =
Settings.System.getUriFor(Settings.System.PEAK_REFRESH_RATE);
+ private final Uri mMinRefreshRateSetting =
+ Settings.System.getUriFor(Settings.System.MIN_REFRESH_RATE);
private final Uri mLowPowerModeSetting =
Settings.Global.getUriFor(Settings.Global.LOW_POWER_MODE);
private final Context mContext;
- private final float mDefaultPeakRefreshRate;
+ private float mDefaultPeakRefreshRate;
SettingsObserver(@NonNull Context context, @NonNull Handler handler) {
super(handler);
@@ -519,20 +544,44 @@
public void observe() {
final ContentResolver cr = mContext.getContentResolver();
- cr.registerContentObserver(mRefreshRateSetting, false /*notifyDescendants*/, this,
+ cr.registerContentObserver(mPeakRefreshRateSetting, false /*notifyDescendants*/, this,
+ UserHandle.USER_SYSTEM);
+ cr.registerContentObserver(mMinRefreshRateSetting, false /*notifyDescendants*/, this,
UserHandle.USER_SYSTEM);
cr.registerContentObserver(mLowPowerModeSetting, false /*notifyDescendants*/, this,
UserHandle.USER_SYSTEM);
+
+ Float deviceConfigDefaultPeakRefresh =
+ mDeviceConfigDisplaySettings.getDefaultPeakRefreshRate();
+ if (deviceConfigDefaultPeakRefresh != null) {
+ mDefaultPeakRefreshRate = deviceConfigDefaultPeakRefresh;
+ }
+
synchronized (mLock) {
updateRefreshRateSettingLocked();
updateLowPowerModeSettingLocked();
}
}
+ public void onDeviceConfigDefaultPeakRefreshRateChanged(Float defaultPeakRefreshRate) {
+ if (defaultPeakRefreshRate == null) {
+ defaultPeakRefreshRate = (float) mContext.getResources().getInteger(
+ R.integer.config_defaultPeakRefreshRate);
+ }
+
+ if (mDefaultPeakRefreshRate != defaultPeakRefreshRate) {
+ synchronized (mLock) {
+ mDefaultPeakRefreshRate = defaultPeakRefreshRate;
+ updateRefreshRateSettingLocked();
+ }
+ }
+ }
+
@Override
public void onChange(boolean selfChange, Uri uri, int userId) {
synchronized (mLock) {
- if (mRefreshRateSetting.equals(uri)) {
+ if (mPeakRefreshRateSetting.equals(uri)
+ || mMinRefreshRateSetting.equals(uri)) {
updateRefreshRateSettingLocked();
} else if (mLowPowerModeSetting.equals(uri)) {
updateLowPowerModeSettingLocked();
@@ -550,15 +599,22 @@
vote = null;
}
updateVoteLocked(Vote.PRIORITY_LOW_POWER_MODE, vote);
- mBrightnessObserver.onLowPowerModeEnabled(inLowPowerMode);
+ mBrightnessObserver.onLowPowerModeEnabledLocked(inLowPowerMode);
}
private void updateRefreshRateSettingLocked() {
+ float minRefreshRate = Settings.System.getFloat(mContext.getContentResolver(),
+ Settings.System.MIN_REFRESH_RATE, 0f);
float peakRefreshRate = Settings.System.getFloat(mContext.getContentResolver(),
Settings.System.PEAK_REFRESH_RATE, mDefaultPeakRefreshRate);
- Vote vote = Vote.forRefreshRates(0f, peakRefreshRate);
+
+ if (peakRefreshRate < minRefreshRate) {
+ peakRefreshRate = minRefreshRate;
+ }
+
+ Vote vote = Vote.forRefreshRates(minRefreshRate, peakRefreshRate);
updateVoteLocked(Vote.PRIORITY_USER_SETTING_REFRESH_RATE, vote);
- mBrightnessObserver.onPeakRefreshRateEnabled(peakRefreshRate > 60f);
+ mBrightnessObserver.onRefreshRateSettingChangedLocked(minRefreshRate, peakRefreshRate);
}
public void dumpLocked(PrintWriter pw) {
@@ -721,8 +777,8 @@
Settings.System.getUriFor(Settings.System.SCREEN_BRIGHTNESS);
private final static int LIGHT_SENSOR_RATE_MS = 250;
- private final int[] mDisplayBrightnessThresholds;
- private final int[] mAmbientBrightnessThresholds;
+ private int[] mDisplayBrightnessThresholds;
+ private int[] mAmbientBrightnessThresholds;
// valid threshold if any item from the array >= 0
private boolean mShouldObserveDisplayChange;
private boolean mShouldObserveAmbientChange;
@@ -735,10 +791,12 @@
private AmbientFilter mAmbientFilter;
private final Context mContext;
- // Enable light sensor only when screen is on, peak refresh rate enabled and low power mode
- // off. After initialization, these states will be updated from the same handler thread.
+
+ // Enable light sensor only when mShouldObserveAmbientChange is true, screen is on, peak
+ // refresh rate changeable and low power mode off. After initialization, these states will
+ // be updated from the same handler thread.
private boolean mScreenOn = false;
- private boolean mPeakRefreshRateEnabled = false;
+ private boolean mRefreshRateChangeable = false;
private boolean mLowPowerModeEnabled = false;
BrightnessObserver(Context context, Handler handler) {
@@ -748,79 +806,61 @@
R.array.config_brightnessThresholdsOfPeakRefreshRate);
mAmbientBrightnessThresholds = context.getResources().getIntArray(
R.array.config_ambientThresholdsOfPeakRefreshRate);
+
if (mDisplayBrightnessThresholds.length != mAmbientBrightnessThresholds.length) {
throw new RuntimeException("display brightness threshold array and ambient "
+ "brightness threshold array have different length");
}
-
- mShouldObserveDisplayChange = checkShouldObserve(mDisplayBrightnessThresholds);
- mShouldObserveAmbientChange = checkShouldObserve(mAmbientBrightnessThresholds);
}
public void observe(SensorManager sensorManager) {
- if (mShouldObserveDisplayChange) {
- final ContentResolver cr = mContext.getContentResolver();
- cr.registerContentObserver(mDisplayBrightnessSetting,
- false /*notifyDescendants*/, this, UserHandle.USER_SYSTEM);
+ mSensorManager = sensorManager;
+ // DeviceConfig is accessible after system ready.
+ int[] brightnessThresholds = mDeviceConfigDisplaySettings.getBrightnessThresholds();
+ int[] ambientThresholds = mDeviceConfigDisplaySettings.getAmbientThresholds();
+
+ if (brightnessThresholds != null && ambientThresholds != null
+ && brightnessThresholds.length == ambientThresholds.length) {
+ mDisplayBrightnessThresholds = brightnessThresholds;
+ mAmbientBrightnessThresholds = ambientThresholds;
}
-
- if (mShouldObserveAmbientChange) {
- Resources resources = mContext.getResources();
- String lightSensorType = resources.getString(
- com.android.internal.R.string.config_displayLightSensorType);
-
- Sensor lightSensor = null;
- if (!TextUtils.isEmpty(lightSensorType)) {
- List<Sensor> sensors = sensorManager.getSensorList(Sensor.TYPE_ALL);
- for (int i = 0; i < sensors.size(); i++) {
- Sensor sensor = sensors.get(i);
- if (lightSensorType.equals(sensor.getStringType())) {
- lightSensor = sensor;
- break;
- }
- }
- }
-
- if (lightSensor == null) {
- lightSensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
- }
-
- if (lightSensor != null) {
- final Resources res = mContext.getResources();
-
- mAmbientFilter = DisplayWhiteBalanceFactory.createBrightnessFilter(res);
- mSensorManager = sensorManager;
- mLightSensor = lightSensor;
-
- onScreenOn(isDefaultDisplayOn());
- }
- }
-
- if (mShouldObserveDisplayChange || mShouldObserveAmbientChange) {
- synchronized (mLock) {
- onBrightnessChangedLocked();
- }
- }
+ restartObserver();
+ mDeviceConfigDisplaySettings.startListening();
}
- public void onPeakRefreshRateEnabled(boolean b) {
- if (mShouldObserveAmbientChange && mPeakRefreshRateEnabled != b) {
- mPeakRefreshRateEnabled = b;
+ public void onRefreshRateSettingChangedLocked(float min, float max) {
+ boolean changeable = (max - min > 1f && max > 60f);
+ if (mRefreshRateChangeable != changeable) {
+ mRefreshRateChangeable = changeable;
updateSensorStatus();
+ if (!changeable) {
+ // Revoke previous vote from BrightnessObserver
+ updateVoteLocked(Vote.PRIORITY_LOW_BRIGHTNESS, null);
+ }
}
}
- public void onLowPowerModeEnabled(boolean b) {
- if (mShouldObserveAmbientChange && mLowPowerModeEnabled != b) {
+ public void onLowPowerModeEnabledLocked(boolean b) {
+ if (mLowPowerModeEnabled != b) {
mLowPowerModeEnabled = b;
updateSensorStatus();
}
}
- public void onDisplayChanged(int displayId) {
- if (displayId == Display.DEFAULT_DISPLAY) {
- onScreenOn(isDefaultDisplayOn());
+ public void onDeviceConfigThresholdsChanged(int[] brightnessThresholds,
+ int[] ambientThresholds) {
+ if (brightnessThresholds != null && ambientThresholds != null
+ && brightnessThresholds.length == ambientThresholds.length) {
+ mDisplayBrightnessThresholds = brightnessThresholds;
+ mAmbientBrightnessThresholds = ambientThresholds;
+ } else {
+ // Invalid or empty. Use device default.
+ mDisplayBrightnessThresholds = mContext.getResources().getIntArray(
+ R.array.config_brightnessThresholdsOfPeakRefreshRate);
+ mAmbientBrightnessThresholds = mContext.getResources().getIntArray(
+ R.array.config_ambientThresholdsOfPeakRefreshRate);
}
+ restartObserver();
}
public void dumpLocked(PrintWriter pw) {
@@ -835,6 +875,12 @@
}
}
+ public void onDisplayChanged(int displayId) {
+ if (displayId == Display.DEFAULT_DISPLAY) {
+ onScreenOn(isDefaultDisplayOn());
+ }
+ }
+
@Override
public void onChange(boolean selfChange, Uri uri, int userId) {
synchronized (mLock) {
@@ -842,6 +888,63 @@
}
}
+ private void restartObserver() {
+ mShouldObserveDisplayChange = checkShouldObserve(mDisplayBrightnessThresholds);
+ mShouldObserveAmbientChange = checkShouldObserve(mAmbientBrightnessThresholds);
+
+ final ContentResolver cr = mContext.getContentResolver();
+ if (mShouldObserveDisplayChange) {
+ // Content Service does not check if an listener has already been registered.
+ // To ensure only one listener is registered, force an unregistration first.
+ cr.unregisterContentObserver(this);
+ cr.registerContentObserver(mDisplayBrightnessSetting,
+ false /*notifyDescendants*/, this, UserHandle.USER_SYSTEM);
+ } else {
+ cr.unregisterContentObserver(this);
+ }
+
+ if (mShouldObserveAmbientChange) {
+ Resources resources = mContext.getResources();
+ String lightSensorType = resources.getString(
+ com.android.internal.R.string.config_displayLightSensorType);
+
+ Sensor lightSensor = null;
+ if (!TextUtils.isEmpty(lightSensorType)) {
+ List<Sensor> sensors = mSensorManager.getSensorList(Sensor.TYPE_ALL);
+ for (int i = 0; i < sensors.size(); i++) {
+ Sensor sensor = sensors.get(i);
+ if (lightSensorType.equals(sensor.getStringType())) {
+ lightSensor = sensor;
+ break;
+ }
+ }
+ }
+
+ if (lightSensor == null) {
+ lightSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
+ }
+
+ if (lightSensor != null) {
+ final Resources res = mContext.getResources();
+
+ mAmbientFilter = DisplayWhiteBalanceFactory.createBrightnessFilter(res);
+ mLightSensor = lightSensor;
+
+ onScreenOn(isDefaultDisplayOn());
+ }
+ } else {
+ mAmbientFilter = null;
+ mLightSensor = null;
+ }
+
+ if (mRefreshRateChangeable) {
+ updateSensorStatus();
+ synchronized (mLock) {
+ onBrightnessChangedLocked();
+ }
+ }
+ }
+
/**
* Checks to see if at least one value is positive, in which case it is necessary to listen
* to value changes.
@@ -903,7 +1006,8 @@
return;
}
- if (mScreenOn && !mLowPowerModeEnabled && mPeakRefreshRateEnabled) {
+ if (mShouldObserveAmbientChange && mScreenOn && !mLowPowerModeEnabled
+ && mRefreshRateChangeable) {
mSensorManager.registerListener(mLightSensorListener,
mLightSensor, LIGHT_SENSOR_RATE_MS * 1000, mHandler);
} else {
@@ -996,6 +1100,88 @@
}
}
};
- };
+ }
}
+
+ private class DeviceConfigDisplaySettings implements DeviceConfig.OnPropertiesChangedListener {
+
+ public DeviceConfigDisplaySettings() {
+ }
+
+ public void startListening() {
+ DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_DISPLAY_MANAGER,
+ BackgroundThread.getExecutor(), this);
+ }
+
+ /*
+ * Return null if no such property or wrong format (not comma separated integers).
+ */
+ public int[] getBrightnessThresholds() {
+ return getIntArrayProperty(
+ DisplayManager.DeviceConfig.KEY_PEAK_REFRESH_RATE_BRIGHTNESS_THRESHOLDS);
+ }
+
+ /*
+ * Return null if no such property or wrong format (not comma separated integers).
+ */
+ public int[] getAmbientThresholds() {
+ return getIntArrayProperty(
+ DisplayManager.DeviceConfig.KEY_PEAK_REFRESH_RATE_AMBIENT_THRESHOLDS);
+ }
+
+ /*
+ * Return null if no such property
+ */
+ public Float getDefaultPeakRefreshRate() {
+ float defaultPeakRefreshRate = DeviceConfig.getFloat(
+ DeviceConfig.NAMESPACE_DISPLAY_MANAGER,
+ DisplayManager.DeviceConfig.KEY_PEAK_REFRESH_RATE_DEFAULT, -1);
+
+ if (defaultPeakRefreshRate == -1) {
+ return null;
+ }
+ return defaultPeakRefreshRate;
+ }
+
+ @Override
+ public void onPropertiesChanged(@NonNull DeviceConfig.Properties properties) {
+ int[] brightnessThresholds = getBrightnessThresholds();
+ int[] ambientThresholds = getAmbientThresholds();
+ Float defaultPeakRefreshRate = getDefaultPeakRefreshRate();
+
+ mHandler.obtainMessage(MSG_BRIGHTNESS_THRESHOLDS_CHANGED,
+ new Pair<int[], int[]>(brightnessThresholds, ambientThresholds))
+ .sendToTarget();
+ mHandler.obtainMessage(MSG_DEFAULT_PEAK_REFRESH_RATE_CHANGED,
+ defaultPeakRefreshRate).sendToTarget();
+ }
+
+ private int[] getIntArrayProperty(String prop) {
+ String strArray = DeviceConfig.getString(DeviceConfig.NAMESPACE_DISPLAY_MANAGER, prop,
+ null);
+
+ if (strArray != null) {
+ return parseIntArray(strArray);
+ }
+
+ return null;
+ }
+
+ private int[] parseIntArray(@NonNull String strArray) {
+ String[] items = strArray.split(",");
+ int[] array = new int[items.length];
+
+ try {
+ for (int i = 0; i < array.length; i++) {
+ array[i] = Integer.parseInt(items[i]);
+ }
+ } catch (NumberFormatException e) {
+ Slog.e(TAG, "Incorrect format for array: '" + strArray + "'", e);
+ array = null;
+ }
+
+ return array;
+ }
+ }
+
}
diff --git a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
index 9782f30..259527a 100644
--- a/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
+++ b/services/core/java/com/android/server/infra/AbstractMasterSystemService.java
@@ -79,7 +79,7 @@
S extends AbstractPerUserSystemService<S, M>> extends SystemService {
/** On a package update, does not refresh the per-user service in the cache. */
- public static final int PACKAGE_UPDATE_POLICY_NO_REFRESH = 0;
+ public static final int PACKAGE_UPDATE_POLICY_NO_REFRESH = 0x00000001;
/**
* On a package update, removes any existing per-user services in the cache.
@@ -87,20 +87,40 @@
* <p>This does not immediately recreate these services. It is assumed they will be recreated
* for the next user request.
*/
- public static final int PACKAGE_UPDATE_POLICY_REFRESH_LAZY = 1;
+ public static final int PACKAGE_UPDATE_POLICY_REFRESH_LAZY = 0x00000002;
/**
* On a package update, removes and recreates any existing per-user services in the cache.
*/
- public static final int PACKAGE_UPDATE_POLICY_REFRESH_EAGER = 2;
+ public static final int PACKAGE_UPDATE_POLICY_REFRESH_EAGER = 0x00000004;
- @IntDef(flag = true, prefix = { "PACKAGE_UPDATE_POLICY_" }, value = {
+ /** On a package restart, does not refresh the per-user service in the cache. */
+ public static final int PACKAGE_RESTART_POLICY_NO_REFRESH = 0x00000010;
+
+ /**
+ * On a package restart, removes any existing per-user services in the cache.
+ *
+ * <p>This does not immediately recreate these services. It is assumed they will be recreated
+ * for the next user request.
+ */
+ public static final int PACKAGE_RESTART_POLICY_REFRESH_LAZY = 0x00000020;
+
+ /**
+ * On a package restart, removes and recreates any existing per-user services in the cache.
+ */
+ public static final int PACKAGE_RESTART_POLICY_REFRESH_EAGER = 0x00000040;
+
+ @IntDef(flag = true, prefix = { "PACKAGE_" }, value = {
PACKAGE_UPDATE_POLICY_NO_REFRESH,
PACKAGE_UPDATE_POLICY_REFRESH_LAZY,
- PACKAGE_UPDATE_POLICY_REFRESH_EAGER
+ PACKAGE_UPDATE_POLICY_REFRESH_EAGER,
+ PACKAGE_RESTART_POLICY_NO_REFRESH,
+ PACKAGE_RESTART_POLICY_REFRESH_LAZY,
+ PACKAGE_RESTART_POLICY_REFRESH_EAGER
})
+
@Retention(RetentionPolicy.SOURCE)
- public @interface PackageUpdatePolicy {}
+ public @interface ServicePackagePolicyFlags {}
/**
* Log tag
@@ -153,12 +173,10 @@
private final SparseArray<S> mServicesCache = new SparseArray<>();
/**
- * Whether the per-user service should be removed from the cache when its apk is updated.
- *
- * <p>One of {@link #PACKAGE_UPDATE_POLICY_NO_REFRESH},
- * {@link #PACKAGE_UPDATE_POLICY_REFRESH_LAZY} or {@link #PACKAGE_UPDATE_POLICY_REFRESH_EAGER}.
+ * Value that determines whether the per-user service should be removed from the cache when its
+ * apk is updated or restarted.
*/
- private final @PackageUpdatePolicy int mPackageUpdatePolicy;
+ private final @ServicePackagePolicyFlags int mServicePackagePolicyFlags;
/**
* Name of the service packages whose APK are being updated, keyed by user id.
@@ -184,11 +202,11 @@
@Nullable ServiceNameResolver serviceNameResolver,
@Nullable String disallowProperty) {
this(context, serviceNameResolver, disallowProperty,
- /*packageUpdatePolicy=*/ PACKAGE_UPDATE_POLICY_REFRESH_LAZY);
+ PACKAGE_UPDATE_POLICY_REFRESH_LAZY | PACKAGE_RESTART_POLICY_REFRESH_LAZY);
}
/**
- * Full constructor.
+ * Full Constructor.
*
* @param context system context.
* @param serviceNameResolver resolver for
@@ -197,19 +215,32 @@
* @param disallowProperty when not {@code null}, defines a {@link UserManager} restriction that
* disables the service. <b>NOTE: </b> you'll also need to add it to
* {@code UserRestrictionsUtils.USER_RESTRICTIONS}.
- * @param packageUpdatePolicy when {@link #PACKAGE_UPDATE_POLICY_REFRESH_LAZY}, the
- * {@link AbstractPerUserSystemService} is removed from the cache when the service
- * package is updated; when {@link #PACKAGE_UPDATE_POLICY_REFRESH_EAGER}, the
- * {@link AbstractPerUserSystemService} is removed from the cache and immediately
- * re-added when the service package is updated; when
- * {@link #PACKAGE_UPDATE_POLICY_NO_REFRESH}, the service is untouched during the update.
+ * @param servicePackagePolicyFlags a combination of
+ * {@link #PACKAGE_UPDATE_POLICY_NO_REFRESH},
+ * {@link #PACKAGE_UPDATE_POLICY_REFRESH_LAZY},
+ * {@link #PACKAGE_UPDATE_POLICY_REFRESH_EAGER},
+ * {@link #PACKAGE_RESTART_POLICY_NO_REFRESH},
+ * {@link #PACKAGE_RESTART_POLICY_REFRESH_LAZY} or
+ * {@link #PACKAGE_RESTART_POLICY_REFRESH_EAGER}
*/
protected AbstractMasterSystemService(@NonNull Context context,
- @Nullable ServiceNameResolver serviceNameResolver,
- @Nullable String disallowProperty, @PackageUpdatePolicy int packageUpdatePolicy) {
+ @Nullable ServiceNameResolver serviceNameResolver, @Nullable String disallowProperty,
+ @ServicePackagePolicyFlags int servicePackagePolicyFlags) {
super(context);
- mPackageUpdatePolicy = packageUpdatePolicy;
+ final int updatePolicyMask = PACKAGE_UPDATE_POLICY_NO_REFRESH
+ | PACKAGE_UPDATE_POLICY_REFRESH_LAZY | PACKAGE_UPDATE_POLICY_REFRESH_EAGER;
+ if ((servicePackagePolicyFlags & updatePolicyMask) == 0) {
+ // If the package update policy is not set, add the default flag
+ servicePackagePolicyFlags |= PACKAGE_UPDATE_POLICY_REFRESH_LAZY;
+ }
+ final int restartPolicyMask = PACKAGE_RESTART_POLICY_NO_REFRESH
+ | PACKAGE_RESTART_POLICY_REFRESH_LAZY | PACKAGE_RESTART_POLICY_REFRESH_EAGER;
+ if ((servicePackagePolicyFlags & restartPolicyMask) == 0) {
+ // If the package restart policy is not set, add the default flag
+ servicePackagePolicyFlags |= PACKAGE_RESTART_POLICY_REFRESH_LAZY;
+ }
+ mServicePackagePolicyFlags = servicePackagePolicyFlags;
mServiceNameResolver = serviceNameResolver;
if (mServiceNameResolver != null) {
@@ -606,6 +637,20 @@
}
/**
+ * Called after the package data that provides the service for the given user is cleared.
+ */
+ protected void onServicePackageDataClearedLocked(@UserIdInt int userId) {
+ if (verbose) Slog.v(mTag, "onServicePackageDataCleared(" + userId + ")");
+ }
+
+ /**
+ * Called after the package that provides the service for the given user is restarted.
+ */
+ protected void onServicePackageRestartedLocked(@UserIdInt int userId) {
+ if (verbose) Slog.v(mTag, "onServicePackageRestarted(" + userId + ")");
+ }
+
+ /**
* Called after the service is removed from the cache.
*/
@SuppressWarnings("unused")
@@ -677,7 +722,7 @@
final int size = mServicesCache.size();
pw.print(prefix); pw.print("Debug: "); pw.print(realDebug);
pw.print(" Verbose: "); pw.println(realVerbose);
- pw.print("Refresh on package update: "); pw.println(mPackageUpdatePolicy);
+ pw.print("Package policy flags: "); pw.println(mServicePackagePolicyFlags);
if (mUpdatingPackageNames != null) {
pw.print("Packages being updated: "); pw.println(mUpdatingPackageNames);
}
@@ -733,7 +778,12 @@
}
mUpdatingPackageNames.put(userId, packageName);
onServicePackageUpdatingLocked(userId);
- if (mPackageUpdatePolicy != PACKAGE_UPDATE_POLICY_NO_REFRESH) {
+ if ((mServicePackagePolicyFlags & PACKAGE_UPDATE_POLICY_NO_REFRESH) != 0) {
+ if (debug) {
+ Slog.d(mTag, "Holding service for user " + userId + " while package "
+ + activePackageName + " is being updated");
+ }
+ } else {
if (debug) {
Slog.d(mTag, "Removing service for user " + userId
+ " because package " + activePackageName
@@ -741,18 +791,14 @@
}
removeCachedServiceLocked(userId);
- if (mPackageUpdatePolicy == PACKAGE_UPDATE_POLICY_REFRESH_EAGER) {
+ if ((mServicePackagePolicyFlags & PACKAGE_UPDATE_POLICY_REFRESH_EAGER)
+ != 0) {
if (debug) {
Slog.d(mTag, "Eagerly recreating service for user "
+ userId);
}
getServiceForUserLocked(userId);
}
- } else {
- if (debug) {
- Slog.d(mTag, "Holding service for user " + userId + " while package "
- + activePackageName + " is being updated");
- }
}
}
}
@@ -804,7 +850,13 @@
if (!doit) {
return true;
}
- removeCachedServiceLocked(getChangingUserId());
+ final String action = intent.getAction();
+ final int userId = getChangingUserId();
+ if (Intent.ACTION_PACKAGE_RESTARTED.equals(action)) {
+ handleActiveServiceRestartedLocked(activePackageName, userId);
+ } else {
+ removeCachedServiceLocked(userId);
+ }
} else {
handlePackageUpdateLocked(pkg);
}
@@ -813,6 +865,23 @@
return false;
}
+ @Override
+ public void onPackageDataCleared(String packageName, int uid) {
+ if (verbose) Slog.v(mTag, "onPackageDataCleared(): " + packageName);
+ final int userId = getChangingUserId();
+ synchronized (mLock) {
+ final S service = peekServiceForUserLocked(userId);
+ if (service != null) {
+ final ComponentName componentName = service.getServiceComponentName();
+ if (componentName != null) {
+ if (packageName.equals(componentName.getPackageName())) {
+ onServicePackageDataClearedLocked(userId);
+ }
+ }
+ }
+ }
+ }
+
private void handleActiveServiceRemoved(@UserIdInt int userId) {
synchronized (mLock) {
removeCachedServiceLocked(userId);
@@ -824,6 +893,31 @@
}
}
+ private void handleActiveServiceRestartedLocked(String activePackageName,
+ @UserIdInt int userId) {
+ if ((mServicePackagePolicyFlags & PACKAGE_RESTART_POLICY_NO_REFRESH) != 0) {
+ if (debug) {
+ Slog.d(mTag, "Holding service for user " + userId + " while package "
+ + activePackageName + " is being restarted");
+ }
+ } else {
+ if (debug) {
+ Slog.d(mTag, "Removing service for user " + userId
+ + " because package " + activePackageName
+ + " is being restarted");
+ }
+ removeCachedServiceLocked(userId);
+
+ if ((mServicePackagePolicyFlags & PACKAGE_RESTART_POLICY_REFRESH_EAGER) != 0) {
+ if (debug) {
+ Slog.d(mTag, "Eagerly recreating service for user " + userId);
+ }
+ getServiceForUserLocked(userId);
+ }
+ }
+ onServicePackageRestartedLocked(userId);
+ }
+
private String getActiveServicePackageNameLocked() {
final int userId = getChangingUserId();
final S service = peekServiceForUserLocked(userId);
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index 0032e9a..e75f545 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -505,6 +505,11 @@
params.installFlags &= ~PackageManager.INSTALL_REQUEST_DOWNGRADE;
}
+ if (callingUid != Process.SYSTEM_UID) {
+ // Only system_server can use INSTALL_DISABLE_VERIFICATION.
+ params.installFlags &= ~PackageManager.INSTALL_DISABLE_VERIFICATION;
+ }
+
boolean isApex = (params.installFlags & PackageManager.INSTALL_APEX) != 0;
if (params.isStaged || isApex) {
mContext.enforceCallingOrSelfPermission(Manifest.permission.INSTALL_PACKAGES, TAG);
diff --git a/services/core/java/com/android/server/power/PowerManagerService.java b/services/core/java/com/android/server/power/PowerManagerService.java
index dc56b03..aa49ba6 100644
--- a/services/core/java/com/android/server/power/PowerManagerService.java
+++ b/services/core/java/com/android/server/power/PowerManagerService.java
@@ -2735,17 +2735,6 @@
if (mScreenBrightnessBoostInProgress) {
return true;
}
-
- // Because summoning the sandman is asyncronous, there is a time-gap where
- // we release the display suspend blocker before the dream service acquires
- // their own wakelock. Within this gap, we can end up suspending before
- // dream service has a chance to start. To avoid this, we check if we want
- // to doze and the sandman is scheduled and if so, keep the display on until
- // that has passed.
- if (mWakefulness == WAKEFULNESS_DOZING && mSandmanScheduled) {
- return true;
- }
-
// Let the system suspend if the screen is off or dozing.
return false;
}
diff --git a/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java b/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
index bad2947..4315514 100644
--- a/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
+++ b/tests/RollbackTest/StagedRollbackTest/src/com/android/tests/rollback/host/StagedRollbackTest.java
@@ -25,6 +25,7 @@
import org.junit.After;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -63,6 +64,7 @@
* Tests watchdog triggered staged rollbacks involving only apks.
*/
@Test
+ @Ignore("b/139175593 flaky test")
public void testBadApkOnly() throws Exception {
runPhase("testBadApkOnlyEnableRollback");
getDevice().reboot();
diff --git a/tests/net/common/java/android/net/util/SocketUtilsTest.kt b/tests/net/common/java/android/net/util/SocketUtilsTest.kt
new file mode 100644
index 0000000..9c7cfb0
--- /dev/null
+++ b/tests/net/common/java/android/net/util/SocketUtilsTest.kt
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.net.util;
+
+import android.system.NetlinkSocketAddress
+import android.system.Os
+import android.system.OsConstants.AF_INET
+import android.system.OsConstants.ETH_P_ALL
+import android.system.OsConstants.IPPROTO_UDP
+import android.system.OsConstants.RTMGRP_NEIGH
+import android.system.OsConstants.SOCK_DGRAM
+import android.system.PacketSocketAddress
+import androidx.test.filters.SmallTest
+import androidx.test.runner.AndroidJUnit4
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
+import org.junit.Assert.fail
+import org.junit.Test
+import org.junit.runner.RunWith
+
+private const val TEST_INDEX = 123
+private const val TEST_PORT = 555
+@RunWith(AndroidJUnit4::class)
+@SmallTest
+class SocketUtilsTest {
+ @Test
+ fun testMakeNetlinkSocketAddress() {
+ val nlAddress = SocketUtils.makeNetlinkSocketAddress(TEST_PORT, RTMGRP_NEIGH)
+ if (nlAddress is NetlinkSocketAddress) {
+ assertEquals(TEST_PORT, nlAddress.getPortId())
+ assertEquals(RTMGRP_NEIGH, nlAddress.getGroupsMask())
+ } else {
+ fail("Not NetlinkSocketAddress object")
+ }
+ }
+
+ @Test
+ fun testMakePacketSocketAddress() {
+ val pkAddress = SocketUtils.makePacketSocketAddress(ETH_P_ALL, TEST_INDEX)
+ assertTrue("Not PacketSocketAddress object", pkAddress is PacketSocketAddress)
+
+ val ff = 0xff.toByte()
+ val pkAddress2 = SocketUtils.makePacketSocketAddress(TEST_INDEX,
+ byteArrayOf(ff, ff, ff, ff, ff, ff))
+ assertTrue("Not PacketSocketAddress object", pkAddress2 is PacketSocketAddress)
+ }
+
+ @Test
+ fun testCloseSocket() {
+ // Expect no exception happening with null object.
+ SocketUtils.closeSocket(null)
+
+ val fd = Os.socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)
+ assertTrue(fd.valid())
+ SocketUtils.closeSocket(fd)
+ assertFalse(fd.valid())
+ // Expecting socket should be still invalid even closed socket again.
+ SocketUtils.closeSocket(fd)
+ assertFalse(fd.valid())
+ }
+}