Merge "Logging improvements when NetworkCapabilities change" am: f60a38e152
am: bdfb4ee19c
Change-Id: Ie7f90ac6b8073e756ff14afcaac7ed291b165e87
diff --git a/Android.mk b/Android.mk
index 8b74585..88a5b66 100644
--- a/Android.mk
+++ b/Android.mk
@@ -965,7 +965,7 @@
-since $(SRC_API_DIR)/23.txt 23 \
-since $(SRC_API_DIR)/24.txt 24 \
-since $(SRC_API_DIR)/25.txt 25 \
- -since ./frameworks/base/api/current.txt O \
+ -since $(SRC_API_DIR)/26.txt 26 \
-werror -hide 111 -hide 113 -hide 121 \
-overview $(LOCAL_PATH)/core/java/overview.html \
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index bc6e9cd..0ff3215 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -6416,17 +6416,7 @@
*/
@Deprecated
public boolean requestVisibleBehind(boolean visible) {
- if (!mResumed) {
- // Do not permit paused or stopped activities to do this.
- visible = false;
- }
- try {
- mVisibleBehind = ActivityManager.getService()
- .requestVisibleBehind(mToken, visible) && visible;
- } catch (RemoteException e) {
- mVisibleBehind = false;
- }
- return mVisibleBehind;
+ return false;
}
/**
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index f398c8d..aca2d91 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -360,6 +360,13 @@
FIRST_START_NON_FATAL_ERROR_CODE + 1;
/**
+ * Result for IActivityManaqer.startActivity: a new activity start was aborted. Never returned
+ * externally.
+ * @hide
+ */
+ public static final int START_ABORTED = FIRST_START_NON_FATAL_ERROR_CODE + 2;
+
+ /**
* Flag for IActivityManaqer.startActivity: do special start mode where
* a new activity is launched only if it is needed.
* @hide
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index e5c4208..4df633f 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -281,7 +281,8 @@
public PermissionInfo getPermissionInfo(String name, int flags)
throws NameNotFoundException {
try {
- PermissionInfo pi = mPM.getPermissionInfo(name, flags);
+ PermissionInfo pi = mPM.getPermissionInfo(name,
+ mContext.getOpPackageName(), flags);
if (pi != null) {
return pi;
}
diff --git a/core/java/android/app/ProgressDialog.java b/core/java/android/app/ProgressDialog.java
index 8ec9622..8a083eb 100644
--- a/core/java/android/app/ProgressDialog.java
+++ b/core/java/android/app/ProgressDialog.java
@@ -42,8 +42,12 @@
*
* <p>The progress range is 0 to {@link #getMax() max}.</p>
*
- * @deprecated Use a progress indicator such as ProgressBar inline inside of
- * an activity rather than using this modal dialog.
+ * @deprecated <code>ProgressDialog</code> is a modal dialog, which prevents the
+ * user from interacting with the app. Instead of using this class, you should
+ * use a progress indicator like {@link android.widget.ProgressBar}, which can
+ * be embedded in your app's UI. Alternatively, you can use a
+ * <a href="/guide/topics/ui/notifiers/notifications.html">notification</a>
+ * to inform the user of the task's progress.
*/
@Deprecated
public class ProgressDialog extends AlertDialog {
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 6c62f5e..48fa3a8 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -127,8 +127,8 @@
* File creation mode: allow all other applications to have read access to
* the created file.
* <p>
- * As of {@link android.os.Build.VERSION_CODES#N} attempting to use this
- * mode will throw a {@link SecurityException}.
+ * Starting from {@link android.os.Build.VERSION_CODES#N}, attempting to use this
+ * mode throws a {@link SecurityException}.
*
* @deprecated Creating world-readable files is very dangerous, and likely
* to cause security holes in applications. It is strongly
@@ -147,7 +147,7 @@
* File creation mode: allow all other applications to have write access to
* the created file.
* <p>
- * As of {@link android.os.Build.VERSION_CODES#N} attempting to use this
+ * Starting from {@link android.os.Build.VERSION_CODES#N}, attempting to use this
* mode will throw a {@link SecurityException}.
*
* @deprecated Creating world-writable files is very dangerous, and likely
@@ -1127,13 +1127,47 @@
* </ul>
* <p>
* Starting in {@link android.os.Build.VERSION_CODES#KITKAT}, no permissions
- * are required to read or write to the returned path; it's always
- * accessible to the calling app. This only applies to paths generated for
- * package name of the calling application. To access paths belonging to
- * other packages,
- * {@link android.Manifest.permission#WRITE_EXTERNAL_STORAGE} and/or
- * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} are required.
+ * are required to read or write to the path that this method returns.
+ * However, starting from {@link android.os.Build.VERSION_CODES#M},
+ * to read the OBB expansion files, you must declare the
+ * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} permission in the app manifest and ask for
+ * permission at runtime as follows:
+ * </p>
* <p>
+ * {@code <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
+ * android:maxSdkVersion="23" />}
+ * </p>
+ * <p>
+ * Starting from {@link android.os.Build.VERSION_CODES#N},
+ * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE}
+ * permission is not required, so don’t ask for this
+ * permission at runtime. To handle both cases, your app must first try to read the OBB file,
+ * and if it fails, you must request
+ * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} permission at runtime.
+ * </p>
+ *
+ * <p>
+ * The following code snippet shows how to do this:
+ * </p>
+ *
+ * <pre>
+ * File obb = new File(obb_filename);
+ * boolean open_failed = false;
+ *
+ * try {
+ * BufferedReader br = new BufferedReader(new FileReader(obb));
+ * open_failed = false;
+ * ReadObbFile(br);
+ * } catch (IOException e) {
+ * open_failed = true;
+ * }
+ *
+ * if (open_failed) {
+ * // request READ_EXTERNAL_STORAGE permission before reading OBB file
+ * ReadObbFileWithPermission();
+ * }
+ * </pre>
+ *
* On devices with multiple users (as described by {@link UserManager}),
* multiple users may share the same OBB storage location. Applications
* should ensure that multiple instances running under different users don't
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index e8e0eb3..126a775 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -71,7 +71,7 @@
String[] currentToCanonicalPackageNames(in String[] names);
String[] canonicalToCurrentPackageNames(in String[] names);
- PermissionInfo getPermissionInfo(String name, int flags);
+ PermissionInfo getPermissionInfo(String name, String packageName, int flags);
ParceledListSlice queryPermissionsByGroup(String group, int flags);
diff --git a/core/java/android/content/pm/LauncherActivityInfo.java b/core/java/android/content/pm/LauncherActivityInfo.java
index 358787e..e9c9588 100644
--- a/core/java/android/content/pm/LauncherActivityInfo.java
+++ b/core/java/android/content/pm/LauncherActivityInfo.java
@@ -20,12 +20,10 @@
import android.content.Context;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Resources;
-import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.DisplayMetrics;
-import android.util.Log;
/**
* A representation of an activity that can belong to this user or a managed
@@ -173,12 +171,6 @@
public Drawable getBadgedIcon(int density) {
Drawable originalIcon = getIcon(density);
- if (originalIcon instanceof BitmapDrawable) {
- // TODO: Go through LauncherAppsService
- return mPm.getUserBadgedIcon(originalIcon, mUser);
- } else {
- Log.e(TAG, "Unable to create badged icon for " + mActivityInfo);
- }
- return originalIcon;
+ return mPm.getUserBadgedIcon(originalIcon, mUser);
}
}
diff --git a/core/java/android/content/pm/LauncherApps.java b/core/java/android/content/pm/LauncherApps.java
index ed41e79..aa9562f 100644
--- a/core/java/android/content/pm/LauncherApps.java
+++ b/core/java/android/content/pm/LauncherApps.java
@@ -608,15 +608,15 @@
}
/**
- * Get {@link ApplicationInfo} for a profile
+ * Returns {@link ApplicationInfo} about an application installed for a specific user profile.
*
* @param packageName The package name of the application
* @param flags Additional option flags {@link PackageManager#getApplicationInfo}
* @param user The UserHandle of the profile.
*
- * @return An {@link ApplicationInfo} containing information about the package or
- * null if the package isn't installed for the given user, or the target user
- * is not enabled.
+ * @return {@link ApplicationInfo} containing information about the package. Returns
+ * {@code null} if the package isn't installed for the given profile, or the profile
+ * isn't enabled.
*/
public ApplicationInfo getApplicationInfo(@NonNull String packageName,
@ApplicationInfoFlags int flags, @NonNull UserHandle user)
diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java
index 4bc62b1..e1cd451 100644
--- a/core/java/android/hardware/SensorManager.java
+++ b/core/java/android/hardware/SensorManager.java
@@ -894,8 +894,9 @@
* to free up resource in sensor system associated with the direct channel.
*
* @param mem A {@link android.os.MemoryFile} shared memory object.
- * @return A {@link android.hardware.SensorDirectChannel} object if successful, null otherwise.
+ * @return A {@link android.hardware.SensorDirectChannel} object.
* @throws NullPointerException when mem is null.
+ * @throws UncheckedIOException if not able to create channel.
* @see SensorDirectChannel#close()
* @see #configureDirectChannel(SensorDirectChannel, Sensor, int)
*/
@@ -916,9 +917,9 @@
* to free up resource in sensor system associated with the direct channel.
*
* @param mem A {@link android.hardware.HardwareBuffer} shared memory object.
- * @return A {@link android.hardware.SensorDirectChannel} object if successful,
- * null otherwise.
+ * @return A {@link android.hardware.SensorDirectChannel} object.
* @throws NullPointerException when mem is null.
+ * @throws UncheckedIOException if not able to create channel.
* @see SensorDirectChannel#close()
* @see #configureDirectChannel(SensorDirectChannel, Sensor, int)
*/
diff --git a/core/java/android/net/VpnService.java b/core/java/android/net/VpnService.java
index 2d9860c..4b79cbb 100644
--- a/core/java/android/net/VpnService.java
+++ b/core/java/android/net/VpnService.java
@@ -99,7 +99,7 @@
* shut down the tunnel gracefully.</li>
* </ol>
*
- * <p>Services extended this class need to be declared with appropriate
+ * <p>Services extending this class need to be declared with an appropriate
* permission and intent filter. Their access must be secured by
* {@link android.Manifest.permission#BIND_VPN_SERVICE} permission, and
* their intent filter must match {@link #SERVICE_INTERFACE} action. Here
@@ -112,6 +112,13 @@
* </intent-filter>
* </service></pre>
*
+ * <p> The Android system starts a VPN in the background by calling
+ * {@link android.content.Context#startService startService()}. In Android 8.0
+ * (API level 26) and higher, the system places VPN apps on the temporary
+ * whitelist for a short period so the app can start in the background. The VPN
+ * app must promote itself to the foreground after it's launched or the system
+ * will shut down the app.
+ *
* @see Builder
*/
public class VpnService extends Service {
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index a7fc2e7..de0d5d76 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -303,10 +303,12 @@
public static final String DISALLOW_DEBUGGING_FEATURES = "no_debugging_features";
/**
- * Specifies if a user is disallowed from configuring VPN.
- * The default value is <code>false</code>.
- * This restriction has an effect in a managed profile only from
- * {@link android.os.Build.VERSION_CODES#M}
+ * Specifies if a user is disallowed from configuring a VPN. The default value is
+ * <code>false</code>. This restriction has an effect when set by device owners and, in Android
+ * 6.0 ({@linkplain android.os.Build.VERSION_CODES#M API level 23}) or higher, profile owners.
+ * <p>This restriction also prevents VPNs from starting. However, in Android 7.0
+ * ({@linkplain android.os.Build.VERSION_CODES#N API level 24}) or higher, the system does
+ * start always-on VPNs created by the device or profile owner.
*
* <p>Key for user restrictions.
* <p>Type: Boolean
@@ -389,10 +391,13 @@
public static final String DISALLOW_ADD_MANAGED_PROFILE = "no_add_managed_profile";
/**
- * Specifies if a user is disallowed from disabling application verification.
- * Starting from {@link android.os.Build.VERSION_CODES#O}, application verification
- * is enforced across all users on the device if a profile owner or device owner sets
- * this restriction to <code>true</code>. The default value is <code>false</code>.
+ * Specifies if a user is disallowed from disabling application verification. The default
+ * value is <code>false</code>.
+ *
+ * <p>In Android 8.0 ({@linkplain android.os.Build.VERSION_CODES#O API level 26}) and higher,
+ * this is a global user restriction. If a device owner or profile owner sets this restriction,
+ * the system enforces app verification across all users on the device. Running in earlier
+ * Android versions, this restriction affects only the profile that sets it.
*
* <p>Key for user restrictions.
* <p>Type: Boolean
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index a82127c..ca7f179 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1422,10 +1422,10 @@
* to the caller package.
*
* <p>
- * <b>NOTE: </b> applications should call
+ * <b>NOTE: </b> Applications should call
* {@link android.view.autofill.AutofillManager#hasEnabledAutofillServices()} and
- * {@link android.view.autofill.AutofillManager#isAutofillSupported()} first, and only
- * broadcast this intent if they return {@code false} and {@code true} respectively.
+ * {@link android.view.autofill.AutofillManager#isAutofillSupported()}, and only use this action
+ * to start an activity if they return {@code false} and {@code true} respectively.
*/
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
public static final String ACTION_REQUEST_SET_AUTOFILL_SERVICE =
diff --git a/core/java/android/util/Log.java b/core/java/android/util/Log.java
index 951aa8d..8691136 100644
--- a/core/java/android/util/Log.java
+++ b/core/java/android/util/Log.java
@@ -30,8 +30,9 @@
/**
* API for sending log output.
*
- * <p>Generally, use the Log.v() Log.d() Log.i() Log.w() and Log.e()
- * methods.
+ * <p>Generally, you should use the {@link #v Log.v()}, {@link #d Log.d()},
+ * {@link #i Log.i()}, {@link #w Log.w()}, and {@link #e Log.e()} methods to write logs.
+ * You can then <a href="{@docRoot}studio/debug/am-logcat.html">view the logs in logcat</a>.
*
* <p>The order in terms of verbosity, from least to most is
* ERROR, WARN, INFO, DEBUG, VERBOSE. Verbose should never be compiled
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index b035b7f..a19f05c 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -491,10 +491,10 @@
if (myHeight <= 0) myHeight = getHeight();
final boolean formatChanged = mFormat != mRequestedFormat;
- final boolean creating = (mSurfaceControl == null || formatChanged)
+ final boolean visibleChanged = mVisible != mRequestedVisible;
+ final boolean creating = (mSurfaceControl == null || formatChanged || visibleChanged)
&& mRequestedVisible;
final boolean sizeChanged = mSurfaceWidth != myWidth || mSurfaceHeight != myHeight;
- final boolean visibleChanged = mVisible != mRequestedVisible;
final boolean windowVisibleChanged = mWindowVisibility != mLastWindowVisibility;
boolean redrawNeeded = false;
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 4882165..25c02d1 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -724,6 +724,8 @@
* @attr ref android.R.styleable#View_nextFocusUp
* @attr ref android.R.styleable#View_onClick
* @attr ref android.R.styleable#View_padding
+ * @attr ref android.R.styleable#View_paddingHorizontal
+ * @attr ref android.R.styleable#View_paddingVertical
* @attr ref android.R.styleable#View_paddingBottom
* @attr ref android.R.styleable#View_paddingLeft
* @attr ref android.R.styleable#View_paddingRight
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index 66df335..1dbc1ac 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -7608,6 +7608,16 @@
* See
* {@link android.R.styleable#ViewGroup_MarginLayout ViewGroup Margin Layout Attributes}
* for a list of all child view attributes that this class supports.
+ *
+ * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_margin
+ * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginHorizontal
+ * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginVertical
+ * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginLeft
+ * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginTop
+ * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginRight
+ * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginBottom
+ * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginStart
+ * @attr ref android.R.styleable#ViewGroup_MarginLayout_layout_marginEnd
*/
public static class MarginLayoutParams extends ViewGroup.LayoutParams {
/**
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index 5b04f41..e1e8317 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -741,7 +741,8 @@
}
/**
- * Returns {@code true} if Autofill is supported for this user.
+ * Returns {@code true} if autofill is supported by the current device and
+ * is supported for this user.
*
* <p>Autofill is typically supported, but it could be unsupported in cases like:
* <ol>
diff --git a/core/java/com/android/internal/backup/package.html b/core/java/com/android/internal/backup/package.html
new file mode 100644
index 0000000..db6f78b
--- /dev/null
+++ b/core/java/com/android/internal/backup/package.html
@@ -0,0 +1,3 @@
+<body>
+{@hide}
+</body>
\ No newline at end of file
diff --git a/core/java/com/android/internal/inputmethod/package.html b/core/java/com/android/internal/inputmethod/package.html
new file mode 100644
index 0000000..db6f78b
--- /dev/null
+++ b/core/java/com/android/internal/inputmethod/package.html
@@ -0,0 +1,3 @@
+<body>
+{@hide}
+</body>
\ No newline at end of file
diff --git a/core/java/com/android/internal/logging/package.html b/core/java/com/android/internal/logging/package.html
new file mode 100644
index 0000000..db6f78b
--- /dev/null
+++ b/core/java/com/android/internal/logging/package.html
@@ -0,0 +1,3 @@
+<body>
+{@hide}
+</body>
\ No newline at end of file
diff --git a/core/java/com/android/internal/os/package.html b/core/java/com/android/internal/os/package.html
new file mode 100644
index 0000000..db6f78b
--- /dev/null
+++ b/core/java/com/android/internal/os/package.html
@@ -0,0 +1,3 @@
+<body>
+{@hide}
+</body>
\ No newline at end of file
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index 8fe9100..544afd9 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -3103,12 +3103,29 @@
}
/**
+ * Check if Setup or Post-Setup update is completed on TV
+ * @return true if completed
+ */
+ private boolean isTvUserSetupComplete() {
+ boolean isTvSetupComplete = Settings.Secure.getInt(getContext().getContentResolver(),
+ Settings.Secure.USER_SETUP_COMPLETE, 0) != 0;
+ isTvSetupComplete &= Settings.Secure.getInt(getContext().getContentResolver(),
+ Settings.Secure.TV_USER_SETUP_COMPLETE, 0) != 0;
+ return isTvSetupComplete;
+ }
+
+ /**
* Helper method for adding launch-search to most applications. Opens the
* search window using default settings.
*
* @return true if search window opened
*/
private boolean launchDefaultSearch(KeyEvent event) {
+ if (getContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK)
+ && !isTvUserSetupComplete()) {
+ // If we are in Setup or Post-Setup update mode on TV, consume the search key
+ return false;
+ }
boolean result;
final Callback cb = getCallback();
if (cb == null || isDestroyed()) {
diff --git a/core/java/com/android/internal/statusbar/package.html b/core/java/com/android/internal/statusbar/package.html
new file mode 100644
index 0000000..db6f78b
--- /dev/null
+++ b/core/java/com/android/internal/statusbar/package.html
@@ -0,0 +1,3 @@
+<body>
+{@hide}
+</body>
\ No newline at end of file
diff --git a/core/java/com/android/internal/widget/package.html b/core/java/com/android/internal/widget/package.html
new file mode 100644
index 0000000..db6f78b
--- /dev/null
+++ b/core/java/com/android/internal/widget/package.html
@@ -0,0 +1,3 @@
+<body>
+{@hide}
+</body>
\ No newline at end of file
diff --git a/core/jni/android/graphics/SurfaceTexture.cpp b/core/jni/android/graphics/SurfaceTexture.cpp
index 9242b70..d098a35 100644
--- a/core/jni/android/graphics/SurfaceTexture.cpp
+++ b/core/jni/android/graphics/SurfaceTexture.cpp
@@ -34,8 +34,8 @@
#include <utils/misc.h>
#include "jni.h"
-#include "JNIHelp.h"
-#include "ScopedLocalRef.h"
+#include <nativehelper/JNIHelp.h>
+#include <nativehelper/ScopedLocalRef.h>
// ----------------------------------------------------------------------------
diff --git a/libs/hwui/GlopBuilder.cpp b/libs/hwui/GlopBuilder.cpp
index 2e9a6e8..c19c1a1 100644
--- a/libs/hwui/GlopBuilder.cpp
+++ b/libs/hwui/GlopBuilder.cpp
@@ -457,11 +457,13 @@
return *this;
}
-GlopBuilder& GlopBuilder::setFillExternalTexture(Texture& texture, Matrix4& textureTransform) {
+GlopBuilder& GlopBuilder::setFillExternalTexture(Texture& texture, Matrix4& textureTransform,
+ bool requiresFilter) {
TRIGGER_STAGE(kFillStage);
REQUIRE_STAGES(kMeshStage | kRoundRectClipStage);
- mOutGlop->fill.texture = { &texture, GL_LINEAR, GL_CLAMP_TO_EDGE, &textureTransform };
+ GLenum filter = requiresFilter ? GL_LINEAR : GL_NEAREST;
+ mOutGlop->fill.texture = { &texture, filter, GL_CLAMP_TO_EDGE, &textureTransform };
setFill(SK_ColorWHITE, 1.0f, SkBlendMode::kSrc, Blend::ModeOrderSwap::NoSwap,
nullptr, nullptr);
diff --git a/libs/hwui/GlopBuilder.h b/libs/hwui/GlopBuilder.h
index 87b1568..6d11da1 100644
--- a/libs/hwui/GlopBuilder.h
+++ b/libs/hwui/GlopBuilder.h
@@ -75,7 +75,8 @@
GlopBuilder& setFillTextureLayer(GlLayer& layer, float alpha);
// TODO: setFillLayer normally forces its own wrap & filter mode,
// which isn't always correct.
- GlopBuilder& setFillExternalTexture(Texture& texture, Matrix4& textureTransform);
+ GlopBuilder& setFillExternalTexture(Texture& texture, Matrix4& textureTransform,
+ bool requiresFilter);
GlopBuilder& setTransform(const Matrix4& canvas, const int transformFlags);
diff --git a/libs/hwui/OpenGLReadback.cpp b/libs/hwui/OpenGLReadback.cpp
index c460c0d..51927d5 100644
--- a/libs/hwui/OpenGLReadback.cpp
+++ b/libs/hwui/OpenGLReadback.cpp
@@ -191,6 +191,7 @@
GL_TEXTURE_2D, texture, 0);
{
+ bool requiresFilter;
// Draw & readback
renderState.setViewport(destWidth, destHeight);
renderState.scissor().setEnabled(false);
@@ -208,12 +209,17 @@
croppedTexTransform.scale(srcRect.getWidth() / sourceTexture.width(),
srcRect.getHeight() / sourceTexture.height(), 1);
croppedTexTransform.multiply(sFlipV);
+ requiresFilter = srcRect.getWidth() != (float) destWidth
+ || srcRect.getHeight() != (float) destHeight;
+ } else {
+ requiresFilter = sourceTexture.width() != (uint32_t) destWidth
+ || sourceTexture.height() != (uint32_t) destHeight;
}
Glop glop;
GlopBuilder(renderState, caches, &glop)
.setRoundRectClipState(nullptr)
.setMeshTexturedUnitQuad(nullptr)
- .setFillExternalTexture(sourceTexture, croppedTexTransform)
+ .setFillExternalTexture(sourceTexture, croppedTexTransform, requiresFilter)
.setTransform(Matrix4::identity(), TransformFlags::None)
.setModelViewMapUnitToRect(Rect(destWidth, destHeight))
.build();
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
index 3b29a6c..1e26231 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java
@@ -77,7 +77,7 @@
private BluetoothAdapter mBluetoothAdapter;
private WifiManager mWifiManager;
- private BluetoothLeScanner mBLEScanner;
+ @Nullable private BluetoothLeScanner mBLEScanner;
private ScanSettings mDefaultScanSettings = new ScanSettings.Builder().build();
private List<DeviceFilter<?>> mFilters;
@@ -185,7 +185,7 @@
mBluetoothAdapter.startDiscovery();
}
- if (shouldScan(mBLEFilters)) {
+ if (shouldScan(mBLEFilters) && mBLEScanner != null) {
mBLEScanCallback = new BLEScanCallback();
mBLEScanner.startScan(mBLEScanFilters, mDefaultScanSettings, mBLEScanCallback);
}
@@ -224,7 +224,7 @@
unregisterReceiver(mBluetoothBroadcastReceiver);
mBluetoothBroadcastReceiver = null;
}
- mBLEScanner.stopScan(mBLEScanCallback);
+ if (mBLEScanner != null) mBLEScanner.stopScan(mBLEScanCallback);
if (mWifiBroadcastReceiver != null) {
unregisterReceiver(mWifiBroadcastReceiver);
mWifiBroadcastReceiver = null;
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index f66a09e..4245b11 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -776,7 +776,4 @@
<dimen name="qs_gutter_height">6dp</dimen>
- <!-- Width of the hollow triangle for empty signal state -->
- <dimen name="mobile_signal_empty_strokewidth">2dp</dimen>
-
</resources>
diff --git a/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java b/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java
index c43820d..f5c82a7 100644
--- a/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java
+++ b/packages/SystemUI/src/com/android/keyguard/PasswordTextView.java
@@ -28,10 +28,8 @@
import android.graphics.Typeface;
import android.os.PowerManager;
import android.os.SystemClock;
-import android.os.UserHandle;
import android.provider.Settings;
import android.text.InputType;
-import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
@@ -248,9 +246,9 @@
mText = mText.substring(0, length - 1);
CharState charState = mTextChars.get(length - 1);
charState.startRemoveAnimation(0, 0);
+ sendAccessibilityEventTypeViewTextChanged(textbefore, textbefore.length() - 1, 1, 0);
}
userActivity();
- sendAccessibilityEventTypeViewTextChanged(textbefore, textbefore.length() - 1, 1, 0);
}
public String getText() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
index c09da21..bd4a1df 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationMenuRow.java
@@ -417,7 +417,7 @@
@Override
public void onHeightUpdate() {
- if (mParent == null || mMenuItems.size() == 0) {
+ if (mParent == null || mMenuItems.size() == 0 || mMenuContainer == null) {
return;
}
int parentHeight = mParent.getCollapsedHeight();
@@ -477,7 +477,7 @@
private void setMenuLocation() {
boolean showOnLeft = mTranslation > 0;
- if ((mIconsPlaced && showOnLeft == mOnLeft) || mSnapping
+ if ((mIconsPlaced && showOnLeft == mOnLeft) || mSnapping || mMenuContainer == null
|| !mMenuContainer.isAttachedToWindow()) {
// Do nothing
return;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java
index 983a796..1c34b7d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SignalDrawable.java
@@ -85,12 +85,8 @@
{-1.9f / VIEWPORT, -1.9f / VIEWPORT},
};
- // The easiest way to understand this is as if we set Style.STROKE and draw the triangle,
- // but that is only theoretically right. Instead, draw the triangle and clip out a smaller
- // one inset by this amount.
- private final float mEmptyStrokeWidth;
private static final float INV_TAN = 1f / (float) Math.tan(Math.PI / 8f);
- private final float mEmptyDiagInset; // == mEmptyStrokeWidth * INV_TAN
+ private static final float CUT_WIDTH_DP = 1f / 12f;
private final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Paint mForegroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
@@ -126,11 +122,6 @@
Utils.getDefaultColor(context, R.color.light_mode_icon_color_dual_tone_fill);
mIntrinsicSize = context.getResources().getDimensionPixelSize(R.dimen.signal_icon_size);
- // mCutPath parameters
- mEmptyStrokeWidth = context.getResources()
- .getDimensionPixelSize(R.dimen.mobile_signal_empty_strokewidth);
- mEmptyDiagInset = mEmptyStrokeWidth * INV_TAN;
-
mHandler = new Handler();
setDarkIntensity(0);
}
@@ -262,20 +253,22 @@
}
if (mState == STATE_EMPTY) {
+ final float cutWidth = CUT_WIDTH_DP * height;
+ final float cutDiagInset = cutWidth * INV_TAN;
+
// Cut out a smaller triangle from the center of mFullPath
mCutPath.reset();
mCutPath.setFillType(FillType.WINDING);
- mCutPath.moveTo(width - padding - mEmptyStrokeWidth,
- height - padding - mEmptyStrokeWidth);
- mCutPath.lineTo(width - padding - mEmptyStrokeWidth, padding + mEmptyDiagInset);
- mCutPath.lineTo(padding + mEmptyDiagInset, height - padding - mEmptyStrokeWidth);
- mCutPath.lineTo(width - padding - mEmptyStrokeWidth,
- height - padding - mEmptyStrokeWidth);
+ mCutPath.moveTo(width - padding - cutWidth,
+ height - padding - cutWidth);
+ mCutPath.lineTo(width - padding - cutWidth, padding + cutDiagInset);
+ mCutPath.lineTo(padding + cutDiagInset, height - padding - cutWidth);
+ mCutPath.lineTo(width - padding - cutWidth,
+ height - padding - cutWidth);
- // In empty state, draw the full path as the foreground paint
- mForegroundPath.set(mFullPath);
- mFullPath.reset();
- mForegroundPath.op(mCutPath, Path.Op.DIFFERENCE);
+ // Draw empty state as only background
+ mForegroundPath.reset();
+ mFullPath.op(mCutPath, Path.Op.DIFFERENCE);
} else if (mState == STATE_AIRPLANE) {
// Airplane mode is slashed, full-signal
mForegroundPath.set(mFullPath);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
index efce871..14868e0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/MobileSignalController.java
@@ -334,6 +334,10 @@
}
private boolean isRoaming() {
+ // During a carrier change, roaming indications need to be supressed.
+ if (isCarrierNetworkChangeActive()) {
+ return false;
+ }
if (isCdma()) {
final int iconMode = mServiceState.getCdmaEriIconMode();
return mServiceState.getCdmaEriIconIndex() != EriInfo.ROAMING_INDICATOR_OFF
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java
index e0d8042..4aa9877 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationMenuRowTest.java
@@ -57,4 +57,10 @@
row.createMenu(null);
assertTrue(row.getMenuView() != null);
}
+
+ @Test
+ public void testResetUncreatedMenu() {
+ NotificationMenuRowPlugin row = new NotificationMenuRow(mContext);
+ row.resetMenu();
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
index 1627925..15186dc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/NetworkControllerSignalTest.java
@@ -496,6 +496,79 @@
DEFAULT_ICON /* typeIcon */);
}
+ @Test
+ public void testCarrierNetworkChange_roamingBeforeNetworkChange() {
+ int strength = SignalStrength.SIGNAL_STRENGTH_GREAT;
+
+ setupDefaultSignal();
+ setLevel(strength);
+ setGsmRoaming(true);
+
+ // Verify baseline
+ verifyLastMobileDataIndicators(true /* visible */,
+ strength /* strengthIcon */,
+ DEFAULT_ICON /* typeIcon */,
+ true /* roaming */);
+
+ // API call is made
+ setCarrierNetworkChange(true /* enabled */);
+
+ // Carrier network change is true, show special indicator, no roaming.
+ verifyLastMobileDataIndicators(true /* visible */,
+ SignalDrawable.getCarrierChangeState(SignalStrength.NUM_SIGNAL_STRENGTH_BINS),
+ 0 /* typeIcon */,
+ false /* roaming */);
+
+ // Revert back
+ setCarrierNetworkChange(false /* enabled */);
+
+ // Verify back in previous state
+ verifyLastMobileDataIndicators(true /* visible */,
+ strength /* strengthIcon */,
+ DEFAULT_ICON /* typeIcon */,
+ true /* roaming */);
+ }
+
+ @Test
+ public void testCarrierNetworkChange_roamingAfterNetworkChange() {
+ int strength = SignalStrength.SIGNAL_STRENGTH_GREAT;
+
+ setupDefaultSignal();
+ setLevel(strength);
+
+ // Verify baseline
+ verifyLastMobileDataIndicators(true /* visible */,
+ strength /* strengthIcon */,
+ DEFAULT_ICON /* typeIcon */,
+ false /* roaming */);
+
+ // API call is made
+ setCarrierNetworkChange(true /* enabled */);
+
+ // Carrier network change is true, show special indicator, no roaming.
+ verifyLastMobileDataIndicators(true /* visible */,
+ SignalDrawable.getCarrierChangeState(SignalStrength.NUM_SIGNAL_STRENGTH_BINS),
+ 0 /* typeIcon */,
+ false /* roaming */);
+
+ setGsmRoaming(true);
+
+ // Roaming should not show.
+ verifyLastMobileDataIndicators(true /* visible */,
+ SignalDrawable.getCarrierChangeState(SignalStrength.NUM_SIGNAL_STRENGTH_BINS),
+ 0 /* typeIcon */,
+ false /* roaming */);
+
+ // Revert back
+ setCarrierNetworkChange(false /* enabled */);
+
+ // Verify back in previous state
+ verifyLastMobileDataIndicators(true /* visible */,
+ strength /* strengthIcon */,
+ DEFAULT_ICON /* typeIcon */,
+ true /* roaming */);
+ }
+
private void verifyEmergencyOnly(boolean isEmergencyOnly) {
ArgumentCaptor<Boolean> emergencyOnly = ArgumentCaptor.forClass(Boolean.class);
Mockito.verify(mCallbackHandler, Mockito.atLeastOnce()).setEmergencyCallsOnly(
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
index 9e4d89c..0e42e6d 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityInputFilter.java
@@ -271,6 +271,7 @@
private void processKeyEvent(EventStreamState state, KeyEvent event, int policyFlags) {
if (!state.shouldProcessKeyEvent(event)) {
+ super.onInputEvent(event, policyFlags);
return;
}
mEventHandler.onKeyEvent(event, policyFlags);
diff --git a/services/backup/java/com/android/server/backup/BackupManagerService.java b/services/backup/java/com/android/server/backup/BackupManagerService.java
index 30de4ba..6f6e1b7 100644
--- a/services/backup/java/com/android/server/backup/BackupManagerService.java
+++ b/services/backup/java/com/android/server/backup/BackupManagerService.java
@@ -5666,13 +5666,15 @@
PerformFullTransportBackupTask pftbt = null;
synchronized (mQueueLock) {
if (mRunningFullBackupTask != null) {
- if (DEBUG_SCHEDULING) {
- Slog.i(TAG, "Telling running backup to stop");
- }
pftbt = mRunningFullBackupTask;
}
}
- pftbt.handleCancel(true);
+ if (pftbt != null) {
+ if (DEBUG_SCHEDULING) {
+ Slog.i(TAG, "Telling running backup to stop");
+ }
+ pftbt.handleCancel(true);
+ }
}
};
new Thread(endFullBackupRunnable, "end-full-backup").start();
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index 4810f4f..f47b0d3 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -383,7 +383,7 @@
findDeviceCallback,
getServiceCallback());
} catch (RemoteException e) {
- throw new RuntimeException(e);
+ Log.e(LOG_TAG, "Error while initiating device discovery", e);
}
}
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 61057dd..75206e4 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -86,6 +86,8 @@
private static final int ACTIVE_LOG_MAX_SIZE = 20;
private static final int CRASH_LOG_MAX_SIZE = 100;
private static final String REASON_AIRPLANE_MODE = "airplane mode";
+ private static final String REASON_DISALLOWED = "disallowed by system";
+ private static final String REASON_SHARING_DISALLOWED = "sharing disallowed by system";
private static final String REASON_RESTARTED = "automatic restart";
private static final String REASON_START_CRASH = "turn-on crash";
private static final String REASON_SYSTEM_BOOT = "system boot";
@@ -227,25 +229,26 @@
@Override
public void onUserRestrictionsChanged(int userId, Bundle newRestrictions,
Bundle prevRestrictions) {
- if (!UserRestrictionsUtils.restrictionsChanged(prevRestrictions, newRestrictions,
- UserManager.DISALLOW_BLUETOOTH, UserManager.DISALLOW_BLUETOOTH_SHARING)) {
- return; // No relevant changes, nothing to do.
+
+ if (UserRestrictionsUtils.restrictionsChanged(prevRestrictions, newRestrictions,
+ UserManager.DISALLOW_BLUETOOTH_SHARING)) {
+ updateOppLauncherComponentState(userId, newRestrictions.getBoolean(
+ UserManager.DISALLOW_BLUETOOTH_SHARING));
}
- final boolean disallowed = newRestrictions.getBoolean(UserManager.DISALLOW_BLUETOOTH);
-
- // DISALLOW_BLUETOOTH is a global restriction that can only be set by DO or PO on the
- // system user, so we only look at the system user.
- if (userId == UserHandle.USER_SYSTEM && disallowed && (mEnable || mEnableExternal)) {
- try {
- disable(null /* packageName */, true /* persist */);
- } catch (RemoteException e) {
- Slog.w(TAG, "Exception when disabling Bluetooth", e);
+ // DISALLOW_BLUETOOTH can only be set by DO or PO on the system user.
+ if (userId == UserHandle.USER_SYSTEM &&
+ UserRestrictionsUtils.restrictionsChanged(
+ prevRestrictions, newRestrictions, UserManager.DISALLOW_BLUETOOTH)) {
+ if (userId == UserHandle.USER_SYSTEM && newRestrictions.getBoolean(
+ UserManager.DISALLOW_BLUETOOTH)) {
+ updateOppLauncherComponentState(userId, true); // Sharing disallowed
+ sendDisableMsg(REASON_DISALLOWED);
+ } else {
+ updateOppLauncherComponentState(userId, newRestrictions.getBoolean(
+ UserManager.DISALLOW_BLUETOOTH_SHARING));
}
}
- final boolean sharingDisallowed = disallowed
- || newRestrictions.getBoolean(UserManager.DISALLOW_BLUETOOTH_SHARING);
- updateOppLauncherComponentState(userId, sharingDisallowed);
}
};
@@ -2118,7 +2121,8 @@
: PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
try {
final IPackageManager imp = AppGlobals.getPackageManager();
- imp.setComponentEnabledSetting(oppLauncherComponent, newState, 0 /* flags */, userId);
+ imp.setComponentEnabledSetting(oppLauncherComponent, newState,
+ PackageManager.DONT_KILL_APP, userId);
} catch (Exception e) {
// The component was not found, do nothing.
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 5f679db..904059a 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -20,6 +20,7 @@
import static android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
import static android.Manifest.permission.INTERACT_ACROSS_USERS;
import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
+import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
import static android.Manifest.permission.READ_FRAME_BUFFER;
import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
@@ -10228,7 +10229,7 @@
@Override
public void moveStackToDisplay(int stackId, int displayId) {
- enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveStackToDisplay()");
+ enforceCallingPermission(INTERNAL_SYSTEM_WINDOW, "moveStackToDisplay()");
synchronized (this) {
final long ident = Binder.clearCallingIdentity();
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index fe0e07e..3de2036 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -16,6 +16,7 @@
package com.android.server.am;
+import static android.Manifest.permission.INTERNAL_SYSTEM_WINDOW;
import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
import static android.Manifest.permission.START_ANY_ACTIVITY;
import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
@@ -38,11 +39,13 @@
import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.os.Process.SYSTEM_UID;
import static android.os.Trace.TRACE_TAG_ACTIVITY_MANAGER;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.FLAG_PRIVATE;
import static android.view.Display.INVALID_DISPLAY;
import static android.view.Display.REMOVE_MODE_DESTROY_CONTENT;
+import static android.view.Display.TYPE_VIRTUAL;
import static com.android.internal.logging.nano.MetricsProto.MetricsEvent.ACTION_PICTURE_IN_PICTURE_EXPANDED_TO_FULLSCREEN;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
@@ -1678,6 +1681,24 @@
return false;
}
+ // Check if the caller can manage activity stacks.
+ final int startAnyPerm = mService.checkPermission(INTERNAL_SYSTEM_WINDOW, callingPid,
+ callingUid);
+ if (startAnyPerm == PERMISSION_GRANTED) {
+ if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:"
+ + " allow launch any on display");
+ return true;
+ }
+
+ if (activityDisplay.mDisplay.getType() == TYPE_VIRTUAL
+ && activityDisplay.mDisplay.getOwnerUid() != SYSTEM_UID) {
+ // Limit launching on virtual displays, because their contents can be read from Surface
+ // by apps that created them.
+ if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:"
+ + " disallow launch on virtual display for not-embedded activity");
+ return false;
+ }
+
if (!activityDisplay.isPrivate()) {
// Anyone can launch on a public display.
if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:"
@@ -1699,15 +1720,6 @@
return true;
}
- // Check if the caller can manage activity stacks.
- final int startAnyPerm = mService.checkPermission(MANAGE_ACTIVITY_STACKS, callingPid,
- callingUid);
- if (startAnyPerm == PERMISSION_GRANTED) {
- if (DEBUG_TASKS) Slog.d(TAG, "Launch on display check:"
- + " allow launch any on display");
- return true;
- }
-
Slog.w(TAG, "Launch on display check: denied");
return false;
}
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index a145435..a31c33e 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -17,6 +17,7 @@
package com.android.server.am;
import static android.app.Activity.RESULT_CANCELED;
+import static android.app.ActivityManager.START_ABORTED;
import static android.app.ActivityManager.START_CANCELED;
import static android.app.ActivityManager.START_CLASS_NOT_FOUND;
import static android.app.ActivityManager.START_DELIVERED_TO_TOP;
@@ -279,7 +280,9 @@
// mLastStartActivityRecord[0] is set in the call to startActivity above.
outActivity[0] = mLastStartActivityRecord[0];
}
- return mLastStartActivityResult;
+
+ // Aborted results are treated as successes externally, but we must track them internally.
+ return mLastStartActivityResult != START_ABORTED ? mLastStartActivityResult : START_SUCCESS;
}
/** DO NOT call this method directly. Use {@link #startActivityLocked} instead. */
@@ -465,7 +468,7 @@
// We pretend to the caller that it was really started, but
// they will just get a cancel result.
ActivityOptions.abort(options);
- return START_SUCCESS;
+ return START_ABORTED;
}
// If permissions need a review before any of the app components can run, we
diff --git a/services/core/java/com/android/server/am/BroadcastQueue.java b/services/core/java/com/android/server/am/BroadcastQueue.java
index b3a2c29..2142c94 100644
--- a/services/core/java/com/android/server/am/BroadcastQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastQueue.java
@@ -802,7 +802,7 @@
IPackageManager pm = AppGlobals.getPackageManager();
for (int i = perms.length-1; i >= 0; i--) {
try {
- PermissionInfo pi = pm.getPermissionInfo(perms[i], 0);
+ PermissionInfo pi = pm.getPermissionInfo(perms[i], "android", 0);
if ((pi.protectionLevel & (PermissionInfo.PROTECTION_MASK_BASE
| PermissionInfo.PROTECTION_FLAG_PRIVILEGED))
!= PermissionInfo.PROTECTION_SIGNATURE) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 9f518c3..d5f059e 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -3996,20 +3996,69 @@
}
@Override
- public PermissionInfo getPermissionInfo(String name, int flags) {
- if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
+ public PermissionInfo getPermissionInfo(String name, String packageName, int flags) {
+ final int callingUid = Binder.getCallingUid();
+ if (getInstantAppPackageName(callingUid) != null) {
return null;
}
// reader
synchronized (mPackages) {
final BasePermission p = mSettings.mPermissions.get(name);
- if (p != null) {
- return generatePermissionInfo(p, flags);
+ if (p == null) {
+ return null;
}
- return null;
+ // If the caller is an app that targets pre 26 SDK drop protection flags.
+ final PermissionInfo permissionInfo = generatePermissionInfo(p, flags);
+ if (permissionInfo != null) {
+ permissionInfo.protectionLevel = adjustPermissionProtectionFlagsLPr(
+ permissionInfo.protectionLevel, packageName, callingUid);
+ }
+ return permissionInfo;
}
}
+ private int adjustPermissionProtectionFlagsLPr(int protectionLevel,
+ String packageName, int uid) {
+ // Signature permission flags area always reported
+ final int protectionLevelMasked = protectionLevel
+ & (PermissionInfo.PROTECTION_NORMAL
+ | PermissionInfo.PROTECTION_DANGEROUS
+ | PermissionInfo.PROTECTION_SIGNATURE);
+ if (protectionLevelMasked == PermissionInfo.PROTECTION_SIGNATURE) {
+ return protectionLevel;
+ }
+
+ // System sees all flags.
+ final int appId = UserHandle.getAppId(uid);
+ if (appId == Process.SYSTEM_UID || appId == Process.ROOT_UID
+ || appId == Process.SHELL_UID) {
+ return protectionLevel;
+ }
+
+ // Normalize package name to handle renamed packages and static libs
+ packageName = resolveInternalPackageNameLPr(packageName,
+ PackageManager.VERSION_CODE_HIGHEST);
+
+ // Apps that target O see flags for all protection levels.
+ final PackageSetting ps = mSettings.mPackages.get(packageName);
+ if (ps == null) {
+ return protectionLevel;
+ }
+ if (ps.appId != appId) {
+ return protectionLevel;
+ }
+
+ final PackageParser.Package pkg = mPackages.get(packageName);
+ if (pkg == null) {
+ return protectionLevel;
+ }
+ if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
+ return protectionLevelMasked;
+ }
+
+ return protectionLevel;
+ }
+
@Override
public @Nullable ParceledListSlice<PermissionInfo> queryPermissionsByGroup(String group,
int flags) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index f3a292b..20d7b28 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -1018,7 +1018,7 @@
throw new RuntimeException(e.getMessage(), e);
}
try {
- ResolveInfo ri = mInterface.resolveIntent(intent, null, 0, mTargetUser);
+ ResolveInfo ri = mInterface.resolveIntent(intent, intent.getType(), 0, mTargetUser);
PrintWriter pw = getOutPrintWriter();
if (ri == null) {
pw.println("No activity found");
@@ -1040,7 +1040,7 @@
throw new RuntimeException(e.getMessage(), e);
}
try {
- List<ResolveInfo> result = mInterface.queryIntentActivities(intent, null, 0,
+ List<ResolveInfo> result = mInterface.queryIntentActivities(intent, intent.getType(), 0,
mTargetUser).getList();
PrintWriter pw = getOutPrintWriter();
if (result == null || result.size() <= 0) {
@@ -1074,7 +1074,7 @@
throw new RuntimeException(e.getMessage(), e);
}
try {
- List<ResolveInfo> result = mInterface.queryIntentServices(intent, null, 0,
+ List<ResolveInfo> result = mInterface.queryIntentServices(intent, intent.getType(), 0,
mTargetUser).getList();
PrintWriter pw = getOutPrintWriter();
if (result == null || result.size() <= 0) {
@@ -1108,7 +1108,7 @@
throw new RuntimeException(e.getMessage(), e);
}
try {
- List<ResolveInfo> result = mInterface.queryIntentReceivers(intent, null, 0,
+ List<ResolveInfo> result = mInterface.queryIntentReceivers(intent, intent.getType(), 0,
mTargetUser).getList();
PrintWriter pw = getOutPrintWriter();
if (result == null || result.size() <= 0) {
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 8112f99..4477e5a 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -1689,8 +1689,17 @@
}
boolean isUserSetupComplete() {
- return Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ boolean isSetupComplete = Settings.Secure.getIntForUser(mContext.getContentResolver(),
Settings.Secure.USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0;
+ if (mHasFeatureLeanback) {
+ isSetupComplete &= isTvUserSetupComplete();
+ }
+ return isSetupComplete;
+ }
+
+ private boolean isTvUserSetupComplete() {
+ return Settings.Secure.getIntForUser(mContext.getContentResolver(),
+ Settings.Secure.TV_USER_SETUP_COMPLETE, 0, UserHandle.USER_CURRENT) != 0;
}
private void handleShortPressOnHome() {
diff --git a/services/core/java/com/android/server/wm/AppWindowContainerController.java b/services/core/java/com/android/server/wm/AppWindowContainerController.java
index 5f34c60..4e4398e 100644
--- a/services/core/java/com/android/server/wm/AppWindowContainerController.java
+++ b/services/core/java/com/android/server/wm/AppWindowContainerController.java
@@ -614,7 +614,7 @@
return STARTING_WINDOW_TYPE_SPLASH_SCREEN;
} else if (taskSwitch && allowTaskSnapshot) {
return snapshot == null ? STARTING_WINDOW_TYPE_NONE
- : snapshotOrientationSameAsDisplay(snapshot) || fromRecents
+ : snapshotOrientationSameAsTask(snapshot) || fromRecents
? STARTING_WINDOW_TYPE_SNAPSHOT : STARTING_WINDOW_TYPE_SPLASH_SCREEN;
} else {
return STARTING_WINDOW_TYPE_NONE;
@@ -640,24 +640,11 @@
return true;
}
- private boolean snapshotOrientationSameAsDisplay(TaskSnapshot snapshot) {
+ private boolean snapshotOrientationSameAsTask(TaskSnapshot snapshot) {
if (snapshot == null) {
return false;
}
- final Rect rect = new Rect(0, 0, snapshot.getSnapshot().getWidth(),
- snapshot.getSnapshot().getHeight());
- rect.inset(snapshot.getContentInsets());
- final Rect taskBoundsWithoutInsets = new Rect();
- mContainer.getTask().getBounds(taskBoundsWithoutInsets);
- final DisplayInfo di = mContainer.getDisplayContent().getDisplayInfo();
- final Rect displayBounds = new Rect(0, 0, di.logicalWidth, di.logicalHeight);
- final Rect stableInsets = new Rect();
- mService.mPolicy.getStableInsetsLw(di.rotation, di.logicalWidth, di.logicalHeight,
- stableInsets);
- displayBounds.inset(stableInsets);
- final boolean snapshotInLandscape = rect.width() >= rect.height();
- final boolean displayInLandscape = displayBounds.width() >= displayBounds.height();
- return snapshotInLandscape == displayInLandscape;
+ return mContainer.getTask().getConfiguration().orientation == snapshot.getOrientation();
}
public void removeStartingWindow() {
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java b/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java
index 70c7e58..6086354 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/NetworkLoggingHandler.java
@@ -25,8 +25,8 @@
import android.os.Looper;
import android.os.Message;
import android.os.SystemClock;
-import android.util.Log;
import android.util.LongSparseArray;
+import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
@@ -60,16 +60,21 @@
/** Delay after which older batches get discarded after a retrieval. */
private static final long RETRIEVED_BATCH_DISCARD_DELAY_MS = 5 * 60 * 1000; // 5m
+ /** Do not call into mDpm with locks held */
private final DevicePolicyManagerService mDpm;
private final AlarmManager mAlarmManager;
private final OnAlarmListener mBatchTimeoutAlarmListener = new OnAlarmListener() {
@Override
public void onAlarm() {
- Log.d(TAG, "Received a batch finalization timeout alarm, finalizing "
+ Slog.d(TAG, "Received a batch finalization timeout alarm, finalizing "
+ mNetworkEvents.size() + " pending events.");
+ Bundle notificationExtras = null;
synchronized (NetworkLoggingHandler.this) {
- finalizeBatchAndNotifyDeviceOwnerLocked();
+ notificationExtras = finalizeBatchAndBuildDeviceOwnerMessageLocked();
+ }
+ if (notificationExtras != null) {
+ notifyDeviceOwner(notificationExtras);
}
}
};
@@ -110,17 +115,21 @@
case LOG_NETWORK_EVENT_MSG: {
final NetworkEvent networkEvent = msg.getData().getParcelable(NETWORK_EVENT_KEY);
if (networkEvent != null) {
+ Bundle notificationExtras = null;
synchronized (NetworkLoggingHandler.this) {
mNetworkEvents.add(networkEvent);
if (mNetworkEvents.size() >= MAX_EVENTS_PER_BATCH) {
- finalizeBatchAndNotifyDeviceOwnerLocked();
+ notificationExtras = finalizeBatchAndBuildDeviceOwnerMessageLocked();
}
}
+ if (notificationExtras != null) {
+ notifyDeviceOwner(notificationExtras);
+ }
}
break;
}
default: {
- Log.d(TAG, "NetworkLoggingHandler received an unknown of message.");
+ Slog.d(TAG, "NetworkLoggingHandler received an unknown of message.");
break;
}
}
@@ -133,40 +142,48 @@
mAlarmManager.setWindow(AlarmManager.ELAPSED_REALTIME_WAKEUP, when,
BATCH_FINALIZATION_TIMEOUT_ALARM_INTERVAL_MS, NETWORK_LOGGING_TIMEOUT_ALARM_TAG,
mBatchTimeoutAlarmListener, this);
- Log.d(TAG, "Scheduled a new batch finalization alarm " + BATCH_FINALIZATION_TIMEOUT_MS
+ Slog.d(TAG, "Scheduled a new batch finalization alarm " + BATCH_FINALIZATION_TIMEOUT_MS
+ "ms from now.");
}
synchronized void pause() {
- Log.d(TAG, "Paused network logging");
+ Slog.d(TAG, "Paused network logging");
mPaused = true;
}
- synchronized void resume() {
- if (!mPaused) {
- Log.d(TAG, "Attempted to resume network logging, but logging is not paused.");
- return;
+ void resume() {
+ Bundle notificationExtras = null;
+ synchronized (this) {
+ if (!mPaused) {
+ Slog.d(TAG, "Attempted to resume network logging, but logging is not paused.");
+ return;
+ }
+
+ Slog.d(TAG, "Resumed network logging. Current batch=" + mCurrentBatchToken
+ + ", LastRetrievedBatch=" + mLastRetrievedBatchToken);
+ mPaused = false;
+
+ // If there is a batch ready that the device owner hasn't been notified about, do it now.
+ if (mBatches.size() > 0 && mLastRetrievedBatchToken != mCurrentBatchToken) {
+ scheduleBatchFinalization();
+ notificationExtras = buildDeviceOwnerMessageLocked();
+ }
}
-
- Log.d(TAG, "Resumed network logging. Current batch=" + mCurrentBatchToken
- + ", LastRetrievedBatch=" + mLastRetrievedBatchToken);
- mPaused = false;
-
- // If there is a batch ready that the device owner hasn't been notified about, do it now.
- if (mBatches.size() > 0 && mLastRetrievedBatchToken != mCurrentBatchToken) {
- scheduleBatchFinalization();
- notifyDeviceOwnerLocked();
+ if (notificationExtras != null) {
+ notifyDeviceOwner(notificationExtras);
}
}
synchronized void discardLogs() {
mBatches.clear();
mNetworkEvents = new ArrayList<>();
- Log.d(TAG, "Discarded all network logs");
+ Slog.d(TAG, "Discarded all network logs");
}
@GuardedBy("this")
- private void finalizeBatchAndNotifyDeviceOwnerLocked() {
+ /** @returns extras if a message should be sent to the device owner */
+ private Bundle finalizeBatchAndBuildDeviceOwnerMessageLocked() {
+ Bundle notificationExtras = null;
if (mNetworkEvents.size() > 0) {
// Finalize the batch and start a new one from scratch.
if (mBatches.size() >= MAX_BATCHES) {
@@ -177,27 +194,39 @@
mBatches.append(mCurrentBatchToken, mNetworkEvents);
mNetworkEvents = new ArrayList<>();
if (!mPaused) {
- notifyDeviceOwnerLocked();
+ notificationExtras = buildDeviceOwnerMessageLocked();
}
} else {
// Don't notify the DO, since there are no events; DPC can still retrieve
// the last full batch if not paused.
- Log.d(TAG, "Was about to finalize the batch, but there were no events to send to"
+ Slog.d(TAG, "Was about to finalize the batch, but there were no events to send to"
+ " the DPC, the batchToken of last available batch: " + mCurrentBatchToken);
}
// Regardless of whether the batch was non-empty schedule a new finalization after timeout.
scheduleBatchFinalization();
+ return notificationExtras;
}
- /** Sends a notification to the DO. Should only be called when there is a batch available. */
@GuardedBy("this")
- private void notifyDeviceOwnerLocked() {
+ /** Build extras notification to the DO. Should only be called when there
+ is a batch available. */
+ private Bundle buildDeviceOwnerMessageLocked() {
final Bundle extras = new Bundle();
final int lastBatchSize = mBatches.valueAt(mBatches.size() - 1).size();
extras.putLong(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_TOKEN, mCurrentBatchToken);
extras.putInt(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_COUNT, lastBatchSize);
- Log.d(TAG, "Sending network logging batch broadcast to device owner, batchToken: "
- + mCurrentBatchToken);
+ return extras;
+ }
+
+ /** Sends a notification to the DO. Should not hold locks as DevicePolicyManagerService may
+ call into NetworkLoggingHandler. */
+ private void notifyDeviceOwner(Bundle extras) {
+ Slog.d(TAG, "Sending network logging batch broadcast to device owner, batchToken: "
+ + extras.getLong(DeviceAdminReceiver.EXTRA_NETWORK_LOGS_TOKEN, -1));
+ if (Thread.holdsLock(this)) {
+ Slog.wtfStack(TAG, "Shouldn't be called with NetworkLoggingHandler lock held");
+ return;
+ }
mDpm.sendDeviceOwnerCommand(DeviceAdminReceiver.ACTION_NETWORK_LOGS_AVAILABLE, extras);
}
diff --git a/tests/net/java/com/android/server/connectivity/TetheringTest.java b/tests/net/java/com/android/server/connectivity/TetheringTest.java
index 636b3f8..3f0eacf 100644
--- a/tests/net/java/com/android/server/connectivity/TetheringTest.java
+++ b/tests/net/java/com/android/server/connectivity/TetheringTest.java
@@ -407,7 +407,7 @@
when(mWifiManager.startSoftAp(any(WifiConfiguration.class))).thenReturn(true);
// Emulate pressing the WiFi tethering button.
- mTethering.startTethering(ConnectivityManager.TETHERING_WIFI, null, false);
+ mTethering.startTethering(TETHERING_WIFI, null, false);
mLooper.dispatchAll();
verify(mWifiManager, times(1)).startSoftAp(null);
verifyNoMoreInteractions(mWifiManager);