diff options
19 files changed, 139 insertions, 341 deletions
diff --git a/api/current.txt b/api/current.txt index e87c6132bafa..5018ecfd6803 100644 --- a/api/current.txt +++ b/api/current.txt @@ -26278,16 +26278,6 @@ package android.net.sip { package android.net.wifi { - public final class IconInfo implements android.os.Parcelable { - ctor public IconInfo(java.lang.String, byte[]); - ctor public IconInfo(android.net.wifi.IconInfo); - method public int describeContents(); - method public byte[] getData(); - method public java.lang.String getFilename(); - method public void writeToParcel(android.os.Parcel, int); - field public static final android.os.Parcelable.Creator<android.net.wifi.IconInfo> CREATOR; - } - public class ScanResult implements android.os.Parcelable { method public int describeContents(); method public boolean is80211mcResponder(); @@ -26536,7 +26526,8 @@ package android.net.wifi { field public static final java.lang.String EXTRA_BSSID_LONG = "android.net.wifi.extra.BSSID_LONG"; field public static final java.lang.String EXTRA_DELAY = "android.net.wifi.extra.DELAY"; field public static final java.lang.String EXTRA_ESS = "android.net.wifi.extra.ESS"; - field public static final java.lang.String EXTRA_ICON_INFO = "android.net.wifi.extra.ICON_INFO"; + field public static final java.lang.String EXTRA_FILENAME = "android.net.wifi.extra.FILENAME"; + field public static final java.lang.String EXTRA_ICON = "android.net.wifi.extra.ICON"; field public static final java.lang.String EXTRA_NETWORK_INFO = "networkInfo"; field public static final java.lang.String EXTRA_NEW_RSSI = "newRssi"; field public static final java.lang.String EXTRA_NEW_STATE = "newState"; diff --git a/api/system-current.txt b/api/system-current.txt index 073729957399..2bf01d1d2c85 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -28561,16 +28561,6 @@ package android.net.wifi { field public boolean truncated; } - public final class IconInfo implements android.os.Parcelable { - ctor public IconInfo(java.lang.String, byte[]); - ctor public IconInfo(android.net.wifi.IconInfo); - method public int describeContents(); - method public byte[] getData(); - method public java.lang.String getFilename(); - method public void writeToParcel(android.os.Parcel, int); - field public static final android.os.Parcelable.Creator<android.net.wifi.IconInfo> CREATOR; - } - public class RttManager { method public void disableResponder(android.net.wifi.RttManager.ResponderCallback); method public void enableResponder(android.net.wifi.RttManager.ResponderCallback); @@ -29066,7 +29056,8 @@ package android.net.wifi { field public static final java.lang.String EXTRA_CHANGE_REASON = "changeReason"; field public static final java.lang.String EXTRA_DELAY = "android.net.wifi.extra.DELAY"; field public static final java.lang.String EXTRA_ESS = "android.net.wifi.extra.ESS"; - field public static final java.lang.String EXTRA_ICON_INFO = "android.net.wifi.extra.ICON_INFO"; + field public static final java.lang.String EXTRA_FILENAME = "android.net.wifi.extra.FILENAME"; + field public static final java.lang.String EXTRA_ICON = "android.net.wifi.extra.ICON"; field public static final java.lang.String EXTRA_MULTIPLE_NETWORKS_CHANGED = "multipleChanges"; field public static final java.lang.String EXTRA_NETWORK_INFO = "networkInfo"; field public static final java.lang.String EXTRA_NEW_RSSI = "newRssi"; diff --git a/api/test-current.txt b/api/test-current.txt index 84d97fbaa04f..da25aa954c25 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -26389,16 +26389,6 @@ package android.net.sip { package android.net.wifi { - public final class IconInfo implements android.os.Parcelable { - ctor public IconInfo(java.lang.String, byte[]); - ctor public IconInfo(android.net.wifi.IconInfo); - method public int describeContents(); - method public byte[] getData(); - method public java.lang.String getFilename(); - method public void writeToParcel(android.os.Parcel, int); - field public static final android.os.Parcelable.Creator<android.net.wifi.IconInfo> CREATOR; - } - public class ScanResult implements android.os.Parcelable { method public int describeContents(); method public boolean is80211mcResponder(); @@ -26647,7 +26637,8 @@ package android.net.wifi { field public static final java.lang.String EXTRA_BSSID_LONG = "android.net.wifi.extra.BSSID_LONG"; field public static final java.lang.String EXTRA_DELAY = "android.net.wifi.extra.DELAY"; field public static final java.lang.String EXTRA_ESS = "android.net.wifi.extra.ESS"; - field public static final java.lang.String EXTRA_ICON_INFO = "android.net.wifi.extra.ICON_INFO"; + field public static final java.lang.String EXTRA_FILENAME = "android.net.wifi.extra.FILENAME"; + field public static final java.lang.String EXTRA_ICON = "android.net.wifi.extra.ICON"; field public static final java.lang.String EXTRA_NETWORK_INFO = "networkInfo"; field public static final java.lang.String EXTRA_NEW_RSSI = "newRssi"; field public static final java.lang.String EXTRA_NEW_STATE = "newState"; diff --git a/core/java/android/os/Process.java b/core/java/android/os/Process.java index f69c996c5368..31376587e144 100644 --- a/core/java/android/os/Process.java +++ b/core/java/android/os/Process.java @@ -92,6 +92,12 @@ public class Process { public static final int VPN_UID = 1016; /** + * Defines the UID/GID for keystore. + * @hide + */ + public static final int KEYSTORE_UID = 1017; + + /** * Defines the UID/GID for the NFC service process. * @hide */ diff --git a/core/java/android/widget/ListPopupWindow.java b/core/java/android/widget/ListPopupWindow.java index 7b99d07d2457..78d18fdbca5f 100644 --- a/core/java/android/widget/ListPopupWindow.java +++ b/core/java/android/widget/ListPopupWindow.java @@ -75,6 +75,7 @@ public class ListPopupWindow implements ShowableListMenu { private int mDropDownWindowLayoutType = WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL; private boolean mDropDownVerticalOffsetSet; private boolean mIsAnimatedFromAnchor = true; + private boolean mOverlapAnchor; private int mDropDownGravity = Gravity.NO_GRAVITY; @@ -672,6 +673,7 @@ public class ListPopupWindow implements ShowableListMenu { mPopup.setOutsideTouchable(!mForceIgnoreOutsideTouch && !mDropDownAlwaysVisible); mPopup.setTouchInterceptor(mTouchInterceptor); mPopup.setEpicenterBounds(mEpicenterBounds); + mPopup.setOverlapAnchor(mOverlapAnchor); mPopup.showAsDropDown(getAnchorView(), mDropDownHorizontalOffset, mDropDownVerticalOffset, mDropDownGravity); mDropDownList.setSelection(ListView.INVALID_POSITION); @@ -1245,6 +1247,13 @@ public class ListPopupWindow implements ShowableListMenu { return listContent + otherHeights; } + /** + * @hide + */ + public void setOverlapAnchor(boolean overlap) { + mOverlapAnchor = overlap; + } + private class PopupDataSetObserver extends DataSetObserver { @Override public void onChanged() { diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java index 26b3ae2c42fc..9f10531841e3 100644 --- a/core/java/android/widget/PopupWindow.java +++ b/core/java/android/widget/PopupWindow.java @@ -55,6 +55,7 @@ import android.view.ViewTreeObserver.OnScrollChangedListener; import android.view.WindowManager; import android.view.WindowManager.LayoutParams; import android.view.WindowManager.LayoutParams.SoftInputModeFlags; +import android.view.WindowManagerGlobal; import com.android.internal.R; @@ -137,6 +138,7 @@ public class PopupWindow { private final int[] mTmpDrawingLocation = new int[2]; private final int[] mTmpScreenLocation = new int[2]; + private final int[] mTmpAppLocation = new int[2]; private final Rect mTempRect = new Rect(); private Context mContext; @@ -242,6 +244,9 @@ public class PopupWindow { private final OnScrollChangedListener mOnScrollChangedListener = this::alignToAnchor; + private final View.OnLayoutChangeListener mOnLayoutChangeListener = + (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> alignToAnchor(); + private int mAnchorXoff; private int mAnchorYoff; private int mAnchoredGravity; @@ -1238,7 +1243,8 @@ public class PopupWindow { mIsShowing = true; mIsDropdown = true; - final WindowManager.LayoutParams p = createPopupLayoutParams(anchor.getWindowToken()); + final WindowManager.LayoutParams p = + createPopupLayoutParams(anchor.getApplicationWindowToken()); preparePopup(p); final boolean aboveAnchor = findDropDownPosition(anchor, p, xoff, yoff, @@ -1547,13 +1553,21 @@ public class PopupWindow { } // Initially, align to the bottom-left corner of the anchor plus offsets. + final int[] appScreenLocation = mTmpAppLocation; + final View appRootView = getAppRootView(anchor); + appRootView.getLocationOnScreen(appScreenLocation); + + final int[] screenLocation = mTmpScreenLocation; + anchor.getLocationOnScreen(screenLocation); + final int[] drawingLocation = mTmpDrawingLocation; - anchor.getLocationInWindow(drawingLocation); + drawingLocation[0] = screenLocation[0] - appScreenLocation[0]; + drawingLocation[1] = screenLocation[1] - appScreenLocation[1]; outParams.x = drawingLocation[0] + xOffset; outParams.y = drawingLocation[1] + anchorHeight + yOffset; final Rect displayFrame = new Rect(); - anchor.getWindowVisibleDisplayFrame(displayFrame); + appRootView.getWindowVisibleDisplayFrame(displayFrame); if (width == MATCH_PARENT) { width = displayFrame.right - displayFrame.left; } @@ -1574,9 +1588,6 @@ public class PopupWindow { outParams.x -= width - anchorWidth; } - final int[] screenLocation = mTmpScreenLocation; - anchor.getLocationOnScreen(screenLocation); - // First, attempt to fit the popup vertically without resizing. final boolean fitsVertical = tryFitVertical(outParams, yOffset, height, anchorHeight, drawingLocation[1], screenLocation[1], displayFrame.top, @@ -1595,7 +1606,9 @@ public class PopupWindow { scrollY + height + anchorHeight + yOffset); if (allowScroll && anchor.requestRectangleOnScreen(r, true)) { // Reset for the new anchor position. - anchor.getLocationInWindow(drawingLocation); + anchor.getLocationOnScreen(screenLocation); + drawingLocation[0] = screenLocation[0] - appScreenLocation[0]; + drawingLocation[1] = screenLocation[1] - appScreenLocation[1]; outParams.x = drawingLocation[0] + xOffset; outParams.y = drawingLocation[1] + anchorHeight + yOffset; @@ -1793,7 +1806,8 @@ public class PopupWindow { Rect displayFrame = null; final Rect visibleDisplayFrame = new Rect(); - anchor.getWindowVisibleDisplayFrame(visibleDisplayFrame); + final View appView = getAppRootView(anchor); + appView.getWindowVisibleDisplayFrame(visibleDisplayFrame); if (ignoreBottomDecorations) { // In the ignore bottom decorations case we want to // still respect all other decorations so we use the inset visible @@ -2240,6 +2254,7 @@ public class PopupWindow { final View anchorRoot = mAnchorRoot != null ? mAnchorRoot.get() : null; if (anchorRoot != null) { anchorRoot.removeOnAttachStateChangeListener(mOnAnchorRootDetachedListener); + anchorRoot.removeOnLayoutChangeListener(mOnLayoutChangeListener); } mAnchor = null; @@ -2258,6 +2273,7 @@ public class PopupWindow { final View anchorRoot = anchor.getRootView(); anchorRoot.addOnAttachStateChangeListener(mOnAnchorRootDetachedListener); + anchorRoot.addOnLayoutChangeListener(mOnLayoutChangeListener); mAnchor = new WeakReference<>(anchor); mAnchorRoot = new WeakReference<>(anchorRoot); @@ -2281,6 +2297,15 @@ public class PopupWindow { } } + private View getAppRootView(View anchor) { + final View appWindowView = WindowManagerGlobal.getInstance().getWindowView( + anchor.getApplicationWindowToken()); + if (appWindowView != null) { + return appWindowView; + } + return anchor.getRootView(); + } + private class PopupDecorView extends FrameLayout { private TransitionListenerAdapter mPendingExitListener; diff --git a/core/java/com/android/internal/view/menu/CascadingMenuPopup.java b/core/java/com/android/internal/view/menu/CascadingMenuPopup.java index ebcec5cb5a42..6dff8b41eeb4 100644 --- a/core/java/com/android/internal/view/menu/CascadingMenuPopup.java +++ b/core/java/com/android/internal/view/menu/CascadingMenuPopup.java @@ -381,6 +381,7 @@ final class CascadingMenuPopup extends MenuPopup implements MenuPresenter, OnKey if (parentView != null) { // This menu is a cascading submenu anchored to a parent view. + popupWindow.setAnchorView(parentView); popupWindow.setTouchModal(false); popupWindow.setEnterTransition(null); @@ -388,42 +389,30 @@ final class CascadingMenuPopup extends MenuPopup implements MenuPresenter, OnKey final boolean showOnRight = nextMenuPosition == HORIZ_POSITION_RIGHT; mLastPosition = nextMenuPosition; - // A popup anchored to mAnchorView with (0,0) offset would be shown at this position. - final int[] offsetOrigin = new int[2]; - mAnchorView.getLocationOnScreen(offsetOrigin); - offsetOrigin[1] += mAnchorView.getHeight(); - - final int[] parentViewScreenLocation = new int[2]; - parentView.getLocationOnScreen(parentViewScreenLocation); - - // Translate the parent view location into the offset coordinate space. - // If used as horizontal/vertical offsets, these values would position the submenu - // at the exact same position as the parent item. - final int parentOffsetLeft = parentViewScreenLocation[0] - offsetOrigin[0]; - final int parentOffsetTop = parentViewScreenLocation[1] - offsetOrigin[1]; - - // Adjust the horizontal offset to display the submenu to the right or to the left + // Compute the horizontal offset to display the submenu to the right or to the left // of the parent item. // By now, mDropDownGravity is the resolved absolute gravity, so // this should work in both LTR and RTL. final int x; if ((mDropDownGravity & Gravity.RIGHT) == Gravity.RIGHT) { if (showOnRight) { - x = parentOffsetLeft + menuWidth; + x = menuWidth; } else { - x = parentOffsetLeft - parentView.getWidth(); + x = -parentView.getWidth(); } } else { if (showOnRight) { - x = parentOffsetLeft + parentView.getWidth(); + x = parentView.getWidth(); } else { - x = parentOffsetLeft - menuWidth; + x = -menuWidth; } } popupWindow.setHorizontalOffset(x); - // Use the same vertical offset as the parent item. - popupWindow.setVerticalOffset(parentOffsetTop); + // Align with the top edge of the parent view (or the bottom edge when the submenu is + // flipped vertically). + popupWindow.setOverlapAnchor(true); + popupWindow.setVerticalOffset(0); } else { if (mHasXOffset) { popupWindow.setHorizontalOffset(mXOffset); diff --git a/core/res/res/values-ldrtl-television/config.xml b/core/res/res/values-ldrtl-television/config.xml index 503b9022aa3c..2a5a0c9a1f76 100644 --- a/core/res/res/values-ldrtl-television/config.xml +++ b/core/res/res/values-ldrtl-television/config.xml @@ -22,7 +22,7 @@ <resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> <!-- The default gravity for the picture-in-picture window. - Currently, this maps to Gravity.TOP | Gravity.LEFT --> - <integer name="config_defaultPictureInPictureGravity">0x33</integer> + Currently, this maps to Gravity.BOTTOM | Gravity.LEFT --> + <integer name="config_defaultPictureInPictureGravity">0x53</integer> </resources> diff --git a/core/res/res/values-television/config.xml b/core/res/res/values-television/config.xml index 1987ac454d86..78eeee99150a 100644 --- a/core/res/res/values-television/config.xml +++ b/core/res/res/values-television/config.xml @@ -34,6 +34,6 @@ <string translatable="false" name="config_defaultPictureInPictureScreenEdgeInsets">56x27</string> <!-- The default gravity for the picture-in-picture window. - Currently, this maps to Gravity.TOP | Gravity.RIGHT --> - <integer name="config_defaultPictureInPictureGravity">0x35</integer> + Currently, this maps to Gravity.BOTTOM | Gravity.RIGHT --> + <integer name="config_defaultPictureInPictureGravity">0x55</integer> </resources> diff --git a/packages/SystemUI/res/drawable/ic_add_circle_qs.xml b/packages/SystemUI/res/drawable/ic_add_circle_qs.xml index 6415ecb44c2e..8e933445be0b 100644 --- a/packages/SystemUI/res/drawable/ic_add_circle_qs.xml +++ b/packages/SystemUI/res/drawable/ic_add_circle_qs.xml @@ -18,7 +18,7 @@ Copyright (C) 2014 The Android Open Source Project android:height="48.0dp" android:viewportWidth="24.0" android:viewportHeight="24.0" - android:tint="?android:attr/colorControlNormal"> + android:tint="?android:attr/colorForeground"> <group android:scaleX="1.2" android:scaleY="1.2" diff --git a/packages/SystemUI/src/com/android/systemui/plugins/PluginManagerImpl.java b/packages/SystemUI/src/com/android/systemui/plugins/PluginManagerImpl.java index 1fb6c8704587..ec5f9e7eb6f5 100644 --- a/packages/SystemUI/src/com/android/systemui/plugins/PluginManagerImpl.java +++ b/packages/SystemUI/src/com/android/systemui/plugins/PluginManagerImpl.java @@ -59,7 +59,6 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage private static PluginManager sInstance; - private final HandlerThread mBackgroundThread; private final ArrayMap<PluginListener<?>, PluginInstanceManager> mPluginMap = new ArrayMap<>(); private final Map<String, ClassLoader> mClassLoaders = new ArrayMap<>(); @@ -71,6 +70,7 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage private ClassLoaderFilter mParentClassLoader; private boolean mListening; private boolean mHasOneShot; + private Looper mLooper; public PluginManagerImpl(Context context) { this(context, new PluginInstanceManagerFactory(), @@ -82,8 +82,7 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage UncaughtExceptionHandler defaultHandler) { mContext = context; mFactory = factory; - mBackgroundThread = new HandlerThread("Plugins"); - mBackgroundThread.start(); + mLooper = Dependency.get(Dependency.BG_LOOPER); isDebuggable = debuggable; mPluginPrefs = new PluginPrefs(mContext); @@ -91,7 +90,7 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage defaultHandler); Thread.setDefaultUncaughtExceptionHandler(uncaughtExceptionHandler); if (isDebuggable) { - new Handler(mBackgroundThread.getLooper()).post(() -> { + new Handler(mLooper).post(() -> { // Plugin dependencies that don't have another good home can go here, but // dependencies that have better places to init can happen elsewhere. Dependency.get(PluginDependencyProvider.class) @@ -120,7 +119,7 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage throw new RuntimeException("Must be called from UI thread"); } PluginInstanceManager<T> p = mFactory.createPluginInstanceManager(mContext, action, null, - false, mBackgroundThread.getLooper(), cls, this); + false, mLooper, cls, this); mPluginPrefs.addAction(action); PluginInfo<T> info = p.getPlugin(); if (info != null) { @@ -154,7 +153,7 @@ public class PluginManagerImpl extends BroadcastReceiver implements PluginManage } mPluginPrefs.addAction(action); PluginInstanceManager p = mFactory.createPluginInstanceManager(mContext, action, listener, - allowMultiple, mBackgroundThread.getLooper(), cls, this); + allowMultiple, mLooper, cls, this); p.loadAll(); mPluginMap.put(listener, p); startListening(); diff --git a/packages/SystemUI/tests/src/com/android/systemui/plugins/PluginManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/plugins/PluginManagerTest.java index a3d5d5fc3871..b8e9fcd29096 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/plugins/PluginManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/plugins/PluginManagerTest.java @@ -29,13 +29,18 @@ import android.net.Uri; import android.support.test.annotation.UiThreadTest; import android.support.test.runner.AndroidJUnit4; import android.test.suitebuilder.annotation.SmallTest; +import android.testing.AndroidTestingRunner; +import android.testing.TestableLooper; +import android.testing.TestableLooper.RunWithLooper; import com.android.internal.messages.nano.SystemMessageProto.SystemMessage; +import com.android.systemui.Dependency; import com.android.systemui.SysuiTestCase; import com.android.systemui.plugins.annotations.ProvidesInterface; import com.android.systemui.plugins.PluginInstanceManager.PluginInfo; import com.android.systemui.plugins.PluginManagerImpl.PluginInstanceManagerFactory; +import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; @@ -45,7 +50,8 @@ import org.mockito.Mockito; import java.lang.Thread.UncaughtExceptionHandler; @SmallTest -@RunWith(AndroidJUnit4.class) +@RunWith(AndroidTestingRunner.class) +@RunWithLooper public class PluginManagerTest extends SysuiTestCase { private PluginInstanceManagerFactory mMockFactory; @@ -59,6 +65,8 @@ public class PluginManagerTest extends SysuiTestCase { @Before public void setup() throws Exception { + mDependency.injectTestDependency(Dependency.BG_LOOPER, + TestableLooper.get(this).getLooper()); mRealExceptionHandler = Thread.getDefaultUncaughtExceptionHandler(); mMockExceptionHandler = mock(UncaughtExceptionHandler.class); mMockFactory = mock(PluginInstanceManagerFactory.class); @@ -72,7 +80,7 @@ public class PluginManagerTest extends SysuiTestCase { mMockListener = mock(PluginListener.class); } - @UiThreadTest + @RunWithLooper(setAsMainLooper = true) @Test public void testOneShot() { Plugin mockPlugin = mock(Plugin.class); diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto index fb714b9b191a..57d25819654f 100644 --- a/proto/src/metrics_constants.proto +++ b/proto/src/metrics_constants.proto @@ -3780,6 +3780,9 @@ message MetricsEvent { // meta-event: a reader has checkpointed the log here. METRICS_CHECKPOINT = 920; + // OPEN: Settings -> Display -> When in VR Mode + VR_DISPLAY_PREFERENCE = 921; + // ---- End O Constants, all O constants go above this line ---- // Add new aosp constants above this line. diff --git a/services/core/java/com/android/server/security/KeyAttestationApplicationIdProviderService.java b/services/core/java/com/android/server/security/KeyAttestationApplicationIdProviderService.java index 0b80d819fd80..ab9ab6713eea 100644 --- a/services/core/java/com/android/server/security/KeyAttestationApplicationIdProviderService.java +++ b/services/core/java/com/android/server/security/KeyAttestationApplicationIdProviderService.java @@ -21,6 +21,7 @@ import android.content.Context; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; +import android.os.Binder; import android.os.RemoteException; import android.os.UserHandle; import android.security.keymaster.KeyAttestationPackageInfo; @@ -45,14 +46,19 @@ public class KeyAttestationApplicationIdProviderService public KeyAttestationApplicationId getKeyAttestationApplicationId(int uid) throws RemoteException { - String[] packageNames = mPackageManager.getPackagesForUid(uid); - if (packageNames == null) { - throw new RemoteException("No packages for uid"); + if (Binder.getCallingUid() != android.os.Process.KEYSTORE_UID) { + throw new SecurityException("This service can only be used by Keystore"); } - int userId = UserHandle.getUserId(uid); - KeyAttestationPackageInfo[] keyAttestationPackageInfos = - new KeyAttestationPackageInfo[packageNames.length]; + KeyAttestationPackageInfo[] keyAttestationPackageInfos = null; + final long token = Binder.clearCallingIdentity(); try { + String[] packageNames = mPackageManager.getPackagesForUid(uid); + if (packageNames == null) { + throw new RemoteException("No packages for uid"); + } + int userId = UserHandle.getUserId(uid); + keyAttestationPackageInfos = new KeyAttestationPackageInfo[packageNames.length]; + for (int i = 0; i < packageNames.length; ++i) { PackageInfo packageInfo = mPackageManager.getPackageInfoAsUser(packageNames[i], PackageManager.GET_SIGNATURES, userId); @@ -61,6 +67,8 @@ public class KeyAttestationApplicationIdProviderService } } catch (NameNotFoundException nnfe) { throw new RemoteException(nnfe.getMessage()); + } finally { + Binder.restoreCallingIdentity(token); } return new KeyAttestationApplicationId(keyAttestationPackageInfos); } diff --git a/services/core/java/com/android/server/security/KeyChainSystemService.java b/services/core/java/com/android/server/security/KeyChainSystemService.java index bfeaee6af7c4..2f681a3f568e 100644 --- a/services/core/java/com/android/server/security/KeyChainSystemService.java +++ b/services/core/java/com/android/server/security/KeyChainSystemService.java @@ -22,10 +22,13 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; +import android.os.Process; import android.os.UserHandle; import android.security.IKeyChainService; import android.util.Slog; +import com.android.server.DeviceIdleController; +import com.android.server.LocalServices; import com.android.server.SystemService; /** @@ -45,6 +48,11 @@ public class KeyChainSystemService extends SystemService { private static final String TAG = "KeyChainSystemService"; + /** + * Maximum time limit for the KeyChain app to deal with packages being removed. + */ + private static final int KEYCHAIN_IDLE_WHITELIST_DURATION_MS = 30 * 1000; + public KeyChainSystemService(final Context context) { super(context); } @@ -77,10 +85,25 @@ public class KeyChainSystemService extends SystemService { } intent.setComponent(service); intent.setAction(broadcastIntent.getAction()); - getContext().startServiceAsUser(intent, UserHandle.of(getSendingUserId())); + startServiceInBackgroundAsUser(intent, UserHandle.of(getSendingUserId())); } catch (RuntimeException e) { Slog.e(TAG, "Unable to forward package removed broadcast to KeyChain", e); } } }; + + + private void startServiceInBackgroundAsUser(final Intent intent, final UserHandle user) { + if (intent.getComponent() == null) { + return; + } + + final String packageName = intent.getComponent().getPackageName(); + final DeviceIdleController.LocalService idleController = + LocalServices.getService(DeviceIdleController.LocalService.class); + idleController.addPowerSaveTempWhitelistApp(Process.myUid(), packageName, + KEYCHAIN_IDLE_WHITELIST_DURATION_MS, user.getIdentifier(), false, "keychain"); + + getContext().startServiceAsUser(intent, user); + } } diff --git a/wifi/java/android/net/wifi/IconInfo.aidl b/wifi/java/android/net/wifi/IconInfo.aidl deleted file mode 100644 index a7bb2ef8bc3f..000000000000 --- a/wifi/java/android/net/wifi/IconInfo.aidl +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Copyright (c) 2017, The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.wifi; - -parcelable IconInfo; diff --git a/wifi/java/android/net/wifi/IconInfo.java b/wifi/java/android/net/wifi/IconInfo.java deleted file mode 100644 index 0eae363861f8..000000000000 --- a/wifi/java/android/net/wifi/IconInfo.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package android.net.wifi; - -import android.os.Parcelable; -import android.text.TextUtils; -import android.os.Parcel; - -import java.util.Arrays; -import java.util.Objects; - -/** - * A class representing icon information. - */ -public final class IconInfo implements Parcelable { - /** - * Name of the icon file. - */ - private final String mFilename; - - /** - * Raw binary data of the icon. - */ - private final byte[] mData; - - public IconInfo(String filename, byte[] data) { - mFilename = filename; - mData = data; - } - - public IconInfo(IconInfo source) { - if (source == null) { - mFilename = null; - mData = null; - return; - } - - mFilename = source.mFilename; - if (source.mData != null) { - mData = Arrays.copyOf(source.mData, source.mData.length); - } else { - mData = null; - } - } - - public String getFilename() { - return mFilename; - } - - public byte[] getData() { - return mData; - } - - @Override - public boolean equals(Object thatObject) { - if (this == thatObject) { - return true; - } - if (!(thatObject instanceof IconInfo)) { - return false; - } - IconInfo that = (IconInfo) thatObject; - return TextUtils.equals(mFilename, that.mFilename) - && Arrays.equals(mData, that.mData); - } - - @Override - public int hashCode() { - return Objects.hash(mFilename, mData); - } - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(mFilename); - dest.writeByteArray(mData); - } - - public static final Creator<IconInfo> CREATOR = - new Creator<IconInfo>() { - @Override - public IconInfo createFromParcel(Parcel in) { - String filename = in.readString(); - byte[] data = in.createByteArray(); - return new IconInfo(filename, data); - } - - @Override - public IconInfo[] newArray(int size) { - return new IconInfo[size]; - } - }; -} diff --git a/wifi/java/android/net/wifi/WifiManager.java b/wifi/java/android/net/wifi/WifiManager.java index 4f2881b87616..824c436ac9fd 100644 --- a/wifi/java/android/net/wifi/WifiManager.java +++ b/wifi/java/android/net/wifi/WifiManager.java @@ -120,7 +120,8 @@ public class WifiManager { * * Included extras: * {@link #EXTRA_BSSID_LONG} - * {@link #EXTRA_ICON_INFO} + * {@link #EXTRA_FILENAME} + * {@link #EXTRA_ICON} * * Receiver Required Permission: android.Manifest.permission.ACCESS_WIFI_STATE * @@ -136,12 +137,18 @@ public class WifiManager { */ public static final String EXTRA_BSSID_LONG = "android.net.wifi.extra.BSSID_LONG"; /** - * Icon information. + * Icon data. * * Retrieve with {@link android.content.Intent#getParcelableExtra(String)} and cast into - * {@link IconInfo}. + * {@link android.graphics.drawable.Icon}. */ - public static final String EXTRA_ICON_INFO = "android.net.wifi.extra.ICON_INFO"; + public static final String EXTRA_ICON = "android.net.wifi.extra.ICON"; + /** + * Name of a file. + * + * Retrieve with {@link android.content.Intent#getStringExtra(String)}. + */ + public static final String EXTRA_FILENAME = "android.net.wifi.extra.FILENAME"; /** * Broadcast intent action indicating a Passpoint OSU Providers List element has been received. @@ -984,9 +991,9 @@ public class WifiManager { /** * Query for a Hotspot 2.0 release 2 OSU icon file. An {@link #ACTION_PASSPOINT_ICON} intent - * will be broadcasted once the request is completed. The return value of - * {@link IconInfo#getData} from the intent extra will indicate the result of the request. - * A value of {@code null} will indicate a failure. + * will be broadcasted once the request is completed. The presence of the intent extra + * {@link #EXTRA_ICON} will indicate the result of the request. + * A missing intent extra {@link #EXTRA_ICON} will indicate a failure. * * @param bssid The BSSID of the AP * @param fileName Name of the icon file (remote file) to query from the AP diff --git a/wifi/tests/src/android/net/wifi/IconInfoTest.java b/wifi/tests/src/android/net/wifi/IconInfoTest.java deleted file mode 100644 index 2fdb484fce19..000000000000 --- a/wifi/tests/src/android/net/wifi/IconInfoTest.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (C) 2017 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License - */ - -package android.net.wifi; - -import static org.junit.Assert.assertEquals; - -import android.net.wifi.IconInfo; -import android.os.Parcel; -import android.test.suitebuilder.annotation.SmallTest; - -import org.junit.Test; - -/** - * Unit tests for {@link android.net.wifi.IconInfo}. - */ -@SmallTest -public class IconInfoTest { - private static final String TEST_FILENAME = "testIcon"; - private static final byte[] TEST_DATA = new byte[] {0x12, 0x23, 0x34, 0x45, 0x56, 0x67}; - - /** - * Verify parcel write and read consistency for the given {@link IconInfo} - * - * @param writeIcon the {@link IconInfo} to write and verify - * @throws Exception - */ - private static void verifyParcel(IconInfo writeIcon) throws Exception { - Parcel parcel = Parcel.obtain(); - writeIcon.writeToParcel(parcel, 0); - - parcel.setDataPosition(0); // Rewind data position back to the beginning for read. - IconInfo readIcon = IconInfo.CREATOR.createFromParcel(parcel); - assertEquals(writeIcon, readIcon); - } - - /** - * Verify parcel serialization for a {@link IconInfo} with null data. - * - * @throws Exception - */ - @Test - public void verifyParcelWithNullData() throws Exception { - verifyParcel(new IconInfo(TEST_FILENAME, (byte[]) null)); - } - - /** - * Verify parcel serialization for a {@link IconInfo} with zero length data. - * - * @throws Exception - */ - @Test - public void verifyParcelWithZeroLengthData() throws Exception { - verifyParcel(new IconInfo(TEST_FILENAME, new byte[0])); - } - - /** - * Verify parcel serialization for a {@link IconInfo} with non-zero length data. - * - * @throws Exception - */ - @Test - public void verifyParcelWithNonZeroLengthData() throws Exception { - verifyParcel(new IconInfo(TEST_FILENAME, TEST_DATA)); - } - - /** - * Verify parcel serialization for a {@link IconInfo} with a null filename. - * - * @throws Exception - */ - @Test - public void verifyParcelWithNullFilename() throws Exception { - verifyParcel(new IconInfo(null, TEST_DATA)); - } - - /** - * Verify the copy constructor with non-null filename and data. - * - * @throws Exception - */ - @Test - public void verifyCopyConstructor() throws Exception { - IconInfo source = new IconInfo(TEST_FILENAME, TEST_DATA); - assertEquals(source, new IconInfo(source)); - } - - /** - * Verify the copy constructor with null data. - * - * @throws Exception - */ - @Test - public void verifyCopyConstructorWithNullData() throws Exception { - IconInfo source = new IconInfo(TEST_FILENAME, (byte[]) null); - assertEquals(source, new IconInfo(source)); - } - - /** - * Verify the copy constructor with null file name. - * - * @throws Exception - */ - @Test - public void verifyCopyConstructorWithNullFilename() throws Exception { - IconInfo source = new IconInfo(null, TEST_DATA); - assertEquals(source, new IconInfo(source)); - } -} |