Merge "MediaControlView2: Add Support for Ad"
diff --git a/core/java/android/app/slice/ISliceManager.aidl b/core/java/android/app/slice/ISliceManager.aidl
index 38d9025..20ec75a 100644
--- a/core/java/android/app/slice/ISliceManager.aidl
+++ b/core/java/android/app/slice/ISliceManager.aidl
@@ -16,17 +16,13 @@
package android.app.slice;
-import android.app.slice.ISliceListener;
import android.app.slice.SliceSpec;
import android.net.Uri;
/** @hide */
interface ISliceManager {
- void addSliceListener(in Uri uri, String pkg, in ISliceListener listener,
- in SliceSpec[] specs);
- void removeSliceListener(in Uri uri, String pkg, in ISliceListener listener);
- void pinSlice(String pkg, in Uri uri, in SliceSpec[] specs);
- void unpinSlice(String pkg, in Uri uri);
+ void pinSlice(String pkg, in Uri uri, in SliceSpec[] specs, in IBinder token);
+ void unpinSlice(String pkg, in Uri uri, in IBinder token);
boolean hasSliceAccess(String pkg);
SliceSpec[] getPinnedSpecs(in Uri uri, String pkg);
int checkSlicePermission(in Uri uri, String pkg, int pid, int uid);
diff --git a/core/java/android/app/slice/SliceManager.java b/core/java/android/app/slice/SliceManager.java
index a978e5b..e2c8662 100644
--- a/core/java/android/app/slice/SliceManager.java
+++ b/core/java/android/app/slice/SliceManager.java
@@ -26,8 +26,10 @@
import android.content.Intent;
import android.content.pm.ResolveInfo;
import android.net.Uri;
+import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
+import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.ServiceManager.ServiceNotFoundException;
@@ -73,6 +75,7 @@
private final Context mContext;
private final ArrayMap<Pair<Uri, SliceCallback>, ISliceListener> mListenerLookup =
new ArrayMap<>();
+ private final IBinder mToken = new Binder();
/**
* Permission denied.
@@ -105,7 +108,6 @@
@Deprecated
public void registerSliceCallback(@NonNull Uri uri, @NonNull SliceCallback callback,
@NonNull List<SliceSpec> specs) {
- registerSliceCallback(uri, specs, mContext.getMainExecutor(), callback);
}
/**
@@ -114,7 +116,6 @@
@Deprecated
public void registerSliceCallback(@NonNull Uri uri, @NonNull SliceCallback callback,
@NonNull List<SliceSpec> specs, Executor executor) {
- registerSliceCallback(uri, specs, executor, callback);
}
/**
@@ -132,7 +133,6 @@
*/
public void registerSliceCallback(@NonNull Uri uri, @NonNull List<SliceSpec> specs,
@NonNull SliceCallback callback) {
- registerSliceCallback(uri, specs, mContext.getMainExecutor(), callback);
}
/**
@@ -150,32 +150,7 @@
*/
public void registerSliceCallback(@NonNull Uri uri, @NonNull List<SliceSpec> specs,
@NonNull @CallbackExecutor Executor executor, @NonNull SliceCallback callback) {
- try {
- mService.addSliceListener(uri, mContext.getPackageName(),
- getListener(uri, callback, new ISliceListener.Stub() {
- @Override
- public void onSliceUpdated(Slice s) throws RemoteException {
- executor.execute(() -> callback.onSliceUpdated(s));
- }
- }), specs.toArray(new SliceSpec[specs.size()]));
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
- private ISliceListener getListener(Uri uri, SliceCallback callback,
- ISliceListener listener) {
- Pair<Uri, SliceCallback> key = new Pair<>(uri, callback);
- if (mListenerLookup.containsKey(key)) {
- try {
- mService.removeSliceListener(uri, mContext.getPackageName(),
- mListenerLookup.get(key));
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
- mListenerLookup.put(key, listener);
- return listener;
}
/**
@@ -189,12 +164,7 @@
* @see #registerSliceCallback
*/
public void unregisterSliceCallback(@NonNull Uri uri, @NonNull SliceCallback callback) {
- try {
- mService.removeSliceListener(uri, mContext.getPackageName(),
- mListenerLookup.remove(new Pair<>(uri, callback)));
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+
}
/**
@@ -215,7 +185,7 @@
public void pinSlice(@NonNull Uri uri, @NonNull List<SliceSpec> specs) {
try {
mService.pinSlice(mContext.getPackageName(), uri,
- specs.toArray(new SliceSpec[specs.size()]));
+ specs.toArray(new SliceSpec[specs.size()]), mToken);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -237,7 +207,7 @@
*/
public void unpinSlice(@NonNull Uri uri) {
try {
- mService.unpinSlice(mContext.getPackageName(), uri);
+ mService.unpinSlice(mContext.getPackageName(), uri, mToken);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/tests/overlaytests/host/test-apps/UpdateOverlay/Android.mk b/core/tests/overlaytests/host/test-apps/UpdateOverlay/Android.mk
index bd6d73d..d26425b 100644
--- a/core/tests/overlaytests/host/test-apps/UpdateOverlay/Android.mk
+++ b/core/tests/overlaytests/host/test-apps/UpdateOverlay/Android.mk
@@ -56,7 +56,7 @@
LOCAL_AAPT_FLAGS := --custom-package $(my_package_prefix)_v1
LOCAL_AAPT_FLAGS += --version-code 1 --version-name v1
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/app/v1/res
-LOCAL_MANIFEST_FILE := app/AndroidManifest.xml
+LOCAL_MANIFEST_FILE := app/v1/AndroidManifest.xml
include $(BUILD_PACKAGE)
include $(CLEAR_VARS)
@@ -67,7 +67,7 @@
LOCAL_AAPT_FLAGS := --custom-package $(my_package_prefix)_v2
LOCAL_AAPT_FLAGS += --version-code 2 --version-name v2
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/app/v2/res
-LOCAL_MANIFEST_FILE := app/AndroidManifest.xml
+LOCAL_MANIFEST_FILE := app/v2/AndroidManifest.xml
include $(BUILD_PACKAGE)
my_package_prefix :=
diff --git a/core/tests/overlaytests/host/test-apps/UpdateOverlay/app/AndroidManifest.xml b/core/tests/overlaytests/host/test-apps/UpdateOverlay/app/v1/AndroidManifest.xml
similarity index 100%
rename from core/tests/overlaytests/host/test-apps/UpdateOverlay/app/AndroidManifest.xml
rename to core/tests/overlaytests/host/test-apps/UpdateOverlay/app/v1/AndroidManifest.xml
diff --git a/core/tests/overlaytests/host/test-apps/UpdateOverlay/app/v2/AndroidManifest.xml b/core/tests/overlaytests/host/test-apps/UpdateOverlay/app/v2/AndroidManifest.xml
new file mode 100644
index 0000000..9ec7d06
--- /dev/null
+++ b/core/tests/overlaytests/host/test-apps/UpdateOverlay/app/v2/AndroidManifest.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2018 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.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.server.om.hosttest.app_overlay">
+ <overlay android:targetPackage="com.android.server.om.hosttest.update_overlay_test"
+ android:category="android.theme" />
+</manifest>
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/CustomEditTextPreferenceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/CustomEditTextPreferenceTest.java
index f50c0a4..9d7f59a 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/CustomEditTextPreferenceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/CustomEditTextPreferenceTest.java
@@ -26,7 +26,6 @@
import android.widget.EditText;
import org.junit.Before;
-import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -35,7 +34,6 @@
import org.robolectric.util.ReflectionHelpers;
@RunWith(SettingsLibRobolectricTestRunner.class)
-@Ignore
public class CustomEditTextPreferenceTest {
@Mock
@@ -50,7 +48,6 @@
}
@Test
- @Ignore
public void bindDialogView_shouldRequestFocus() {
final String testText = "";
final EditText editText = spy(new EditText(RuntimeEnvironment.application));
@@ -63,7 +60,6 @@
}
@Test
- @Ignore
public void getEditText_noDialog_shouldNotCrash() {
ReflectionHelpers.setField(mPreference, "mFragment",
mock(CustomEditTextPreference.CustomPreferenceDialogFragment.class));
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
index 5d1bdab..deb975b 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSliceView.java
@@ -160,8 +160,8 @@
mRow.addView(button);
PendingIntent pendingIntent = null;
- if (rc.getContentIntent() != null) {
- pendingIntent = rc.getContentIntent().getAction();
+ if (rc.getPrimaryAction() != null) {
+ pendingIntent = rc.getPrimaryAction().getAction();
}
mClickActions.put(button, pendingIntent);
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index db62961..05237af 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -524,6 +524,7 @@
private void addCompatibilityModeRequestsLocked(@NonNull AutofillManagerServiceImpl service
, int userId) {
+ mAutofillCompatState.reset();
final ArrayMap<String, Pair<Long, String>> compatPackages =
service.getCompatibilityPackagesLocked();
if (compatPackages == null || compatPackages.isEmpty()) {
@@ -626,6 +627,15 @@
}
}
}
+
+ void reset() {
+ synchronized (mLock) {
+ if (mUserSpecs != null) {
+ mUserSpecs.clear();
+ mUserSpecs = null;
+ }
+ }
+ }
}
final class AutoFillManagerServiceStub extends IAutoFillManager.Stub {
@@ -1045,6 +1055,9 @@
Settings.Secure.AUTOFILL_SERVICE), false, this, UserHandle.USER_ALL);
resolver.registerContentObserver(Settings.Secure.getUriFor(
Settings.Secure.USER_SETUP_COMPLETE), false, this, UserHandle.USER_ALL);
+ resolver.registerContentObserver(Settings.Global.getUriFor(
+ Settings.Global.AUTOFILL_COMPAT_ALLOWED_PACKAGES), false, this,
+ UserHandle.USER_ALL);
}
@Override
diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java
index 7467954..fd51be5 100644
--- a/services/core/java/com/android/server/om/OverlayManagerService.java
+++ b/services/core/java/com/android/server/om/OverlayManagerService.java
@@ -64,6 +64,8 @@
import com.android.server.pm.Installer;
import com.android.server.pm.UserManagerService;
+import libcore.util.EmptyArray;
+
import org.xmlpull.v1.XmlPullParserException;
import java.io.File;
@@ -303,10 +305,10 @@
schedulePersistSettings();
}
- private static Set<String> getDefaultOverlayPackages() {
+ private static String[] getDefaultOverlayPackages() {
final String str = SystemProperties.get(DEFAULT_OVERLAYS_PROP);
if (TextUtils.isEmpty(str)) {
- return Collections.emptySet();
+ return EmptyArray.STRING;
}
final ArraySet<String> defaultPackages = new ArraySet<>();
@@ -315,7 +317,7 @@
defaultPackages.add(packageName);
}
}
- return defaultPackages;
+ return defaultPackages.toArray(new String[defaultPackages.size()]);
}
private final class PackageReceiver extends BroadcastReceiver {
diff --git a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
index 43b1708..74eb2ea 100644
--- a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
+++ b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java
@@ -60,13 +60,13 @@
private final PackageManagerHelper mPackageManager;
private final IdmapManager mIdmapManager;
private final OverlayManagerSettings mSettings;
- private final Set<String> mDefaultOverlays;
+ private final String[] mDefaultOverlays;
private final OverlayChangeListener mListener;
OverlayManagerServiceImpl(@NonNull final PackageManagerHelper packageManager,
@NonNull final IdmapManager idmapManager,
@NonNull final OverlayManagerSettings settings,
- @NonNull final Set<String> defaultOverlays,
+ @NonNull final String[] defaultOverlays,
@NonNull final OverlayChangeListener listener) {
mPackageManager = packageManager;
mIdmapManager = idmapManager;
@@ -104,31 +104,27 @@
for (int i = 0; i < overlayPackagesSize; i++) {
final PackageInfo overlayPackage = overlayPackages.get(i);
final OverlayInfo oi = storedOverlayInfos.get(overlayPackage.packageName);
- if (oi == null || !oi.targetPackageName.equals(overlayPackage.overlayTarget)
- || !Objects.equals(oi.category, overlayPackage.overlayCategory)) {
- // Update the overlay if it didn't exist or had the wrong target package.
+ if (oi == null || !oi.targetPackageName.equals(overlayPackage.overlayTarget)) {
+ // Reset the overlay if it didn't exist or had the wrong target package.
mSettings.init(overlayPackage.packageName, newUserId,
overlayPackage.overlayTarget,
overlayPackage.applicationInfo.getBaseCodePath(),
- overlayPackage.isStaticOverlayPackage(), overlayPackage.overlayPriority,
+ overlayPackage.isStaticOverlayPackage(),
+ overlayPackage.overlayPriority,
overlayPackage.overlayCategory);
- if (oi == null) {
- // This overlay does not exist in our settings.
- if (overlayPackage.isStaticOverlayPackage() ||
- mDefaultOverlays.contains(overlayPackage.packageName)) {
- // Enable this overlay by default.
- if (DEBUG) {
- Slog.d(TAG, "Enabling overlay " + overlayPackage.packageName
- + " for user " + newUserId + " by default");
- }
- mSettings.setEnabled(overlayPackage.packageName, newUserId, true);
- }
- } else {
+ if (oi != null) {
// The targetPackageName we have stored doesn't match the overlay's target.
// Queue the old target for an update as well.
packagesToUpdateAssets.add(oi.targetPackageName);
}
+ } else {
+ // Update all other components of an overlay that don't require a hard reset.
+ if (!Objects.equals(oi.category, overlayPackage.overlayCategory)) {
+ // When changing categories, it is ok just to update our internal state.
+ mSettings.setCategory(overlayPackage.packageName, newUserId,
+ overlayPackage.overlayCategory);
+ }
}
try {
@@ -160,6 +156,42 @@
iter.remove();
}
}
+
+ // Collect all of the categories in which we have at least one overlay enabled.
+ final ArraySet<String> enabledCategories = new ArraySet<>();
+ final ArrayMap<String, List<OverlayInfo>> userOverlays =
+ mSettings.getOverlaysForUser(newUserId);
+ final int userOverlayTargetCount = userOverlays.size();
+ for (int i = 0; i < userOverlayTargetCount; i++) {
+ final List<OverlayInfo> overlayList = userOverlays.valueAt(i);
+ final int overlayCount = overlayList != null ? overlayList.size() : 0;
+ for (int j = 0; j < overlayCount; j++) {
+ final OverlayInfo oi = overlayList.get(j);
+ if (oi.isEnabled()) {
+ enabledCategories.add(oi.category);
+ }
+ }
+ }
+
+ // Enable the default overlay if its category does not have a single overlay enabled.
+ for (final String defaultOverlay : mDefaultOverlays) {
+ try {
+ final OverlayInfo oi = mSettings.getOverlayInfo(defaultOverlay, newUserId);
+ if (!enabledCategories.contains(oi.category)) {
+ Slog.w(TAG, "Enabling default overlay '" + defaultOverlay + "' for target '"
+ + oi.targetPackageName + "' in category '" + oi.category + "' for user "
+ + newUserId);
+ mSettings.setEnabled(oi.packageName, newUserId, true);
+ if (updateState(oi.targetPackageName, oi.packageName, newUserId, 0)) {
+ packagesToUpdateAssets.add(oi.targetPackageName);
+ }
+ }
+ } catch (OverlayManagerSettings.BadKeyException e) {
+ Slog.e(TAG, "Failed to set default overlay '" + defaultOverlay + "' for user "
+ + newUserId, e);
+ }
+ }
+
return new ArrayList<>(packagesToUpdateAssets);
}
@@ -325,6 +357,11 @@
mSettings.init(packageName, userId, pkg.overlayTarget,
pkg.applicationInfo.getBaseCodePath(), pkg.isStaticOverlayPackage(),
pkg.overlayPriority, pkg.overlayCategory);
+ } else {
+ if (!Objects.equals(oldOi.category, pkg.overlayCategory)) {
+ // Update the category in-place.
+ mSettings.setCategory(packageName, userId, pkg.overlayCategory);
+ }
}
if (updateState(pkg.overlayTarget, packageName, userId, 0)) {
diff --git a/services/core/java/com/android/server/om/OverlayManagerSettings.java b/services/core/java/com/android/server/om/OverlayManagerSettings.java
index e57fa0b..0b9412b 100644
--- a/services/core/java/com/android/server/om/OverlayManagerSettings.java
+++ b/services/core/java/com/android/server/om/OverlayManagerSettings.java
@@ -20,6 +20,7 @@
import static com.android.server.om.OverlayManagerService.TAG;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.content.om.OverlayInfo;
import android.util.ArrayMap;
import android.util.Slog;
@@ -39,6 +40,7 @@
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
+import java.util.Objects;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -70,6 +72,9 @@
new SettingsItem(packageName, userId, targetPackageName, baseCodePath,
isStatic, priority, overlayCategory);
if (isStatic) {
+ // All static overlays are always enabled.
+ item.setEnabled(true);
+
int i;
for (i = mItems.size() - 1; i >= 0; i--) {
SettingsItem parentItem = mItems.get(i);
@@ -122,6 +127,15 @@
return mItems.get(idx).setBaseCodePath(path);
}
+ boolean setCategory(@NonNull final String packageName, final int userId,
+ @Nullable String category) throws BadKeyException {
+ final int idx = select(packageName, userId);
+ if (idx < 0) {
+ throw new BadKeyException(packageName, userId);
+ }
+ return mItems.get(idx).setCategory(category);
+ }
+
boolean getEnabled(@NonNull final String packageName, final int userId) throws BadKeyException {
final int idx = select(packageName, userId);
if (idx < 0) {
@@ -420,7 +434,7 @@
private OverlayInfo mCache;
private boolean mIsStatic;
private int mPriority;
- private final String mCategory;
+ private String mCategory;
SettingsItem(@NonNull final String packageName, final int userId,
@NonNull final String targetPackageName, @NonNull final String baseCodePath,
@@ -431,7 +445,7 @@
mTargetPackageName = targetPackageName;
mBaseCodePath = baseCodePath;
mState = state;
- mIsEnabled = isEnabled;
+ mIsEnabled = isEnabled || isStatic;
mCategory = category;
mCache = null;
mIsStatic = isStatic;
@@ -483,7 +497,11 @@
return mIsEnabled;
}
- private boolean setEnabled(final boolean enable) {
+ private boolean setEnabled(boolean enable) {
+ if (mIsStatic) {
+ return false;
+ }
+
if (mIsEnabled != enable) {
mIsEnabled = enable;
invalidateCache();
@@ -492,6 +510,15 @@
return false;
}
+ private boolean setCategory(String category) {
+ if (!Objects.equals(mCategory, category)) {
+ mCategory = category.intern();
+ invalidateCache();
+ return true;
+ }
+ return false;
+ }
+
private OverlayInfo getOverlayInfo() {
if (mCache == null) {
mCache = new OverlayInfo(mPackageName, mTargetPackageName, mCategory, mBaseCodePath,
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 7a5a6c5..1b4a733 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -5244,9 +5244,7 @@
final boolean attachedInParent = attached != null && !layoutInScreen;
// Ensure that windows with a DEFAULT or NEVER display cutout mode are laid out in
// the cutout safe zone.
- // Windows that are attached to a parent and laid out in said parent are already avoiding
- // the cutout according to that parent and don't need to be further constrained.
- if (cutoutMode != LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS && !attachedInParent) {
+ if (cutoutMode != LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS) {
final Rect displayCutoutSafeExceptMaybeTop = mTmpRect;
displayCutoutSafeExceptMaybeTop.set(displayFrames.mDisplayCutoutSafe);
if (layoutInScreen && layoutInsetDecor && !requestedFullscreen
@@ -5257,7 +5255,14 @@
// the window from that area.
displayCutoutSafeExceptMaybeTop.top = Integer.MIN_VALUE;
}
- pf.intersectUnchecked(displayCutoutSafeExceptMaybeTop);
+ // Windows that are attached to a parent and laid out in said parent are already
+ // avoidingthe cutout according to that parent and don't need to be further constrained.
+ if (!attachedInParent) {
+ pf.intersectUnchecked(displayCutoutSafeExceptMaybeTop);
+ }
+ // Make sure that NO_LIMITS windows clipped to the display don't extend into the display
+ // don't extend under the cutout.
+ df.intersectUnchecked(displayCutoutSafeExceptMaybeTop);
}
// Content should never appear in the cutout.
diff --git a/services/core/java/com/android/server/slice/PinnedSliceState.java b/services/core/java/com/android/server/slice/PinnedSliceState.java
index 8da16d7..f9a4ea2 100644
--- a/services/core/java/com/android/server/slice/PinnedSliceState.java
+++ b/services/core/java/com/android/server/slice/PinnedSliceState.java
@@ -16,7 +16,6 @@
import static android.app.slice.SliceManager.PERMISSION_GRANTED;
-import android.app.slice.ISliceListener;
import android.app.slice.Slice;
import android.app.slice.SliceProvider;
import android.app.slice.SliceSpec;
@@ -106,10 +105,6 @@
setSlicePinned(false);
}
- public void onChange() {
- mService.getHandler().post(this::handleBind);
- }
-
private void setSlicePinned(boolean pinned) {
synchronized (mLock) {
if (mSlicePinned == pinned) return;
@@ -122,45 +117,23 @@
}
}
- public void addSliceListener(ISliceListener listener, String pkg, SliceSpec[] specs,
- boolean hasPermission) {
+ public void pin(String pkg, SliceSpec[] specs, IBinder token) {
synchronized (mLock) {
- if (mListeners.size() == 0) {
- mService.listen(mUri);
- }
+ mListeners.put(token, new ListenerInfo(token, pkg, true,
+ Binder.getCallingUid(), Binder.getCallingPid()));
try {
- listener.asBinder().linkToDeath(mDeathRecipient, 0);
+ token.linkToDeath(mDeathRecipient, 0);
} catch (RemoteException e) {
}
- mListeners.put(listener.asBinder(), new ListenerInfo(listener, pkg, hasPermission,
- Binder.getCallingUid(), Binder.getCallingPid()));
mergeSpecs(specs);
- setSlicePinned(hasPermission);
- }
- }
-
- public boolean removeSliceListener(ISliceListener listener) {
- synchronized (mLock) {
- listener.asBinder().unlinkToDeath(mDeathRecipient, 0);
- if (mListeners.containsKey(listener.asBinder()) && mListeners.size() == 1) {
- mService.unlisten(mUri);
- }
- mListeners.remove(listener.asBinder());
- }
- return !hasPinOrListener();
- }
-
- public void pin(String pkg, SliceSpec[] specs) {
- synchronized (mLock) {
setSlicePinned(true);
- mPinnedPkgs.add(pkg);
- mergeSpecs(specs);
}
}
- public boolean unpin(String pkg) {
+ public boolean unpin(String pkg, IBinder token) {
synchronized (mLock) {
- mPinnedPkgs.remove(pkg);
+ token.unlinkToDeath(mDeathRecipient, 0);
+ mListeners.remove(token);
}
return !hasPinOrListener();
}
@@ -171,30 +144,6 @@
}
}
- public void recheckPackage(String pkg) {
- synchronized (mLock) {
- for (int i = 0; i < mListeners.size(); i++) {
- ListenerInfo info = mListeners.valueAt(i);
- if (!info.hasPermission && Objects.equals(info.pkg, pkg)) {
- mService.getHandler().post(() -> {
- // This bind lets the app itself participate in the permission grant.
- Slice s = doBind(info);
- if (mService.checkAccess(info.pkg, mUri, info.callingUid, info.callingPid)
- == PERMISSION_GRANTED) {
- info.hasPermission = true;
- setSlicePinned(true);
- try {
- info.listener.onSliceUpdated(s);
- } catch (RemoteException e) {
- checkSelfRemove();
- }
- }
- });
- }
- }
- }
- }
-
@VisibleForTesting
public boolean hasPinOrListener() {
synchronized (mLock) {
@@ -213,7 +162,6 @@
private void checkSelfRemove() {
if (!hasPinOrListener()) {
// All the listeners died, remove from pinned state.
- mService.unlisten(mUri);
mService.removePinnedSlice(mUri);
}
}
@@ -223,7 +171,7 @@
synchronized (mLock) {
for (int i = mListeners.size() - 1; i >= 0; i--) {
ListenerInfo l = mListeners.valueAt(i);
- if (!l.listener.asBinder().isBinderAlive()) {
+ if (!l.token.isBinderAlive()) {
mListeners.removeAt(i);
}
}
@@ -231,62 +179,6 @@
}
}
- private void handleBind() {
- Slice cachedSlice = doBind(null);
- synchronized (mLock) {
- if (!hasPinOrListener()) return;
- for (int i = mListeners.size() - 1; i >= 0; i--) {
- ListenerInfo info = mListeners.valueAt(i);
- Slice s = cachedSlice;
- if (s == null || s.hasHint(Slice.HINT_CALLER_NEEDED)
- || !info.hasPermission) {
- s = doBind(info);
- }
- if (s == null) {
- mListeners.removeAt(i);
- continue;
- }
- try {
- info.listener.onSliceUpdated(s);
- } catch (RemoteException e) {
- Log.e(TAG, "Unable to notify slice " + mUri, e);
- mListeners.removeAt(i);
- continue;
- }
- }
- checkSelfRemove();
- }
- }
-
- private Slice doBind(ListenerInfo info) {
- try (ContentProviderClient client = getClient()) {
- if (client == null) return null;
- Bundle extras = new Bundle();
- extras.putParcelable(SliceProvider.EXTRA_BIND_URI, mUri);
- extras.putParcelableArrayList(SliceProvider.EXTRA_SUPPORTED_SPECS,
- new ArrayList<>(Arrays.asList(mSupportedSpecs)));
- if (info != null) {
- extras.putString(SliceProvider.EXTRA_OVERRIDE_PKG, info.pkg);
- extras.putInt(SliceProvider.EXTRA_OVERRIDE_UID, info.callingUid);
- extras.putInt(SliceProvider.EXTRA_OVERRIDE_PID, info.callingPid);
- }
- final Bundle res;
- try {
- res = client.call(SliceProvider.METHOD_SLICE, null, extras);
- } catch (RemoteException e) {
- Log.e(TAG, "Unable to bind slice " + mUri, e);
- return null;
- }
- if (res == null) return null;
- Bundle.setDefusable(res, true);
- return res.getParcelable(SliceProvider.EXTRA_SLICE);
- } catch (Throwable t) {
- // Calling out of the system process, make sure they don't throw anything at us.
- Log.e(TAG, "Caught throwable while binding " + mUri, t);
- return null;
- }
- }
-
private void handleSendPinned() {
try (ContentProviderClient client = getClient()) {
if (client == null) return;
@@ -315,15 +207,15 @@
private class ListenerInfo {
- private ISliceListener listener;
+ private IBinder token;
private String pkg;
private boolean hasPermission;
private int callingUid;
private int callingPid;
- public ListenerInfo(ISliceListener listener, String pkg, boolean hasPermission,
+ public ListenerInfo(IBinder token, String pkg, boolean hasPermission,
int callingUid, int callingPid) {
- this.listener = listener;
+ this.token = token;
this.pkg = pkg;
this.hasPermission = hasPermission;
this.callingUid = callingUid;
diff --git a/services/core/java/com/android/server/slice/SliceManagerService.java b/services/core/java/com/android/server/slice/SliceManagerService.java
index a1def44..51e4709 100644
--- a/services/core/java/com/android/server/slice/SliceManagerService.java
+++ b/services/core/java/com/android/server/slice/SliceManagerService.java
@@ -28,7 +28,6 @@
import android.app.AppOpsManager;
import android.app.ContentProviderHolder;
import android.app.IActivityManager;
-import android.app.slice.ISliceListener;
import android.app.slice.ISliceManager;
import android.app.slice.SliceManager;
import android.app.slice.SliceSpec;
@@ -39,7 +38,6 @@
import android.content.IntentFilter;
import android.content.pm.PackageManagerInternal;
import android.content.pm.ResolveInfo;
-import android.database.ContentObserver;
import android.net.Uri;
import android.os.Binder;
import android.os.Environment;
@@ -52,7 +50,6 @@
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.AtomicFile;
-import android.util.Log;
import android.util.Slog;
import android.util.Xml.Encoding;
@@ -94,7 +91,6 @@
@GuardedBy("mLock")
private final ArraySet<SliceGrant> mUserGrants = new ArraySet<>();
private final Handler mHandler;
- private final ContentObserver mObserver;
@GuardedBy("mSliceAccessFile")
private final AtomicFile mSliceAccessFile;
@GuardedBy("mAccessList")
@@ -113,16 +109,6 @@
mAssistUtils = new AssistUtils(context);
mHandler = new Handler(looper);
- mObserver = new ContentObserver(mHandler) {
- @Override
- public void onChange(boolean selfChange, Uri uri, int userId) {
- try {
- getPinnedSlice(maybeAddUserId(uri, userId)).onChange();
- } catch (IllegalStateException e) {
- Log.e(TAG, "Received change for unpinned slice " + uri, e);
- }
- }
- };
final File systemDir = new File(Environment.getDataDirectory(), "system");
mSliceAccessFile = new AtomicFile(new File(systemDir, "slice_access.xml"));
mAccessList = new SliceFullAccessList(mContext);
@@ -163,40 +149,19 @@
/// ----- ISliceManager stuff -----
@Override
- public void addSliceListener(Uri uri, String pkg, ISliceListener listener, SliceSpec[] specs)
- throws RemoteException {
+ public void pinSlice(String pkg, Uri uri, SliceSpec[] specs, IBinder token) throws RemoteException {
verifyCaller(pkg);
+ enforceAccess(pkg, uri);
uri = maybeAddUserId(uri, Binder.getCallingUserHandle().getIdentifier());
- enforceCrossUser(pkg, uri);
- getOrCreatePinnedSlice(uri).addSliceListener(listener, pkg, specs,
- checkAccess(pkg, uri, Binder.getCallingUid(), Binder.getCallingUid())
- == PERMISSION_GRANTED);
+ getOrCreatePinnedSlice(uri).pin(pkg, specs, token);
}
@Override
- public void removeSliceListener(Uri uri, String pkg, ISliceListener listener)
- throws RemoteException {
+ public void unpinSlice(String pkg, Uri uri, IBinder token) throws RemoteException {
verifyCaller(pkg);
+ enforceAccess(pkg, uri);
uri = maybeAddUserId(uri, Binder.getCallingUserHandle().getIdentifier());
- if (getPinnedSlice(uri).removeSliceListener(listener)) {
- removePinnedSlice(uri);
- }
- }
-
- @Override
- public void pinSlice(String pkg, Uri uri, SliceSpec[] specs) throws RemoteException {
- verifyCaller(pkg);
- enforceFullAccess(pkg, "pinSlice", uri);
- uri = maybeAddUserId(uri, Binder.getCallingUserHandle().getIdentifier());
- getOrCreatePinnedSlice(uri).pin(pkg, specs);
- }
-
- @Override
- public void unpinSlice(String pkg, Uri uri) throws RemoteException {
- verifyCaller(pkg);
- enforceFullAccess(pkg, "unpinSlice", uri);
- uri = maybeAddUserId(uri, Binder.getCallingUserHandle().getIdentifier());
- if (getPinnedSlice(uri).unpin(pkg)) {
+ if (getPinnedSlice(uri).unpin(pkg, token)) {
removePinnedSlice(uri);
}
}
@@ -253,11 +218,6 @@
} finally {
Binder.restoreCallingIdentity(ident);
}
- synchronized (mLock) {
- for (PinnedSliceState p : mPinnedSlicesByUri.values()) {
- p.recheckPackage(pkg);
- }
- }
}
// Backup/restore interface
@@ -457,21 +417,6 @@
return cn.getPackageName().equals(pkg);
}
- public void listen(Uri uri) {
- mContext.getContentResolver().registerContentObserver(uri, true, mObserver);
- }
-
- public void unlisten(Uri uri) {
- mContext.getContentResolver().unregisterContentObserver(mObserver);
- synchronized (mLock) {
- mPinnedSlicesByUri.forEach((u, s) -> {
- if (s.isListening()) {
- listen(u);
- }
- });
- }
- }
-
private boolean isDefaultHomeApp(String pkg, int userId) {
String defaultHome = getDefaultHome(userId);
diff --git a/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerLayoutTest.java b/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerLayoutTest.java
index 293f9af..c6800be 100644
--- a/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerLayoutTest.java
+++ b/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerLayoutTest.java
@@ -77,6 +77,7 @@
assertInsetByTopBottom(mAppWindow.stableFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
assertInsetByTopBottom(mAppWindow.contentFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
assertInsetByTopBottom(mAppWindow.decorFrame, 0, 0);
+ assertInsetBy(mAppWindow.displayFrame, 0, 0, 0, 0);
}
@Test
@@ -91,6 +92,7 @@
assertInsetByTopBottom(mAppWindow.stableFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
assertInsetByTopBottom(mAppWindow.contentFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
assertInsetByTopBottom(mAppWindow.decorFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mAppWindow.displayFrame, 0, NAV_BAR_HEIGHT);
}
@Test
@@ -106,6 +108,7 @@
assertInsetByTopBottom(mAppWindow.stableFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
assertInsetByTopBottom(mAppWindow.contentFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
assertInsetByTopBottom(mAppWindow.decorFrame, 0, NAV_BAR_HEIGHT);
+ assertInsetByTopBottom(mAppWindow.displayFrame, 0, NAV_BAR_HEIGHT);
}
@Test
@@ -130,6 +133,7 @@
assertInsetByTopBottom(mAppWindow.stableFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
assertInsetByTopBottom(mAppWindow.contentFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
assertInsetByTopBottom(mAppWindow.decorFrame, 0, 0);
+ assertInsetByTopBottom(mAppWindow.displayFrame, 0, 0);
}
@Test
@@ -146,6 +150,7 @@
assertInsetByTopBottom(mAppWindow.stableFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
assertInsetByTopBottom(mAppWindow.contentFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
assertInsetByTopBottom(mAppWindow.decorFrame, 0, 0);
+ assertInsetByTopBottom(mAppWindow.displayFrame, STATUS_BAR_HEIGHT, 0);
}
@Test
@@ -162,6 +167,7 @@
assertInsetByTopBottom(mAppWindow.stableFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
assertInsetByTopBottom(mAppWindow.contentFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
assertInsetByTopBottom(mAppWindow.decorFrame, 0, 0);
+ assertInsetBy(mAppWindow.displayFrame, 0, 0, 0, 0);
}
@Test
@@ -178,6 +184,7 @@
assertInsetByTopBottom(mAppWindow.stableFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
assertInsetByTopBottom(mAppWindow.contentFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
assertInsetByTopBottom(mAppWindow.decorFrame, 0, 0);
+ assertInsetByTopBottom(mAppWindow.displayFrame, STATUS_BAR_HEIGHT, 0);
}
@Test
@@ -195,6 +202,7 @@
assertInsetByTopBottom(mAppWindow.stableFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
assertInsetByTopBottom(mAppWindow.contentFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT);
assertInsetByTopBottom(mAppWindow.decorFrame, 0, 0);
+ assertInsetByTopBottom(mAppWindow.displayFrame, 0, 0);
}
@@ -212,6 +220,7 @@
assertInsetBy(mAppWindow.contentFrame,
DISPLAY_CUTOUT_HEIGHT, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT, 0);
assertInsetBy(mAppWindow.decorFrame, 0, 0, 0, 0);
+ assertInsetBy(mAppWindow.displayFrame, DISPLAY_CUTOUT_HEIGHT, 0, 0, 0);
}
@Test
@@ -228,6 +237,7 @@
assertInsetBy(mAppWindow.contentFrame,
NAV_BAR_HEIGHT, STATUS_BAR_HEIGHT, DISPLAY_CUTOUT_HEIGHT, 0);
assertInsetBy(mAppWindow.decorFrame, 0, 0, 0, 0);
+ assertInsetBy(mAppWindow.displayFrame, 0, 0, DISPLAY_CUTOUT_HEIGHT, 0);
}
@Test
diff --git a/services/tests/uiservicestests/src/com/android/server/slice/PinnedSliceStateTest.java b/services/tests/uiservicestests/src/com/android/server/slice/PinnedSliceStateTest.java
index cfd155e..1052e8f 100644
--- a/services/tests/uiservicestests/src/com/android/server/slice/PinnedSliceStateTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/slice/PinnedSliceStateTest.java
@@ -71,6 +71,7 @@
private PinnedSliceState mPinnedSliceManager;
private IContentProvider mIContentProvider;
private ContentProvider mContentProvider;
+ private IBinder mToken = new Binder();
@Before
public void setup() {
@@ -108,7 +109,7 @@
TestableLooper.get(this).processAllMessages();
// When pinned for the first time, a pinned message should be sent.
- mPinnedSliceManager.pin("pkg", FIRST_SPECS);
+ mPinnedSliceManager.pin("pkg", FIRST_SPECS, mToken);
TestableLooper.get(this).processAllMessages();
verify(mIContentProvider).call(anyString(), eq(SliceProvider.METHOD_PIN), eq(null),
@@ -119,112 +120,27 @@
}
@Test
- public void testSendPinnedOnListen() throws RemoteException {
- TestableLooper.get(this).processAllMessages();
-
- // When a listener is added for the first time, a pinned message should be sent.
- ISliceListener listener = mock(ISliceListener.class);
- when(listener.asBinder()).thenReturn(new Binder());
-
- mPinnedSliceManager.addSliceListener(listener, mContext.getPackageName(), FIRST_SPECS,
- true);
- TestableLooper.get(this).processAllMessages();
-
- verify(mIContentProvider).call(anyString(), eq(SliceProvider.METHOD_PIN), eq(null),
- argThat(b -> {
- assertEquals(TEST_URI, b.getParcelable(SliceProvider.EXTRA_BIND_URI));
- return true;
- }));
- }
-
- @Test
- public void testNoSendPinnedWithoutPermission() throws RemoteException {
- TestableLooper.get(this).processAllMessages();
-
- // When a listener is added for the first time, a pinned message should be sent.
- ISliceListener listener = mock(ISliceListener.class);
- when(listener.asBinder()).thenReturn(new Binder());
-
- mPinnedSliceManager.addSliceListener(listener, mContext.getPackageName(), FIRST_SPECS,
- false);
- TestableLooper.get(this).processAllMessages();
-
- verify(mIContentProvider, never()).call(anyString(), eq(SliceProvider.METHOD_PIN), eq(null),
- any());
- }
-
- @Test
- public void testSendUnpinnedOnDestroy() throws RemoteException {
- TestableLooper.get(this).processAllMessages();
- clearInvocations(mIContentProvider);
-
- mPinnedSliceManager.pin("pkg", FIRST_SPECS);
- mPinnedSliceManager.destroy();
- TestableLooper.get(this).processAllMessages();
-
- verify(mIContentProvider).call(anyString(), eq(SliceProvider.METHOD_UNPIN), eq(null),
- argThat(b -> {
- assertEquals(TEST_URI, b.getParcelable(SliceProvider.EXTRA_BIND_URI));
- return true;
- }));
- }
-
- @Test
public void testPkgPin() {
assertFalse(mPinnedSliceManager.hasPinOrListener());
- mPinnedSliceManager.pin("pkg", FIRST_SPECS);
+ mPinnedSliceManager.pin("pkg", FIRST_SPECS, mToken);
assertTrue(mPinnedSliceManager.hasPinOrListener());
- assertTrue(mPinnedSliceManager.unpin("pkg"));
+ assertTrue(mPinnedSliceManager.unpin("pkg", mToken));
assertFalse(mPinnedSliceManager.hasPinOrListener());
}
@Test
public void testMultiPkgPin() {
+ IBinder t2 = new Binder();
assertFalse(mPinnedSliceManager.hasPinOrListener());
- mPinnedSliceManager.pin("pkg", FIRST_SPECS);
+ mPinnedSliceManager.pin("pkg", FIRST_SPECS, mToken);
assertTrue(mPinnedSliceManager.hasPinOrListener());
- mPinnedSliceManager.pin("pkg2", FIRST_SPECS);
+ mPinnedSliceManager.pin("pkg2", FIRST_SPECS, t2);
- assertFalse(mPinnedSliceManager.unpin("pkg"));
- assertTrue(mPinnedSliceManager.unpin("pkg2"));
- assertFalse(mPinnedSliceManager.hasPinOrListener());
- }
-
- @Test
- public void testListenerPin() {
- ISliceListener listener = mock(ISliceListener.class);
- when(listener.asBinder()).thenReturn(new Binder());
- assertFalse(mPinnedSliceManager.hasPinOrListener());
-
- mPinnedSliceManager.addSliceListener(listener, mContext.getPackageName(), FIRST_SPECS,
- true);
- assertTrue(mPinnedSliceManager.hasPinOrListener());
-
- assertTrue(mPinnedSliceManager.removeSliceListener(listener));
- assertFalse(mPinnedSliceManager.hasPinOrListener());
- }
-
- @Test
- public void testMultiListenerPin() {
- ISliceListener listener = mock(ISliceListener.class);
- Binder value = new Binder();
- when(listener.asBinder()).thenReturn(value);
- ISliceListener listener2 = mock(ISliceListener.class);
- Binder value2 = new Binder();
- when(listener2.asBinder()).thenReturn(value2);
- assertFalse(mPinnedSliceManager.hasPinOrListener());
-
- mPinnedSliceManager.addSliceListener(listener, mContext.getPackageName(), FIRST_SPECS,
- true);
- assertTrue(mPinnedSliceManager.hasPinOrListener());
- mPinnedSliceManager.addSliceListener(listener2, mContext.getPackageName(), FIRST_SPECS,
- true);
-
- assertFalse(mPinnedSliceManager.removeSliceListener(listener));
- assertTrue(mPinnedSliceManager.removeSliceListener(listener2));
+ assertFalse(mPinnedSliceManager.unpin("pkg", mToken));
+ assertTrue(mPinnedSliceManager.unpin("pkg2", t2));
assertFalse(mPinnedSliceManager.hasPinOrListener());
}
@@ -236,8 +152,7 @@
when(listener.asBinder()).thenReturn(binder);
assertFalse(mPinnedSliceManager.hasPinOrListener());
- mPinnedSliceManager.addSliceListener(listener, mContext.getPackageName(), FIRST_SPECS,
- true);
+ mPinnedSliceManager.pin(mContext.getPackageName(), FIRST_SPECS, binder);
assertTrue(mPinnedSliceManager.hasPinOrListener());
ArgumentCaptor<DeathRecipient> arg = ArgumentCaptor.forClass(DeathRecipient.class);
@@ -246,79 +161,7 @@
when(binder.isBinderAlive()).thenReturn(false);
arg.getValue().binderDied();
- verify(mSliceService).unlisten(eq(TEST_URI));
verify(mSliceService).removePinnedSlice(eq(TEST_URI));
assertFalse(mPinnedSliceManager.hasPinOrListener());
}
-
- @Test
- public void testPkgListenerPin() {
- ISliceListener listener = mock(ISliceListener.class);
- when(listener.asBinder()).thenReturn(new Binder());
- assertFalse(mPinnedSliceManager.hasPinOrListener());
-
- mPinnedSliceManager.addSliceListener(listener, mContext.getPackageName(), FIRST_SPECS,
- true);
- assertTrue(mPinnedSliceManager.hasPinOrListener());
- mPinnedSliceManager.pin("pkg", FIRST_SPECS);
-
- assertFalse(mPinnedSliceManager.removeSliceListener(listener));
- assertTrue(mPinnedSliceManager.unpin("pkg"));
- assertFalse(mPinnedSliceManager.hasPinOrListener());
- }
-
- @Test
- public void testBind() throws RemoteException {
- TestableLooper.get(this).processAllMessages();
- clearInvocations(mIContentProvider);
-
- ISliceListener listener = mock(ISliceListener.class);
- when(listener.asBinder()).thenReturn(new Binder());
- Slice s = new Slice.Builder(TEST_URI).build();
- Bundle b = new Bundle();
- b.putParcelable(SliceProvider.EXTRA_SLICE, s);
- when(mIContentProvider.call(anyString(), eq(SliceProvider.METHOD_SLICE), eq(null),
- any())).thenReturn(b);
-
- assertFalse(mPinnedSliceManager.hasPinOrListener());
-
- mPinnedSliceManager.addSliceListener(listener, mContext.getPackageName(), FIRST_SPECS,
- true);
-
- mPinnedSliceManager.onChange();
- TestableLooper.get(this).processAllMessages();
-
- verify(mIContentProvider).call(anyString(), eq(SliceProvider.METHOD_SLICE), eq(null),
- argThat(bundle -> {
- assertEquals(TEST_URI, bundle.getParcelable(SliceProvider.EXTRA_BIND_URI));
- return true;
- }));
- verify(listener).onSliceUpdated(eq(s));
- }
-
- @Test
- public void testRecheckPackage() throws RemoteException {
- TestableLooper.get(this).processAllMessages();
-
- ISliceListener listener = mock(ISliceListener.class);
- when(listener.asBinder()).thenReturn(new Binder());
-
- mPinnedSliceManager.addSliceListener(listener, mContext.getPackageName(), FIRST_SPECS,
- false);
- TestableLooper.get(this).processAllMessages();
-
- verify(mIContentProvider, never()).call(anyString(), eq(SliceProvider.METHOD_PIN), eq(null),
- any());
-
- when(mSliceService.checkAccess(any(), any(), anyInt(), anyInt()))
- .thenReturn(PERMISSION_GRANTED);
- mPinnedSliceManager.recheckPackage(mContext.getPackageName());
- TestableLooper.get(this).processAllMessages();
-
- verify(mIContentProvider).call(anyString(), eq(SliceProvider.METHOD_PIN), eq(null),
- argThat(b -> {
- assertEquals(TEST_URI, b.getParcelable(SliceProvider.EXTRA_BIND_URI));
- return true;
- }));
- }
}
\ No newline at end of file
diff --git a/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java
index fe9ea7a..6fc3009 100644
--- a/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/slice/SliceManagerServiceTest.java
@@ -32,6 +32,8 @@
import android.app.slice.SliceSpec;
import android.content.pm.PackageManagerInternal;
import android.net.Uri;
+import android.os.Binder;
+import android.os.IBinder;
import android.os.RemoteException;
import android.support.test.filters.SmallTest;
import android.testing.AndroidTestingRunner;
@@ -59,6 +61,7 @@
private SliceManagerService mService;
private PinnedSliceState mCreatedSliceState;
+ private IBinder mToken = new Binder();
@Before
public void setup() {
@@ -77,43 +80,11 @@
}
@Test
- public void testAddListenerCreatesPinned() throws RemoteException {
- mService.addSliceListener(TEST_URI, "pkg", mock(ISliceListener.class), EMPTY_SPECS);
- verify(mService, times(1)).createPinnedSlice(eq(TEST_URI));
- }
-
- @Test
- public void testAddListenerCreatesOnePinned() throws RemoteException {
- mService.addSliceListener(TEST_URI, "pkg", mock(ISliceListener.class), EMPTY_SPECS);
- mService.addSliceListener(TEST_URI, "pkg", mock(ISliceListener.class), EMPTY_SPECS);
- verify(mService, times(1)).createPinnedSlice(eq(TEST_URI));
- }
-
- @Test
- public void testRemoveListenerDestroysPinned() throws RemoteException {
- ISliceListener listener = mock(ISliceListener.class);
- mService.addSliceListener(TEST_URI, "pkg", listener, EMPTY_SPECS);
-
- when(mCreatedSliceState.removeSliceListener(eq(listener))).thenReturn(false);
- mService.removeSliceListener(TEST_URI, "pkg", listener);
- verify(mCreatedSliceState, never()).destroy();
-
- when(mCreatedSliceState.removeSliceListener(eq(listener))).thenReturn(true);
- mService.removeSliceListener(TEST_URI, "pkg", listener);
- verify(mCreatedSliceState).destroy();
- }
-
- @Test(expected = IllegalStateException.class)
- public void testUnrecognizedThrows() throws RemoteException {
- mService.removeSliceListener(TEST_URI, "pkg", mock(ISliceListener.class));
- }
-
- @Test
public void testAddPinCreatesPinned() throws RemoteException {
doReturn("pkg").when(mService).getDefaultHome(anyInt());
- mService.pinSlice("pkg", TEST_URI, EMPTY_SPECS);
- mService.pinSlice("pkg", TEST_URI, EMPTY_SPECS);
+ mService.pinSlice("pkg", TEST_URI, EMPTY_SPECS, mToken);
+ mService.pinSlice("pkg", TEST_URI, EMPTY_SPECS, mToken);
verify(mService, times(1)).createPinnedSlice(eq(TEST_URI));
}
@@ -121,15 +92,11 @@
public void testRemovePinDestroysPinned() throws RemoteException {
doReturn("pkg").when(mService).getDefaultHome(anyInt());
- mService.pinSlice("pkg", TEST_URI, EMPTY_SPECS);
+ mService.pinSlice("pkg", TEST_URI, EMPTY_SPECS, mToken);
- when(mCreatedSliceState.unpin(eq("pkg"))).thenReturn(false);
- mService.unpinSlice("pkg", TEST_URI);
+ when(mCreatedSliceState.unpin(eq("pkg"), eq(mToken))).thenReturn(false);
+ mService.unpinSlice("pkg", TEST_URI, mToken);
verify(mCreatedSliceState, never()).destroy();
-
- when(mCreatedSliceState.unpin(eq("pkg"))).thenReturn(true);
- mService.unpinSlice("pkg", TEST_URI);
- verify(mCreatedSliceState).destroy();
}
}
\ No newline at end of file
diff --git a/telephony/java/android/provider/Telephony.java b/telephony/java/android/provider/Telephony.java
index 63263bd..e7f0cc2 100644
--- a/telephony/java/android/provider/Telephony.java
+++ b/telephony/java/android/provider/Telephony.java
@@ -2732,6 +2732,7 @@
* This should be spread to other technologies,
* but is currently only used for LTE (14) and eHRPD (13).
* <P>Type: INTEGER</P>
+ * @deprecated this column is no longer supported, use {@link #NETWORK_TYPE_BITMASK} instead
*/
@Deprecated
public static final String BEARER = "bearer";
@@ -2744,13 +2745,14 @@
* Bitmask for a radio tech R is (1 << (R - 1))
* <P>Type: INTEGER</P>
* @hide
+ * @deprecated this column is no longer supported, use {@link #NETWORK_TYPE_BITMASK} instead
*/
@Deprecated
public static final String BEARER_BITMASK = "bearer_bitmask";
/**
* Radio technology (network type) bitmask.
- * To check what values can be contained, refer to
+ * To check what values can be contained, refer to the NETWORK_TYPE_ constants in
* {@link android.telephony.TelephonyManager}.
* Bitmask for a radio tech R is (1 << (R - 1))
* <P>Type: INTEGER</P>
diff --git a/telephony/java/android/telephony/ServiceState.java b/telephony/java/android/telephony/ServiceState.java
index ec348df..7255507 100644
--- a/telephony/java/android/telephony/ServiceState.java
+++ b/telephony/java/android/telephony/ServiceState.java
@@ -178,7 +178,6 @@
/**
* Number of radio technologies for GSM, UMTS and CDMA.
- * @hide
*/
private static final int NEXT_RIL_RADIO_TECHNOLOGY = 20;