summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/ApplicationPackageManager.java11
-rw-r--r--core/java/android/content/om/TEST_MAPPING26
-rw-r--r--core/java/android/content/pm/PackageItemInfo.java2
-rw-r--r--core/java/android/text/util/Linkify.java17
-rw-r--r--core/java/android/webkit/WebView.java16
-rw-r--r--core/java/android/widget/TextView.java4
-rw-r--r--core/java/com/android/internal/policy/DecorView.java7
-rw-r--r--core/res/res/values/attrs.xml3
-rw-r--r--core/res/res/values/config.xml3
-rw-r--r--packages/SystemUI/src/com/android/systemui/ImageWallpaper.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/glwallpaper/GLWallpaperRenderer.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java107
-rw-r--r--packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java66
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java17
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/FloatingRotationButton.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java25
-rw-r--r--packages/overlays/NavigationBarModeGesturalOverlay/res/values/config.xml9
-rw-r--r--services/core/java/com/android/server/appop/AppOpsService.java2
-rw-r--r--services/core/java/com/android/server/appop/HistoricalRegistry.java181
-rw-r--r--services/core/java/com/android/server/wm/DisplayPolicy.java20
-rw-r--r--services/tests/servicestests/src/com/android/server/appop/AppOpsServiceTest.java24
22 files changed, 472 insertions, 88 deletions
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 685eedc31303..769fd487c2a9 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -2754,12 +2754,11 @@ public class ApplicationPackageManager extends PackageManager {
public Drawable loadUnbadgedItemIcon(@NonNull PackageItemInfo itemInfo,
@Nullable ApplicationInfo appInfo) {
if (itemInfo.showUserIcon != UserHandle.USER_NULL) {
- Bitmap bitmap = getUserManager().getUserIcon(itemInfo.showUserIcon);
- if (bitmap == null) {
- return UserIcons.getDefaultUserIcon(
- mContext.getResources(), itemInfo.showUserIcon, /* light= */ false);
- }
- return new BitmapDrawable(bitmap);
+ // Indicates itemInfo is for a different user (e.g. a profile's parent), so use a
+ // generic user icon (users generally lack permission to view each other's actual icons)
+ int targetUserId = itemInfo.showUserIcon;
+ return UserIcons.getDefaultUserIcon(
+ mContext.getResources(), targetUserId, /* light= */ false);
}
Drawable dr = null;
if (itemInfo.packageName != null) {
diff --git a/core/java/android/content/om/TEST_MAPPING b/core/java/android/content/om/TEST_MAPPING
new file mode 100644
index 000000000000..d35dfdbf32c8
--- /dev/null
+++ b/core/java/android/content/om/TEST_MAPPING
@@ -0,0 +1,26 @@
+{
+ "presubmit": [
+ {
+ "name": "FrameworksServicesTests",
+ "options": [
+ {
+ "include-filter": "com.android.server.om"
+ }
+ ]
+ },
+ {
+ "name": "OverlayDeviceTests"
+ },
+ {
+ "name": "OverlayHostTests"
+ },
+ {
+ "name": "CtsAppSecurityHostTestCases",
+ "options": [
+ {
+ "include-filter": "android.appsecurity.cts.OverlayHostTest"
+ }
+ ]
+ }
+ ]
+}
diff --git a/core/java/android/content/pm/PackageItemInfo.java b/core/java/android/content/pm/PackageItemInfo.java
index 081c5ad78762..d0ab8f713de8 100644
--- a/core/java/android/content/pm/PackageItemInfo.java
+++ b/core/java/android/content/pm/PackageItemInfo.java
@@ -159,7 +159,7 @@ public class PackageItemInfo {
public Bundle metaData;
/**
- * If different of UserHandle.USER_NULL, The icon of this item will be the one of that user.
+ * If different of UserHandle.USER_NULL, The icon of this item will represent that user.
* @hide
*/
public int showUserIcon;
diff --git a/core/java/android/text/util/Linkify.java b/core/java/android/text/util/Linkify.java
index 50e7ec30ec3a..df54209bc043 100644
--- a/core/java/android/text/util/Linkify.java
+++ b/core/java/android/text/util/Linkify.java
@@ -67,6 +67,14 @@ import java.util.regex.Pattern;
* create <code>http://example.com</code> when the clickable URL link is
* created.
*
+ * <p class="note"><b>Note:</b> When using {@link #MAP_ADDRESSES} or {@link #ALL}
+ * to match street addresses on API level {@link android.os.Build.VERSION_CODES#O_MR1}
+ * and earlier, methods in this class may throw
+ * {@link android.util.AndroidRuntimeException} or other exceptions if the
+ * device's WebView implementation is currently being updated, because
+ * {@link android.webkit.WebView#findAddress} is required to match street
+ * addresses.
+ *
* @see MatchFilter
* @see TransformFilter
*/
@@ -95,10 +103,11 @@ public class Linkify {
/**
* Bit field indicating that street addresses should be matched in methods that
- * take an options mask. Note that this uses the
- * {@link android.webkit.WebView#findAddress(String) findAddress()} method in
- * {@link android.webkit.WebView} for finding addresses, which has various
- * limitations and has been deprecated.
+ * take an options mask. Note that this should be avoided, as it uses the
+ * {@link android.webkit.WebView#findAddress(String)} method, which has various
+ * limitations and has been deprecated: see the documentation for
+ * {@link android.webkit.WebView#findAddress(String)} for more information.
+ *
* @deprecated use {@link android.view.textclassifier.TextClassifier#generateLinks(
* TextLinks.Request)} instead and avoid it even when targeting API levels where no alternative
* is available.
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 137b67c6e63e..14be73dec41c 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -1603,9 +1603,9 @@ public class WebView extends AbsoluteLayout
}
/**
- * Gets the first substring consisting of the address of a physical
- * location. Currently, only addresses in the United States are detected,
- * and consist of:
+ * Gets the first substring which appears to be the address of a physical
+ * location. Only addresses in the United States can be detected, which
+ * must consist of:
* <ul>
* <li>a house number</li>
* <li>a street name</li>
@@ -1621,9 +1621,17 @@ public class WebView extends AbsoluteLayout
* or abbreviated using USPS standards. The house number may not exceed
* five digits.
*
+ * <p class="note"><b>Note:</b> This function is deprecated and should be
+ * avoided on all API levels, as it cannot detect addresses outside of the
+ * United States and has a high rate of false positives. On API level
+ * {@link android.os.Build.VERSION_CODES#O_MR1} and earlier, it also causes
+ * the entire WebView implementation to be loaded and initialized, which
+ * can throw {@link android.util.AndroidRuntimeException} or other exceptions
+ * if the WebView implementation is currently being updated.
+ *
* @param addr the string to search for addresses
* @return the address, or if no address is found, {@code null}
- * @deprecated this method is superseded by {@link TextClassifier#generateLinks(
+ * @deprecated This method is superseded by {@link TextClassifier#generateLinks(
* android.view.textclassifier.TextLinks.Request)}. Avoid using this method even when targeting
* API levels where no alternative is available.
*/
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index a9e183ad5bf2..073965b35101 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -4960,6 +4960,10 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener
* android.text.util.Linkify#ALL Linkify.ALL} and peers for
* possible values.
*
+ * <p class="note"><b>Note:</b>
+ * {@link android.text.util.Linkify#MAP_ADDRESSES Linkify.MAP_ADDRESSES}
+ * is deprecated and should be avoided; see its documentation.
+ *
* @attr ref android.R.styleable#TextView_autoLink
*/
@android.view.RemotableViewMethod
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index 1a1615026bdf..585a27978c4f 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -1160,16 +1160,17 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
// Note: We don't need to check for IN_SCREEN or INSET_DECOR because unlike the status bar,
// these flags wouldn't make the window draw behind the navigation bar, unless
// LAYOUT_HIDE_NAVIGATION was set.
+ boolean hideNavigation = (sysUiVisibility & SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0;
boolean forceConsumingNavBar = (mForceWindowDrawsBarBackgrounds
&& (attrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) == 0
&& (sysUiVisibility & SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) == 0
- && (sysUiVisibility & SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0)
- || mLastShouldAlwaysConsumeSystemBars;
+ && !hideNavigation)
+ || (mLastShouldAlwaysConsumeSystemBars && hideNavigation);
boolean consumingNavBar =
((attrs.flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0
&& (sysUiVisibility & SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION) == 0
- && (sysUiVisibility & SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0)
+ && !hideNavigation)
|| forceConsumingNavBar;
// If we didn't request fullscreen layout, but we still got it because of the
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 81accdf82b00..2f301946402b 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -1560,7 +1560,8 @@
<flag name="email" value="0x02" />
<!-- Match phone numbers. -->
<flag name="phone" value="0x04" />
- <!-- Match map addresses. -->
+ <!-- Match map addresses.
+ Deprecated: see {@link android.text.util.Linkify#MAP_ADDRESSES}. -->
<flag name="map" value="0x08" />
<!-- Match all patterns (equivalent to web|email|phone|map). -->
<flag name="all" value="0x0f" />
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 9bd56ad2f91d..14abb77aad7d 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -3279,7 +3279,8 @@
various workspace stacks.
0 - Nav bar is always opaque when either the freeform stack or docked stack is visible.
1 - Nav bar is always translucent when the freeform stack is visible, otherwise always
- opaque.
+ opaque.
+ 2 - Nav bar is never forced opaque.
-->
<integer name="config_navBarOpacityMode">0</integer>
diff --git a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
index 84842563cbdc..e9eda4f5577b 100644
--- a/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/ImageWallpaper.java
@@ -83,7 +83,7 @@ public class ImageWallpaper extends WallpaperService {
@Override
public void onCreate(SurfaceHolder surfaceHolder) {
setFixedSizeAllowed(true);
- setOffsetNotificationsEnabled(false);
+ setOffsetNotificationsEnabled(true);
updateSurfaceSize();
}
@@ -96,6 +96,12 @@ public class ImageWallpaper extends WallpaperService {
}
@Override
+ public void onOffsetsChanged(float xOffset, float yOffset, float xOffsetStep,
+ float yOffsetStep, int xPixelOffset, int yPixelOffset) {
+ mRenderer.updateOffsets(xOffset, yOffset);
+ }
+
+ @Override
public void onAmbientModeChanged(boolean inAmbientMode, long animationDuration) {
mRenderer.updateAmbientMode(inAmbientMode,
(mNeedTransition || animationDuration != 0) ? animationDuration : 0);
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/GLWallpaperRenderer.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/GLWallpaperRenderer.java
index 5d85cbf88f4e..b615a5f32835 100644
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/GLWallpaperRenderer.java
+++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/GLWallpaperRenderer.java
@@ -52,6 +52,13 @@ public interface GLWallpaperRenderer {
void updateAmbientMode(boolean inAmbientMode, long duration);
/**
+ * Notify the wallpaper offsets changed.
+ * @param xOffset offset along x axis.
+ * @param yOffset offset along y axis.
+ */
+ void updateOffsets(float xOffset, float yOffset);
+
+ /**
* Ask renderer to report the surface size it needs.
*/
Size reportSurfaceSize();
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java
index 4be7623f90f2..626d0cfed997 100644
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java
+++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageGLWallpaper.java
@@ -33,9 +33,12 @@ import static android.opengl.GLES20.glUniform1i;
import static android.opengl.GLES20.glVertexAttribPointer;
import android.graphics.Bitmap;
+import android.graphics.Rect;
import android.opengl.GLUtils;
import android.util.Log;
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
@@ -91,6 +94,8 @@ class ImageGLWallpaper {
private int mUniTexture;
private int mTextureId;
+ private float[] mCurrentTexCoordinate;
+
ImageGLWallpaper(ImageGLProgram program) {
mProgram = program;
@@ -195,4 +200,106 @@ class ImageGLWallpaper {
glUniform1i(mUniTexture, 0);
}
+ /**
+ * This method adjust s(x-axis), t(y-axis) texture coordinates to get current display area
+ * of texture and will be used during transition.
+ * The adjustment happens if either the width or height of the surface is larger than
+ * corresponding size of the display area.
+ * If both width and height are larger than corresponding size of the display area,
+ * the adjustment will happen at both s, t side.
+ *
+ * @param surface The size of the surface.
+ * @param scissor The display area.
+ * @param xOffset The offset amount along s axis.
+ * @param yOffset The offset amount along t axis.
+ */
+ void adjustTextureCoordinates(Rect surface, Rect scissor, float xOffset, float yOffset) {
+ mCurrentTexCoordinate = TEXTURES.clone();
+
+ if (surface == null || scissor == null) {
+ mTextureBuffer.put(mCurrentTexCoordinate);
+ mTextureBuffer.position(0);
+ return;
+ }
+
+ int surfaceWidth = surface.width();
+ int surfaceHeight = surface.height();
+ int scissorWidth = scissor.width();
+ int scissorHeight = scissor.height();
+
+ if (surfaceWidth > scissorWidth) {
+ // Calculate the new s pos in pixels.
+ float pixelS = (float) Math.round((surfaceWidth - scissorWidth) * xOffset);
+ // Calculate the s pos in texture coordinate.
+ float coordinateS = pixelS / surfaceWidth;
+ // Calculate the percentage occupied by the scissor width in surface width.
+ float surfacePercentageW = (float) scissorWidth / surfaceWidth;
+ // Need also consider the case if surface height is smaller than scissor height.
+ if (surfaceHeight < scissorHeight) {
+ // We will narrow the surface percentage to keep aspect ratio.
+ surfacePercentageW *= (float) surfaceHeight / scissorHeight;
+ }
+ // Determine the final s pos, also limit the legal s pos to prevent from out of range.
+ float s = coordinateS + surfacePercentageW > 1f ? 1f - surfacePercentageW : coordinateS;
+ // Traverse the s pos in texture coordinates array and adjust the s pos accordingly.
+ for (int i = 0; i < mCurrentTexCoordinate.length; i += 2) {
+ // indices 2, 4 and 6 are the end of s coordinates.
+ if (i == 2 || i == 4 || i == 6) {
+ mCurrentTexCoordinate[i] = Math.min(1f, s + surfacePercentageW);
+ } else {
+ mCurrentTexCoordinate[i] = s;
+ }
+ }
+ }
+
+ if (surfaceHeight > scissorHeight) {
+ // Calculate the new t pos in pixels.
+ float pixelT = (float) Math.round((surfaceHeight - scissorHeight) * yOffset);
+ // Calculate the t pos in texture coordinate.
+ float coordinateT = pixelT / surfaceHeight;
+ // Calculate the percentage occupied by the scissor height in surface height.
+ float surfacePercentageH = (float) scissorHeight / surfaceHeight;
+ // Need also consider the case if surface width is smaller than scissor width.
+ if (surfaceWidth < scissorWidth) {
+ // We will narrow the surface percentage to keep aspect ratio.
+ surfacePercentageH *= (float) surfaceWidth / scissorWidth;
+ }
+ // Determine the final t pos, also limit the legal t pos to prevent from out of range.
+ float t = coordinateT + surfacePercentageH > 1f ? 1f - surfacePercentageH : coordinateT;
+ // Traverse the t pos in texture coordinates array and adjust the t pos accordingly.
+ for (int i = 1; i < mCurrentTexCoordinate.length; i += 2) {
+ // indices 1, 3 and 11 are the end of t coordinates.
+ if (i == 1 || i == 3 || i == 11) {
+ mCurrentTexCoordinate[i] = Math.min(1f, t + surfacePercentageH);
+ } else {
+ mCurrentTexCoordinate[i] = t;
+ }
+ }
+ }
+
+ mTextureBuffer.put(mCurrentTexCoordinate);
+ mTextureBuffer.position(0);
+ }
+
+ /**
+ * Called to dump current state.
+ * @param prefix prefix.
+ * @param fd fd.
+ * @param out out.
+ * @param args args.
+ */
+ public void dump(String prefix, FileDescriptor fd, PrintWriter out, String[] args) {
+ StringBuilder sb = new StringBuilder();
+ sb.append('{');
+ if (mCurrentTexCoordinate != null) {
+ for (int i = 0; i < mCurrentTexCoordinate.length; i++) {
+ sb.append(mCurrentTexCoordinate[i]).append(',');
+ if (i == mCurrentTexCoordinate.length - 1) {
+ sb.deleteCharAt(sb.length() - 1);
+ }
+ }
+ }
+ sb.append('}');
+ out.print(prefix); out.print("mTexCoordinates="); out.println(sb.toString());
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java
index 21711fb1890c..93d8dd6146a6 100644
--- a/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java
+++ b/packages/SystemUI/src/com/android/systemui/glwallpaper/ImageWallpaperRenderer.java
@@ -29,6 +29,8 @@ import android.graphics.Rect;
import android.util.Log;
import android.util.MathUtils;
import android.util.Size;
+import android.view.DisplayInfo;
+import android.view.WindowManager;
import com.android.systemui.R;
@@ -41,8 +43,8 @@ import java.io.PrintWriter;
public class ImageWallpaperRenderer implements GLWallpaperRenderer,
ImageRevealHelper.RevealStateListener {
private static final String TAG = ImageWallpaperRenderer.class.getSimpleName();
- private static final float SCALE_VIEWPORT_MIN = 0.98f;
- private static final float SCALE_VIEWPORT_MAX = 1f;
+ private static final float SCALE_VIEWPORT_MIN = 1f;
+ private static final float SCALE_VIEWPORT_MAX = 1.1f;
private final WallpaperManager mWallpaperManager;
private final ImageGLProgram mProgram;
@@ -51,8 +53,13 @@ public class ImageWallpaperRenderer implements GLWallpaperRenderer,
private final ImageRevealHelper mImageRevealHelper;
private SurfaceProxy mProxy;
- private Rect mSurfaceSize;
+ private final Rect mScissor;
+ private final Rect mSurfaceSize = new Rect();
+ private final Rect mViewport = new Rect();
private Bitmap mBitmap;
+ private boolean mScissorMode;
+ private float mXOffset;
+ private float mYOffset;
public ImageWallpaperRenderer(Context context, SurfaceProxy proxy) {
mWallpaperManager = context.getSystemService(WallpaperManager.class);
@@ -60,6 +67,11 @@ public class ImageWallpaperRenderer implements GLWallpaperRenderer,
Log.w(TAG, "WallpaperManager not available");
}
+ DisplayInfo displayInfo = new DisplayInfo();
+ WindowManager wm = context.getSystemService(WindowManager.class);
+ wm.getDefaultDisplay().getDisplayInfo(displayInfo);
+ mScissor = new Rect(0, 0, displayInfo.logicalWidth, displayInfo.logicalHeight);
+
mProxy = proxy;
mProgram = new ImageGLProgram(context);
mWallpaper = new ImageGLWallpaper(mProgram);
@@ -91,7 +103,7 @@ public class ImageWallpaperRenderer implements GLWallpaperRenderer,
mBitmap = mWallpaperManager.getBitmap();
mWallpaperManager.forgetLoadedWallpaper();
if (mBitmap != null) {
- mSurfaceSize = new Rect(0, 0, mBitmap.getWidth(), mBitmap.getHeight());
+ mSurfaceSize.set(0, 0, mBitmap.getWidth(), mBitmap.getHeight());
}
}
return mBitmap != null;
@@ -107,13 +119,17 @@ public class ImageWallpaperRenderer implements GLWallpaperRenderer,
float threshold = mImageProcessHelper.getThreshold();
float reveal = mImageRevealHelper.getReveal();
- glClear(GL_COLOR_BUFFER_BIT);
-
glUniform1f(mWallpaper.getHandle(ImageGLWallpaper.U_AOD2OPACITY), 1);
glUniform1f(mWallpaper.getHandle(ImageGLWallpaper.U_PER85), threshold);
glUniform1f(mWallpaper.getHandle(ImageGLWallpaper.U_REVEAL), reveal);
- scaleViewport(reveal);
+ glClear(GL_COLOR_BUFFER_BIT);
+ // We only need to scale viewport while doing transition.
+ if (mScissorMode) {
+ scaleViewport(reveal);
+ } else {
+ glViewport(0, 0, mSurfaceSize.width(), mSurfaceSize.height());
+ }
mWallpaper.useTexture();
mWallpaper.draw();
}
@@ -124,6 +140,15 @@ public class ImageWallpaperRenderer implements GLWallpaperRenderer,
}
@Override
+ public void updateOffsets(float xOffset, float yOffset) {
+ mXOffset = xOffset;
+ mYOffset = yOffset;
+ int left = (int) ((mSurfaceSize.width() - mScissor.width()) * xOffset);
+ int right = left + mScissor.width();
+ mScissor.set(left, mScissor.top, right, mScissor.bottom);
+ }
+
+ @Override
public Size reportSurfaceSize() {
return new Size(mSurfaceSize.width(), mSurfaceSize.height());
}
@@ -134,15 +159,18 @@ public class ImageWallpaperRenderer implements GLWallpaperRenderer,
}
private void scaleViewport(float reveal) {
- int width = mSurfaceSize.width();
- int height = mSurfaceSize.height();
+ int left = mScissor.left;
+ int top = mScissor.top;
+ int width = mScissor.width();
+ int height = mScissor.height();
// Interpolation between SCALE_VIEWPORT_MAX and SCALE_VIEWPORT_MIN by reveal.
- float vpScaled = MathUtils.lerp(SCALE_VIEWPORT_MAX, SCALE_VIEWPORT_MIN, reveal);
+ float vpScaled = MathUtils.lerp(SCALE_VIEWPORT_MIN, SCALE_VIEWPORT_MAX, reveal);
// Calculate the offset amount from the lower left corner.
- float offset = (SCALE_VIEWPORT_MAX - vpScaled) / 2;
+ float offset = (SCALE_VIEWPORT_MIN - vpScaled) / 2;
// Change the viewport.
- glViewport((int) (width * offset), (int) (height * offset),
+ mViewport.set((int) (left + width * offset), (int) (top + height * offset),
(int) (width * vpScaled), (int) (height * vpScaled));
+ glViewport(mViewport.left, mViewport.top, mViewport.right, mViewport.bottom);
}
@Override
@@ -152,11 +180,19 @@ public class ImageWallpaperRenderer implements GLWallpaperRenderer,
@Override
public void onRevealStart() {
+ mScissorMode = true;
+ // Use current display area of texture.
+ mWallpaper.adjustTextureCoordinates(mSurfaceSize, mScissor, mXOffset, mYOffset);
mProxy.preRender();
}
@Override
public void onRevealEnd() {
+ mScissorMode = false;
+ // reset texture coordinates to use full texture.
+ mWallpaper.adjustTextureCoordinates(null, null, 0, 0);
+ // We need draw full texture back before finishing render.
+ mProxy.requestRender();
mProxy.postRender();
}
@@ -164,6 +200,12 @@ public class ImageWallpaperRenderer implements GLWallpaperRenderer,
public void dump(String prefix, FileDescriptor fd, PrintWriter out, String[] args) {
out.print(prefix); out.print("mProxy="); out.print(mProxy);
out.print(prefix); out.print("mSurfaceSize="); out.print(mSurfaceSize);
+ out.print(prefix); out.print("mScissor="); out.print(mScissor);
+ out.print(prefix); out.print("mViewport="); out.print(mViewport);
+ out.print(prefix); out.print("mScissorMode="); out.print(mScissorMode);
+ out.print(prefix); out.print("mXOffset="); out.print(mXOffset);
+ out.print(prefix); out.print("mYOffset="); out.print(mYOffset);
out.print(prefix); out.print("threshold="); out.print(mImageProcessHelper.getThreshold());
+ mWallpaper.dump(prefix, fd, out, args);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index fd76a79eab2e..ca12deb3904e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -43,6 +43,7 @@ import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.app.IBatteryStats;
import com.android.internal.logging.nano.MetricsProto;
import com.android.internal.widget.LockPatternUtils;
+import com.android.internal.widget.ViewClippingUtil;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.settingslib.Utils;
@@ -118,6 +119,13 @@ public class KeyguardIndicationController implements StateListener,
private final DevicePolicyManager mDevicePolicyManager;
private boolean mDozing;
+ private final ViewClippingUtil.ClippingParameters mClippingParams =
+ new ViewClippingUtil.ClippingParameters() {
+ @Override
+ public boolean shouldFinish(View view) {
+ return view == mIndicationArea;
+ }
+ };
/**
* Creates a new KeyguardIndicationController and registers callbacks.
@@ -413,6 +421,7 @@ public class KeyguardIndicationController implements StateListener,
R.integer.wired_charging_keyguard_text_animation_duration_down);
textView.animate().cancel();
float translation = textView.getTranslationY();
+ ViewClippingUtil.setClippingDeactivated(textView, true, mClippingParams);
textView.animate()
.translationYBy(yTranslation)
.setInterpolator(Interpolators.LINEAR)
@@ -434,6 +443,8 @@ public class KeyguardIndicationController implements StateListener,
@Override
public void onAnimationEnd(Animator animation) {
if (mCancelled) {
+ ViewClippingUtil.setClippingDeactivated(textView, false,
+ mClippingParams);
return;
}
textView.animate()
@@ -445,6 +456,12 @@ public class KeyguardIndicationController implements StateListener,
public void onAnimationCancel(Animator animation) {
textView.setTranslationY(translation);
}
+
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ ViewClippingUtil.setClippingDeactivated(textView, false,
+ mClippingParams);
+ }
});
}
});
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
index 905a8e68f3d1..4ea1ed5b9451 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
@@ -320,7 +320,7 @@ public class NotificationLockscreenUserManagerImpl implements
private boolean hideSilentNotificationsOnLockscreen() {
return Settings.Secure.getInt(mContext.getContentResolver(),
- Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 0) == 0;
+ Settings.Secure.LOCK_SCREEN_SHOW_SILENT_NOTIFICATIONS, 1) == 0;
}
private void setShowLockscreenNotifications(boolean show) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FloatingRotationButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FloatingRotationButton.java
index a4965ba59c6a..f5016da29ad7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/FloatingRotationButton.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/FloatingRotationButton.java
@@ -73,8 +73,7 @@ public class FloatingRotationButton implements RotationButton {
return false;
}
mIsShowing = true;
- int flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
- | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
+ int flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
final WindowManager.LayoutParams lp = new WindowManager.LayoutParams(mDiameter, mDiameter,
mMargin, mMargin, WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL, flags,
PixelFormat.TRANSLUCENT);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 4e4d6a42c4b6..e3dcbeb0ce65 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -303,6 +303,8 @@ public class NotificationPanelView extends PanelView implements
private int mCurrentPanelAlpha;
private final Paint mAlphaPaint = new Paint();
private Runnable mPanelAlphaEndAction;
+ private float mBottomAreaShadeAlpha;
+ private final ValueAnimator mBottomAreaShadeAlphaAnimator;
private AnimatorListenerAdapter mAnimatorListenerAdapter = new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
@@ -366,6 +368,14 @@ public class NotificationPanelView extends PanelView implements
mPulseExpansionHandler = pulseExpansionHandler;
mThemeResId = context.getThemeResId();
dynamicPrivacyController.addListener(this);
+
+ mBottomAreaShadeAlphaAnimator = ValueAnimator.ofFloat(1f, 0);
+ mBottomAreaShadeAlphaAnimator.addUpdateListener(animation -> {
+ mBottomAreaShadeAlpha = (float) animation.getAnimatedValue();
+ updateKeyguardBottomAreaAlpha();
+ });
+ mBottomAreaShadeAlphaAnimator.setDuration(160);
+ mBottomAreaShadeAlphaAnimator.setInterpolator(Interpolators.ALPHA_OUT);
}
/**
@@ -1368,10 +1378,20 @@ public class NotificationPanelView extends PanelView implements
updateDozingVisibilities(false /* animate */);
}
+ maybeAnimateBottomAreaAlpha();
resetHorizontalPanelPosition();
updateQsState();
}
+ private void maybeAnimateBottomAreaAlpha() {
+ mBottomAreaShadeAlphaAnimator.cancel();
+ if (mBarState == StatusBarState.SHADE_LOCKED) {
+ mBottomAreaShadeAlphaAnimator.start();
+ } else {
+ mBottomAreaShadeAlpha = 1f;
+ }
+ }
+
private final Runnable mAnimateKeyguardStatusViewInvisibleEndRunnable = new Runnable() {
@Override
public void run() {
@@ -1980,6 +2000,7 @@ public class NotificationPanelView extends PanelView implements
? 0 : KeyguardBouncer.ALPHA_EXPANSION_THRESHOLD, 1f,
0f, 1f, getExpandedFraction());
float alpha = Math.min(expansionAlpha, 1 - getQsExpansionFraction());
+ alpha *= mBottomAreaShadeAlpha;
mKeyguardBottomArea.setAffordanceAlpha(alpha);
mKeyguardBottomArea.setImportantForAccessibility(alpha == 0f
? IMPORTANT_FOR_ACCESSIBILITY_NO_HIDE_DESCENDANTS
@@ -2890,6 +2911,10 @@ public class NotificationPanelView extends PanelView implements
mNotificationStackScroller.setDark(mDozing, animate, wakeUpTouchLocation);
mKeyguardBottomArea.setDozing(mDozing, animate);
+ if (dozing) {
+ mBottomAreaShadeAlphaAnimator.cancel();
+ }
+
if (mBarState == StatusBarState.KEYGUARD
|| mBarState == StatusBarState.SHADE_LOCKED) {
updateDozingVisibilities(animate);
diff --git a/packages/overlays/NavigationBarModeGesturalOverlay/res/values/config.xml b/packages/overlays/NavigationBarModeGesturalOverlay/res/values/config.xml
index f1d2e0b27353..96ed7b4cc353 100644
--- a/packages/overlays/NavigationBarModeGesturalOverlay/res/values/config.xml
+++ b/packages/overlays/NavigationBarModeGesturalOverlay/res/values/config.xml
@@ -37,6 +37,15 @@
{@link Window#setEnsuringNavigationBarContrastWhenTransparent}. -->
<bool name="config_navBarNeedsScrim">false</bool>
+ <!-- Controls the opacity of the navigation bar depending on the visibility of the
+ various workspace stacks.
+ 0 - Nav bar is always opaque when either the freeform stack or docked stack is visible.
+ 1 - Nav bar is always translucent when the freeform stack is visible, otherwise always
+ opaque.
+ 2 - Nav bar is never forced opaque.
+ -->
+ <integer name="config_navBarOpacityMode">2</integer>
+
<!-- Controls whether seamless rotation should be allowed even though the navbar can move
(which normally prevents seamless rotation). -->
<bool name="config_allowSeamlessRotationDespiteNavBarMoving">true</bool>
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 0a7684553c08..7569363a7134 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -201,7 +201,7 @@ public class AppOpsService extends IAppOpsService.Stub {
@VisibleForTesting
final SparseArray<UidState> mUidStates = new SparseArray<>();
- private final HistoricalRegistry mHistoricalRegistry = new HistoricalRegistry(this);
+ final HistoricalRegistry mHistoricalRegistry = new HistoricalRegistry(this);
long mLastRealtime;
diff --git a/services/core/java/com/android/server/appop/HistoricalRegistry.java b/services/core/java/com/android/server/appop/HistoricalRegistry.java
index 69a1c9f584cb..9cf342c0e4fb 100644
--- a/services/core/java/com/android/server/appop/HistoricalRegistry.java
+++ b/services/core/java/com/android/server/appop/HistoricalRegistry.java
@@ -108,6 +108,12 @@ import java.util.concurrent.TimeUnit;
* must be called with the mInMemoryLock, xxxDMLocked suffix means the method
* must be called with the mOnDiskLock and mInMemoryLock locks acquired in that
* exact order.
+ * <p>
+ * INITIALIZATION: We can initialize persistence only after the system is ready
+ * as we need to check the optional configuration override from the settings
+ * database which is not initialized at the time the app ops service is created.
+ * This means that all entry points that touch persistence should be short
+ * circuited via isPersistenceInitialized() check.
*/
// TODO (bug:122218838): Make sure we handle start of epoch time
// TODO (bug:122218838): Validate changed time is handled correctly
@@ -177,14 +183,33 @@ final class HistoricalRegistry {
// Object managing persistence (read/write)
@GuardedBy("mOnDiskLock")
- private Persistence mPersistence = new Persistence(mBaseSnapshotInterval,
- mIntervalCompressionMultiplier);
+ private Persistence mPersistence;
HistoricalRegistry(@NonNull Object lock) {
mInMemoryLock = lock;
- if (mMode != AppOpsManager.HISTORICAL_MODE_DISABLED) {
- synchronized (mOnDiskLock) {
- synchronized (mInMemoryLock) {
+ }
+
+ void systemReady(@NonNull ContentResolver resolver) {
+ final Uri uri = Settings.Global.getUriFor(Settings.Global.APPOP_HISTORY_PARAMETERS);
+ resolver.registerContentObserver(uri, false, new ContentObserver(
+ FgThread.getHandler()) {
+ @Override
+ public void onChange(boolean selfChange) {
+ updateParametersFromSetting(resolver);
+ }
+ });
+
+ updateParametersFromSetting(resolver);
+
+ synchronized (mOnDiskLock) {
+ synchronized (mInMemoryLock) {
+ if (mMode != AppOpsManager.HISTORICAL_MODE_DISABLED) {
+ // Can be uninitialized if there is no config in the settings table.
+ if (!isPersistenceInitializedMLocked()) {
+ mPersistence = new Persistence(mBaseSnapshotInterval,
+ mIntervalCompressionMultiplier);
+ }
+
// When starting always adjust history to now.
final long lastPersistTimeMills =
mPersistence.getLastPersistTimeMillisDLocked();
@@ -197,16 +222,8 @@ final class HistoricalRegistry {
}
}
- void systemReady(@NonNull ContentResolver resolver) {
- updateParametersFromSetting(resolver);
- final Uri uri = Settings.Global.getUriFor(Settings.Global.APPOP_HISTORY_PARAMETERS);
- resolver.registerContentObserver(uri, false, new ContentObserver(
- FgThread.getHandler()) {
- @Override
- public void onChange(boolean selfChange) {
- updateParametersFromSetting(resolver);
- }
- });
+ private boolean isPersistenceInitializedMLocked() {
+ return mPersistence != null;
}
private void updateParametersFromSetting(@NonNull ContentResolver resolver) {
@@ -274,6 +291,11 @@ final class HistoricalRegistry {
makeRelativeToEpochStart(currentOps, nowMillis);
currentOps.accept(visitor);
+ if(isPersistenceInitializedMLocked()) {
+ Slog.e(LOG_TAG, "Interaction before persistence initialized");
+ return;
+ }
+
final List<HistoricalOps> ops = mPersistence.readHistoryDLocked();
if (ops != null) {
// TODO (bug:122218838): Make sure this is properly dumped
@@ -302,12 +324,21 @@ final class HistoricalRegistry {
void getHistoricalOpsFromDiskRaw(int uid, @NonNull String packageName,
@Nullable String[] opNames, long beginTimeMillis, long endTimeMillis,
@OpFlags int flags, @NonNull RemoteCallback callback) {
- final HistoricalOps result = new HistoricalOps(beginTimeMillis, endTimeMillis);
- mPersistence.collectHistoricalOpsDLocked(result, uid, packageName, opNames,
- beginTimeMillis, endTimeMillis, flags);
- final Bundle payload = new Bundle();
- payload.putParcelable(AppOpsManager.KEY_HISTORICAL_OPS, result);
- callback.sendResult(payload);
+ synchronized (mOnDiskLock) {
+ synchronized (mInMemoryLock) {
+ if (!isPersistenceInitializedMLocked()) {
+ Slog.e(LOG_TAG, "Interaction before persistence initialized");
+ callback.sendResult(new Bundle());
+ return;
+ }
+ final HistoricalOps result = new HistoricalOps(beginTimeMillis, endTimeMillis);
+ mPersistence.collectHistoricalOpsDLocked(result, uid, packageName, opNames,
+ beginTimeMillis, endTimeMillis, flags);
+ final Bundle payload = new Bundle();
+ payload.putParcelable(AppOpsManager.KEY_HISTORICAL_OPS, result);
+ callback.sendResult(payload);
+ }
+ }
}
void getHistoricalOps(int uid, @NonNull String packageName,
@@ -331,6 +362,12 @@ final class HistoricalRegistry {
boolean collectOpsFromDisk;
synchronized (mInMemoryLock) {
+ if (!isPersistenceInitializedMLocked()) {
+ Slog.e(LOG_TAG, "Interaction before persistence initialized");
+ callback.sendResult(new Bundle());
+ return;
+ }
+
currentOps = getUpdatedPendingHistoricalOpsMLocked(currentTimeMillis);
if (!(inMemoryAdjBeginTimeMillis >= currentOps.getEndTimeMillis()
|| inMemoryAdjEndTimeMillis <= currentOps.getBeginTimeMillis())) {
@@ -374,6 +411,10 @@ final class HistoricalRegistry {
@UidState int uidState, @OpFlags int flags) {
synchronized (mInMemoryLock) {
if (mMode == AppOpsManager.HISTORICAL_MODE_ENABLED_ACTIVE) {
+ if (!isPersistenceInitializedMLocked()) {
+ Slog.e(LOG_TAG, "Interaction before persistence initialized");
+ return;
+ }
getUpdatedPendingHistoricalOpsMLocked(System.currentTimeMillis())
.increaseAccessCount(op, uid, packageName, uidState, flags, 1);
}
@@ -384,6 +425,10 @@ final class HistoricalRegistry {
@UidState int uidState, @OpFlags int flags) {
synchronized (mInMemoryLock) {
if (mMode == AppOpsManager.HISTORICAL_MODE_ENABLED_ACTIVE) {
+ if (!isPersistenceInitializedMLocked()) {
+ Slog.e(LOG_TAG, "Interaction before persistence initialized");
+ return;
+ }
getUpdatedPendingHistoricalOpsMLocked(System.currentTimeMillis())
.increaseRejectCount(op, uid, packageName, uidState, flags, 1);
}
@@ -394,6 +439,10 @@ final class HistoricalRegistry {
@UidState int uidState, @OpFlags int flags, long increment) {
synchronized (mInMemoryLock) {
if (mMode == AppOpsManager.HISTORICAL_MODE_ENABLED_ACTIVE) {
+ if (!isPersistenceInitializedMLocked()) {
+ Slog.e(LOG_TAG, "Interaction before persistence initialized");
+ return;
+ }
getUpdatedPendingHistoricalOpsMLocked(System.currentTimeMillis())
.increaseAccessDuration(op, uid, packageName, uidState, flags, increment);
}
@@ -404,6 +453,8 @@ final class HistoricalRegistry {
long baseSnapshotInterval, long intervalCompressionMultiplier) {
synchronized (mOnDiskLock) {
synchronized (mInMemoryLock) {
+ // NOTE: We allow this call if persistence is not initialized as
+ // it is a part of the persistence initialization process.
boolean resampleHistory = false;
Slog.i(LOG_TAG, "New history parameters: mode:"
+ AppOpsManager.historicalModeToString(mMode) + " baseSnapshotInterval:"
@@ -412,7 +463,7 @@ final class HistoricalRegistry {
if (mMode != mode) {
mMode = mode;
if (mMode == AppOpsManager.HISTORICAL_MODE_DISABLED) {
- clearHistoryOnDiskLocked();
+ clearHistoryOnDiskDLocked();
}
}
if (mBaseSnapshotInterval != baseSnapshotInterval) {
@@ -433,6 +484,10 @@ final class HistoricalRegistry {
void offsetHistory(long offsetMillis) {
synchronized (mOnDiskLock) {
synchronized (mInMemoryLock) {
+ if (!isPersistenceInitializedMLocked()) {
+ Slog.e(LOG_TAG, "Interaction before persistence initialized");
+ return;
+ }
final List<HistoricalOps> history = mPersistence.readHistoryDLocked();
clearHistory();
if (history != null) {
@@ -453,6 +508,10 @@ final class HistoricalRegistry {
void addHistoricalOps(HistoricalOps ops) {
final List<HistoricalOps> pendingWrites;
synchronized (mInMemoryLock) {
+ if (!isPersistenceInitializedMLocked()) {
+ Slog.e(LOG_TAG, "Interaction before persistence initialized");
+ return;
+ }
// The history files start from mBaseSnapshotInterval - take this into account.
ops.offsetBeginAndEndTime(mBaseSnapshotInterval);
mPendingWrites.offerFirst(ops);
@@ -468,6 +527,10 @@ final class HistoricalRegistry {
}
void resetHistoryParameters() {
+ if (!isPersistenceInitializedMLocked()) {
+ Slog.e(LOG_TAG, "Interaction before persistence initialized");
+ return;
+ }
setHistoryParameters(DEFAULT_MODE, DEFAULT_SNAPSHOT_INTERVAL_MILLIS,
DEFAULT_COMPRESSION_STEP);
}
@@ -475,6 +538,10 @@ final class HistoricalRegistry {
void clearHistory(int uid, String packageName) {
synchronized (mOnDiskLock) {
synchronized (mInMemoryLock) {
+ if (!isPersistenceInitializedMLocked()) {
+ Slog.e(LOG_TAG, "Interaction before persistence initialized");
+ return;
+ }
if (mMode != AppOpsManager.HISTORICAL_MODE_ENABLED_ACTIVE) {
return;
}
@@ -493,18 +560,24 @@ final class HistoricalRegistry {
void clearHistory() {
synchronized (mOnDiskLock) {
- clearHistoryOnDiskLocked();
+ synchronized (mInMemoryLock) {
+ if (!isPersistenceInitializedMLocked()) {
+ Slog.e(LOG_TAG, "Interaction before persistence initialized");
+ return;
+ }
+ clearHistoryOnDiskDLocked();
+ }
}
}
- private void clearHistoryOnDiskLocked() {
+ private void clearHistoryOnDiskDLocked() {
BackgroundThread.getHandler().removeMessages(MSG_WRITE_PENDING_HISTORY);
synchronized (mInMemoryLock) {
mCurrentHistoricalOps = null;
mNextPersistDueTimeMillis = System.currentTimeMillis();
mPendingWrites.clear();
}
- mPersistence.clearHistoryDLocked();
+ Persistence.clearHistoryDLocked();
}
private @NonNull HistoricalOps getUpdatedPendingHistoricalOpsMLocked(long now) {
@@ -639,7 +712,7 @@ final class HistoricalRegistry {
mIntervalCompressionMultiplier = intervalCompressionMultiplier;
}
- private final AtomicDirectory mHistoricalAppOpsDir = new AtomicDirectory(
+ private static final AtomicDirectory sHistoricalAppOpsDir = new AtomicDirectory(
new File(new File(Environment.getDataSystemDirectory(), "appops"), "history"));
private File generateFile(@NonNull File baseDir, int depth) {
@@ -663,8 +736,8 @@ final class HistoricalRegistry {
persistHistoricalOpsDLocked(historicalOps);
}
- void clearHistoryDLocked() {
- mHistoricalAppOpsDir.delete();
+ static void clearHistoryDLocked() {
+ sHistoricalAppOpsDir.delete();
}
void persistHistoricalOpsDLocked(@NonNull List<HistoricalOps> ops) {
@@ -673,8 +746,8 @@ final class HistoricalRegistry {
enforceOpsWellFormed(ops);
}
try {
- final File newBaseDir = mHistoricalAppOpsDir.startWrite();
- final File oldBaseDir = mHistoricalAppOpsDir.getBackupDirectory();
+ final File newBaseDir = sHistoricalAppOpsDir.startWrite();
+ final File oldBaseDir = sHistoricalAppOpsDir.getBackupDirectory();
final HistoricalFilesInvariant filesInvariant;
if (DEBUG) {
filesInvariant = new HistoricalFilesInvariant();
@@ -686,10 +759,10 @@ final class HistoricalRegistry {
if (DEBUG) {
filesInvariant.stopTracking(newBaseDir);
}
- mHistoricalAppOpsDir.finishWrite();
+ sHistoricalAppOpsDir.finishWrite();
} catch (Throwable t) {
wtf("Failed to write historical app ops, restoring backup", t, null);
- mHistoricalAppOpsDir.failWrite();
+ sHistoricalAppOpsDir.failWrite();
}
}
@@ -715,22 +788,36 @@ final class HistoricalRegistry {
long getLastPersistTimeMillisDLocked() {
File baseDir = null;
try {
- baseDir = mHistoricalAppOpsDir.startRead();
+ baseDir = sHistoricalAppOpsDir.startRead();
final File[] files = baseDir.listFiles();
if (files != null && files.length > 0) {
- final Set<File> historyFiles = new ArraySet<>();
- Collections.addAll(historyFiles, files);
- for (int i = 0;; i++) {
- final File file = generateFile(baseDir, i);
- if (historyFiles.contains(file)) {
- return file.lastModified();
+ File shortestFile = null;
+ for (File candidate : files) {
+ final String candidateName = candidate.getName();
+ if (!candidateName.endsWith(HISTORY_FILE_SUFFIX)) {
+ continue;
+ }
+ if (shortestFile == null) {
+ shortestFile = candidate;
+ } else if (candidateName.length() < shortestFile.getName().length()) {
+ shortestFile = candidate;
}
}
+ if (shortestFile == null) {
+ return 0;
+ }
+ final String shortestNameNoExtension = shortestFile.getName()
+ .replace(HISTORY_FILE_SUFFIX, "");
+ try {
+ return Long.parseLong(shortestNameNoExtension);
+ } catch (NumberFormatException e) {
+ return 0;
+ }
}
- mHistoricalAppOpsDir.finishRead();
+ sHistoricalAppOpsDir.finishRead();
} catch (Throwable e) {
wtf("Error reading historical app ops. Deleting history.", e, baseDir);
- mHistoricalAppOpsDir.delete();
+ sHistoricalAppOpsDir.delete();
}
return 0;
}
@@ -755,7 +842,7 @@ final class HistoricalRegistry {
long filterBeginTimeMillis, long filterEndTimeMillis, @OpFlags int filterFlags) {
File baseDir = null;
try {
- baseDir = mHistoricalAppOpsDir.startRead();
+ baseDir = sHistoricalAppOpsDir.startRead();
final HistoricalFilesInvariant filesInvariant;
if (DEBUG) {
filesInvariant = new HistoricalFilesInvariant();
@@ -770,11 +857,11 @@ final class HistoricalRegistry {
if (DEBUG) {
filesInvariant.stopTracking(baseDir);
}
- mHistoricalAppOpsDir.finishRead();
+ sHistoricalAppOpsDir.finishRead();
return ops;
} catch (Throwable t) {
wtf("Error reading historical app ops. Deleting history.", t, baseDir);
- mHistoricalAppOpsDir.delete();
+ sHistoricalAppOpsDir.delete();
}
return null;
}
@@ -1241,7 +1328,7 @@ final class HistoricalRegistry {
private void writeHistoricalOpsDLocked(@Nullable List<HistoricalOps> allOps,
long intervalOverflowMillis, @NonNull File file) throws IOException {
- final FileOutputStream output = mHistoricalAppOpsDir.openWrite(file);
+ final FileOutputStream output = sHistoricalAppOpsDir.openWrite(file);
try {
final XmlSerializer serializer = Xml.newSerializer();
serializer.setOutput(output, StandardCharsets.UTF_8.name());
@@ -1263,9 +1350,9 @@ final class HistoricalRegistry {
}
serializer.endTag(null, TAG_HISTORY);
serializer.endDocument();
- mHistoricalAppOpsDir.closeWrite(output);
+ sHistoricalAppOpsDir.closeWrite(output);
} catch (IOException e) {
- mHistoricalAppOpsDir.failWrite(output);
+ sHistoricalAppOpsDir.failWrite(output);
throw e;
}
}
diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java
index 21f01ff38a0e..7badc7a43774 100644
--- a/services/core/java/com/android/server/wm/DisplayPolicy.java
+++ b/services/core/java/com/android/server/wm/DisplayPolicy.java
@@ -198,6 +198,8 @@ public class DisplayPolicy {
private static final int NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED = 0;
// Nav bar is always translucent when the freeform stack is visible, otherwise always opaque.
private static final int NAV_BAR_TRANSLUCENT_WHEN_FREEFORM_OPAQUE_OTHERWISE = 1;
+ // Nav bar is never forced opaque.
+ private static final int NAV_BAR_FORCE_TRANSPARENT = 2;
/**
* These are the system UI flags that, when changing, can cause the layout
@@ -3288,8 +3290,10 @@ public class DisplayPolicy {
: mTopFullscreenOpaqueWindowState;
vis = mStatusBarController.applyTranslucentFlagLw(fullscreenTransWin, vis, oldVis);
vis = mNavigationBarController.applyTranslucentFlagLw(fullscreenTransWin, vis, oldVis);
- final int dockedVis = mStatusBarController.applyTranslucentFlagLw(
+ int dockedVis = mStatusBarController.applyTranslucentFlagLw(
mTopDockedOpaqueWindowState, 0, 0);
+ dockedVis = mNavigationBarController.applyTranslucentFlagLw(
+ mTopDockedOpaqueWindowState, dockedVis, 0);
final boolean fullscreenDrawsStatusBarBackground =
drawsStatusBarBackground(vis, mTopFullscreenOpaqueWindowState);
@@ -3297,6 +3301,8 @@ public class DisplayPolicy {
drawsStatusBarBackground(dockedVis, mTopDockedOpaqueWindowState);
final boolean fullscreenDrawsNavBarBackground =
drawsNavigationBarBackground(vis, mTopFullscreenOpaqueWindowState);
+ final boolean dockedDrawsNavigationBarBackground =
+ drawsNavigationBarBackground(dockedVis, mTopDockedOpaqueWindowState);
// prevent status bar interaction from clearing certain flags
int type = win.getAttrs().type;
@@ -3321,7 +3327,7 @@ public class DisplayPolicy {
}
vis = configureNavBarOpacity(vis, dockedStackVisible, freeformStackVisible, resizing,
- fullscreenDrawsNavBarBackground);
+ fullscreenDrawsNavBarBackground, dockedDrawsNavigationBarBackground);
// update status bar
boolean immersiveSticky =
@@ -3439,8 +3445,14 @@ public class DisplayPolicy {
*/
private int configureNavBarOpacity(int visibility, boolean dockedStackVisible,
boolean freeformStackVisible, boolean isDockedDividerResizing,
- boolean fullscreenDrawsBackground) {
- if (mNavBarOpacityMode == NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED) {
+ boolean fullscreenDrawsBackground, boolean dockedDrawsNavigationBarBackground) {
+ if (mNavBarOpacityMode == NAV_BAR_FORCE_TRANSPARENT) {
+ if (fullscreenDrawsBackground && dockedDrawsNavigationBarBackground) {
+ visibility = setNavBarTransparentFlag(visibility);
+ } else if (dockedStackVisible) {
+ visibility = setNavBarOpaqueFlag(visibility);
+ }
+ } else if (mNavBarOpacityMode == NAV_BAR_OPAQUE_WHEN_FREEFORM_OR_DOCKED) {
if (dockedStackVisible || freeformStackVisible || isDockedDividerResizing) {
visibility = setNavBarOpaqueFlag(visibility);
} else if (fullscreenDrawsBackground) {
diff --git a/services/tests/servicestests/src/com/android/server/appop/AppOpsServiceTest.java b/services/tests/servicestests/src/com/android/server/appop/AppOpsServiceTest.java
index d90117905de6..552058f6e8c2 100644
--- a/services/tests/servicestests/src/com/android/server/appop/AppOpsServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/appop/AppOpsServiceTest.java
@@ -37,12 +37,15 @@ import android.os.Handler;
import android.os.HandlerThread;
import android.os.Process;
import android.os.RemoteCallback;
+import android.provider.Settings;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+import org.junit.AfterClass;
import org.junit.Before;
+import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -68,11 +71,14 @@ public class AppOpsServiceTest {
private File mAppOpsFile;
private Context mContext;
private Handler mHandler;
+ private AppOpsManager mAppOpsManager;
private AppOpsService mAppOpsService;
private String mMyPackageName;
private int mMyUid;
private long mTestStartMillis;
+ private static String sDefaultAppopHistoryParameters;
+
@Before
public void setUp() {
mContext = InstrumentationRegistry.getTargetContext();
@@ -88,11 +94,29 @@ public class AppOpsServiceTest {
mMyPackageName = mContext.getOpPackageName();
mMyUid = Process.myUid();
+ mAppOpsManager = mContext.getSystemService(AppOpsManager.class);
mAppOpsService = new AppOpsService(mAppOpsFile, mHandler);
+ mAppOpsService.mHistoricalRegistry.systemReady(mContext.getContentResolver());
mAppOpsService.mContext = mContext;
mTestStartMillis = System.currentTimeMillis();
}
+ @BeforeClass
+ public static void configureDesiredAppopHistoryParameters() {
+ final Context context = InstrumentationRegistry.getTargetContext();
+ sDefaultAppopHistoryParameters = Settings.Global.getString(context.getContentResolver(),
+ Settings.Global.APPOP_HISTORY_PARAMETERS);
+ Settings.Global.putString(InstrumentationRegistry.getTargetContext().getContentResolver(),
+ Settings.Global.APPOP_HISTORY_PARAMETERS, null);
+ }
+
+ @AfterClass
+ public static void restoreDefaultAppopHistoryParameters() {
+ Settings.Global.putString(InstrumentationRegistry.getTargetContext().getContentResolver(),
+ Settings.Global.APPOP_HISTORY_PARAMETERS,
+ sDefaultAppopHistoryParameters);
+ }
+
@Test
public void testGetOpsForPackage_noOpsLogged() {
assertThat(getLoggedOps()).isNull();