Merge "Simplify the media button handling logic"
diff --git a/libs/hwui/JankTracker.cpp b/libs/hwui/JankTracker.cpp
index 7be71ee..8126d57 100644
--- a/libs/hwui/JankTracker.cpp
+++ b/libs/hwui/JankTracker.cpp
@@ -264,10 +264,15 @@
// the actual time spent blocked.
nsecs_t forgiveAmount = std::min(expectedDequeueDuration,
frame[FrameInfoIndex::DequeueBufferDuration]);
+ LOG_ALWAYS_FATAL_IF(forgiveAmount >= totalDuration,
+ "Impossible dequeue duration! dequeue duration reported %" PRId64
+ ", total duration %" PRId64, forgiveAmount, totalDuration);
totalDuration -= forgiveAmount;
}
}
+ LOG_ALWAYS_FATAL_IF(totalDuration <= 0, "Impossible totalDuration %" PRId64, totalDuration);
uint32_t framebucket = frameCountIndexForFrameTime(totalDuration);
+ LOG_ALWAYS_FATAL_IF(framebucket < 0, "framebucket < 0 (%u)", framebucket);
// Keep the fast path as fast as possible.
if (CC_LIKELY(totalDuration < mFrameInterval)) {
mData->frameCounts[framebucket]++;
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 5b20716..bf17e38 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -1878,6 +1878,15 @@
<!-- PiP BTW notification description. [CHAR LIMIT=NONE] -->
<string name="pip_notification_message">If you don’t want <xliff:g id="name" example="Google Maps">%s</xliff:g> to use this feature, tap to open settings and turn it off.</string>
+ <!-- PiP section of the tuner. [CHAR LIMIT=NONE] -->
+ <string name="picture_in_picture" translatable="false">Picture-in-Picture</string>
+
+ <!-- PiP minimize title. [CHAR LIMIT=NONE]-->
+ <string name="pip_minimize_title" translatable="false">Minimize</string>
+
+ <!-- PiP minimize description. [CHAR LIMIT=NONE] -->
+ <string name="pip_minimize_description" translatable="false">Drag or fling the PIP to the edges of the screen to minimize it.</string>
+
<!-- Tuner string -->
<string name="change_theme_reboot" translatable="false">Changing the theme requires a restart.</string>
<!-- Tuner string -->
diff --git a/packages/SystemUI/res/xml/tuner_prefs.xml b/packages/SystemUI/res/xml/tuner_prefs.xml
index bc3edd5..908fb20 100644
--- a/packages/SystemUI/res/xml/tuner_prefs.xml
+++ b/packages/SystemUI/res/xml/tuner_prefs.xml
@@ -122,6 +122,18 @@
</PreferenceScreen>
<PreferenceScreen
+ android:key="picture_in_picture"
+ android:title="@string/picture_in_picture">
+
+ <com.android.systemui.tuner.TunerSwitch
+ android:key="pip_minimize"
+ android:title="@string/pip_minimize_title"
+ android:summary="@string/pip_minimize_description"
+ sysui:defValue="false" />
+
+ </PreferenceScreen>
+
+ <PreferenceScreen
android:key="doze"
android:title="@string/tuner_doze">
diff --git a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
index b689a850..a0f491f 100644
--- a/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/pip/phone/PipTouchHandler.java
@@ -37,8 +37,10 @@
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.policy.PipSnapAlgorithm;
+import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.statusbar.FlingAnimationUtils;
+import com.android.systemui.tuner.TunerService;
import java.io.PrintWriter;
@@ -46,9 +48,11 @@
* Manages all the touch handling for PIP on the Phone, including moving, dismissing and expanding
* the PIP.
*/
-public class PipTouchHandler {
+public class PipTouchHandler implements TunerService.Tunable {
private static final String TAG = "PipTouchHandler";
+ private static final String TUNER_KEY_MINIMIZE = "pip_minimize";
+
// These values are used for metrics and should never change
private static final int METRIC_VALUE_DISMISSED_BY_TAP = 0;
private static final int METRIC_VALUE_DISMISSED_BY_DRAG = 1;
@@ -97,6 +101,9 @@
}
};
+ // Allow the PIP to be dragged to the edge of the screen to be minimized.
+ private boolean mEnableMinimize = false;
+
// Behaviour states
private boolean mIsMenuVisible;
private boolean mIsMinimized;
@@ -169,6 +176,9 @@
mExpandedShortestEdgeSize = context.getResources().getDimensionPixelSize(
R.dimen.pip_expanded_shortest_edge_size);
+ // Register any tuner settings changes
+ Dependency.get(TunerService.class).addTunable(this, TUNER_KEY_MINIMIZE);
+
// Register the listener for input consumer touch events
inputConsumerController.setTouchListener(this::handleTouchEvent);
inputConsumerController.setRegistrationListener(this::onRegistrationChanged);
@@ -189,6 +199,20 @@
}
}
+ @Override
+ public void onTuningChanged(String key, String newValue) {
+ if (newValue == null) {
+ // Reset back to default
+ mEnableMinimize = false;
+ return;
+ }
+ switch (key) {
+ case TUNER_KEY_MINIMIZE:
+ mEnableMinimize = Integer.parseInt(newValue) != 0;
+ break;
+ }
+ }
+
public void onConfigurationChanged() {
mMotionHelper.onConfigurationChanged();
mMotionHelper.synchronizePinnedStackBounds();
@@ -368,6 +392,9 @@
* Sets the minimized state.
*/
void setMinimizedStateInternal(boolean isMinimized) {
+ if (!mEnableMinimize) {
+ return;
+ }
setMinimizedState(isMinimized, false /* fromController */);
}
@@ -375,6 +402,9 @@
* Sets the minimized state.
*/
void setMinimizedState(boolean isMinimized, boolean fromController) {
+ if (!mEnableMinimize) {
+ return;
+ }
if (mIsMinimized != isMinimized) {
MetricsLogger.action(mContext, MetricsEvent.ACTION_PICTURE_IN_PICTURE_MINIMIZED,
isMinimized);
@@ -483,7 +513,7 @@
final PointF lastDelta = touchState.getLastTouchDelta();
float left = mTmpBounds.left + lastDelta.x;
float top = mTmpBounds.top + lastDelta.y;
- if (!touchState.allowDraggingOffscreen()) {
+ if (!touchState.allowDraggingOffscreen() || !mEnableMinimize) {
left = Math.max(mMovementBounds.left, Math.min(mMovementBounds.right, left));
}
if (ENABLE_DISMISS_DRAG_TO_EDGE) {
@@ -550,10 +580,10 @@
final float velocity = PointF.length(vel.x, vel.y);
final boolean isFling = velocity > mFlingAnimationUtils.getMinVelocityPxPerSecond();
final boolean isHorizontal = Math.abs(vel.x) > Math.abs(vel.y);
- final boolean onLeft = mMotionHelper.getBounds().left < mMovementBounds.centerX();
- final boolean isFlingToBot = !isHorizontal && mMovementWithinDismiss && vel.y > 0;
- final boolean isFlingToEdge = isHorizontal && mMovementWithinMinimize
- && (onLeft ? vel.x < 0 : vel.x > 0);
+ final boolean isFlingToBot = isFling
+ && !isHorizontal && mMovementWithinDismiss && vel.y > 0;
+ final boolean isFlingToEdge = isFling && isHorizontal && mMovementWithinMinimize
+ && (mStartedOnLeft ? vel.x < 0 : vel.x > 0);
if (ENABLE_DISMISS_DRAG_TO_EDGE
&& (mMotionHelper.shouldDismissPip() || isFlingToBot)) {
@@ -563,7 +593,8 @@
MetricsEvent.ACTION_PICTURE_IN_PICTURE_DISMISSED,
METRIC_VALUE_DISMISSED_BY_DRAG);
return true;
- } else if (!mIsMinimized && (mMotionHelper.shouldMinimizePip() || isFlingToEdge)) {
+ } else if (mEnableMinimize &&
+ !mIsMinimized && (mMotionHelper.shouldMinimizePip() || isFlingToEdge)) {
// Pip should be minimized
setMinimizedStateInternal(true);
if (mMenuController.isMenuVisible()) {
@@ -631,6 +662,7 @@
pw.println(innerPrefix + "mImeHeight=" + mImeHeight);
pw.println(innerPrefix + "mSavedSnapFraction=" + mSavedSnapFraction);
pw.println(innerPrefix + "mEnableDragToDismiss=" + ENABLE_DISMISS_DRAG_TO_TARGET);
+ pw.println(innerPrefix + "mEnableMinimize=" + mEnableMinimize);
mSnapAlgorithm.dump(pw, innerPrefix);
mTouchState.dump(pw, innerPrefix);
mMotionHelper.dump(pw, innerPrefix);
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index 8e3e3ea..77a02b4 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -202,16 +202,17 @@
new HashMap<Account, Integer>();
final Object cacheLock = new Object();
/** protected by the {@link #cacheLock} */
- final HashMap<String, Account[]> accountCache =
- new LinkedHashMap<>();
+ final HashMap<String, Account[]> accountCache = new LinkedHashMap<>();
/** protected by the {@link #cacheLock} */
private final Map<Account, Map<String, String>> userDataCache = new HashMap<>();
/** protected by the {@link #cacheLock} */
private final Map<Account, Map<String, String>> authTokenCache = new HashMap<>();
/** protected by the {@link #cacheLock} */
private final TokenCache accountTokenCaches = new TokenCache();
+ /** protected by the {@link #cacheLock} */
+ private final Map<Account, Map<String, Integer>> visibilityCache = new HashMap<>();
- /** protected by the {@link #mReceiversForType}
+ /** protected by the {@link #mReceiversForType},
* type -> (packageName -> number of active receivers)
* type == null is used to get notifications about all account types
*/
@@ -524,25 +525,29 @@
String.format("uid %s cannot get secrets for account %s", callingUid, account);
throw new SecurityException(msg);
}
- return getPackagesAndVisibilityForAccount(account, accounts);
+ synchronized (accounts.cacheLock) {
+ return getPackagesAndVisibilityForAccountLocked(account, accounts);
+ }
}
/**
- * Returns all package names and visibility values, which were set for given account.
+ * Returns Map with all package names and visibility values for given account.
+ * The method and returned map must be guarded by accounts.cacheLock
*
* @param account Account to get visibility values.
* @param accounts UserAccount that currently hosts the account and application
*
- * @return Map from package names to visibility.
+ * @return Map with cache for package names to visibility.
*/
- private Map<String, Integer> getPackagesAndVisibilityForAccount(Account account,
+ private @NonNull Map<String, Integer> getPackagesAndVisibilityForAccountLocked(Account account,
UserAccounts accounts) {
- final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
- try {
- return accounts.accountsDb.findAllVisibilityValuesForAccount(account);
- } finally {
- StrictMode.setThreadPolicy(oldPolicy);
+ Map<String, Integer> accountVisibility = accounts.visibilityCache.get(account);
+ if (accountVisibility == null) {
+ Log.d(TAG, "Visibility was not initialized");
+ accountVisibility = new HashMap<>();
+ accounts.visibilityCache.put(account, accountVisibility);
}
+ return accountVisibility;
}
@Override
@@ -572,14 +577,13 @@
* @return Visibility value, AccountManager.VISIBILITY_UNDEFINED if no value was stored.
*
*/
- private int getAccountVisibility(Account account, String packageName, UserAccounts accounts) {
- final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
- try {
- Integer visibility =
- accounts.accountsDb.findAccountVisibility(account, packageName);
+ private int getAccountVisibilityFromCache(Account account, String packageName,
+ UserAccounts accounts) {
+ synchronized (accounts.cacheLock) {
+ Map<String, Integer> accountVisibility =
+ getPackagesAndVisibilityForAccountLocked(account, accounts);
+ Integer visibility = accountVisibility.get(packageName);
return visibility != null ? visibility : AccountManager.VISIBILITY_UNDEFINED;
- } finally {
- StrictMode.setThreadPolicy(oldPolicy);
}
}
@@ -595,9 +599,7 @@
*/
private Integer resolveAccountVisibility(Account account, @NonNull String packageName,
UserAccounts accounts) {
-
Preconditions.checkNotNull(packageName, "packageName cannot be null");
-
int uid = -1;
try {
long identityToken = clearCallingIdentity();
@@ -630,7 +632,7 @@
}
// Return stored value if it was set.
- int visibility = getAccountVisibility(account, packageName, accounts);
+ int visibility = getAccountVisibilityFromCache(account, packageName, accounts);
if (AccountManager.VISIBILITY_UNDEFINED != visibility) {
return visibility;
@@ -652,13 +654,13 @@
|| canReadContacts || isPrivileged) {
// Use legacy for preO apps with GET_ACCOUNTS permission or pre/postO with signature
// match.
- visibility = getAccountVisibility(account,
+ visibility = getAccountVisibilityFromCache(account,
AccountManager.PACKAGE_NAME_KEY_LEGACY_VISIBLE, accounts);
if (AccountManager.VISIBILITY_UNDEFINED == visibility) {
visibility = AccountManager.VISIBILITY_USER_MANAGED_VISIBLE;
}
} else {
- visibility = getAccountVisibility(account,
+ visibility = getAccountVisibilityFromCache(account,
AccountManager.PACKAGE_NAME_KEY_LEGACY_NOT_VISIBLE, accounts);
if (AccountManager.VISIBILITY_UNDEFINED == visibility) {
visibility = AccountManager.VISIBILITY_USER_MANAGED_NOT_VISIBLE;
@@ -751,21 +753,10 @@
packagesToVisibility = new HashMap<>();
}
- final long accountId = accounts.accountsDb.findDeAccountId(account);
- if (accountId < 0) {
+ if (!updateAccountVisibilityLocked(account, packageName, newVisibility, accounts)) {
return false;
}
- final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
- try {
- if (!accounts.accountsDb.setAccountVisibility(accountId, packageName,
- newVisibility)) {
- return false;
- }
- } finally {
- StrictMode.setThreadPolicy(oldPolicy);
- }
-
if (notify) {
for (Entry<String, Integer> packageToVisibility : packagesToVisibility.entrySet()) {
if (packageToVisibility.getValue() != AccountManager.VISIBILITY_NOT_VISIBLE) {
@@ -778,6 +769,29 @@
}
}
+ // Update account visibility in cache and database.
+ private boolean updateAccountVisibilityLocked(Account account, String packageName,
+ int newVisibility, UserAccounts accounts) {
+ final long accountId = accounts.accountsDb.findDeAccountId(account);
+ if (accountId < 0) {
+ return false;
+ }
+
+ final StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
+ try {
+ if (!accounts.accountsDb.setAccountVisibility(accountId, packageName,
+ newVisibility)) {
+ return false;
+ }
+ } finally {
+ StrictMode.setThreadPolicy(oldPolicy);
+ }
+ Map<String, Integer> accountVisibility =
+ getPackagesAndVisibilityForAccountLocked(account, accounts);
+ accountVisibility.put(packageName, newVisibility);
+ return true;
+ }
+
@Override
public void registerAccountListener(String[] accountTypes, String opPackageName) {
int callingUid = Binder.getCallingUid();
@@ -1042,9 +1056,12 @@
accounts.userDataCache.remove(account);
accounts.authTokenCache.remove(account);
accounts.accountTokenCaches.remove(account);
+ accounts.visibilityCache.remove(account);
- for (Entry<String, Integer> packageToVisibility : packagesToVisibility.entrySet()) {
- if (packageToVisibility.getValue() != AccountManager.VISIBILITY_NOT_VISIBLE) {
+ for (Entry<String, Integer> packageToVisibility :
+ packagesToVisibility.entrySet()) {
+ if (packageToVisibility.getValue()
+ != AccountManager.VISIBILITY_NOT_VISIBLE) {
notifyPackage(packageToVisibility.getKey(), accounts);
}
}
@@ -1067,6 +1084,7 @@
}
accounts.accountCache.put(accountType, accountsForType);
}
+ accounts.visibilityCache.putAll(accountsDb.findAllVisibilityValues());
} finally {
if (accountDeleted) {
sendAccountsChangedBroadcast(accounts.userId);
@@ -1181,19 +1199,31 @@
}
private void removeVisibilityValuesForPackage(String packageName) {
+ if (isSpecialPackageKey(packageName)) {
+ return;
+ }
synchronized (mUsers) {
- for (int i = 0; i < mUsers.size(); i++) {
- UserAccounts accounts = mUsers.valueAt(i);
- try {
- int uid = mPackageManager.getPackageUidAsUser(packageName, accounts.userId);
- } catch (NameNotFoundException e) {
- // package does not exist - remove visibility values
- accounts.accountsDb.deleteAccountVisibilityForPackage(packageName);
+ int numberOfUsers = mUsers.size();
+ for (int i = 0; i < numberOfUsers; i++) {
+ UserAccounts accounts = mUsers.valueAt(i);
+ try {
+ mPackageManager.getPackageUidAsUser(packageName, accounts.userId);
+ } catch (NameNotFoundException e) {
+ // package does not exist - remove visibility values
+ accounts.accountsDb.deleteAccountVisibilityForPackage(packageName);
+ synchronized(accounts.cacheLock) {
+ for (Account account : accounts.visibilityCache.keySet()) {
+ Map<String, Integer> accountVisibility =
+ getPackagesAndVisibilityForAccountLocked(account, accounts);
+ accountVisibility.remove(packageName);
+ }
+ }
}
}
}
}
+
private void onCleanupUser(int userId) {
Log.i(TAG, "onCleanupUser " + userId);
UserAccounts accounts;
@@ -1849,6 +1879,7 @@
*/
Map<String, String> tmpData = accounts.userDataCache.get(accountToRename);
Map<String, String> tmpTokens = accounts.authTokenCache.get(accountToRename);
+ Map<String, Integer> tmpVisibility = accounts.visibilityCache.get(accountToRename);
removeAccountFromCacheLocked(accounts, accountToRename);
/*
* Update the cached data associated with the renamed
@@ -1856,6 +1887,7 @@
*/
accounts.userDataCache.put(renamedAccount, tmpData);
accounts.authTokenCache.put(renamedAccount, tmpTokens);
+ accounts.visibilityCache.put(renamedAccount, tmpVisibility);
accounts.previousNameCache.put(
renamedAccount,
new AtomicReference<>(accountToRename.name));
@@ -5369,6 +5401,7 @@
accounts.userDataCache.remove(account);
accounts.authTokenCache.remove(account);
accounts.previousNameCache.remove(account);
+ accounts.visibilityCache.remove(account);
}
/**
diff --git a/services/core/java/com/android/server/accounts/AccountsDb.java b/services/core/java/com/android/server/accounts/AccountsDb.java
index 22543cb..8ca7ea1 100644
--- a/services/core/java/com/android/server/accounts/AccountsDb.java
+++ b/services/core/java/com/android/server/accounts/AccountsDb.java
@@ -909,7 +909,7 @@
}
Integer findAccountVisibility(Account account, String packageName) {
- SQLiteDatabase db = mDeDatabase.getWritableDatabase();
+ SQLiteDatabase db = mDeDatabase.getReadableDatabase();
final Cursor cursor = db.query(TABLE_VISIBILITY, new String[] {VISIBILITY_VALUE},
SELECTION_ACCOUNTS_ID_BY_ACCOUNT + " AND " + VISIBILITY_PACKAGE + "=? ",
new String[] {account.name, account.type, packageName}, null, null, null);
@@ -924,7 +924,7 @@
}
Integer findAccountVisibility(long accountId, String packageName) {
- SQLiteDatabase db = mDeDatabase.getWritableDatabase();
+ SQLiteDatabase db = mDeDatabase.getReadableDatabase();
final Cursor cursor = db.query(TABLE_VISIBILITY, new String[] {VISIBILITY_VALUE},
VISIBILITY_ACCOUNTS_ID + "=? AND " + VISIBILITY_PACKAGE + "=? ",
new String[] {String.valueOf(accountId), packageName}, null, null, null);
@@ -972,6 +972,41 @@
return result;
}
+ /**
+ * Returns a map account -> (package -> visibility)
+ */
+ Map <Account, Map<String, Integer>> findAllVisibilityValues() {
+ SQLiteDatabase db = mDeDatabase.getReadableDatabase();
+ Map<Account, Map<String, Integer>> result = new HashMap<>();
+ Cursor cursor = db.rawQuery(
+ "SELECT " + TABLE_VISIBILITY + "." + VISIBILITY_PACKAGE
+ + ", " + TABLE_VISIBILITY + "." + VISIBILITY_VALUE
+ + ", " + TABLE_ACCOUNTS + "." + ACCOUNTS_NAME
+ + ", " + TABLE_ACCOUNTS + "." + ACCOUNTS_TYPE
+ + " FROM " + TABLE_VISIBILITY
+ + " JOIN " + TABLE_ACCOUNTS
+ + " ON " + TABLE_ACCOUNTS + "." + ACCOUNTS_ID
+ + " = " + TABLE_VISIBILITY + "." + VISIBILITY_ACCOUNTS_ID, null);
+ try {
+ while (cursor.moveToNext()) {
+ String packageName = cursor.getString(0);
+ Integer visibility = cursor.getInt(1);
+ String accountName = cursor.getString(2);
+ String accountType = cursor.getString(3);
+ Account account = new Account(accountName, accountType);
+ Map <String, Integer> accountVisibility = result.get(account);
+ if (accountVisibility == null) {
+ accountVisibility = new HashMap<>();
+ result.put(account, accountVisibility);
+ }
+ accountVisibility.put(packageName, visibility);
+ }
+ } finally {
+ cursor.close();
+ }
+ return result;
+ }
+
boolean deleteAccountVisibilityForPackage(String packageName) {
SQLiteDatabase db = mDeDatabase.getWritableDatabase();
return db.delete(TABLE_VISIBILITY, VISIBILITY_PACKAGE + "=? ",
diff --git a/services/core/java/com/android/server/storage/CacheQuotaStrategy.java b/services/core/java/com/android/server/storage/CacheQuotaStrategy.java
index 41c5331..82dd9ac 100644
--- a/services/core/java/com/android/server/storage/CacheQuotaStrategy.java
+++ b/services/core/java/com/android/server/storage/CacheQuotaStrategy.java
@@ -197,7 +197,7 @@
.setQuota(CacheQuotaHint.QUOTA_NOT_SET)
.build());
} catch (PackageManager.NameNotFoundException e) {
- Slog.w(TAG, "Unable to find package for quota calculation", e);
+ // This may happen if an app has a recorded usage, but has been uninstalled.
continue;
}
}
diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
index 374aee1..00f6273 100644
--- a/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/accounts/AccountManagerServiceTest.java
@@ -94,7 +94,7 @@
* <p>Run with:<pre>
* mmma -j40 frameworks/base/services/tests/servicestests
* adb install -r ${OUT}/data/app/FrameworksServicesTests/FrameworksServicesTests.apk
- * adb shell am instrument -w -e class package com.android.server.accounts \
+ * adb shell am instrument -w -e package com.android.server.accounts \
* com.android.frameworks.servicestests\
* /android.support.test.runner.AndroidJUnitRunner
* </pre>
diff --git a/services/tests/servicestests/src/com/android/server/accounts/AccountsDbTest.java b/services/tests/servicestests/src/com/android/server/accounts/AccountsDbTest.java
index 2cb8af4..aa37407 100644
--- a/services/tests/servicestests/src/com/android/server/accounts/AccountsDbTest.java
+++ b/services/tests/servicestests/src/com/android/server/accounts/AccountsDbTest.java
@@ -385,6 +385,42 @@
}
@Test
+ public void testFindAllVisibilityValues() {
+ long accId = 10;
+ long accId2 = 11;
+ String packageName1 = "com.example.one";
+ String packageName2 = "com.example.two";
+ Account account = new Account("name", "example.com");
+ Account account2 = new Account("name2", "example2.com");
+ assertNull(mAccountsDb.findAccountVisibility(account, packageName1));
+
+ mAccountsDb.insertDeAccount(account, accId);
+ assertNull(mAccountsDb.findAccountVisibility(account, packageName1));
+ assertNull(mAccountsDb.findAccountVisibility(accId, packageName1));
+ mAccountsDb.insertDeAccount(account2, accId2);
+
+ mAccountsDb.setAccountVisibility(accId, packageName1, 1);
+ mAccountsDb.setAccountVisibility(accId, packageName2, 2);
+ mAccountsDb.setAccountVisibility(accId2, packageName1, 1);
+
+ Map<Account, Map<String, Integer>> vis = mAccountsDb.findAllVisibilityValues();
+ assertEquals(vis.size(), 2);
+ Map<String, Integer> accnt1Visibility = vis.get(account);
+ assertEquals(accnt1Visibility.size(), 2);
+ assertEquals(accnt1Visibility.get(packageName1), Integer.valueOf(1));
+ assertEquals(accnt1Visibility.get(packageName2), Integer.valueOf(2));
+ Map<String, Integer> accnt2Visibility = vis.get(account2);
+ assertEquals(accnt2Visibility.size(), 1);
+ assertEquals(accnt2Visibility.get(packageName1), Integer.valueOf(1));
+
+ mAccountsDb.setAccountVisibility(accId2, packageName2, 3);
+ vis = mAccountsDb.findAllVisibilityValues();
+ accnt2Visibility = vis.get(account2);
+ assertEquals(accnt2Visibility.size(), 2);
+ assertEquals(accnt2Visibility.get(packageName2), Integer.valueOf(3));
+ }
+
+ @Test
public void testVisibilityCleanupTrigger() {
long accId = 10;
String packageName1 = "com.example.one";