Merge "Open dialog panel after long pressing a direct share target to allow pin/unpin the target. Communicate with ShortcutManager/Launcherapps to store pin info in ShortcutService." into tm-dev
diff --git a/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java b/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java
index 38500af..f6ae56f 100644
--- a/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java
+++ b/apex/blobstore/framework/java/android/app/blob/BlobStoreManager.java
@@ -507,6 +507,22 @@
}
/**
+ * Release all the leases which are currently held by the caller.
+ *
+ * @hide
+ */
+ public void releaseAllLeases() throws Exception {
+ try {
+ mService.releaseAllLeases(mContext.getOpPackageName());
+ } catch (ParcelableException e) {
+ e.maybeRethrow(IOException.class);
+ throw new RuntimeException(e);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Return the remaining quota size for acquiring a lease (in bytes) which indicates the
* remaining amount of data that an app can acquire a lease on before the System starts
* rejecting lease requests.
diff --git a/apex/blobstore/framework/java/android/app/blob/IBlobStoreManager.aidl b/apex/blobstore/framework/java/android/app/blob/IBlobStoreManager.aidl
index 39a9fb4..1566fa8 100644
--- a/apex/blobstore/framework/java/android/app/blob/IBlobStoreManager.aidl
+++ b/apex/blobstore/framework/java/android/app/blob/IBlobStoreManager.aidl
@@ -31,6 +31,7 @@
void acquireLease(in BlobHandle handle, int descriptionResId, in CharSequence description,
long leaseTimeoutMillis, in String packageName);
void releaseLease(in BlobHandle handle, in String packageName);
+ void releaseAllLeases(in String packageName);
long getRemainingLeaseQuotaBytes(String packageName);
void waitForIdle(in RemoteCallback callback);
diff --git a/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java b/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java
index c83ca8c..9ac3e41 100644
--- a/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java
+++ b/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java
@@ -554,6 +554,21 @@
}
}
+ private void releaseAllLeasesInternal(int callingUid, String callingPackage) {
+ synchronized (mBlobsLock) {
+ // Remove the package from the leasee list
+ mBlobsMap.forEach((blobHandle, blobMetadata) -> {
+ blobMetadata.removeLeasee(callingPackage, callingUid);
+ });
+ writeBlobsInfoAsync();
+
+ if (LOGV) {
+ Slog.v(TAG, "Release all leases associated with pkg="
+ + callingPackage + ", uid=" + callingUid);
+ }
+ }
+ }
+
private long getRemainingLeaseQuotaBytesInternal(int callingUid, String callingPackage) {
synchronized (mBlobsLock) {
final long remainingQuota = BlobStoreConfig.getAppDataBytesLimit()
@@ -1376,7 +1391,7 @@
}
}
- private boolean isAllowedBlobAccess(int uid, String packageName) {
+ private boolean isAllowedBlobStoreAccess(int uid, String packageName) {
return (!Process.isSdkSandboxUid(uid) && !Process.isIsolated(uid)
&& !mPackageManagerInternal.isInstantApp(packageName, UserHandle.getUserId(uid)));
}
@@ -1442,7 +1457,7 @@
final int callingUid = Binder.getCallingUid();
verifyCallingPackage(callingUid, packageName);
- if (!isAllowedBlobAccess(callingUid, packageName)) {
+ if (!isAllowedBlobStoreAccess(callingUid, packageName)) {
throw new SecurityException("Caller not allowed to create session; "
+ "callingUid=" + callingUid + ", callingPackage=" + packageName);
}
@@ -1491,7 +1506,7 @@
final int callingUid = Binder.getCallingUid();
verifyCallingPackage(callingUid, packageName);
- if (!isAllowedBlobAccess(callingUid, packageName)) {
+ if (!isAllowedBlobStoreAccess(callingUid, packageName)) {
throw new SecurityException("Caller not allowed to open blob; "
+ "callingUid=" + callingUid + ", callingPackage=" + packageName);
}
@@ -1522,7 +1537,7 @@
final int callingUid = Binder.getCallingUid();
verifyCallingPackage(callingUid, packageName);
- if (!isAllowedBlobAccess(callingUid, packageName)) {
+ if (!isAllowedBlobStoreAccess(callingUid, packageName)) {
throw new SecurityException("Caller not allowed to open blob; "
+ "callingUid=" + callingUid + ", callingPackage=" + packageName);
}
@@ -1546,7 +1561,7 @@
final int callingUid = Binder.getCallingUid();
verifyCallingPackage(callingUid, packageName);
- if (!isAllowedBlobAccess(callingUid, packageName)) {
+ if (!isAllowedBlobStoreAccess(callingUid, packageName)) {
throw new SecurityException("Caller not allowed to open blob; "
+ "callingUid=" + callingUid + ", callingPackage=" + packageName);
}
@@ -1555,6 +1570,21 @@
}
@Override
+ public void releaseAllLeases(@NonNull String packageName) {
+ Objects.requireNonNull(packageName, "packageName must not be null");
+
+ final int callingUid = Binder.getCallingUid();
+ verifyCallingPackage(callingUid, packageName);
+
+ if (!isAllowedBlobStoreAccess(callingUid, packageName)) {
+ throw new SecurityException("Caller not allowed to open blob; "
+ + "callingUid=" + callingUid + ", callingPackage=" + packageName);
+ }
+
+ releaseAllLeasesInternal(callingUid, packageName);
+ }
+
+ @Override
public long getRemainingLeaseQuotaBytes(@NonNull String packageName) {
final int callingUid = Binder.getCallingUid();
verifyCallingPackage(callingUid, packageName);
@@ -1629,7 +1659,7 @@
final int callingUid = Binder.getCallingUid();
verifyCallingPackage(callingUid, packageName);
- if (!isAllowedBlobAccess(callingUid, packageName)) {
+ if (!isAllowedBlobStoreAccess(callingUid, packageName)) {
throw new SecurityException("Caller not allowed to open blob; "
+ "callingUid=" + callingUid + ", callingPackage=" + packageName);
}
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/Agent.java b/apex/jobscheduler/service/java/com/android/server/tare/Agent.java
index c0a8148..f4faec8 100644
--- a/apex/jobscheduler/service/java/com/android/server/tare/Agent.java
+++ b/apex/jobscheduler/service/java/com/android/server/tare/Agent.java
@@ -28,8 +28,8 @@
import static com.android.server.tare.EconomicPolicy.eventToString;
import static com.android.server.tare.EconomicPolicy.getEventType;
import static com.android.server.tare.TareUtils.appToString;
+import static com.android.server.tare.TareUtils.cakeToString;
import static com.android.server.tare.TareUtils.getCurrentTimeMillis;
-import static com.android.server.tare.TareUtils.narcToString;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -161,7 +161,7 @@
@GuardedBy("mLock")
private boolean isAffordableLocked(long balance, long price, long ctp) {
- return balance >= price && mScribe.getRemainingConsumableNarcsLocked() >= ctp;
+ return balance >= price && mScribe.getRemainingConsumableCakesLocked() >= ctp;
}
@GuardedBy("mLock")
@@ -464,13 +464,13 @@
+ eventToString(transaction.eventId)
+ (transaction.tag == null ? "" : ":" + transaction.tag)
+ " for " + appToString(userId, pkgName)
- + " by " + narcToString(transaction.delta - newDelta));
+ + " by " + cakeToString(transaction.delta - newDelta));
transaction = new Ledger.Transaction(
transaction.startTimeMs, transaction.endTimeMs,
transaction.eventId, transaction.tag, newDelta, transaction.ctp);
}
ledger.recordTransaction(transaction);
- mScribe.adjustRemainingConsumableNarcsLocked(-transaction.ctp);
+ mScribe.adjustRemainingConsumableCakesLocked(-transaction.ctp);
if (transaction.delta != 0 && notifyOnAffordabilityChange) {
final ArraySet<ActionAffordabilityNote> actionAffordabilityNotes =
mActionAffordabilityNotes.get(userId, pkgName);
@@ -724,7 +724,7 @@
private void reclaimAssetsLocked(final int userId, @NonNull final String pkgName) {
final Ledger ledger = mScribe.getLedgerLocked(userId, pkgName);
if (ledger.getCurrentBalance() != 0) {
- mScribe.adjustRemainingConsumableNarcsLocked(-ledger.getCurrentBalance());
+ mScribe.adjustRemainingConsumableCakesLocked(-ledger.getCurrentBalance());
}
mScribe.discardLedgerLocked(userId, pkgName);
mCurrentOngoingEvents.delete(userId, pkgName);
@@ -872,7 +872,7 @@
return;
}
mTrendCalculator.reset(getBalanceLocked(userId, pkgName),
- mScribe.getRemainingConsumableNarcsLocked(),
+ mScribe.getRemainingConsumableCakesLocked(),
mActionAffordabilityNotes.get(userId, pkgName));
ongoingEvents.forEach(mTrendCalculator);
final long lowerTimeMs = mTrendCalculator.getTimeToCrossLowerThresholdMs();
@@ -1260,11 +1260,11 @@
pw.print(" runtime=");
TimeUtils.formatDuration(nowElapsed - ongoingEvent.startTimeElapsed, pw);
pw.print(" delta/sec=");
- pw.print(narcToString(ongoingEvent.getDeltaPerSec()));
+ pw.print(cakeToString(ongoingEvent.getDeltaPerSec()));
final long ctp = ongoingEvent.getCtpPerSec();
if (ctp != 0) {
pw.print(" ctp/sec=");
- pw.print(narcToString(ongoingEvent.getCtpPerSec()));
+ pw.print(cakeToString(ongoingEvent.getCtpPerSec()));
}
pw.print(" refCount=");
pw.print(ongoingEvent.refCount);
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/AlarmManagerEconomicPolicy.java b/apex/jobscheduler/service/java/com/android/server/tare/AlarmManagerEconomicPolicy.java
index 71e00cf..c2e8188 100644
--- a/apex/jobscheduler/service/java/com/android/server/tare/AlarmManagerEconomicPolicy.java
+++ b/apex/jobscheduler/service/java/com/android/server/tare/AlarmManagerEconomicPolicy.java
@@ -97,8 +97,8 @@
import static com.android.server.tare.Modifier.COST_MODIFIER_DEVICE_IDLE;
import static com.android.server.tare.Modifier.COST_MODIFIER_POWER_SAVE_MODE;
import static com.android.server.tare.Modifier.COST_MODIFIER_PROCESS_STATE;
-import static com.android.server.tare.TareUtils.arcToNarc;
-import static com.android.server.tare.TareUtils.narcToString;
+import static com.android.server.tare.TareUtils.arcToCake;
+import static com.android.server.tare.TareUtils.cakeToString;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -219,143 +219,143 @@
Slog.e(TAG, "Global setting key incorrect: ", e);
}
- mMinSatiatedBalanceExempted = arcToNarc(mParser.getInt(KEY_AM_MIN_SATIATED_BALANCE_EXEMPTED,
+ mMinSatiatedBalanceExempted = arcToCake(mParser.getInt(KEY_AM_MIN_SATIATED_BALANCE_EXEMPTED,
DEFAULT_AM_MIN_SATIATED_BALANCE_EXEMPTED));
- mMinSatiatedBalanceOther = arcToNarc(mParser.getInt(KEY_AM_MIN_SATIATED_BALANCE_OTHER_APP,
+ mMinSatiatedBalanceOther = arcToCake(mParser.getInt(KEY_AM_MIN_SATIATED_BALANCE_OTHER_APP,
DEFAULT_AM_MIN_SATIATED_BALANCE_OTHER_APP));
- mMaxSatiatedBalance = arcToNarc(mParser.getInt(KEY_AM_MAX_SATIATED_BALANCE,
+ mMaxSatiatedBalance = arcToCake(mParser.getInt(KEY_AM_MAX_SATIATED_BALANCE,
DEFAULT_AM_MAX_SATIATED_BALANCE));
- mInitialSatiatedConsumptionLimit = arcToNarc(mParser.getInt(
+ mInitialSatiatedConsumptionLimit = arcToCake(mParser.getInt(
KEY_AM_INITIAL_CONSUMPTION_LIMIT, DEFAULT_AM_INITIAL_CONSUMPTION_LIMIT));
mHardSatiatedConsumptionLimit = Math.max(mInitialSatiatedConsumptionLimit,
- arcToNarc(mParser.getInt(
+ arcToCake(mParser.getInt(
KEY_AM_HARD_CONSUMPTION_LIMIT, DEFAULT_AM_HARD_CONSUMPTION_LIMIT)));
- final long exactAllowWhileIdleWakeupBasePrice = arcToNarc(
+ final long exactAllowWhileIdleWakeupBasePrice = arcToCake(
mParser.getInt(KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_BASE_PRICE,
DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_BASE_PRICE));
mActions.put(ACTION_ALARM_WAKEUP_EXACT_ALLOW_WHILE_IDLE,
new Action(ACTION_ALARM_WAKEUP_EXACT_ALLOW_WHILE_IDLE,
- arcToNarc(mParser.getInt(
+ arcToCake(mParser.getInt(
KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_CTP,
DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_WAKEUP_CTP)),
exactAllowWhileIdleWakeupBasePrice));
mActions.put(ACTION_ALARM_WAKEUP_EXACT,
new Action(ACTION_ALARM_WAKEUP_EXACT,
- arcToNarc(mParser.getInt(KEY_AM_ACTION_ALARM_EXACT_WAKEUP_CTP,
+ arcToCake(mParser.getInt(KEY_AM_ACTION_ALARM_EXACT_WAKEUP_CTP,
DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_CTP)),
- arcToNarc(mParser.getInt(KEY_AM_ACTION_ALARM_EXACT_WAKEUP_BASE_PRICE,
+ arcToCake(mParser.getInt(KEY_AM_ACTION_ALARM_EXACT_WAKEUP_BASE_PRICE,
DEFAULT_AM_ACTION_ALARM_EXACT_WAKEUP_BASE_PRICE))));
final long inexactAllowWhileIdleWakeupBasePrice =
- arcToNarc(mParser.getInt(
+ arcToCake(mParser.getInt(
KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_BASE_PRICE,
DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_BASE_PRICE));
mActions.put(ACTION_ALARM_WAKEUP_INEXACT_ALLOW_WHILE_IDLE,
new Action(ACTION_ALARM_WAKEUP_INEXACT_ALLOW_WHILE_IDLE,
- arcToNarc(mParser.getInt(
+ arcToCake(mParser.getInt(
KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_CTP,
DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_WAKEUP_CTP)),
inexactAllowWhileIdleWakeupBasePrice));
mActions.put(ACTION_ALARM_WAKEUP_INEXACT,
new Action(ACTION_ALARM_WAKEUP_INEXACT,
- arcToNarc(mParser.getInt(
+ arcToCake(mParser.getInt(
KEY_AM_ACTION_ALARM_INEXACT_WAKEUP_CTP,
DEFAULT_AM_ACTION_ALARM_INEXACT_WAKEUP_CTP)),
- arcToNarc(mParser.getInt(
+ arcToCake(mParser.getInt(
KEY_AM_ACTION_ALARM_INEXACT_WAKEUP_BASE_PRICE,
DEFAULT_AM_ACTION_ALARM_INEXACT_WAKEUP_BASE_PRICE))));
final long exactAllowWhileIdleNonWakeupBasePrice =
- arcToNarc(mParser.getInt(
+ arcToCake(mParser.getInt(
KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_BASE_PRICE,
DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE));
mActions.put(ACTION_ALARM_NONWAKEUP_EXACT_ALLOW_WHILE_IDLE,
new Action(ACTION_ALARM_NONWAKEUP_EXACT_ALLOW_WHILE_IDLE,
- arcToNarc(mParser.getInt(
+ arcToCake(mParser.getInt(
KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_CTP,
DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_EXACT_NONWAKEUP_CTP)),
exactAllowWhileIdleNonWakeupBasePrice));
mActions.put(ACTION_ALARM_NONWAKEUP_EXACT,
new Action(ACTION_ALARM_NONWAKEUP_EXACT,
- arcToNarc(mParser.getInt(
+ arcToCake(mParser.getInt(
KEY_AM_ACTION_ALARM_EXACT_NONWAKEUP_CTP,
DEFAULT_AM_ACTION_ALARM_EXACT_NONWAKEUP_CTP)),
- arcToNarc(mParser.getInt(
+ arcToCake(mParser.getInt(
KEY_AM_ACTION_ALARM_EXACT_NONWAKEUP_BASE_PRICE,
DEFAULT_AM_ACTION_ALARM_EXACT_NONWAKEUP_BASE_PRICE))));
final long inexactAllowWhileIdleNonWakeupBasePrice =
- arcToNarc(mParser.getInt(
+ arcToCake(mParser.getInt(
KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE,
DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_BASE_PRICE));
mActions.put(ACTION_ALARM_NONWAKEUP_INEXACT_ALLOW_WHILE_IDLE,
new Action(ACTION_ALARM_NONWAKEUP_INEXACT_ALLOW_WHILE_IDLE,
- arcToNarc(mParser.getInt(
+ arcToCake(mParser.getInt(
KEY_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_CTP,
DEFAULT_AM_ACTION_ALARM_ALLOW_WHILE_IDLE_INEXACT_NONWAKEUP_CTP)),
inexactAllowWhileIdleNonWakeupBasePrice));
mActions.put(ACTION_ALARM_NONWAKEUP_INEXACT,
new Action(ACTION_ALARM_NONWAKEUP_INEXACT,
- arcToNarc(mParser.getInt(
+ arcToCake(mParser.getInt(
KEY_AM_ACTION_ALARM_INEXACT_NONWAKEUP_CTP,
DEFAULT_AM_ACTION_ALARM_INEXACT_NONWAKEUP_CTP)),
- arcToNarc(mParser.getInt(
+ arcToCake(mParser.getInt(
KEY_AM_ACTION_ALARM_INEXACT_NONWAKEUP_BASE_PRICE,
DEFAULT_AM_ACTION_ALARM_INEXACT_NONWAKEUP_BASE_PRICE))));
mActions.put(ACTION_ALARM_CLOCK,
new Action(ACTION_ALARM_CLOCK,
- arcToNarc(mParser.getInt(
+ arcToCake(mParser.getInt(
KEY_AM_ACTION_ALARM_ALARMCLOCK_CTP,
DEFAULT_AM_ACTION_ALARM_ALARMCLOCK_CTP)),
- arcToNarc(mParser.getInt(
+ arcToCake(mParser.getInt(
KEY_AM_ACTION_ALARM_ALARMCLOCK_BASE_PRICE,
DEFAULT_AM_ACTION_ALARM_ALARMCLOCK_BASE_PRICE))));
mRewards.put(REWARD_TOP_ACTIVITY, new Reward(REWARD_TOP_ACTIVITY,
- arcToNarc(mParser.getInt(KEY_AM_REWARD_TOP_ACTIVITY_INSTANT,
+ arcToCake(mParser.getInt(KEY_AM_REWARD_TOP_ACTIVITY_INSTANT,
DEFAULT_AM_REWARD_TOP_ACTIVITY_INSTANT)),
- (long) (arcToNarc(1) * mParser.getFloat(KEY_AM_REWARD_TOP_ACTIVITY_ONGOING,
+ (long) (arcToCake(1) * mParser.getFloat(KEY_AM_REWARD_TOP_ACTIVITY_ONGOING,
DEFAULT_AM_REWARD_TOP_ACTIVITY_ONGOING)),
- arcToNarc(mParser.getInt(KEY_AM_REWARD_TOP_ACTIVITY_MAX,
+ arcToCake(mParser.getInt(KEY_AM_REWARD_TOP_ACTIVITY_MAX,
DEFAULT_AM_REWARD_TOP_ACTIVITY_MAX))));
mRewards.put(REWARD_NOTIFICATION_SEEN, new Reward(REWARD_NOTIFICATION_SEEN,
- arcToNarc(mParser.getInt(KEY_AM_REWARD_NOTIFICATION_SEEN_INSTANT,
+ arcToCake(mParser.getInt(KEY_AM_REWARD_NOTIFICATION_SEEN_INSTANT,
DEFAULT_AM_REWARD_NOTIFICATION_SEEN_INSTANT)),
- arcToNarc(mParser.getInt(KEY_AM_REWARD_NOTIFICATION_SEEN_ONGOING,
+ arcToCake(mParser.getInt(KEY_AM_REWARD_NOTIFICATION_SEEN_ONGOING,
DEFAULT_AM_REWARD_NOTIFICATION_SEEN_ONGOING)),
- arcToNarc(mParser.getInt(KEY_AM_REWARD_NOTIFICATION_SEEN_MAX,
+ arcToCake(mParser.getInt(KEY_AM_REWARD_NOTIFICATION_SEEN_MAX,
DEFAULT_AM_REWARD_NOTIFICATION_SEEN_MAX))));
mRewards.put(REWARD_NOTIFICATION_INTERACTION,
new Reward(REWARD_NOTIFICATION_INTERACTION,
- arcToNarc(mParser.getInt(
+ arcToCake(mParser.getInt(
KEY_AM_REWARD_NOTIFICATION_INTERACTION_INSTANT,
DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_INSTANT)),
- arcToNarc(mParser.getInt(
+ arcToCake(mParser.getInt(
KEY_AM_REWARD_NOTIFICATION_INTERACTION_ONGOING,
DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_ONGOING)),
- arcToNarc(mParser.getInt(
+ arcToCake(mParser.getInt(
KEY_AM_REWARD_NOTIFICATION_INTERACTION_MAX,
DEFAULT_AM_REWARD_NOTIFICATION_INTERACTION_MAX))));
mRewards.put(REWARD_WIDGET_INTERACTION, new Reward(REWARD_WIDGET_INTERACTION,
- arcToNarc(mParser.getInt(KEY_AM_REWARD_WIDGET_INTERACTION_INSTANT,
+ arcToCake(mParser.getInt(KEY_AM_REWARD_WIDGET_INTERACTION_INSTANT,
DEFAULT_AM_REWARD_WIDGET_INTERACTION_INSTANT)),
- arcToNarc(mParser.getInt(KEY_AM_REWARD_WIDGET_INTERACTION_ONGOING,
+ arcToCake(mParser.getInt(KEY_AM_REWARD_WIDGET_INTERACTION_ONGOING,
DEFAULT_AM_REWARD_WIDGET_INTERACTION_ONGOING)),
- arcToNarc(mParser.getInt(KEY_AM_REWARD_WIDGET_INTERACTION_MAX,
+ arcToCake(mParser.getInt(KEY_AM_REWARD_WIDGET_INTERACTION_MAX,
DEFAULT_AM_REWARD_WIDGET_INTERACTION_MAX))));
mRewards.put(REWARD_OTHER_USER_INTERACTION,
new Reward(REWARD_OTHER_USER_INTERACTION,
- arcToNarc(mParser.getInt(KEY_AM_REWARD_OTHER_USER_INTERACTION_INSTANT,
+ arcToCake(mParser.getInt(KEY_AM_REWARD_OTHER_USER_INTERACTION_INSTANT,
DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_INSTANT)),
- arcToNarc(mParser.getInt(
+ arcToCake(mParser.getInt(
KEY_AM_REWARD_OTHER_USER_INTERACTION_ONGOING,
DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_ONGOING)),
- arcToNarc(mParser.getInt(
+ arcToCake(mParser.getInt(
KEY_AM_REWARD_OTHER_USER_INTERACTION_MAX,
DEFAULT_AM_REWARD_OTHER_USER_INTERACTION_MAX))));
}
@@ -364,14 +364,14 @@
void dump(IndentingPrintWriter pw) {
pw.println("Min satiated balances:");
pw.increaseIndent();
- pw.print("Exempted", narcToString(mMinSatiatedBalanceExempted)).println();
- pw.print("Other", narcToString(mMinSatiatedBalanceOther)).println();
+ pw.print("Exempted", cakeToString(mMinSatiatedBalanceExempted)).println();
+ pw.print("Other", cakeToString(mMinSatiatedBalanceOther)).println();
pw.decreaseIndent();
- pw.print("Max satiated balance", narcToString(mMaxSatiatedBalance)).println();
+ pw.print("Max satiated balance", cakeToString(mMaxSatiatedBalance)).println();
pw.print("Consumption limits: [");
- pw.print(narcToString(mInitialSatiatedConsumptionLimit));
+ pw.print(cakeToString(mInitialSatiatedConsumptionLimit));
pw.print(", ");
- pw.print(narcToString(mHardSatiatedConsumptionLimit));
+ pw.print(cakeToString(mHardSatiatedConsumptionLimit));
pw.println("]");
pw.println();
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/EconomicPolicy.java b/apex/jobscheduler/service/java/com/android/server/tare/EconomicPolicy.java
index 1e48015..3a26aae 100644
--- a/apex/jobscheduler/service/java/com/android/server/tare/EconomicPolicy.java
+++ b/apex/jobscheduler/service/java/com/android/server/tare/EconomicPolicy.java
@@ -21,7 +21,7 @@
import static com.android.server.tare.Modifier.COST_MODIFIER_POWER_SAVE_MODE;
import static com.android.server.tare.Modifier.COST_MODIFIER_PROCESS_STATE;
import static com.android.server.tare.Modifier.NUM_COST_MODIFIERS;
-import static com.android.server.tare.TareUtils.narcToString;
+import static com.android.server.tare.TareUtils.cakeToString;
import android.annotation.CallSuper;
import android.annotation.IntDef;
@@ -203,7 +203,7 @@
abstract long getMaxSatiatedBalance();
/**
- * Returns the maximum number of narcs that should be consumed during a full 100% discharge
+ * Returns the maximum number of cakes that should be consumed during a full 100% discharge
* cycle. This is the initial limit. The system may choose to increase the limit over time,
* but the increased limit should never exceed the value returned from
* {@link #getHardSatiatedConsumptionLimit()}.
@@ -211,7 +211,7 @@
abstract long getInitialSatiatedConsumptionLimit();
/**
- * Returns the maximum number of narcs that should be consumed during a full 100% discharge
+ * Returns the maximum number of cakes that should be consumed during a full 100% discharge
* cycle. This is the hard limit that should never be exceeded.
*/
abstract long getHardSatiatedConsumptionLimit();
@@ -430,9 +430,9 @@
pw.print(actionToString(action.id));
pw.print(": ");
pw.print("ctp=");
- pw.print(narcToString(action.costToProduce));
+ pw.print(cakeToString(action.costToProduce));
pw.print(", basePrice=");
- pw.print(narcToString(action.basePrice));
+ pw.print(cakeToString(action.basePrice));
pw.println();
}
@@ -440,11 +440,11 @@
pw.print(rewardToString(reward.id));
pw.print(": ");
pw.print("instant=");
- pw.print(narcToString(reward.instantReward));
+ pw.print(cakeToString(reward.instantReward));
pw.print(", ongoing/sec=");
- pw.print(narcToString(reward.ongoingRewardPerSecond));
+ pw.print(cakeToString(reward.ongoingRewardPerSecond));
pw.print(", maxDaily=");
- pw.print(narcToString(reward.maxDailyReward));
+ pw.print(cakeToString(reward.maxDailyReward));
pw.println();
}
}
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/InternalResourceService.java b/apex/jobscheduler/service/java/com/android/server/tare/InternalResourceService.java
index c934807..ce4604f 100644
--- a/apex/jobscheduler/service/java/com/android/server/tare/InternalResourceService.java
+++ b/apex/jobscheduler/service/java/com/android/server/tare/InternalResourceService.java
@@ -23,8 +23,8 @@
import static android.text.format.DateUtils.MINUTE_IN_MILLIS;
import static com.android.server.tare.TareUtils.appToString;
+import static com.android.server.tare.TareUtils.cakeToString;
import static com.android.server.tare.TareUtils.getCurrentTimeMillis;
-import static com.android.server.tare.TareUtils.narcToString;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -528,9 +528,9 @@
void maybePerformQuantitativeEasingLocked() {
// We don't need to increase the limit if the device runs out of consumable credits
// when the battery is low.
- final long remainingConsumableNarcs = mScribe.getRemainingConsumableNarcsLocked();
+ final long remainingConsumableCakes = mScribe.getRemainingConsumableCakesLocked();
if (mCurrentBatteryLevel <= QUANTITATIVE_EASING_BATTERY_THRESHOLD
- || remainingConsumableNarcs > 0) {
+ || remainingConsumableCakes > 0) {
return;
}
final long currentConsumptionLimit = mScribe.getSatiatedConsumptionLimitLocked();
@@ -539,8 +539,8 @@
final long newConsumptionLimit = Math.min(currentConsumptionLimit + shortfall,
mCompleteEconomicPolicy.getHardSatiatedConsumptionLimit());
if (newConsumptionLimit != currentConsumptionLimit) {
- Slog.i(TAG, "Increasing consumption limit from " + narcToString(currentConsumptionLimit)
- + " to " + narcToString(newConsumptionLimit));
+ Slog.i(TAG, "Increasing consumption limit from " + cakeToString(currentConsumptionLimit)
+ + " to " + cakeToString(newConsumptionLimit));
mScribe.setConsumptionLimitLocked(newConsumptionLimit);
adjustCreditSupplyLocked(/* allowIncrease */ true);
}
@@ -562,16 +562,16 @@
@GuardedBy("mLock")
private void adjustCreditSupplyLocked(boolean allowIncrease) {
final long newLimit = getConsumptionLimitLocked();
- final long remainingConsumableNarcs = mScribe.getRemainingConsumableNarcsLocked();
- if (remainingConsumableNarcs == newLimit) {
+ final long remainingConsumableCakes = mScribe.getRemainingConsumableCakesLocked();
+ if (remainingConsumableCakes == newLimit) {
return;
}
- if (remainingConsumableNarcs > newLimit) {
- mScribe.adjustRemainingConsumableNarcsLocked(newLimit - remainingConsumableNarcs);
+ if (remainingConsumableCakes > newLimit) {
+ mScribe.adjustRemainingConsumableCakesLocked(newLimit - remainingConsumableCakes);
} else if (allowIncrease) {
final double perc = mCurrentBatteryLevel / 100d;
- final long shortfall = newLimit - remainingConsumableNarcs;
- mScribe.adjustRemainingConsumableNarcsLocked((long) (perc * shortfall));
+ final long shortfall = newLimit - remainingConsumableCakes;
+ mScribe.adjustRemainingConsumableCakesLocked((long) (perc * shortfall));
}
mAgent.onCreditSupplyChanged();
}
@@ -919,7 +919,7 @@
+ cost.price * (action.ongoingDurationMs / 1000);
}
return mAgent.getBalanceLocked(userId, pkgName) >= requiredBalance
- && mScribe.getRemainingConsumableNarcsLocked() >= requiredBalance;
+ && mScribe.getRemainingConsumableCakesLocked() >= requiredBalance;
}
}
@@ -947,7 +947,7 @@
}
final long minBalance = Math.min(
mAgent.getBalanceLocked(userId, pkgName),
- mScribe.getRemainingConsumableNarcsLocked());
+ mScribe.getRemainingConsumableCakesLocked());
return minBalance * 1000 / totalCostPerSecond;
}
}
@@ -1103,21 +1103,21 @@
final long consumptionLimit = getConsumptionLimitLocked();
pw.print("Consumption limit (current/initial-satiated/current-satiated): ");
- pw.print(narcToString(consumptionLimit));
+ pw.print(cakeToString(consumptionLimit));
pw.print("/");
- pw.print(narcToString(mCompleteEconomicPolicy.getInitialSatiatedConsumptionLimit()));
+ pw.print(cakeToString(mCompleteEconomicPolicy.getInitialSatiatedConsumptionLimit()));
pw.print("/");
- pw.println(narcToString(mScribe.getSatiatedConsumptionLimitLocked()));
+ pw.println(cakeToString(mScribe.getSatiatedConsumptionLimitLocked()));
- final long remainingConsumable = mScribe.getRemainingConsumableNarcsLocked();
+ final long remainingConsumable = mScribe.getRemainingConsumableCakesLocked();
pw.print("Goods remaining: ");
- pw.print(narcToString(remainingConsumable));
+ pw.print(cakeToString(remainingConsumable));
pw.print(" (");
pw.print(String.format("%.2f", 100f * remainingConsumable / consumptionLimit));
pw.println("% of current limit)");
pw.print("Device wealth: ");
- pw.println(narcToString(mScribe.getNarcsInCirculationForLoggingLocked()));
+ pw.println(cakeToString(mScribe.getCakesInCirculationForLoggingLocked()));
pw.println();
pw.print("Exempted apps", mExemptedApps);
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/JobSchedulerEconomicPolicy.java b/apex/jobscheduler/service/java/com/android/server/tare/JobSchedulerEconomicPolicy.java
index 0eddd22..99b93ce 100644
--- a/apex/jobscheduler/service/java/com/android/server/tare/JobSchedulerEconomicPolicy.java
+++ b/apex/jobscheduler/service/java/com/android/server/tare/JobSchedulerEconomicPolicy.java
@@ -106,8 +106,8 @@
import static com.android.server.tare.Modifier.COST_MODIFIER_DEVICE_IDLE;
import static com.android.server.tare.Modifier.COST_MODIFIER_POWER_SAVE_MODE;
import static com.android.server.tare.Modifier.COST_MODIFIER_PROCESS_STATE;
-import static com.android.server.tare.TareUtils.arcToNarc;
-import static com.android.server.tare.TareUtils.narcToString;
+import static com.android.server.tare.TareUtils.arcToCake;
+import static com.android.server.tare.TareUtils.cakeToString;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -221,116 +221,116 @@
Slog.e(TAG, "Global setting key incorrect: ", e);
}
- mMinSatiatedBalanceExempted = arcToNarc(
+ mMinSatiatedBalanceExempted = arcToCake(
mParser.getInt(KEY_JS_MIN_SATIATED_BALANCE_EXEMPTED,
DEFAULT_JS_MIN_SATIATED_BALANCE_EXEMPTED));
- mMinSatiatedBalanceOther = arcToNarc(
+ mMinSatiatedBalanceOther = arcToCake(
mParser.getInt(KEY_JS_MIN_SATIATED_BALANCE_OTHER_APP,
DEFAULT_JS_MIN_SATIATED_BALANCE_OTHER_APP));
- mMaxSatiatedBalance = arcToNarc(mParser.getInt(KEY_JS_MAX_SATIATED_BALANCE,
+ mMaxSatiatedBalance = arcToCake(mParser.getInt(KEY_JS_MAX_SATIATED_BALANCE,
DEFAULT_JS_MAX_SATIATED_BALANCE));
- mInitialSatiatedConsumptionLimit = arcToNarc(mParser.getInt(
+ mInitialSatiatedConsumptionLimit = arcToCake(mParser.getInt(
KEY_JS_INITIAL_CONSUMPTION_LIMIT, DEFAULT_JS_INITIAL_CONSUMPTION_LIMIT));
mHardSatiatedConsumptionLimit = Math.max(mInitialSatiatedConsumptionLimit,
- arcToNarc(mParser.getInt(
+ arcToCake(mParser.getInt(
KEY_JS_HARD_CONSUMPTION_LIMIT, DEFAULT_JS_HARD_CONSUMPTION_LIMIT)));
mActions.put(ACTION_JOB_MAX_START, new Action(ACTION_JOB_MAX_START,
- arcToNarc(mParser.getInt(KEY_JS_ACTION_JOB_MAX_START_CTP,
+ arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_MAX_START_CTP,
DEFAULT_JS_ACTION_JOB_MAX_START_CTP)),
- arcToNarc(mParser.getInt(KEY_JS_ACTION_JOB_MAX_START_BASE_PRICE,
+ arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_MAX_START_BASE_PRICE,
DEFAULT_JS_ACTION_JOB_MAX_START_BASE_PRICE))));
mActions.put(ACTION_JOB_MAX_RUNNING, new Action(ACTION_JOB_MAX_RUNNING,
- arcToNarc(mParser.getInt(KEY_JS_ACTION_JOB_MAX_RUNNING_CTP,
+ arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_MAX_RUNNING_CTP,
DEFAULT_JS_ACTION_JOB_MAX_RUNNING_CTP)),
- arcToNarc(mParser.getInt(KEY_JS_ACTION_JOB_MAX_RUNNING_BASE_PRICE,
+ arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_MAX_RUNNING_BASE_PRICE,
DEFAULT_JS_ACTION_JOB_MAX_RUNNING_BASE_PRICE))));
mActions.put(ACTION_JOB_HIGH_START, new Action(ACTION_JOB_HIGH_START,
- arcToNarc(mParser.getInt(KEY_JS_ACTION_JOB_HIGH_START_CTP,
+ arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_HIGH_START_CTP,
DEFAULT_JS_ACTION_JOB_HIGH_START_CTP)),
- arcToNarc(mParser.getInt(KEY_JS_ACTION_JOB_HIGH_START_BASE_PRICE,
+ arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_HIGH_START_BASE_PRICE,
DEFAULT_JS_ACTION_JOB_HIGH_START_BASE_PRICE))));
mActions.put(ACTION_JOB_HIGH_RUNNING, new Action(ACTION_JOB_HIGH_RUNNING,
- arcToNarc(mParser.getInt(KEY_JS_ACTION_JOB_HIGH_RUNNING_CTP,
+ arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_HIGH_RUNNING_CTP,
DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_CTP)),
- arcToNarc(mParser.getInt(KEY_JS_ACTION_JOB_HIGH_RUNNING_BASE_PRICE,
+ arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_HIGH_RUNNING_BASE_PRICE,
DEFAULT_JS_ACTION_JOB_HIGH_RUNNING_BASE_PRICE))));
mActions.put(ACTION_JOB_DEFAULT_START, new Action(ACTION_JOB_DEFAULT_START,
- arcToNarc(mParser.getInt(KEY_JS_ACTION_JOB_DEFAULT_START_CTP,
+ arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_DEFAULT_START_CTP,
DEFAULT_JS_ACTION_JOB_DEFAULT_START_CTP)),
- arcToNarc(mParser.getInt(KEY_JS_ACTION_JOB_DEFAULT_START_BASE_PRICE,
+ arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_DEFAULT_START_BASE_PRICE,
DEFAULT_JS_ACTION_JOB_DEFAULT_START_BASE_PRICE))));
mActions.put(ACTION_JOB_DEFAULT_RUNNING, new Action(ACTION_JOB_DEFAULT_RUNNING,
- arcToNarc(mParser.getInt(KEY_JS_ACTION_JOB_DEFAULT_RUNNING_CTP,
+ arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_DEFAULT_RUNNING_CTP,
DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_CTP)),
- arcToNarc(mParser.getInt(KEY_JS_ACTION_JOB_DEFAULT_RUNNING_BASE_PRICE,
+ arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_DEFAULT_RUNNING_BASE_PRICE,
DEFAULT_JS_ACTION_JOB_DEFAULT_RUNNING_BASE_PRICE))));
mActions.put(ACTION_JOB_LOW_START, new Action(ACTION_JOB_LOW_START,
- arcToNarc(mParser.getInt(KEY_JS_ACTION_JOB_LOW_START_CTP,
+ arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_LOW_START_CTP,
DEFAULT_JS_ACTION_JOB_LOW_START_CTP)),
- arcToNarc(mParser.getInt(KEY_JS_ACTION_JOB_LOW_START_BASE_PRICE,
+ arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_LOW_START_BASE_PRICE,
DEFAULT_JS_ACTION_JOB_LOW_START_BASE_PRICE))));
mActions.put(ACTION_JOB_LOW_RUNNING, new Action(ACTION_JOB_LOW_RUNNING,
- arcToNarc(mParser.getInt(KEY_JS_ACTION_JOB_LOW_RUNNING_CTP,
+ arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_LOW_RUNNING_CTP,
DEFAULT_JS_ACTION_JOB_LOW_RUNNING_CTP)),
- arcToNarc(mParser.getInt(KEY_JS_ACTION_JOB_LOW_RUNNING_BASE_PRICE,
+ arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_LOW_RUNNING_BASE_PRICE,
DEFAULT_JS_ACTION_JOB_LOW_RUNNING_BASE_PRICE))));
mActions.put(ACTION_JOB_MIN_START, new Action(ACTION_JOB_MIN_START,
- arcToNarc(mParser.getInt(KEY_JS_ACTION_JOB_MIN_START_CTP,
+ arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_MIN_START_CTP,
DEFAULT_JS_ACTION_JOB_MIN_START_CTP)),
- arcToNarc(mParser.getInt(KEY_JS_ACTION_JOB_MIN_START_BASE_PRICE,
+ arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_MIN_START_BASE_PRICE,
DEFAULT_JS_ACTION_JOB_MIN_START_BASE_PRICE))));
mActions.put(ACTION_JOB_MIN_RUNNING, new Action(ACTION_JOB_MIN_RUNNING,
- arcToNarc(mParser.getInt(KEY_JS_ACTION_JOB_MIN_RUNNING_CTP,
+ arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_MIN_RUNNING_CTP,
DEFAULT_JS_ACTION_JOB_MIN_RUNNING_CTP)),
- arcToNarc(mParser.getInt(KEY_JS_ACTION_JOB_MIN_RUNNING_BASE_PRICE,
+ arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_MIN_RUNNING_BASE_PRICE,
DEFAULT_JS_ACTION_JOB_MIN_RUNNING_BASE_PRICE))));
mActions.put(ACTION_JOB_TIMEOUT, new Action(ACTION_JOB_TIMEOUT,
- arcToNarc(mParser.getInt(KEY_JS_ACTION_JOB_TIMEOUT_PENALTY_CTP,
+ arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_TIMEOUT_PENALTY_CTP,
DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_CTP)),
- arcToNarc(mParser.getInt(KEY_JS_ACTION_JOB_TIMEOUT_PENALTY_BASE_PRICE,
+ arcToCake(mParser.getInt(KEY_JS_ACTION_JOB_TIMEOUT_PENALTY_BASE_PRICE,
DEFAULT_JS_ACTION_JOB_TIMEOUT_PENALTY_BASE_PRICE))));
mRewards.put(REWARD_TOP_ACTIVITY, new Reward(REWARD_TOP_ACTIVITY,
- arcToNarc(mParser.getInt(KEY_JS_REWARD_TOP_ACTIVITY_INSTANT,
+ arcToCake(mParser.getInt(KEY_JS_REWARD_TOP_ACTIVITY_INSTANT,
DEFAULT_JS_REWARD_TOP_ACTIVITY_INSTANT)),
- (long) (arcToNarc(1) * mParser.getFloat(KEY_JS_REWARD_TOP_ACTIVITY_ONGOING,
+ (long) (arcToCake(1) * mParser.getFloat(KEY_JS_REWARD_TOP_ACTIVITY_ONGOING,
DEFAULT_JS_REWARD_TOP_ACTIVITY_ONGOING)),
- arcToNarc(mParser.getInt(KEY_JS_REWARD_TOP_ACTIVITY_MAX,
+ arcToCake(mParser.getInt(KEY_JS_REWARD_TOP_ACTIVITY_MAX,
DEFAULT_JS_REWARD_TOP_ACTIVITY_MAX))));
mRewards.put(REWARD_NOTIFICATION_SEEN, new Reward(REWARD_NOTIFICATION_SEEN,
- arcToNarc(mParser.getInt(KEY_JS_REWARD_NOTIFICATION_SEEN_INSTANT,
+ arcToCake(mParser.getInt(KEY_JS_REWARD_NOTIFICATION_SEEN_INSTANT,
DEFAULT_JS_REWARD_NOTIFICATION_SEEN_INSTANT)),
- arcToNarc(mParser.getInt(KEY_JS_REWARD_NOTIFICATION_SEEN_ONGOING,
+ arcToCake(mParser.getInt(KEY_JS_REWARD_NOTIFICATION_SEEN_ONGOING,
DEFAULT_JS_REWARD_NOTIFICATION_SEEN_ONGOING)),
- arcToNarc(mParser.getInt(KEY_JS_REWARD_NOTIFICATION_SEEN_MAX,
+ arcToCake(mParser.getInt(KEY_JS_REWARD_NOTIFICATION_SEEN_MAX,
DEFAULT_JS_REWARD_NOTIFICATION_SEEN_MAX))));
mRewards.put(REWARD_NOTIFICATION_INTERACTION,
new Reward(REWARD_NOTIFICATION_INTERACTION,
- arcToNarc(mParser.getInt(
+ arcToCake(mParser.getInt(
KEY_JS_REWARD_NOTIFICATION_INTERACTION_INSTANT,
DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_INSTANT)),
- arcToNarc(mParser.getInt(
+ arcToCake(mParser.getInt(
KEY_JS_REWARD_NOTIFICATION_INTERACTION_ONGOING,
DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_ONGOING)),
- arcToNarc(mParser.getInt(
+ arcToCake(mParser.getInt(
KEY_JS_REWARD_NOTIFICATION_INTERACTION_MAX,
DEFAULT_JS_REWARD_NOTIFICATION_INTERACTION_MAX))));
mRewards.put(REWARD_WIDGET_INTERACTION, new Reward(REWARD_WIDGET_INTERACTION,
- arcToNarc(mParser.getInt(KEY_JS_REWARD_WIDGET_INTERACTION_INSTANT,
+ arcToCake(mParser.getInt(KEY_JS_REWARD_WIDGET_INTERACTION_INSTANT,
DEFAULT_JS_REWARD_WIDGET_INTERACTION_INSTANT)),
- arcToNarc(mParser.getInt(KEY_JS_REWARD_WIDGET_INTERACTION_ONGOING,
+ arcToCake(mParser.getInt(KEY_JS_REWARD_WIDGET_INTERACTION_ONGOING,
DEFAULT_JS_REWARD_WIDGET_INTERACTION_ONGOING)),
- arcToNarc(mParser.getInt(KEY_JS_REWARD_WIDGET_INTERACTION_MAX,
+ arcToCake(mParser.getInt(KEY_JS_REWARD_WIDGET_INTERACTION_MAX,
DEFAULT_JS_REWARD_WIDGET_INTERACTION_MAX))));
mRewards.put(REWARD_OTHER_USER_INTERACTION,
new Reward(REWARD_OTHER_USER_INTERACTION,
- arcToNarc(mParser.getInt(KEY_JS_REWARD_OTHER_USER_INTERACTION_INSTANT,
+ arcToCake(mParser.getInt(KEY_JS_REWARD_OTHER_USER_INTERACTION_INSTANT,
DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_INSTANT)),
- arcToNarc(mParser.getInt(
+ arcToCake(mParser.getInt(
KEY_JS_REWARD_OTHER_USER_INTERACTION_ONGOING,
DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_ONGOING)),
- arcToNarc(mParser.getInt(
+ arcToCake(mParser.getInt(
KEY_JS_REWARD_OTHER_USER_INTERACTION_MAX,
DEFAULT_JS_REWARD_OTHER_USER_INTERACTION_MAX))));
}
@@ -339,14 +339,14 @@
void dump(IndentingPrintWriter pw) {
pw.println("Min satiated balances:");
pw.increaseIndent();
- pw.print("Exempted", narcToString(mMinSatiatedBalanceExempted)).println();
- pw.print("Other", narcToString(mMinSatiatedBalanceOther)).println();
+ pw.print("Exempted", cakeToString(mMinSatiatedBalanceExempted)).println();
+ pw.print("Other", cakeToString(mMinSatiatedBalanceOther)).println();
pw.decreaseIndent();
- pw.print("Max satiated balance", narcToString(mMaxSatiatedBalance)).println();
+ pw.print("Max satiated balance", cakeToString(mMaxSatiatedBalance)).println();
pw.print("Consumption limits: [");
- pw.print(narcToString(mInitialSatiatedConsumptionLimit));
+ pw.print(cakeToString(mInitialSatiatedConsumptionLimit));
pw.print(", ");
- pw.print(narcToString(mHardSatiatedConsumptionLimit));
+ pw.print(cakeToString(mHardSatiatedConsumptionLimit));
pw.println("]");
pw.println();
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/Ledger.java b/apex/jobscheduler/service/java/com/android/server/tare/Ledger.java
index dfdc20a..2e2a9b5 100644
--- a/apex/jobscheduler/service/java/com/android/server/tare/Ledger.java
+++ b/apex/jobscheduler/service/java/com/android/server/tare/Ledger.java
@@ -18,9 +18,9 @@
import static android.text.format.DateUtils.HOUR_IN_MILLIS;
+import static com.android.server.tare.TareUtils.cakeToString;
import static com.android.server.tare.TareUtils.dumpTime;
import static com.android.server.tare.TareUtils.getCurrentTimeMillis;
-import static com.android.server.tare.TareUtils.narcToString;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -129,7 +129,7 @@
}
void dump(IndentingPrintWriter pw, int numRecentTransactions) {
- pw.print("Current balance", narcToString(getCurrentBalance())).println();
+ pw.print("Current balance", cakeToString(getCurrentBalance())).println();
final int size = mTransactions.size();
for (int i = Math.max(0, size - numRecentTransactions); i < size; ++i) {
@@ -146,9 +146,9 @@
pw.print(")");
}
pw.print(" --> ");
- pw.print(narcToString(transaction.delta));
+ pw.print(cakeToString(transaction.delta));
pw.print(" (ctp=");
- pw.print(narcToString(transaction.ctp));
+ pw.print(cakeToString(transaction.ctp));
pw.println(")");
}
}
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/README.md b/apex/jobscheduler/service/java/com/android/server/tare/README.md
index 33eadff..72d5069 100644
--- a/apex/jobscheduler/service/java/com/android/server/tare/README.md
+++ b/apex/jobscheduler/service/java/com/android/server/tare/README.md
@@ -105,5 +105,7 @@
* ARC: Android Resource Credits are the "currency" units used as an abstraction layer over the real
battery drain. They allow the system to standardize costs and prices across various devices.
+* Cake: A lie; also the smallest unit of an ARC (1 cake = one-billionth of an ARC = 1 nano-ARC).
+ When the apps request to do something, we shall let them eat cake.
* NARC: The smallest unit of an ARC. A narc is 1 nano-ARC.
* Satiated: used to refer to when the device is fully charged (at 100% battery level)
\ No newline at end of file
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/Scribe.java b/apex/jobscheduler/service/java/com/android/server/tare/Scribe.java
index 8662110..7442877 100644
--- a/apex/jobscheduler/service/java/com/android/server/tare/Scribe.java
+++ b/apex/jobscheduler/service/java/com/android/server/tare/Scribe.java
@@ -84,7 +84,7 @@
private static final String XML_ATTR_USER_ID = "userId";
private static final String XML_ATTR_VERSION = "version";
private static final String XML_ATTR_LAST_RECLAMATION_TIME = "lastReclamationTime";
- private static final String XML_ATTR_REMAINING_CONSUMABLE_NARCS = "remainingConsumableNarcs";
+ private static final String XML_ATTR_REMAINING_CONSUMABLE_CAKES = "remainingConsumableCakes";
private static final String XML_ATTR_CONSUMPTION_LIMIT = "consumptionLimit";
/** Version of the file schema. */
@@ -100,7 +100,7 @@
@GuardedBy("mIrs.getLock()")
private long mSatiatedConsumptionLimit;
@GuardedBy("mIrs.getLock()")
- private long mRemainingConsumableNarcs;
+ private long mRemainingConsumableCakes;
@GuardedBy("mIrs.getLock()")
private final SparseArrayMap<String, Ledger> mLedgers = new SparseArrayMap<>();
@@ -122,10 +122,10 @@
}
@GuardedBy("mIrs.getLock()")
- void adjustRemainingConsumableNarcsLocked(long delta) {
+ void adjustRemainingConsumableCakesLocked(long delta) {
if (delta != 0) {
// No point doing any work if the change is 0.
- mRemainingConsumableNarcs += delta;
+ mRemainingConsumableCakes += delta;
postWrite();
}
}
@@ -168,7 +168,7 @@
* call it for normal operation.
*/
@GuardedBy("mIrs.getLock()")
- long getNarcsInCirculationForLoggingLocked() {
+ long getCakesInCirculationForLoggingLocked() {
long sum = 0;
for (int uIdx = mLedgers.numMaps() - 1; uIdx >= 0; --uIdx) {
for (int pIdx = mLedgers.numElementsForKeyAt(uIdx) - 1; pIdx >= 0; --pIdx) {
@@ -178,10 +178,10 @@
return sum;
}
- /** Returns the total amount of narcs that remain to be consumed. */
+ /** Returns the total amount of cakes that remain to be consumed. */
@GuardedBy("mIrs.getLock()")
- long getRemainingConsumableNarcsLocked() {
- return mRemainingConsumableNarcs;
+ long getRemainingConsumableCakesLocked() {
+ return mRemainingConsumableCakes;
}
@GuardedBy("mIrs.getLock()")
@@ -189,11 +189,11 @@
mLedgers.clear();
if (!recordExists()) {
mSatiatedConsumptionLimit = mIrs.getInitialSatiatedConsumptionLimitLocked();
- mRemainingConsumableNarcs = mIrs.getConsumptionLimitLocked();
+ mRemainingConsumableCakes = mIrs.getConsumptionLimitLocked();
return;
}
mSatiatedConsumptionLimit = 0;
- mRemainingConsumableNarcs = 0;
+ mRemainingConsumableCakes = 0;
final SparseArray<ArraySet<String>> installedPackagesPerUser = new SparseArray<>();
final List<PackageInfo> installedPackages = mIrs.getInstalledPackages();
@@ -254,8 +254,8 @@
parser.getAttributeLong(null, XML_ATTR_CONSUMPTION_LIMIT,
mIrs.getInitialSatiatedConsumptionLimitLocked());
final long consumptionLimit = mIrs.getConsumptionLimitLocked();
- mRemainingConsumableNarcs = Math.min(consumptionLimit,
- parser.getAttributeLong(null, XML_ATTR_REMAINING_CONSUMABLE_NARCS,
+ mRemainingConsumableCakes = Math.min(consumptionLimit,
+ parser.getAttributeLong(null, XML_ATTR_REMAINING_CONSUMABLE_CAKES,
consumptionLimit));
break;
case XML_TAG_USER:
@@ -285,11 +285,11 @@
@GuardedBy("mIrs.getLock()")
void setConsumptionLimitLocked(long limit) {
- if (mRemainingConsumableNarcs > limit) {
- mRemainingConsumableNarcs = limit;
+ if (mRemainingConsumableCakes > limit) {
+ mRemainingConsumableCakes = limit;
} else if (limit > mSatiatedConsumptionLimit) {
- final long diff = mSatiatedConsumptionLimit - mRemainingConsumableNarcs;
- mRemainingConsumableNarcs = (limit - diff);
+ final long diff = mSatiatedConsumptionLimit - mRemainingConsumableCakes;
+ mRemainingConsumableCakes = (limit - diff);
}
mSatiatedConsumptionLimit = limit;
postWrite();
@@ -306,7 +306,7 @@
TareHandlerThread.getHandler().removeCallbacks(mCleanRunnable);
TareHandlerThread.getHandler().removeCallbacks(mWriteRunnable);
mLedgers.clear();
- mRemainingConsumableNarcs = 0;
+ mRemainingConsumableCakes = 0;
mSatiatedConsumptionLimit = 0;
mLastReclamationTime = 0;
}
@@ -491,8 +491,8 @@
out.startTag(null, XML_TAG_HIGH_LEVEL_STATE);
out.attributeLong(null, XML_ATTR_LAST_RECLAMATION_TIME, mLastReclamationTime);
out.attributeLong(null, XML_ATTR_CONSUMPTION_LIMIT, mSatiatedConsumptionLimit);
- out.attributeLong(null, XML_ATTR_REMAINING_CONSUMABLE_NARCS,
- mRemainingConsumableNarcs);
+ out.attributeLong(null, XML_ATTR_REMAINING_CONSUMABLE_CAKES,
+ mRemainingConsumableCakes);
out.endTag(null, XML_TAG_HIGH_LEVEL_STATE);
for (int uIdx = mLedgers.numMaps() - 1; uIdx >= 0; --uIdx) {
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/TareUtils.java b/apex/jobscheduler/service/java/com/android/server/tare/TareUtils.java
index 78508d4..87db863 100644
--- a/apex/jobscheduler/service/java/com/android/server/tare/TareUtils.java
+++ b/apex/jobscheduler/service/java/com/android/server/tare/TareUtils.java
@@ -26,7 +26,7 @@
import java.time.Clock;
class TareUtils {
- private static final long NARC_IN_ARC = 1_000_000_000L;
+ private static final long CAKE_IN_ARC = 1_000_000_000L;
@SuppressLint("SimpleDateFormat")
private static final SimpleDateFormat sDumpDateFormat =
@@ -35,8 +35,8 @@
@VisibleForTesting
static Clock sSystemClock = Clock.systemUTC();
- static long arcToNarc(int arcs) {
- return arcs * NARC_IN_ARC;
+ static long arcToCake(int arcs) {
+ return arcs * CAKE_IN_ARC;
}
static void dumpTime(IndentingPrintWriter pw, long time) {
@@ -47,26 +47,26 @@
return sSystemClock.millis();
}
- static int narcToArc(long narcs) {
- return (int) (narcs / NARC_IN_ARC);
+ static int cakeToArc(long cakes) {
+ return (int) (cakes / CAKE_IN_ARC);
}
@NonNull
- static String narcToString(long narcs) {
- if (narcs == 0) {
+ static String cakeToString(long cakes) {
+ if (cakes == 0) {
return "0 ARCs";
}
- final long sub = Math.abs(narcs) % NARC_IN_ARC;
- final long arcs = narcToArc(narcs);
+ final long sub = Math.abs(cakes) % CAKE_IN_ARC;
+ final long arcs = cakeToArc(cakes);
if (arcs == 0) {
return sub == 1
- ? sub + " narc"
- : sub + " narcs";
+ ? sub + " cake"
+ : sub + " cakes";
}
StringBuilder sb = new StringBuilder();
sb.append(arcs);
if (sub > 0) {
- sb.append(".").append(sub / (NARC_IN_ARC / 1000));
+ sb.append(".").append(sub / (CAKE_IN_ARC / 1000));
}
sb.append(" ARC");
if (arcs != 1 || sub > 0) {
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index dd3ddaf..29f21f1 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -763,6 +763,14 @@
* (for example, when apps are displayed side by side in split-screen mode
* in landscape orientation).
*
+ * <p>In multiple-screen scenarios, the width measurement can span screens.
+ * For example, if the app is spanning both screens of a dual-screen device
+ * (with the screens side by side), {@code screenWidthDp} represents the
+ * width of both screens, excluding the area occupied by screen decorations.
+ * When the app is restricted to a single screen in a multiple-screen
+ * environment, {@code screenWidthDp} is the width of the screen on which
+ * the app is running.
+ *
* <p>Differs from {@link android.view.WindowMetrics} by not including
* screen decorations in the width measurement and by expressing the
* measurement in dp rather than px. Use {@code screenWidthDp} to obtain the
@@ -792,6 +800,14 @@
* (for example, when apps are displayed one above another in split-screen
* mode in portrait orientation).
*
+ * <p>In multiple-screen scenarios, the height measurement can span screens.
+ * For example, if the app is spanning both screens of a dual-screen device
+ * rotated 90 degrees (one screen above the other), {@code screenHeightDp}
+ * represents the height of both screens, excluding the area occupied by
+ * screen decorations. When the app is restricted to a single screen in a
+ * multiple-screen environment, {@code screenHeightDp} is the height of the
+ * screen on which the app is running.
+ *
* <p>Differs from {@link android.view.WindowMetrics} by not including
* screen decorations in the height measurement and by expressing the
* measurement in dp rather than px. Use {@code screenHeightDp} to obtain
diff --git a/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java b/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java
index aa98f1f..cf611fb 100644
--- a/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraExtensionCharacteristics.java
@@ -824,24 +824,34 @@
if (!isExtensionSupported(mCameraId, extension, mChars)) {
throw new IllegalArgumentException("Unsupported extension");
}
- Pair<IPreviewExtenderImpl, IImageCaptureExtenderImpl> extenders =
- initializeExtension(extension);
- extenders.second.onInit(mCameraId, mChars.getNativeMetadata());
- extenders.second.init(mCameraId, mChars.getNativeMetadata());
- CameraMetadataNative captureRequestMeta =
- extenders.second.getAvailableCaptureRequestKeys();
+
+ CameraMetadataNative captureRequestMeta = null;
+ if (areAdvancedExtensionsSupported()) {
+ IAdvancedExtenderImpl extender = initializeAdvancedExtension(extension);
+ extender.init(mCameraId);
+ captureRequestMeta = extender.getAvailableCaptureRequestKeys(mCameraId);
+ } else {
+ Pair<IPreviewExtenderImpl, IImageCaptureExtenderImpl> extenders =
+ initializeExtension(extension);
+ extenders.second.onInit(mCameraId, mChars.getNativeMetadata());
+ extenders.second.init(mCameraId, mChars.getNativeMetadata());
+ captureRequestMeta = extenders.second.getAvailableCaptureRequestKeys();
+ extenders.second.onDeInit();
+ }
if (captureRequestMeta != null) {
int[] requestKeys = captureRequestMeta.get(
CameraCharacteristics.REQUEST_AVAILABLE_REQUEST_KEYS);
if (requestKeys == null) {
- throw new AssertionError("android.request.availableRequestKeys must be non-null"
- + " in the characteristics");
+ throw new AssertionError(
+ "android.request.availableRequestKeys must be non-null"
+ + " in the characteristics");
}
- CameraCharacteristics requestChars = new CameraCharacteristics(captureRequestMeta);
+ CameraCharacteristics requestChars = new CameraCharacteristics(
+ captureRequestMeta);
Object crKey = CaptureRequest.Key.class;
- Class<CaptureRequest.Key<?>> crKeyTyped = (Class<CaptureRequest.Key<?>>)crKey;
+ Class<CaptureRequest.Key<?>> crKeyTyped = (Class<CaptureRequest.Key<?>>) crKey;
ret.addAll(requestChars.getAvailableKeyList(CaptureRequest.class, crKeyTyped,
requestKeys, /*includeSynthetic*/ false));
@@ -854,7 +864,6 @@
if (!ret.contains(CaptureRequest.JPEG_ORIENTATION)) {
ret.add(CaptureRequest.JPEG_ORIENTATION);
}
- extenders.second.onDeInit();
} catch (RemoteException e) {
throw new IllegalStateException("Failed to query the available capture request keys!");
} finally {
@@ -894,12 +903,19 @@
throw new IllegalArgumentException("Unsupported extension");
}
- Pair<IPreviewExtenderImpl, IImageCaptureExtenderImpl> extenders =
- initializeExtension(extension);
- extenders.second.onInit(mCameraId, mChars.getNativeMetadata());
- extenders.second.init(mCameraId, mChars.getNativeMetadata());
- CameraMetadataNative captureResultMeta =
- extenders.second.getAvailableCaptureResultKeys();
+ CameraMetadataNative captureResultMeta = null;
+ if (areAdvancedExtensionsSupported()) {
+ IAdvancedExtenderImpl extender = initializeAdvancedExtension(extension);
+ extender.init(mCameraId);
+ captureResultMeta = extender.getAvailableCaptureResultKeys(mCameraId);
+ } else {
+ Pair<IPreviewExtenderImpl, IImageCaptureExtenderImpl> extenders =
+ initializeExtension(extension);
+ extenders.second.onInit(mCameraId, mChars.getNativeMetadata());
+ extenders.second.init(mCameraId, mChars.getNativeMetadata());
+ captureResultMeta = extenders.second.getAvailableCaptureResultKeys();
+ extenders.second.onDeInit();
+ }
if (captureResultMeta != null) {
int[] resultKeys = captureResultMeta.get(
@@ -926,7 +942,6 @@
ret.add(CaptureResult.SENSOR_TIMESTAMP);
}
}
- extenders.second.onDeInit();
} catch (RemoteException e) {
throw new IllegalStateException("Failed to query the available capture result keys!");
} finally {
diff --git a/core/java/android/hardware/camera2/CameraExtensionSession.java b/core/java/android/hardware/camera2/CameraExtensionSession.java
index ee3441f..6ddaddf 100644
--- a/core/java/android/hardware/camera2/CameraExtensionSession.java
+++ b/core/java/android/hardware/camera2/CameraExtensionSession.java
@@ -265,8 +265,8 @@
* from the camera device, to produce a single high-quality output result.
*
* <p>Note that single capture requests currently do not support
- * client parameters except for {@link CaptureRequest#JPEG_ORIENTATION orientation} and
- * {@link CaptureRequest#JPEG_QUALITY quality} in case of ImageFormat.JPEG output target.
+ * client parameters except for controls advertised in
+ * {@link CameraExtensionCharacteristics#getAvailableCaptureRequestKeys}.
* The rest of the settings included in the request will be entirely overridden by
* the device-specific extension. </p>
*
@@ -275,6 +275,11 @@
* arguments that include further targets will cause
* IllegalArgumentException to be thrown. </p>
*
+ * <p>Starting with Android {@link android.os.Build.VERSION_CODES#TIRAMISU} single capture
+ * requests will also support the preview {@link android.graphics.ImageFormat#PRIVATE} target
+ * surface. These can typically be used for enabling AF/AE triggers. Do note, that single
+ * capture requests referencing both output surfaces remain unsupported.</p>
+ *
* <p>Each request will produce one new frame for one target Surface, set
* with the CaptureRequest builder's
* {@link CaptureRequest.Builder#addTarget} method.</p>
@@ -319,8 +324,10 @@
* rate possible.</p>
*
* <p>Note that repeating capture requests currently do not support
- * client parameters. Settings included in the request will
- * be completely overridden by the device-specific extension.</p>
+ * client parameters except for controls advertised in
+ * {@link CameraExtensionCharacteristics#getAvailableCaptureRequestKeys}.
+ * The rest of the settings included in the request will be entirely overridden by
+ * the device-specific extension. </p>
*
* <p>The {@link CaptureRequest.Builder#addTarget} supports only one
* target surface. {@link CaptureRequest} arguments that include further
diff --git a/core/java/android/hardware/camera2/extension/IAdvancedExtenderImpl.aidl b/core/java/android/hardware/camera2/extension/IAdvancedExtenderImpl.aidl
index f279c59..935a542 100644
--- a/core/java/android/hardware/camera2/extension/IAdvancedExtenderImpl.aidl
+++ b/core/java/android/hardware/camera2/extension/IAdvancedExtenderImpl.aidl
@@ -19,6 +19,7 @@
import android.hardware.camera2.extension.LatencyRange;
import android.hardware.camera2.extension.Size;
import android.hardware.camera2.extension.SizeList;
+import android.hardware.camera2.impl.CameraMetadataNative;
/** @hide */
interface IAdvancedExtenderImpl
@@ -30,4 +31,6 @@
@nullable List<SizeList> getSupportedPreviewOutputResolutions(in String cameraId);
@nullable List<SizeList> getSupportedCaptureOutputResolutions(in String cameraId);
ISessionProcessorImpl getSessionProcessor();
+ CameraMetadataNative getAvailableCaptureRequestKeys(in String cameraId);
+ CameraMetadataNative getAvailableCaptureResultKeys(in String cameraId);
}
diff --git a/core/java/android/hardware/camera2/extension/ICaptureCallback.aidl b/core/java/android/hardware/camera2/extension/ICaptureCallback.aidl
index 6ab0ad2..f3062ad 100644
--- a/core/java/android/hardware/camera2/extension/ICaptureCallback.aidl
+++ b/core/java/android/hardware/camera2/extension/ICaptureCallback.aidl
@@ -16,6 +16,7 @@
package android.hardware.camera2.extension;
import android.hardware.camera2.extension.Request;
+import android.hardware.camera2.impl.CameraMetadataNative;
/** @hide */
interface ICaptureCallback
@@ -25,4 +26,5 @@
void onCaptureFailed(int captureSequenceId);
void onCaptureSequenceCompleted(int captureSequenceId);
void onCaptureSequenceAborted(int captureSequenceId);
+ void onCaptureCompleted(long shutterTimestamp, int requestId, in CameraMetadataNative results);
}
diff --git a/core/java/android/hardware/camera2/extension/ISessionProcessorImpl.aidl b/core/java/android/hardware/camera2/extension/ISessionProcessorImpl.aidl
index 6fdf4df..0eca5a7 100644
--- a/core/java/android/hardware/camera2/extension/ISessionProcessorImpl.aidl
+++ b/core/java/android/hardware/camera2/extension/ISessionProcessorImpl.aidl
@@ -15,6 +15,7 @@
*/
package android.hardware.camera2.extension;
+import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.extension.CameraSessionConfig;
import android.hardware.camera2.extension.ICaptureCallback;
import android.hardware.camera2.extension.IRequestProcessorImpl;
@@ -30,5 +31,7 @@
void onCaptureSessionEnd();
int startRepeating(in ICaptureCallback callback);
void stopRepeating();
- int startCapture(in ICaptureCallback callback, int jpegRotation, int jpegQuality);
+ int startCapture(in ICaptureCallback callback);
+ void setParameters(in CaptureRequest captureRequest);
+ int startTrigger(in CaptureRequest captureRequest, in ICaptureCallback callback);
}
diff --git a/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java
index 3c52d65..5503e28 100644
--- a/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java
@@ -86,6 +86,7 @@
// maps camera extension output ids to camera registered image readers
private final HashMap<Integer, ImageReader> mReaderMap = new HashMap<>();
private final RequestProcessor mRequestProcessor = new RequestProcessor();
+ private final int mSessionId;
private Surface mClientRepeatingRequestSurface;
private Surface mClientCaptureSurface;
@@ -175,7 +176,7 @@
CameraAdvancedExtensionSessionImpl ret = new CameraAdvancedExtensionSessionImpl(clientId,
extender, cameraDevice, repeatingRequestSurface, burstCaptureSurface,
- config.getStateCallback(), config.getExecutor());
+ config.getStateCallback(), config.getExecutor(), sessionId);
ret.initialize();
return ret;
@@ -184,7 +185,8 @@
private CameraAdvancedExtensionSessionImpl(long extensionClientId,
@NonNull IAdvancedExtenderImpl extender, @NonNull CameraDevice cameraDevice,
@Nullable Surface repeatingRequestSurface, @Nullable Surface burstCaptureSurface,
- @NonNull CameraExtensionSession.StateCallback callback, @NonNull Executor executor) {
+ @NonNull CameraExtensionSession.StateCallback callback, @NonNull Executor executor,
+ int sessionId) {
mExtensionClientId = extensionClientId;
mAdvancedExtender = extender;
mCameraDevice = cameraDevice;
@@ -197,6 +199,7 @@
mHandler = new Handler(mHandlerThread.getLooper());
mInitialized = false;
mInitializeHandler = new InitializeSessionHandler();
+ mSessionId = sessionId;
}
/**
@@ -367,6 +370,8 @@
}
try {
+ mSessionProcessor.setParameters(request);
+
seqId = mSessionProcessor.startRepeating(new RequestCallbackHandler(request,
executor, listener));
} catch (RemoteException e) {
@@ -388,35 +393,33 @@
throw new IllegalStateException("Uninitialized component");
}
- if (mClientCaptureSurface == null) {
- throw new IllegalArgumentException("No output surface registered for single"
- + " requests!");
+ if (request.getTargets().size() != 1) {
+ throw new IllegalArgumentException("Single capture to both preview & still" +
+ " capture outputs target is not supported!");
}
- if (!request.containsTarget(mClientCaptureSurface) ||
- (request.getTargets().size() != 1)) {
+ if ((mClientCaptureSurface != null) && request.containsTarget(mClientCaptureSurface)) {
+ try {
+ mSessionProcessor.setParameters(request);
+
+ seqId = mSessionProcessor.startCapture(new RequestCallbackHandler(request,
+ executor, listener));
+ } catch (RemoteException e) {
+ throw new CameraAccessException(CameraAccessException.CAMERA_ERROR, "Failed " +
+ " to submit capture request, extension service failed to respond!");
+ }
+ } else if ((mClientRepeatingRequestSurface != null) &&
+ request.containsTarget(mClientRepeatingRequestSurface)) {
+ try {
+ seqId = mSessionProcessor.startTrigger(request,
+ new RequestCallbackHandler(request, executor, listener));
+ } catch (RemoteException e) {
+ throw new CameraAccessException(CameraAccessException.CAMERA_ERROR, "Failed " +
+ " to submit trigger request, extension service failed to respond!");
+ }
+ } else {
throw new IllegalArgumentException("Invalid single capture output target!");
}
-
- try {
- // This will override the extension capture stage jpeg parameters with the user set
- // jpeg quality and rotation. This will guarantee that client configured jpeg
- // parameters always have highest priority.
- Integer jpegRotation = request.get(CaptureRequest.JPEG_ORIENTATION);
- if (jpegRotation == null) {
- jpegRotation = CameraExtensionUtils.JPEG_DEFAULT_ROTATION;
- }
- Byte jpegQuality = request.get(CaptureRequest.JPEG_QUALITY);
- if (jpegQuality == null) {
- jpegQuality = CameraExtensionUtils.JPEG_DEFAULT_QUALITY;
- }
-
- seqId = mSessionProcessor.startCapture(new RequestCallbackHandler(request,
- executor, listener), jpegRotation, jpegQuality);
- } catch (RemoteException e) {
- throw new CameraAccessException(CameraAccessException.CAMERA_ERROR,
- "Failed to submit capture request, extension service failed to respond!");
- }
}
return seqId;
@@ -661,6 +664,28 @@
Binder.restoreCallingIdentity(ident);
}
}
+
+ @Override
+ public void onCaptureCompleted(long timestamp, int requestId, CameraMetadataNative result) {
+ if (result == null) {
+ Log.e(TAG,"Invalid capture result!");
+ return;
+ }
+
+ result.set(CaptureResult.SENSOR_TIMESTAMP, timestamp);
+ TotalCaptureResult totalResult = new TotalCaptureResult(mCameraDevice.getId(), result,
+ mClientRequest, requestId, timestamp, new ArrayList<>(), mSessionId,
+ new PhysicalCaptureResultInfo[0]);
+ final long ident = Binder.clearCallingIdentity();
+ try {
+ mExecutor.execute(
+ () -> mClientCallbacks.onCaptureResultAvailable(
+ CameraAdvancedExtensionSessionImpl.this, mClientRequest,
+ totalResult));
+ } finally {
+ Binder.restoreCallingIdentity(ident);
+ }
+ }
}
private final class CaptureCallbackHandler extends CameraCaptureSession.CaptureCallback {
diff --git a/core/java/android/hardware/camera2/impl/CameraExtensionJpegProcessor.java b/core/java/android/hardware/camera2/impl/CameraExtensionJpegProcessor.java
index 1514a2b..aee20db 100644
--- a/core/java/android/hardware/camera2/impl/CameraExtensionJpegProcessor.java
+++ b/core/java/android/hardware/camera2/impl/CameraExtensionJpegProcessor.java
@@ -303,6 +303,7 @@
jpegBuffer, jpegCapacity, jpegParams.mQuality,
0, 0, yuvImage.getWidth(), yuvImage.getHeight(),
jpegParams.mRotation);
+ jpegImage.setTimestamp(yuvImage.getTimestamp());
yuvImage.close();
try {
diff --git a/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java
index 916d16d..1263da6 100644
--- a/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraExtensionSessionImpl.java
@@ -475,8 +475,8 @@
mInternalRepeatingRequestEnabled = false;
try {
return setRepeatingRequest(mPreviewExtender.getCaptureStage(),
- new RepeatingRequestHandler(request, executor, listener,
- mRepeatingRequestImageCallback));
+ new PreviewRequestHandler(request, executor, listener,
+ mRepeatingRequestImageCallback), request);
} catch (RemoteException e) {
Log.e(TAG, "Failed to set repeating request! Extension service does not "
+ "respond");
@@ -530,7 +530,9 @@
CaptureRequest request = requestBuilder.build();
CameraMetadataNative.update(request.getNativeMetadata(), captureStage.parameters);
ret.add(request);
- captureMap.put(request, captureStage.id);
+ if (captureMap != null) {
+ captureMap.put(request, captureStage.id);
+ }
}
return ret;
@@ -583,33 +585,57 @@
throw new IllegalStateException("Uninitialized component");
}
- if (mClientCaptureSurface == null) {
- throw new IllegalArgumentException("No output surface registered for single requests!");
+ if (request.getTargets().size() != 1) {
+ throw new IllegalArgumentException("Single capture to both preview & still capture " +
+ "outputs target is not supported!");
}
- if (!request.containsTarget(mClientCaptureSurface) || (request.getTargets().size() != 1)) {
- throw new IllegalArgumentException("Invalid single capture output target!");
+ int seqId = -1;
+ if ((mClientCaptureSurface != null) && request.containsTarget(mClientCaptureSurface)) {
+ HashMap<CaptureRequest, Integer> requestMap = new HashMap<>();
+ List<CaptureRequest> burstRequest;
+ try {
+ burstRequest = createBurstRequest(mCameraDevice,
+ mImageExtender.getCaptureStages(), request, mCameraBurstSurface,
+ CameraDevice.TEMPLATE_STILL_CAPTURE, requestMap);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to initialize internal burst request! Extension service does"
+ + " not respond!");
+ throw new CameraAccessException(CameraAccessException.CAMERA_ERROR);
+ }
+ if (burstRequest == null) {
+ throw new UnsupportedOperationException(
+ "Failed to create still capture burst request");
+ }
+
+ seqId = mCaptureSession.captureBurstRequests(burstRequest,
+ new CameraExtensionUtils.HandlerExecutor(mHandler),
+ new BurstRequestHandler(request, executor, listener, requestMap,
+ mBurstCaptureImageCallback));
+ } else if ((mClientRepeatingRequestSurface != null) &&
+ request.containsTarget(mClientRepeatingRequestSurface)) {
+
+ CaptureRequest captureRequest = null;
+ try {
+ ArrayList<CaptureStageImpl> captureStageList = new ArrayList<>();
+ captureStageList.add(mPreviewExtender.getCaptureStage());
+
+ captureRequest = createRequest(mCameraDevice, captureStageList,
+ mCameraRepeatingSurface, CameraDevice.TEMPLATE_PREVIEW, request);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to initialize capture request! Extension service does"
+ + " not respond!");
+ throw new CameraAccessException(CameraAccessException.CAMERA_ERROR);
+ }
+
+ seqId = mCaptureSession.capture(captureRequest, new PreviewRequestHandler(request,
+ executor, listener, mRepeatingRequestImageCallback, true /*singleCapture*/),
+ mHandler);
+ } else {
+ throw new IllegalArgumentException("Capture request to unknown output surface!");
}
- HashMap<CaptureRequest, Integer> requestMap = new HashMap<>();
- List<CaptureRequest> burstRequest;
- try {
- burstRequest = createBurstRequest(mCameraDevice,
- mImageExtender.getCaptureStages(), request, mCameraBurstSurface,
- CameraDevice.TEMPLATE_STILL_CAPTURE, requestMap);
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to initialize internal burst request! Extension service does"
- + " not respond!");
- throw new CameraAccessException(CameraAccessException.CAMERA_ERROR);
- }
- if (burstRequest == null) {
- throw new UnsupportedOperationException("Failed to create still capture burst request");
- }
-
- return mCaptureSession.captureBurstRequests(burstRequest,
- new CameraExtensionUtils.HandlerExecutor(mHandler),
- new BurstRequestHandler(request, executor, listener, requestMap,
- mBurstCaptureImageCallback));
+ return seqId;
}
@Override
@@ -847,7 +873,7 @@
} else {
try {
setRepeatingRequest(mPreviewExtender.getCaptureStage(),
- new RepeatingRequestHandler(null, null, null,
+ new PreviewRequestHandler(null, null, null,
mRepeatingRequestImageCallback));
} catch (CameraAccessException | RemoteException e) {
Log.e(TAG,
@@ -1010,7 +1036,7 @@
if (timestamp != null) {
if (mCaptureResultsSupported && (mCaptureResultHandler == null)) {
mCaptureResultHandler = new CaptureResultHandler(mClientRequest, mExecutor,
- mCallbacks, result.getSessionId());
+ mCallbacks, result.getSequenceId());
}
if (mImageProcessor != null) {
if (mCapturePendingMap.indexOfKey(timestamp) >= 0) {
@@ -1179,7 +1205,7 @@
*/
try {
setRepeatingRequest(mPreviewExtender.getCaptureStage(),
- new RepeatingRequestHandler(null, null, null,
+ new PreviewRequestHandler(null, null, null,
mImageCallback));
} catch (CameraAccessException | RemoteException e) {
Log.e(TAG, "Failed to start the internal repeating request!");
@@ -1320,17 +1346,20 @@
}
}
- // This handler can operate in two modes:
+ // This handler can operate in three modes:
// 1) Using valid client callbacks, which means camera buffers will be propagated the
// registered output surfaces and clients will be notified accordingly.
// 2) Without any client callbacks where an internal repeating request is kept active
// to satisfy the extensions continuous preview/(repeating request) requirement.
- private class RepeatingRequestHandler extends CameraCaptureSession.CaptureCallback {
+ // 3) Single capture mode, where internal repeating requests are ignored and the preview
+ // logic is only triggered for the image processor case.
+ private class PreviewRequestHandler extends CameraCaptureSession.CaptureCallback {
private final Executor mExecutor;
private final ExtensionCaptureCallback mCallbacks;
private final CaptureRequest mClientRequest;
private final boolean mClientNotificationsEnabled;
private final CameraOutputImageCallback mRepeatingImageCallback;
+ private final boolean mSingleCapture;
private OnImageAvailableListener mImageCallback = null;
private LongSparseArray<Pair<Image, TotalCaptureResult>> mPendingResultMap =
new LongSparseArray<>();
@@ -1338,15 +1367,22 @@
private boolean mRequestUpdatedNeeded = false;
- public RepeatingRequestHandler(@Nullable CaptureRequest clientRequest,
+ public PreviewRequestHandler(@Nullable CaptureRequest clientRequest,
@Nullable Executor executor, @Nullable ExtensionCaptureCallback listener,
@NonNull CameraOutputImageCallback imageCallback) {
+ this(clientRequest, executor, listener, imageCallback, false /*singleCapture*/);
+ }
+
+ public PreviewRequestHandler(@Nullable CaptureRequest clientRequest,
+ @Nullable Executor executor, @Nullable ExtensionCaptureCallback listener,
+ @NonNull CameraOutputImageCallback imageCallback, boolean singleCapture) {
mClientRequest = clientRequest;
mExecutor = executor;
mCallbacks = listener;
mClientNotificationsEnabled =
(mClientRequest != null) && (mExecutor != null) && (mCallbacks != null);
mRepeatingImageCallback = imageCallback;
+ mSingleCapture = singleCapture;
}
@Override
@@ -1393,7 +1429,7 @@
public void onCaptureSequenceAborted(@NonNull CameraCaptureSession session,
int sequenceId) {
synchronized (mInterfaceLock) {
- if (mInternalRepeatingRequestEnabled) {
+ if (mInternalRepeatingRequestEnabled && !mSingleCapture) {
resumeInternalRepeatingRequest(true);
}
}
@@ -1420,10 +1456,10 @@
long frameNumber) {
synchronized (mInterfaceLock) {
- if (mRequestUpdatedNeeded) {
+ if (mRequestUpdatedNeeded && !mSingleCapture) {
mRequestUpdatedNeeded = false;
resumeInternalRepeatingRequest(false);
- } else if (mInternalRepeatingRequestEnabled) {
+ } else if (mInternalRepeatingRequestEnabled && !mSingleCapture) {
resumeInternalRepeatingRequest(true);
}
}
@@ -1471,10 +1507,10 @@
if (mCaptureResultsSupported && mClientNotificationsEnabled &&
(mCaptureResultHandler == null)) {
mCaptureResultHandler = new CaptureResultHandler(mClientRequest, mExecutor,
- mCallbacks, result.getSessionId());
+ mCallbacks, result.getSequenceId());
}
- if (mPreviewProcessorType ==
- IPreviewExtenderImpl.PROCESSOR_TYPE_REQUEST_UPDATE_ONLY) {
+ if ((!mSingleCapture) && (mPreviewProcessorType ==
+ IPreviewExtenderImpl.PROCESSOR_TYPE_REQUEST_UPDATE_ONLY)) {
CaptureStageImpl captureStage = null;
try {
captureStage = mPreviewRequestUpdateProcessor.process(
@@ -1582,10 +1618,10 @@
try {
if (internal) {
setRepeatingRequest(mPreviewExtender.getCaptureStage(),
- new RepeatingRequestHandler(null, null, null,
+ new PreviewRequestHandler(null, null, null,
mRepeatingImageCallback));
} else {
- setRepeatingRequest(mPreviewExtender.getCaptureStage(), this);
+ setRepeatingRequest(mPreviewExtender.getCaptureStage(), this, mClientRequest);
}
} catch (RemoteException e) {
Log.e(TAG, "Failed to resume internal repeating request, extension service"
@@ -1733,7 +1769,7 @@
}
private static Size findSmallestAspectMatchedSize(@NonNull List<Size> sizes,
- @NonNull Size arSize) {
+ @NonNull Size arSize) {
final float TOLL = .01f;
if (arSize.getHeight() == 0) {
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index cc93adc..0bed342 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -2280,8 +2280,11 @@
}
/**
- * {@link #getX(int)} for the first pointer index (may be an
- * arbitrary pointer identifier).
+ * Equivalent to {@link #getX(int)} for pointer index 0 (regardless of the
+ * pointer identifier).
+ *
+ * @return The X coordinate of the first pointer index in the coordinate
+ * space of the view that received this motion event.
*
* @see #AXIS_X
*/
@@ -2290,8 +2293,11 @@
}
/**
- * {@link #getY(int)} for the first pointer index (may be an
- * arbitrary pointer identifier).
+ * Equivalent to {@link #getY(int)} for pointer index 0 (regardless of the
+ * pointer identifier).
+ *
+ * @return The Y coordinate of the first pointer index in the coordinate
+ * space of the view that received this motion event.
*
* @see #AXIS_Y
*/
@@ -2433,13 +2439,20 @@
}
/**
- * Returns the X coordinate of this event for the given pointer
- * <em>index</em> (use {@link #getPointerId(int)} to find the pointer
- * identifier for this index).
- * Whole numbers are pixels; the
- * value may have a fraction for input devices that are sub-pixel precise.
- * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
- * (the first pointer that is down) to {@link #getPointerCount()}-1.
+ * Returns the X coordinate of the pointer referenced by
+ * {@code pointerIndex} for this motion event. The coordinate is in the
+ * coordinate space of the view that received this motion event.
+ *
+ * <p>Use {@link #getPointerId(int)} to get the pointer identifier for the
+ * pointer referenced by {@code pointerIndex}.
+ *
+ * @param pointerIndex Index of the pointer for which the X coordinate is
+ * returned. May be a value in the range of 0 (the first pointer that
+ * is down) to {@link #getPointerCount()} - 1.
+ * @return The X coordinate of the pointer referenced by
+ * {@code pointerIndex} for this motion event. The unit is pixels. The
+ * value may contain a fractional portion for devices that are subpixel
+ * precise.
*
* @see #AXIS_X
*/
@@ -2448,13 +2461,20 @@
}
/**
- * Returns the Y coordinate of this event for the given pointer
- * <em>index</em> (use {@link #getPointerId(int)} to find the pointer
- * identifier for this index).
- * Whole numbers are pixels; the
- * value may have a fraction for input devices that are sub-pixel precise.
- * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
- * (the first pointer that is down) to {@link #getPointerCount()}-1.
+ * Returns the Y coordinate of the pointer referenced by
+ * {@code pointerIndex} for this motion event. The coordinate is in the
+ * coordinate space of the view that received this motion event.
+ *
+ * <p>Use {@link #getPointerId(int)} to get the pointer identifier for the
+ * pointer referenced by {@code pointerIndex}.
+ *
+ * @param pointerIndex Index of the pointer for which the Y coordinate is
+ * returned. May be a value in the range of 0 (the first pointer that
+ * is down) to {@link #getPointerCount()} - 1.
+ * @return The Y coordinate of the pointer referenced by
+ * {@code pointerIndex} for this motion event. The unit is pixels. The
+ * value may contain a fractional portion for devices that are subpixel
+ * precise.
*
* @see #AXIS_Y
*/
@@ -2700,12 +2720,13 @@
}
/**
- * Returns the original raw X coordinate of this event. For touch
- * events on the screen, this is the original location of the event
- * on the screen, before it had been adjusted for the containing window
- * and views.
+ * Equivalent to {@link #getRawX(int)} for pointer index 0 (regardless of
+ * the pointer identifier).
*
- * @see #getX(int)
+ * @return The X coordinate of the first pointer index in the coordinate
+ * space of the device display.
+ *
+ * @see #getX()
* @see #AXIS_X
*/
public final float getRawX() {
@@ -2713,12 +2734,13 @@
}
/**
- * Returns the original raw Y coordinate of this event. For touch
- * events on the screen, this is the original location of the event
- * on the screen, before it had been adjusted for the containing window
- * and views.
+ * Equivalent to {@link #getRawY(int)} for pointer index 0 (regardless of
+ * the pointer identifier).
*
- * @see #getY(int)
+ * @return The Y coordinate of the first pointer index in the coordinate
+ * space of the device display.
+ *
+ * @see #getY()
* @see #AXIS_Y
*/
public final float getRawY() {
@@ -2726,13 +2748,38 @@
}
/**
- * Returns the original raw X coordinate of this event. For touch
- * events on the screen, this is the original location of the event
- * on the screen, before it had been adjusted for the containing window
- * and views.
+ * Returns the X coordinate of the pointer referenced by
+ * {@code pointerIndex} for this motion event. The coordinate is in the
+ * coordinate space of the device display, irrespective of system
+ * decorations and whether or not the system is in multi-window mode. If the
+ * app spans multiple screens in a multiple-screen environment, the
+ * coordinate space includes all of the spanned screens.
*
- * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
- * (the first pointer that is down) to {@link #getPointerCount()}-1.
+ * <p>In multi-window mode, the coordinate space extends beyond the bounds
+ * of the app window to encompass the entire display area. For example, if
+ * the motion event occurs in the right-hand window of split-screen mode in
+ * landscape orientation, the left edge of the screen—not the left
+ * edge of the window—is the origin from which the X coordinate is
+ * calculated.
+ *
+ * <p>In multiple-screen scenarios, the coordinate space can span screens.
+ * For example, if the app is spanning both screens of a dual-screen device,
+ * and the motion event occurs on the right-hand screen, the X coordinate is
+ * calculated from the left edge of the left-hand screen to the point of the
+ * motion event on the right-hand screen. When the app is restricted to a
+ * single screen in a multiple-screen environment, the coordinate space
+ * includes only the screen on which the app is running.
+ *
+ * <p>Use {@link #getPointerId(int)} to get the pointer identifier for the
+ * pointer referenced by {@code pointerIndex}.
+ *
+ * @param pointerIndex Index of the pointer for which the X coordinate is
+ * returned. May be a value in the range of 0 (the first pointer that
+ * is down) to {@link #getPointerCount()} - 1.
+ * @return The X coordinate of the pointer referenced by
+ * {@code pointerIndex} for this motion event. The unit is pixels. The
+ * value may contain a fractional portion for devices that are subpixel
+ * precise.
*
* @see #getX(int)
* @see #AXIS_X
@@ -2742,13 +2789,38 @@
}
/**
- * Returns the original raw Y coordinate of this event. For touch
- * events on the screen, this is the original location of the event
- * on the screen, before it had been adjusted for the containing window
- * and views.
+ * Returns the Y coordinate of the pointer referenced by
+ * {@code pointerIndex} for this motion event. The coordinate is in the
+ * coordinate space of the device display, irrespective of system
+ * decorations and whether or not the system is in multi-window mode. If the
+ * app spans multiple screens in a multiple-screen environment, the
+ * coordinate space includes all of the spanned screens.
*
- * @param pointerIndex Raw index of pointer to retrieve. Value may be from 0
- * (the first pointer that is down) to {@link #getPointerCount()}-1.
+ * <p>In multi-window mode, the coordinate space extends beyond the bounds
+ * of the app window to encompass the entire device screen. For example, if
+ * the motion event occurs in the lower window of split-screen mode in
+ * portrait orientation, the top edge of the screen—not the top edge
+ * of the window—is the origin from which the Y coordinate is
+ * determined.
+ *
+ * <p>In multiple-screen scenarios, the coordinate space can span screens.
+ * For example, if the app is spanning both screens of a dual-screen device
+ * that's rotated 90 degrees, and the motion event occurs on the lower
+ * screen, the Y coordinate is calculated from the top edge of the upper
+ * screen to the point of the motion event on the lower screen. When the app
+ * is restricted to a single screen in a multiple-screen environment, the
+ * coordinate space includes only the screen on which the app is running.
+ *
+ * <p>Use {@link #getPointerId(int)} to get the pointer identifier for the
+ * pointer referenced by {@code pointerIndex}.
+ *
+ * @param pointerIndex Index of the pointer for which the Y coordinate is
+ * returned. May be a value in the range of 0 (the first pointer that
+ * is down) to {@link #getPointerCount()} - 1.
+ * @return The Y coordinate of the pointer referenced by
+ * {@code pointerIndex} for this motion event. The unit is pixels. The
+ * value may contain a fractional portion for devices that are subpixel
+ * precise.
*
* @see #getY(int)
* @see #AXIS_Y
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 757f409..b23d8ca 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -1864,6 +1864,11 @@
-->
<string name="config_defaultNetworkRecommendationProviderPackage" translatable="false"></string>
+ <!-- The package name of the default search selector app. Must be granted the POST_NOTIFICATIONS
+ permission.
+ -->
+ <string name="config_defaultSearchSelectorPackageName" translatable="false"></string>
+
<!-- Whether to enable geocoder overlay which allows geocoder to be replaced
by an app at run-time. When disabled, only the
config_geocoderProviderPackageName package will be searched for
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 3334822..21b2351 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3413,6 +3413,9 @@
<!-- Network Recommendation -->
<java-symbol type="string" name="config_defaultNetworkRecommendationProviderPackage" />
+ <!-- Search Selector -->
+ <java-symbol type="string" name="config_defaultSearchSelectorPackageName" />
+
<!-- Optional IPsec algorithms -->
<java-symbol type="array" name="config_optionalIpSecAlgorithms" />
diff --git a/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java b/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java
index e7a23f2..43fba52 100644
--- a/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java
+++ b/core/tests/coretests/src/com/android/internal/app/ResolverActivityTest.java
@@ -516,8 +516,6 @@
onView(withText(R.string.resolver_work_tab))
.perform(click());
waitForIdle();
- // wait for the share sheet to expand
- Thread.sleep(ChooserActivity.LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
onView(first(allOf(withText(workResolvedComponentInfos.get(0)
.getResolveInfoAt(0).activityInfo.applicationInfo.name), isCompletelyDisplayed())))
.perform(click());
@@ -616,8 +614,6 @@
onView(withText(R.string.resolver_work_tab))
.perform(click());
waitForIdle();
- // wait for the share sheet to expand
- Thread.sleep(ChooserActivity.LIST_VIEW_UPDATE_INTERVAL_IN_MILLIS);
onView(first(allOf(
withText(workResolvedComponentInfos.get(0)
.getResolveInfoAt(0).activityInfo.applicationInfo.name),
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index f7acda7e..6a5416d 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -2283,6 +2283,10 @@
<string name="media_output_broadcast_code">Password</string>
<!-- Button for change broadcast name and broadcast code [CHAR LIMIT=60] -->
<string name="media_output_broadcast_dialog_save">Save</string>
+ <!-- The "starting" text when Broadcast is starting [CHAR LIMIT=60] -->
+ <string name="media_output_broadcast_starting">Starting…</string>
+ <!-- The button text when Broadcast start failed [CHAR LIMIT=60] -->
+ <string name="media_output_broadcast_start_failed">Can\u2019t broadcast</string>
<!-- Label for clip data when copying the build number off QS [CHAR LIMIT=NONE]-->
<string name="build_number_clip_data_label">Build number</string>
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
index c0ba51f..f435579 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -860,7 +860,7 @@
private void setupUserSwitcher() {
final UserRecord currentUser = mUserSwitcherController.getCurrentUserRecord();
if (currentUser == null) {
- Log.wtf(TAG, "Current user in user switcher is null.");
+ Log.e(TAG, "Current user in user switcher is null.");
return;
}
Drawable userIcon = findUserIcon(currentUser.info.id);
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
index bde772d..e5e7eb6 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
@@ -19,7 +19,10 @@
import static android.view.WindowInsets.Type.navigationBars;
import static android.view.WindowInsets.Type.statusBars;
+import android.annotation.NonNull;
import android.app.WallpaperColors;
+import android.bluetooth.BluetoothLeBroadcast;
+import android.bluetooth.BluetoothLeBroadcastMetadata;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.res.Configuration;
@@ -59,6 +62,9 @@
import com.android.systemui.broadcast.BroadcastSender;
import com.android.systemui.statusbar.phone.SystemUIDialog;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+
/**
* Base dialog for media output UI
*/
@@ -69,6 +75,7 @@
private static final String EMPTY_TITLE = " ";
private static final String PREF_NAME = "MediaOutputDialog";
private static final String PREF_IS_LE_BROADCAST_FIRST_LAUNCH = "PrefIsLeBroadcastFirstLaunch";
+ private static final boolean DEBUG = true;
private final Handler mMainThreadHandler = new Handler(Looper.getMainLooper());
private final RecyclerView.LayoutManager mLayoutManager;
@@ -91,6 +98,7 @@
private Button mAppButton;
private int mListMaxHeight;
private WallpaperColors mWallpaperColors;
+ private Executor mExecutor;
MediaOutputBaseAdapter mAdapter;
@@ -103,6 +111,79 @@
}
};
+ private final BluetoothLeBroadcast.Callback mBroadcastCallback =
+ new BluetoothLeBroadcast.Callback() {
+ @Override
+ public void onBroadcastStarted(int reason, int broadcastId) {
+ if (DEBUG) {
+ Log.d(TAG, "onBroadcastStarted(), reason = " + reason
+ + ", broadcastId = " + broadcastId);
+ }
+ mMainThreadHandler.post(() -> startLeBroadcastDialog());
+ }
+
+ @Override
+ public void onBroadcastStartFailed(int reason) {
+ if (DEBUG) {
+ Log.d(TAG, "onBroadcastStartFailed(), reason = " + reason);
+ }
+ handleLeBroadcastStartFailed();
+ }
+
+ @Override
+ public void onBroadcastMetadataChanged(int broadcastId,
+ @NonNull BluetoothLeBroadcastMetadata metadata) {
+ if (DEBUG) {
+ Log.d(TAG, "onBroadcastMetadataChanged(), broadcastId = " + broadcastId
+ + ", metadata = " + metadata);
+ }
+ mMainThreadHandler.post(() -> refresh());
+ }
+
+ @Override
+ public void onBroadcastStopped(int reason, int broadcastId) {
+ if (DEBUG) {
+ Log.d(TAG, "onBroadcastStopped(), reason = " + reason
+ + ", broadcastId = " + broadcastId);
+ }
+ mMainThreadHandler.post(() -> refresh());
+ }
+
+ @Override
+ public void onBroadcastStopFailed(int reason) {
+ if (DEBUG) {
+ Log.d(TAG, "onBroadcastStopFailed(), reason = " + reason);
+ }
+ mMainThreadHandler.post(() -> refresh());
+ }
+
+ @Override
+ public void onBroadcastUpdated(int reason, int broadcastId) {
+ if (DEBUG) {
+ Log.d(TAG, "onBroadcastUpdated(), reason = " + reason
+ + ", broadcastId = " + broadcastId);
+ }
+ mMainThreadHandler.post(() -> refresh());
+ }
+
+ @Override
+ public void onBroadcastUpdateFailed(int reason, int broadcastId) {
+ if (DEBUG) {
+ Log.d(TAG, "onBroadcastUpdateFailed(), reason = " + reason
+ + ", broadcastId = " + broadcastId);
+ }
+ mMainThreadHandler.post(() -> refresh());
+ }
+
+ @Override
+ public void onPlaybackStarted(int reason, int broadcastId) {
+ }
+
+ @Override
+ public void onPlaybackStopped(int reason, int broadcastId) {
+ }
+ };
+
public MediaOutputBaseDialog(Context context, BroadcastSender broadcastSender,
MediaOutputController mediaOutputController) {
super(context, R.style.Theme_SystemUI_Dialog_Media);
@@ -114,6 +195,7 @@
mLayoutManager = new LinearLayoutManager(mContext);
mListMaxHeight = context.getResources().getDimensionPixelSize(
R.dimen.media_output_dialog_list_max_height);
+ mExecutor = Executors.newSingleThreadExecutor();
}
@Override
@@ -171,11 +253,18 @@
public void onStart() {
super.onStart();
mMediaOutputController.start(this);
+ if(isBroadcastSupported()) {
+ mMediaOutputController.registerLeBroadcastServiceCallBack(mExecutor,
+ mBroadcastCallback);
+ }
}
@Override
public void onStop() {
super.onStop();
+ if(isBroadcastSupported()) {
+ mMediaOutputController.unregisterLeBroadcastServiceCallBack(mBroadcastCallback);
+ }
mMediaOutputController.stop();
}
@@ -254,35 +343,12 @@
mAdapter.notifyDataSetChanged();
}
}
- // Show when remote media session is available
+ // Show when remote media session is available or
+ // when the device supports BT LE audio + media is playing
mStopButton.setVisibility(getStopButtonVisibility());
- if (isBroadcastSupported() && mMediaOutputController.isPlaying()) {
- mStopButton.setText(R.string.media_output_broadcast);
- mStopButton.setOnClickListener(v -> {
- SharedPreferences sharedPref = mContext.getSharedPreferences(PREF_NAME,
- Context.MODE_PRIVATE);
-
- if (sharedPref != null
- && sharedPref.getBoolean(PREF_IS_LE_BROADCAST_FIRST_LAUNCH, true)) {
- Log.d(TAG, "PREF_IS_LE_BROADCAST_FIRST_LAUNCH: true");
-
- mMediaOutputController.launchLeBroadcastNotifyDialog(mDialogView,
- mBroadcastSender,
- MediaOutputController.BroadcastNotifyDialog.ACTION_FIRST_LAUNCH);
- SharedPreferences.Editor editor = sharedPref.edit();
- editor.putBoolean(PREF_IS_LE_BROADCAST_FIRST_LAUNCH, false);
- editor.apply();
- } else {
- mMediaOutputController.launchMediaOutputBroadcastDialog(mDialogView,
- mBroadcastSender);
- }
- });
- } else {
- mStopButton.setOnClickListener(v -> {
- mMediaOutputController.releaseSession();
- dismiss();
- });
- }
+ mStopButton.setEnabled(true);
+ mStopButton.setText(getStopButtonText());
+ mStopButton.setOnClickListener(v -> onStopButtonClick());
}
private Drawable resizeDrawable(Drawable drawable, int size) {
@@ -301,6 +367,56 @@
Bitmap.createScaledBitmap(bitmap, size, size, false));
}
+ protected void handleLeBroadcastStartFailed() {
+ mStopButton.setText(R.string.media_output_broadcast_start_failed);
+ mStopButton.setEnabled(false);
+ mMainThreadHandler.postDelayed(() -> refresh(), 3000);
+ }
+
+ protected void startLeBroadcast() {
+ mStopButton.setText(R.string.media_output_broadcast_starting);
+ mStopButton.setEnabled(false);
+ if (!mMediaOutputController.startBluetoothLeBroadcast()) {
+ // If the system can't execute "broadcast start", then UI shows the error.
+ handleLeBroadcastStartFailed();
+ }
+ }
+
+ protected boolean startLeBroadcastDialogForFirstTime(){
+ SharedPreferences sharedPref = mContext.getSharedPreferences(PREF_NAME,
+ Context.MODE_PRIVATE);
+ if (sharedPref != null
+ && sharedPref.getBoolean(PREF_IS_LE_BROADCAST_FIRST_LAUNCH, true)) {
+ Log.d(TAG, "PREF_IS_LE_BROADCAST_FIRST_LAUNCH: true");
+
+ mMediaOutputController.launchLeBroadcastNotifyDialog(mDialogView,
+ mBroadcastSender,
+ MediaOutputController.BroadcastNotifyDialog.ACTION_FIRST_LAUNCH,
+ (d, w) -> {
+ startLeBroadcast();
+ });
+ SharedPreferences.Editor editor = sharedPref.edit();
+ editor.putBoolean(PREF_IS_LE_BROADCAST_FIRST_LAUNCH, false);
+ editor.apply();
+ return true;
+ }
+ return false;
+ }
+
+ protected void startLeBroadcastDialog() {
+ mMediaOutputController.launchMediaOutputBroadcastDialog(mDialogView,
+ mBroadcastSender);
+ refresh();
+ }
+
+ protected void stopLeBroadcast() {
+ mStopButton.setEnabled(false);
+ if (!mMediaOutputController.stopBluetoothLeBroadcast()) {
+ // If the system can't execute "broadcast stop", then UI does refresh.
+ mMainThreadHandler.post(() -> refresh());
+ }
+ }
+
abstract Drawable getAppSourceIcon();
abstract int getHeaderIconRes();
@@ -315,6 +431,15 @@
abstract int getStopButtonVisibility();
+ public CharSequence getStopButtonText() {
+ return mContext.getText(R.string.keyboard_key_media_stop);
+ }
+
+ public void onStopButtonClick() {
+ mMediaOutputController.releaseSession();
+ dismiss();
+ }
+
public boolean isBroadcastSupported() {
return false;
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialog.java
index 494dae0..9b3b3ce 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialog.java
@@ -142,8 +142,11 @@
mBroadcastNotify = getDialogView().requireViewById(R.id.broadcast_info);
mBroadcastNotify.setOnClickListener(v -> {
- mMediaOutputController.launchLeBroadcastNotifyDialog(null, null,
- MediaOutputController.BroadcastNotifyDialog.ACTION_BROADCAST_INFO_ICON);
+ mMediaOutputController.launchLeBroadcastNotifyDialog(
+ /* view= */ null,
+ /* broadcastSender= */ null,
+ MediaOutputController.BroadcastNotifyDialog.ACTION_BROADCAST_INFO_ICON,
+ /* onClickListener= */ null);
});
mBroadcastName = getDialogView().requireViewById(R.id.broadcast_name_summary);
mBroadcastNameEdit = getDialogView().requireViewById(R.id.broadcast_name_edit);
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
index ec2a950..0fbec3b 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputController.java
@@ -18,10 +18,13 @@
import static android.provider.Settings.ACTION_BLUETOOTH_PAIRING_SETTINGS;
+import android.annotation.CallbackExecutor;
import android.app.AlertDialog;
import android.app.Notification;
import android.app.WallpaperColors;
+import android.bluetooth.BluetoothLeBroadcast;
import android.content.Context;
+import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
@@ -58,7 +61,7 @@
import com.android.settingslib.RestrictedLockUtilsInternal;
import com.android.settingslib.Utils;
import com.android.settingslib.bluetooth.BluetoothUtils;
-import com.android.settingslib.bluetooth.CachedBluetoothDevice;
+import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.media.BluetoothMediaDevice;
import com.android.settingslib.media.InfoMediaManager;
@@ -83,6 +86,7 @@
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.Executor;
import javax.inject.Inject;
@@ -642,17 +646,14 @@
}
void launchLeBroadcastNotifyDialog(View mediaOutputDialog, BroadcastSender broadcastSender,
- BroadcastNotifyDialog action) {
+ BroadcastNotifyDialog action, final DialogInterface.OnClickListener listener) {
final AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
switch (action) {
case ACTION_FIRST_LAUNCH:
builder.setTitle(R.string.media_output_first_broadcast_title);
builder.setMessage(R.string.media_output_first_notify_broadcast_message);
builder.setNegativeButton(android.R.string.cancel, null);
- builder.setPositiveButton(R.string.media_output_broadcast,
- (d, w) -> {
- launchMediaOutputBroadcastDialog(mediaOutputDialog, broadcastSender);
- });
+ builder.setPositiveButton(R.string.media_output_broadcast, listener);
break;
case ACTION_BROADCAST_INFO_ICON:
builder.setTitle(R.string.media_output_broadcast);
@@ -685,18 +686,64 @@
|| features.contains(MediaRoute2Info.FEATURE_REMOTE_GROUP_PLAYBACK));
}
- boolean isBluetoothLeDevice(@NonNull MediaDevice device) {
- if (device instanceof BluetoothMediaDevice) {
- final CachedBluetoothDevice cachedDevice =
- ((BluetoothMediaDevice) device).getCachedDevice();
- boolean isConnectedLeAudioDevice =
- (cachedDevice != null) ? cachedDevice.isConnectedLeAudioDevice() : false;
- if (DEBUG) {
- Log.d(TAG, "isConnectedLeAudioDevice=" + isConnectedLeAudioDevice);
- }
- return isConnectedLeAudioDevice;
+ boolean isBroadcastSupported() {
+ LocalBluetoothLeBroadcast broadcast =
+ mLocalBluetoothManager.getProfileManager().getLeAudioBroadcastProfile();
+ return broadcast != null ? true : false;
+ }
+
+ boolean isBluetoothLeBroadcastEnabled() {
+ LocalBluetoothLeBroadcast broadcast =
+ mLocalBluetoothManager.getProfileManager().getLeAudioBroadcastProfile();
+ if (broadcast == null) {
+ return false;
}
- return false;
+ return broadcast.isEnabled(null);
+ }
+
+ boolean startBluetoothLeBroadcast() {
+ LocalBluetoothLeBroadcast broadcast =
+ mLocalBluetoothManager.getProfileManager().getLeAudioBroadcastProfile();
+ if (broadcast == null) {
+ Log.d(TAG, "The broadcast profile is null");
+ return false;
+ }
+ broadcast.startBroadcast(getAppSourceName(), /*language*/ null);
+ return true;
+ }
+
+ boolean stopBluetoothLeBroadcast() {
+ LocalBluetoothLeBroadcast broadcast =
+ mLocalBluetoothManager.getProfileManager().getLeAudioBroadcastProfile();
+ if (broadcast == null) {
+ Log.d(TAG, "The broadcast profile is null");
+ return false;
+ }
+ broadcast.stopLatestBroadcast();
+ return true;
+ }
+
+ void registerLeBroadcastServiceCallBack(
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull BluetoothLeBroadcast.Callback callback) {
+ LocalBluetoothLeBroadcast broadcast =
+ mLocalBluetoothManager.getProfileManager().getLeAudioBroadcastProfile();
+ if (broadcast == null) {
+ Log.d(TAG, "The broadcast profile is null");
+ return;
+ }
+ broadcast.registerServiceCallBack(executor, callback);
+ }
+
+ void unregisterLeBroadcastServiceCallBack(
+ @NonNull BluetoothLeBroadcast.Callback callback) {
+ LocalBluetoothLeBroadcast broadcast =
+ mLocalBluetoothManager.getProfileManager().getLeAudioBroadcastProfile();
+ if (broadcast == null) {
+ Log.d(TAG, "The broadcast profile is null");
+ return;
+ }
+ broadcast.unregisterServiceCallBack(callback);
}
private boolean isPlayBackInfoLocal() {
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java
index fc10397..9248433 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialog.java
@@ -27,7 +27,6 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.UiEvent;
import com.android.internal.logging.UiEventLogger;
-import com.android.settingslib.media.MediaDevice;
import com.android.systemui.R;
import com.android.systemui.broadcast.BroadcastSender;
import com.android.systemui.dagger.SysUISingleton;
@@ -93,18 +92,41 @@
isActiveRemoteDevice = mMediaOutputController.isActiveRemoteDevice(
mMediaOutputController.getCurrentConnectedMediaDevice());
}
- boolean isBroadCastSupported = isBroadcastSupported();
+ boolean showBroadcastButton = isBroadcastSupported() && mMediaOutputController.isPlaying();
- return (isActiveRemoteDevice || isBroadCastSupported) ? View.VISIBLE : View.GONE;
+ return (isActiveRemoteDevice || showBroadcastButton) ? View.VISIBLE : View.GONE;
}
@Override
public boolean isBroadcastSupported() {
- MediaDevice device = mMediaOutputController.getCurrentConnectedMediaDevice();
- if (device == null) {
- return false;
+ return mMediaOutputController.isBroadcastSupported();
+ }
+
+ @Override
+ public CharSequence getStopButtonText() {
+ int resId = R.string.keyboard_key_media_stop;
+ if (isBroadcastSupported() && mMediaOutputController.isPlaying()
+ && !mMediaOutputController.isBluetoothLeBroadcastEnabled()) {
+ resId = R.string.media_output_broadcast;
}
- return mMediaOutputController.isBluetoothLeDevice(device);
+ return mContext.getText(resId);
+ }
+
+ @Override
+ public void onStopButtonClick() {
+ if (isBroadcastSupported() && mMediaOutputController.isPlaying()) {
+ if (!mMediaOutputController.isBluetoothLeBroadcastEnabled()) {
+ if (startLeBroadcastDialogForFirstTime()) {
+ return;
+ }
+ startLeBroadcast();
+ } else {
+ stopLeBroadcast();
+ }
+ } else {
+ mMediaOutputController.releaseSession();
+ dismiss();
+ }
}
@VisibleForTesting
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
index 380fa6d..7c53388 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
@@ -18,6 +18,7 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
@@ -26,18 +27,23 @@
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
+import android.media.session.MediaController;
import android.media.session.MediaSessionManager;
+import android.media.session.PlaybackState;
import android.os.Bundle;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.View;
+import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.core.graphics.drawable.IconCompat;
import androidx.test.filters.SmallTest;
+import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.animation.DialogLaunchAnimator;
@@ -50,6 +56,8 @@
import org.junit.Test;
import org.junit.runner.RunWith;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Optional;
@SmallTest
@@ -61,8 +69,14 @@
// Mock
private MediaOutputBaseAdapter mMediaOutputBaseAdapter = mock(MediaOutputBaseAdapter.class);
+ private MediaController mMediaController = mock(MediaController.class);
+ private PlaybackState mPlaybackState = mock(PlaybackState.class);
private MediaSessionManager mMediaSessionManager = mock(MediaSessionManager.class);
private LocalBluetoothManager mLocalBluetoothManager = mock(LocalBluetoothManager.class);
+ private final LocalBluetoothProfileManager mLocalBluetoothProfileManager = mock(
+ LocalBluetoothProfileManager.class);
+ private final LocalBluetoothLeBroadcast mLocalBluetoothLeBroadcast = mock(
+ LocalBluetoothLeBroadcast.class);
private ActivityStarter mStarter = mock(ActivityStarter.class);
private BroadcastSender mBroadcastSender = mock(BroadcastSender.class);
private NotificationEntryManager mNotificationEntryManager =
@@ -71,15 +85,26 @@
NearbyMediaDevicesManager.class);
private final DialogLaunchAnimator mDialogLaunchAnimator = mock(DialogLaunchAnimator.class);
+ private List<MediaController> mMediaControllers = new ArrayList<>();
private MediaOutputBaseDialogImpl mMediaOutputBaseDialogImpl;
private MediaOutputController mMediaOutputController;
private int mHeaderIconRes;
private IconCompat mIconCompat;
private CharSequence mHeaderTitle;
private CharSequence mHeaderSubtitle;
+ private String mStopText;
+ private boolean mIsBroadcasting;
@Before
public void setUp() {
+ when(mLocalBluetoothManager.getProfileManager()).thenReturn(mLocalBluetoothProfileManager);
+ when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(null);
+ when(mMediaController.getPlaybackState()).thenReturn(mPlaybackState);
+ when(mPlaybackState.getState()).thenReturn(PlaybackState.STATE_NONE);
+ when(mMediaController.getPackageName()).thenReturn(TEST_PACKAGE);
+ mMediaControllers.add(mMediaController);
+ when(mMediaSessionManager.getActiveSessions(any())).thenReturn(mMediaControllers);
+
mMediaOutputController = new MediaOutputController(mContext, TEST_PACKAGE,
mMediaSessionManager, mLocalBluetoothManager, mStarter,
mNotificationEntryManager, mDialogLaunchAnimator,
@@ -173,6 +198,59 @@
verify(mMediaOutputBaseAdapter).notifyDataSetChanged();
}
+ @Test
+ public void onStart_isBroadcasting_verifyRegisterLeBroadcastServiceCallBack() {
+ when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(
+ mLocalBluetoothLeBroadcast);
+ mIsBroadcasting = true;
+
+ mMediaOutputBaseDialogImpl.onStart();
+
+ verify(mLocalBluetoothLeBroadcast).registerServiceCallBack(any(), any());
+ }
+
+ @Test
+ public void onStart_notBroadcasting_noRegisterLeBroadcastServiceCallBack() {
+ when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(
+ mLocalBluetoothLeBroadcast);
+ mIsBroadcasting = false;
+
+ mMediaOutputBaseDialogImpl.onStart();
+
+ verify(mLocalBluetoothLeBroadcast, never()).registerServiceCallBack(any(), any());
+ }
+
+ @Test
+ public void onStart_isBroadcasting_verifyUnregisterLeBroadcastServiceCallBack() {
+ when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(
+ mLocalBluetoothLeBroadcast);
+ mIsBroadcasting = true;
+
+ mMediaOutputBaseDialogImpl.onStop();
+
+ verify(mLocalBluetoothLeBroadcast).unregisterServiceCallBack(any());
+ }
+
+ @Test
+ public void onStop_notBroadcasting_noUnregisterLeBroadcastServiceCallBack() {
+ when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(
+ mLocalBluetoothLeBroadcast);
+ mIsBroadcasting = false;
+
+ mMediaOutputBaseDialogImpl.onStop();
+
+ verify(mLocalBluetoothLeBroadcast, never()).unregisterServiceCallBack(any());
+ }
+
+ @Test
+ public void refresh_checkStopText() {
+ mStopText = "test_string";
+ mMediaOutputBaseDialogImpl.refresh();
+ final Button stop = mMediaOutputBaseDialogImpl.mDialogView.requireViewById(R.id.stop);
+
+ assertThat(stop.getText().toString()).isEqualTo(mStopText);
+ }
+
class MediaOutputBaseDialogImpl extends MediaOutputBaseDialog {
MediaOutputBaseDialogImpl(Context context, BroadcastSender broadcastSender,
@@ -216,5 +294,15 @@
int getStopButtonVisibility() {
return 0;
}
+
+ @Override
+ public boolean isBroadcastSupported() {
+ return mIsBroadcasting;
+ }
+
+ @Override
+ public CharSequence getStopButtonText() {
+ return mStopText;
+ }
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java
index db56f87..e6ad6ed 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputDialogTest.java
@@ -18,13 +18,16 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.Mockito.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.media.MediaRoute2Info;
+import android.media.session.MediaController;
import android.media.session.MediaSessionManager;
+import android.media.session.PlaybackState;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.View;
@@ -32,7 +35,9 @@
import androidx.test.filters.SmallTest;
import com.android.internal.logging.UiEventLogger;
+import com.android.settingslib.bluetooth.LocalBluetoothLeBroadcast;
import com.android.settingslib.bluetooth.LocalBluetoothManager;
+import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
import com.android.settingslib.media.LocalMediaManager;
import com.android.settingslib.media.MediaDevice;
import com.android.systemui.SysuiTestCase;
@@ -60,7 +65,13 @@
// Mock
private final MediaSessionManager mMediaSessionManager = mock(MediaSessionManager.class);
+ private MediaController mMediaController = mock(MediaController.class);
+ private PlaybackState mPlaybackState = mock(PlaybackState.class);
private final LocalBluetoothManager mLocalBluetoothManager = mock(LocalBluetoothManager.class);
+ private final LocalBluetoothProfileManager mLocalBluetoothProfileManager = mock(
+ LocalBluetoothProfileManager.class);
+ private final LocalBluetoothLeBroadcast mLocalBluetoothLeBroadcast = mock(
+ LocalBluetoothLeBroadcast.class);
private final ActivityStarter mStarter = mock(ActivityStarter.class);
private final BroadcastSender mBroadcastSender = mock(BroadcastSender.class);
private final LocalMediaManager mLocalMediaManager = mock(LocalMediaManager.class);
@@ -72,12 +83,21 @@
private final NearbyMediaDevicesManager mNearbyMediaDevicesManager = mock(
NearbyMediaDevicesManager.class);
+ private List<MediaController> mMediaControllers = new ArrayList<>();
private MediaOutputDialog mMediaOutputDialog;
private MediaOutputController mMediaOutputController;
private final List<String> mFeatures = new ArrayList<>();
@Before
public void setUp() {
+ when(mLocalBluetoothManager.getProfileManager()).thenReturn(mLocalBluetoothProfileManager);
+ when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(null);
+ when(mMediaController.getPlaybackState()).thenReturn(mPlaybackState);
+ when(mPlaybackState.getState()).thenReturn(PlaybackState.STATE_NONE);
+ when(mMediaController.getPackageName()).thenReturn(TEST_PACKAGE);
+ mMediaControllers.add(mMediaController);
+ when(mMediaSessionManager.getActiveSessions(any())).thenReturn(mMediaControllers);
+
mMediaOutputController = new MediaOutputController(mContext, TEST_PACKAGE,
mMediaSessionManager, mLocalBluetoothManager, mStarter,
mNotificationEntryManager, mDialogLaunchAnimator,
@@ -116,6 +136,13 @@
mFeatures.add(MediaRoute2Info.FEATURE_REMOTE_GROUP_PLAYBACK);
assertThat(mMediaOutputDialog.getStopButtonVisibility()).isEqualTo(View.VISIBLE);
+
+ mFeatures.clear();
+ when(mLocalBluetoothProfileManager.getLeAudioBroadcastProfile()).thenReturn(
+ mLocalBluetoothLeBroadcast);
+ when(mLocalBluetoothLeBroadcast.isEnabled(any())).thenReturn(false);
+ when(mPlaybackState.getState()).thenReturn(PlaybackState.STATE_PLAYING);
+ assertThat(mMediaOutputDialog.getStopButtonVisibility()).isEqualTo(View.VISIBLE);
}
@Test
diff --git a/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java b/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java
index c9903ea..e27b7a6 100644
--- a/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java
+++ b/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java
@@ -19,6 +19,7 @@
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
+import android.graphics.Camera;
import android.graphics.GraphicBuffer;
import android.graphics.Rect;
import android.hardware.HardwareBuffer;
@@ -752,13 +753,65 @@
public ISessionProcessorImpl getSessionProcessor() {
return new SessionProcessorImplStub(mAdvancedExtender.createSessionProcessor());
}
+
+ @Override
+ public CameraMetadataNative getAvailableCaptureRequestKeys(String cameraId) {
+ if (RESULT_API_SUPPORTED) {
+ List<CaptureRequest.Key> supportedCaptureKeys =
+ mAdvancedExtender.getAvailableCaptureRequestKeys();
+
+ if ((supportedCaptureKeys != null) && !supportedCaptureKeys.isEmpty()) {
+ CameraMetadataNative ret = new CameraMetadataNative();
+ long vendorId = mMetadataVendorIdMap.containsKey(cameraId) ?
+ mMetadataVendorIdMap.get(cameraId) : Long.MAX_VALUE;
+ ret.setVendorId(vendorId);
+ int requestKeyTags [] = new int[supportedCaptureKeys.size()];
+ int i = 0;
+ for (CaptureRequest.Key key : supportedCaptureKeys) {
+ requestKeyTags[i++] = CameraMetadataNative.getTag(key.getName(), vendorId);
+ }
+ ret.set(CameraCharacteristics.REQUEST_AVAILABLE_REQUEST_KEYS, requestKeyTags);
+
+ return ret;
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public CameraMetadataNative getAvailableCaptureResultKeys(String cameraId) {
+ if (RESULT_API_SUPPORTED) {
+ List<CaptureResult.Key> supportedResultKeys =
+ mAdvancedExtender.getAvailableCaptureResultKeys();
+
+ if ((supportedResultKeys != null) && !supportedResultKeys.isEmpty()) {
+ CameraMetadataNative ret = new CameraMetadataNative();
+ long vendorId = mMetadataVendorIdMap.containsKey(cameraId) ?
+ mMetadataVendorIdMap.get(cameraId) : Long.MAX_VALUE;
+ ret.setVendorId(vendorId);
+ int resultKeyTags [] = new int[supportedResultKeys.size()];
+ int i = 0;
+ for (CaptureResult.Key key : supportedResultKeys) {
+ resultKeyTags[i++] = CameraMetadataNative.getTag(key.getName(), vendorId);
+ }
+ ret.set(CameraCharacteristics.REQUEST_AVAILABLE_RESULT_KEYS, resultKeyTags);
+
+ return ret;
+ }
+ }
+
+ return null;
+ }
}
private class CaptureCallbackStub implements SessionProcessorImpl.CaptureCallback {
private final ICaptureCallback mCaptureCallback;
+ private final String mCameraId;
- private CaptureCallbackStub(ICaptureCallback captureCallback) {
+ private CaptureCallbackStub(ICaptureCallback captureCallback, String cameraId) {
mCaptureCallback = captureCallback;
+ mCameraId = cameraId;
}
@Override
@@ -820,6 +873,29 @@
}
}
}
+
+ @Override
+ public void onCaptureCompleted(long timestamp, int requestId,
+ Map<CaptureResult.Key, Object> result) {
+
+ if (result == null) {
+ Log.e(TAG, "Invalid capture result received!");
+ }
+
+ CameraMetadataNative captureResults = new CameraMetadataNative();
+ if (mMetadataVendorIdMap.containsKey(mCameraId)) {
+ captureResults.setVendorId(mMetadataVendorIdMap.get(mCameraId));
+ }
+ for (Map.Entry<CaptureResult.Key, Object> entry : result.entrySet()) {
+ captureResults.set(entry.getKey(), entry.getValue());
+ }
+
+ try {
+ mCaptureCallback.onCaptureCompleted(timestamp, requestId, captureResults);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Failed to notify capture complete due to remote exception!");
+ }
+ }
}
private class RequestCallbackStub extends IRequestCallback.Stub {
@@ -1124,7 +1200,7 @@
@Override
public int startRepeating(ICaptureCallback callback) {
- return mSessionProcessor.startRepeating(new CaptureCallbackStub(callback));
+ return mSessionProcessor.startRepeating(new CaptureCallbackStub(callback, mCameraId));
}
@Override
@@ -1133,12 +1209,29 @@
}
@Override
- public int startCapture(ICaptureCallback callback, int jpegRotation, int jpegQuality) {
+ public void setParameters(CaptureRequest captureRequest) {
HashMap<CaptureRequest.Key<?>, Object> paramMap = new HashMap<>();
- paramMap.put(CaptureRequest.JPEG_ORIENTATION, jpegRotation);
- paramMap.put(CaptureRequest.JPEG_QUALITY, jpegQuality);
+ for (CaptureRequest.Key captureRequestKey : captureRequest.getKeys()) {
+ paramMap.put(captureRequestKey, captureRequest.get(captureRequestKey));
+ }
+
mSessionProcessor.setParameters(paramMap);
- return mSessionProcessor.startCapture(new CaptureCallbackStub(callback));
+ }
+
+ @Override
+ public int startTrigger(CaptureRequest captureRequest, ICaptureCallback callback) {
+ HashMap<CaptureRequest.Key<?>, Object> triggerMap = new HashMap<>();
+ for (CaptureRequest.Key captureRequestKey : captureRequest.getKeys()) {
+ triggerMap.put(captureRequestKey, captureRequest.get(captureRequestKey));
+ }
+
+ return mSessionProcessor.startTrigger(triggerMap,
+ new CaptureCallbackStub(callback, mCameraId));
+ }
+
+ @Override
+ public int startCapture(ICaptureCallback callback) {
+ return mSessionProcessor.startCapture(new CaptureCallbackStub(callback, mCameraId));
}
}
diff --git a/services/cloudsearch/java/com/android/server/cloudsearch/RemoteCloudSearchService.java b/services/cloudsearch/java/com/android/server/cloudsearch/RemoteCloudSearchService.java
index eb16d3b..d1c0482 100644
--- a/services/cloudsearch/java/com/android/server/cloudsearch/RemoteCloudSearchService.java
+++ b/services/cloudsearch/java/com/android/server/cloudsearch/RemoteCloudSearchService.java
@@ -35,6 +35,7 @@
private static final String TAG = "RemoteCloudSearchService";
+ private static final long TIMEOUT_IDLE_BOUND_TIMEOUT_MS = 10 * DateUtils.MINUTE_IN_MILLIS;
private static final long TIMEOUT_REMOTE_REQUEST_MILLIS = 2 * DateUtils.SECOND_IN_MILLIS;
private final RemoteCloudSearchServiceCallbacks mCallback;
@@ -57,7 +58,7 @@
@Override
protected long getTimeoutIdleBindMillis() {
- return PERMANENT_BOUND_TIMEOUT_MS;
+ return TIMEOUT_IDLE_BOUND_TIMEOUT_MS;
}
@Override
diff --git a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
index e58d736..7b412a0 100644
--- a/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
+++ b/services/core/java/com/android/server/pm/permission/DefaultPermissionGrantPolicy.java
@@ -613,6 +613,10 @@
pm, setupWizardPackage, userId, NEARBY_DEVICES_PERMISSIONS);
}
+ // SearchSelector
+ grantPermissionsToSystemPackage(pm, getDefaultSearchSelectorPackage(), userId,
+ NOTIFICATION_PERMISSIONS);
+
// Camera
grantPermissionsToSystemPackage(pm,
getDefaultSystemHandlerActivityPackage(pm, MediaStore.ACTION_IMAGE_CAPTURE, userId),
@@ -941,6 +945,10 @@
new Intent(Intent.ACTION_MAIN).addCategory(category), userId);
}
+ private String getDefaultSearchSelectorPackage() {
+ return mContext.getString(R.string.config_defaultSearchSelectorPackageName);
+ }
+
@SafeVarargs
private final void grantPermissionToEachSystemPackage(PackageManagerWrapper pm,
ArrayList<String> packages, int userId, Set<String>... permissions) {
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
index 186eccc..092f3be 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceImpl.java
@@ -2645,12 +2645,9 @@
// Cache newImplicitPermissions before modifing permissionsState as for the
// shared uids the original and new state are the same object
- // TODO(205888750): remove the line for LEGACY_REVIEW once propagated through
- // droidfood
if (!origState.hasPermissionState(permName)
&& (pkg.getImplicitPermissions().contains(permName)
- || (permName.equals(Manifest.permission.ACTIVITY_RECOGNITION)))
- || NOTIFICATION_PERMISSIONS.contains(permName)) {
+ || (permName.equals(Manifest.permission.ACTIVITY_RECOGNITION)))) {
if (pkg.getImplicitPermissions().contains(permName)) {
// If permName is an implicit permission, try to auto-grant
newImplicitPermissions.add(permName);
@@ -2808,12 +2805,14 @@
}
// Remove review flag as it is not necessary anymore
- if (!NOTIFICATION_PERMISSIONS.contains(perm)) {
+ // TODO(b/227186603) re-enable check for notification permission once
+ // droidfood state has been cleared
+ //if (!NOTIFICATION_PERMISSIONS.contains(perm)) {
if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
flags &= ~FLAG_PERMISSION_REVIEW_REQUIRED;
wasChanged = true;
}
- }
+ //}
if ((flags & FLAG_PERMISSION_REVOKED_COMPAT) != 0
&& !isPermissionSplitFromNonRuntime(permName,
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 2b431b6..dc2b6f8 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -1459,8 +1459,9 @@
Slog.i(TAG, SECONDARY_ZYGOTE_PRELOAD);
TimingsTraceAndSlog traceLog = TimingsTraceAndSlog.newAsyncLog();
traceLog.traceBegin(SECONDARY_ZYGOTE_PRELOAD);
- if (!Process.ZYGOTE_PROCESS.preloadDefault(Build.SUPPORTED_32_BIT_ABIS[0])) {
- Slog.e(TAG, "Unable to preload default resources");
+ String[] abis32 = Build.SUPPORTED_32_BIT_ABIS;
+ if (abis32.length > 0 && !Process.ZYGOTE_PROCESS.preloadDefault(abis32[0])) {
+ Slog.e(TAG, "Unable to preload default resources for secondary");
}
traceLog.traceEnd();
} catch (Exception ex) {
diff --git a/services/tests/mockingservicestests/src/com/android/server/tare/ScribeTest.java b/services/tests/mockingservicestests/src/com/android/server/tare/ScribeTest.java
index c2cf2ff..14f95e9 100644
--- a/services/tests/mockingservicestests/src/com/android/server/tare/ScribeTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/tare/ScribeTest.java
@@ -107,7 +107,7 @@
@Test
public void testWriteHighLevelStateToDisk() {
long lastReclamationTime = System.currentTimeMillis();
- long remainingConsumableNarcs = 2000L;
+ long remainingConsumableCakes = 2000L;
long consumptionLimit = 500_000L;
when(mIrs.getConsumptionLimitLocked()).thenReturn(consumptionLimit);
@@ -118,20 +118,20 @@
ledger.recordTransaction(new Ledger.Transaction(0, 1000L, 1, null, -5000, 3000));
mScribeUnderTest.setLastReclamationTimeLocked(lastReclamationTime);
mScribeUnderTest.setConsumptionLimitLocked(consumptionLimit);
- mScribeUnderTest.adjustRemainingConsumableNarcsLocked(
- remainingConsumableNarcs - consumptionLimit);
+ mScribeUnderTest.adjustRemainingConsumableCakesLocked(
+ remainingConsumableCakes - consumptionLimit);
assertEquals(lastReclamationTime, mScribeUnderTest.getLastReclamationTimeLocked());
- assertEquals(remainingConsumableNarcs,
- mScribeUnderTest.getRemainingConsumableNarcsLocked());
+ assertEquals(remainingConsumableCakes,
+ mScribeUnderTest.getRemainingConsumableCakesLocked());
assertEquals(consumptionLimit, mScribeUnderTest.getSatiatedConsumptionLimitLocked());
mScribeUnderTest.writeImmediatelyForTesting();
mScribeUnderTest.loadFromDiskLocked();
assertEquals(lastReclamationTime, mScribeUnderTest.getLastReclamationTimeLocked());
- assertEquals(remainingConsumableNarcs,
- mScribeUnderTest.getRemainingConsumableNarcsLocked());
+ assertEquals(remainingConsumableCakes,
+ mScribeUnderTest.getRemainingConsumableCakesLocked());
assertEquals(consumptionLimit, mScribeUnderTest.getSatiatedConsumptionLimitLocked());
}
@@ -234,32 +234,32 @@
@Test
public void testChangingConsumable() {
assertEquals(0, mScribeUnderTest.getSatiatedConsumptionLimitLocked());
- assertEquals(0, mScribeUnderTest.getRemainingConsumableNarcsLocked());
+ assertEquals(0, mScribeUnderTest.getRemainingConsumableCakesLocked());
// Limit increased, so remaining value should be adjusted as well
mScribeUnderTest.setConsumptionLimitLocked(1000);
assertEquals(1000, mScribeUnderTest.getSatiatedConsumptionLimitLocked());
- assertEquals(1000, mScribeUnderTest.getRemainingConsumableNarcsLocked());
+ assertEquals(1000, mScribeUnderTest.getRemainingConsumableCakesLocked());
// Limit decreased below remaining, so remaining value should be adjusted as well
mScribeUnderTest.setConsumptionLimitLocked(500);
assertEquals(500, mScribeUnderTest.getSatiatedConsumptionLimitLocked());
- assertEquals(500, mScribeUnderTest.getRemainingConsumableNarcsLocked());
+ assertEquals(500, mScribeUnderTest.getRemainingConsumableCakesLocked());
- mScribeUnderTest.adjustRemainingConsumableNarcsLocked(-100);
+ mScribeUnderTest.adjustRemainingConsumableCakesLocked(-100);
assertEquals(500, mScribeUnderTest.getSatiatedConsumptionLimitLocked());
- assertEquals(400, mScribeUnderTest.getRemainingConsumableNarcsLocked());
+ assertEquals(400, mScribeUnderTest.getRemainingConsumableCakesLocked());
// Limit increased, so remaining value should be adjusted by the difference as well
mScribeUnderTest.setConsumptionLimitLocked(1000);
assertEquals(1000, mScribeUnderTest.getSatiatedConsumptionLimitLocked());
- assertEquals(900, mScribeUnderTest.getRemainingConsumableNarcsLocked());
+ assertEquals(900, mScribeUnderTest.getRemainingConsumableCakesLocked());
// Limit decreased, but above remaining, so remaining value should left alone
mScribeUnderTest.setConsumptionLimitLocked(950);
assertEquals(950, mScribeUnderTest.getSatiatedConsumptionLimitLocked());
- assertEquals(900, mScribeUnderTest.getRemainingConsumableNarcsLocked());
+ assertEquals(900, mScribeUnderTest.getRemainingConsumableCakesLocked());
}
private void assertLedgersEqual(Ledger expected, Ledger actual) {