summaryrefslogtreecommitdiffstats
path: root/core/java/com
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/com')
-rw-r--r--core/java/com/android/internal/app/ChooserActivity.java25
-rw-r--r--core/java/com/android/internal/app/IBatteryStats.aidl8
-rw-r--r--core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl5
-rw-r--r--core/java/com/android/internal/app/IVoiceInteractor.aidl8
-rw-r--r--core/java/com/android/internal/app/ResolverActivity.java14
-rw-r--r--core/java/com/android/internal/inputmethod/InputMethodSubtypeSwitchingController.java33
-rw-r--r--core/java/com/android/internal/inputmethod/InputMethodUtils.java10
-rw-r--r--core/java/com/android/internal/logging/MetricsLogger.java1
-rw-r--r--core/java/com/android/internal/os/BatterySipper.java16
-rw-r--r--core/java/com/android/internal/os/BatteryStatsHelper.java24
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java264
-rw-r--r--core/java/com/android/internal/os/CameraPowerCalculator.java48
-rw-r--r--core/java/com/android/internal/os/FlashlightPowerCalculator.java46
-rw-r--r--core/java/com/android/internal/os/PowerProfile.java9
-rw-r--r--core/java/com/android/internal/os/ProcessCpuTracker.java44
-rw-r--r--core/java/com/android/internal/os/SomeArgs.java2
-rw-r--r--core/java/com/android/internal/os/ZygoteInit.java2
-rw-r--r--core/java/com/android/internal/policy/IKeyguardService.aidl24
-rw-r--r--core/java/com/android/internal/policy/PhoneWindow.java116
-rw-r--r--core/java/com/android/internal/util/ScreenShapeHelper.java12
-rw-r--r--core/java/com/android/internal/view/BaseIWindow.java4
-rw-r--r--core/java/com/android/internal/view/FloatingActionMode.java48
-rw-r--r--core/java/com/android/internal/widget/FloatingToolbar.java113
-rw-r--r--core/java/com/android/internal/widget/LockPatternUtils.java18
-rw-r--r--core/java/com/android/internal/widget/SwipeDismissLayout.java31
25 files changed, 747 insertions, 178 deletions
diff --git a/core/java/com/android/internal/app/ChooserActivity.java b/core/java/com/android/internal/app/ChooserActivity.java
index ea18c12..c1ec6e6 100644
--- a/core/java/com/android/internal/app/ChooserActivity.java
+++ b/core/java/com/android/internal/app/ChooserActivity.java
@@ -659,11 +659,16 @@ public class ChooserActivity extends ResolverActivity {
return super.getCount() + mServiceTargets.size() + mCallerTargets.size();
}
- public int getCallerTargetsCount() {
+ @Override
+ public int getUnfilteredCount() {
+ return super.getUnfilteredCount() + mServiceTargets.size() + mCallerTargets.size();
+ }
+
+ public int getCallerTargetCount() {
return mCallerTargets.size();
}
- public int getServiceTargetsCount() {
+ public int getServiceTargetCount() {
return mServiceTargets.size();
}
@@ -696,6 +701,11 @@ public class ChooserActivity extends ResolverActivity {
@Override
public TargetInfo getItem(int position) {
+ return targetInfoForPosition(position, true);
+ }
+
+ @Override
+ public TargetInfo targetInfoForPosition(int position, boolean filtered) {
int offset = 0;
final int callerTargetCount = mCallerTargets.size();
@@ -710,7 +720,8 @@ public class ChooserActivity extends ResolverActivity {
}
offset += serviceTargetCount;
- return super.getItem(position - offset);
+ return filtered ? super.getItem(position - offset)
+ : getDisplayInfoAt(position - offset);
}
public void addServiceResults(DisplayResolveInfo origTarget, List<ChooserTarget> targets) {
@@ -764,8 +775,8 @@ public class ChooserActivity extends ResolverActivity {
@Override
public int getCount() {
return (int) (
- Math.ceil((float) mChooserListAdapter.getCallerTargetsCount() / mColumnCount)
- + Math.ceil((float) mChooserListAdapter.getServiceTargetsCount() / mColumnCount)
+ Math.ceil((float) mChooserListAdapter.getCallerTargetCount() / mColumnCount)
+ + Math.ceil((float) mChooserListAdapter.getServiceTargetCount() / mColumnCount)
+ Math.ceil((float) mChooserListAdapter.getStandardTargetCount() / mColumnCount)
);
}
@@ -845,14 +856,14 @@ public class ChooserActivity extends ResolverActivity {
}
int getFirstRowPosition(int row) {
- final int callerCount = mChooserListAdapter.getCallerTargetsCount();
+ final int callerCount = mChooserListAdapter.getCallerTargetCount();
final int callerRows = (int) Math.ceil((float) callerCount / mColumnCount);
if (row < callerRows) {
return row * mColumnCount;
}
- final int serviceCount = mChooserListAdapter.getServiceTargetsCount();
+ final int serviceCount = mChooserListAdapter.getServiceTargetCount();
final int serviceRows = (int) Math.ceil((float) serviceCount / mColumnCount);
if (row < callerRows + serviceRows) {
diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl
index 7c5c565..929cacd 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -34,6 +34,12 @@ interface IBatteryStats {
void noteStopAudio(int uid);
void noteResetVideo();
void noteResetAudio();
+ void noteFlashlightOn(int uid);
+ void noteFlashlightOff(int uid);
+ void noteStartCamera(int uid);
+ void noteStopCamera(int uid);
+ void noteResetCamera();
+ void noteResetFlashlight();
// Remaining methods are only used in Java.
byte[] getStatistics();
@@ -72,8 +78,6 @@ interface IBatteryStats {
void noteVibratorOn(int uid, long durationMillis);
void noteVibratorOff(int uid);
- void noteFlashlightOn();
- void noteFlashlightOff();
void noteStartGps(int uid);
void noteStopGps(int uid);
void noteScreenState(int state);
diff --git a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
index 644adb6..a2bd700 100644
--- a/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
+++ b/core/java/com/android/internal/app/IVoiceInteractionManagerService.aidl
@@ -97,6 +97,11 @@ interface IVoiceInteractionManagerService {
void showSessionForActiveService(IVoiceInteractionSessionShowCallback showCallback);
/**
+ * Hides the session from the active service, if it is showing.
+ */
+ void hideCurrentSession();
+
+ /**
* Notifies the active service that a launch was requested from the Keyguard. This will only
* be called if {@link #activeServiceSupportsLaunchFromKeyguard()} returns true.
*/
diff --git a/core/java/com/android/internal/app/IVoiceInteractor.aidl b/core/java/com/android/internal/app/IVoiceInteractor.aidl
index 84e9cf0..44feafb 100644
--- a/core/java/com/android/internal/app/IVoiceInteractor.aidl
+++ b/core/java/com/android/internal/app/IVoiceInteractor.aidl
@@ -27,14 +27,14 @@ import com.android.internal.app.IVoiceInteractorRequest;
*/
interface IVoiceInteractor {
IVoiceInteractorRequest startConfirmation(String callingPackage,
- IVoiceInteractorCallback callback, CharSequence prompt, in Bundle extras);
+ IVoiceInteractorCallback callback, in VoiceInteractor.Prompt prompt, in Bundle extras);
IVoiceInteractorRequest startPickOption(String callingPackage,
- IVoiceInteractorCallback callback, CharSequence prompt,
+ IVoiceInteractorCallback callback, in VoiceInteractor.Prompt prompt,
in VoiceInteractor.PickOptionRequest.Option[] options, in Bundle extras);
IVoiceInteractorRequest startCompleteVoice(String callingPackage,
- IVoiceInteractorCallback callback, CharSequence message, in Bundle extras);
+ IVoiceInteractorCallback callback, in VoiceInteractor.Prompt prompt, in Bundle extras);
IVoiceInteractorRequest startAbortVoice(String callingPackage,
- IVoiceInteractorCallback callback, CharSequence message, in Bundle extras);
+ IVoiceInteractorCallback callback, in VoiceInteractor.Prompt prompt, in Bundle extras);
IVoiceInteractorRequest startCommand(String callingPackage,
IVoiceInteractorCallback callback, String command, in Bundle extras);
boolean[] supportsCommands(String callingPackage, in String[] commands);
diff --git a/core/java/com/android/internal/app/ResolverActivity.java b/core/java/com/android/internal/app/ResolverActivity.java
index 4696757..ba4af89 100644
--- a/core/java/com/android/internal/app/ResolverActivity.java
+++ b/core/java/com/android/internal/app/ResolverActivity.java
@@ -785,7 +785,7 @@ public class ResolverActivity extends Activity {
}
mAlwaysUseOption = alwaysUseOption;
- int count = mAdapter.mDisplayList.size();
+ int count = mAdapter.getUnfilteredCount();
if (count > 1 || (count == 1 && mAdapter.getOtherProfile() != null)) {
setContentView(layoutId);
mAdapterView = (AbsListView) findViewById(R.id.resolver_list);
@@ -1392,6 +1392,18 @@ public class ResolverActivity extends Activity {
return result;
}
+ public int getUnfilteredCount() {
+ return mDisplayList.size();
+ }
+
+ public int getDisplayInfoCount() {
+ return mDisplayList.size();
+ }
+
+ public DisplayResolveInfo getDisplayInfoAt(int index) {
+ return mDisplayList.get(index);
+ }
+
public TargetInfo getItem(int position) {
if (mFilterLastUsed && mLastChosenPosition >= 0 && position >= mLastChosenPosition) {
position++;
diff --git a/core/java/com/android/internal/inputmethod/InputMethodSubtypeSwitchingController.java b/core/java/com/android/internal/inputmethod/InputMethodSubtypeSwitchingController.java
index ce94727..e607a3f 100644
--- a/core/java/com/android/internal/inputmethod/InputMethodSubtypeSwitchingController.java
+++ b/core/java/com/android/internal/inputmethod/InputMethodSubtypeSwitchingController.java
@@ -20,6 +20,7 @@ import android.content.Context;
import android.content.pm.PackageManager;
import android.text.TextUtils;
import android.util.Log;
+import android.util.Printer;
import android.util.Slog;
import android.view.inputmethod.InputMethodInfo;
import android.view.inputmethod.InputMethodSubtype;
@@ -314,6 +315,15 @@ public class InputMethodSubtypeSwitchingController {
}
return null;
}
+
+ protected void dump(final Printer pw, final String prefix) {
+ final int N = mImeSubtypeList.size();
+ for (int i = 0; i < N; ++i) {
+ final int rank = i;
+ final ImeSubtypeListItem item = mImeSubtypeList.get(i);
+ pw.println(prefix + "rank=" + rank + " item=" + item);
+ }
+ }
}
private static class DynamicRotationList {
@@ -388,6 +398,14 @@ public class InputMethodSubtypeSwitchingController {
}
return null;
}
+
+ protected void dump(final Printer pw, final String prefix) {
+ for (int i = 0; i < mUsageHistoryOfSubtypeListItemIndex.length; ++i) {
+ final int rank = mUsageHistoryOfSubtypeListItemIndex[i];
+ final ImeSubtypeListItem item = mImeSubtypeList.get(i);
+ pw.println(prefix + "rank=" + rank + " item=" + item);
+ }
+ }
}
@VisibleForTesting
@@ -478,6 +496,13 @@ public class InputMethodSubtypeSwitchingController {
}
return result;
}
+
+ protected void dump(final Printer pw) {
+ pw.println(" mSwitchingAwareRotationList:");
+ mSwitchingAwareRotationList.dump(pw, " ");
+ pw.println(" mSwitchingUnawareRotationList:");
+ mSwitchingUnawareRotationList.dump(pw, " ");
+ }
}
private final InputMethodSettings mSettings;
@@ -526,4 +551,12 @@ public class InputMethodSubtypeSwitchingController {
return mSubtypeList.getSortedInputMethodAndSubtypeList(
showSubtypes, includingAuxiliarySubtypes, isScreenLocked);
}
+
+ public void dump(final Printer pw) {
+ if (mController != null) {
+ mController.dump(pw);
+ } else {
+ pw.println(" mController=null");
+ }
+ }
}
diff --git a/core/java/com/android/internal/inputmethod/InputMethodUtils.java b/core/java/com/android/internal/inputmethod/InputMethodUtils.java
index 06bdb24..042db71 100644
--- a/core/java/com/android/internal/inputmethod/InputMethodUtils.java
+++ b/core/java/com/android/internal/inputmethod/InputMethodUtils.java
@@ -379,6 +379,14 @@ public class InputMethodUtils {
// The length of localeStr is guaranteed to always return a 1 <= value <= 3
// because localeStr is not empty.
if (localeParams.length == 1) {
+ if (localeParams.length >= 1 && "tl".equals(localeParams[0])) {
+ // Convert a locale whose language is "tl" to one whose language is "fil".
+ // For example, "tl_PH" will get converted to "fil_PH".
+ // Versions of Android earlier than Lollipop did not support three letter language
+ // codes, and used "tl" (Tagalog) as the language string for "fil" (Filipino).
+ // On Lollipop and above, the current three letter version must be used.
+ localeParams[0] = "fil";
+ }
return new Locale(localeParams[0]);
} else if (localeParams.length == 2) {
return new Locale(localeParams[0], localeParams[1]);
@@ -397,7 +405,7 @@ public class InputMethodUtils {
for (int i = 0; i < N; ++i) {
final InputMethodSubtype subtype = imi.getSubtypeAt(i);
if (checkCountry) {
- final Locale subtypeLocale = constructLocaleFromString(subtype.getLocale());
+ final Locale subtypeLocale = subtype.getLocaleObject();
if (subtypeLocale == null ||
!TextUtils.equals(subtypeLocale.getLanguage(), locale.getLanguage()) ||
!TextUtils.equals(subtypeLocale.getCountry(), locale.getCountry())) {
diff --git a/core/java/com/android/internal/logging/MetricsLogger.java b/core/java/com/android/internal/logging/MetricsLogger.java
index 230d96d..2f21efd 100644
--- a/core/java/com/android/internal/logging/MetricsLogger.java
+++ b/core/java/com/android/internal/logging/MetricsLogger.java
@@ -27,6 +27,7 @@ import android.view.View;
*/
public class MetricsLogger implements MetricsConstants {
// Temporary constants go here, to await migration to MetricsConstants.
+ public static final int ACTION_EMERGENCY_CALL = 200;
public static void visible(Context context, int category) throws IllegalArgumentException {
if (Build.IS_DEBUGGABLE && category == VIEW_UNKNOWN) {
diff --git a/core/java/com/android/internal/os/BatterySipper.java b/core/java/com/android/internal/os/BatterySipper.java
index 056b0aa..049d3eb 100644
--- a/core/java/com/android/internal/os/BatterySipper.java
+++ b/core/java/com/android/internal/os/BatterySipper.java
@@ -42,6 +42,8 @@ public class BatterySipper implements Comparable<BatterySipper> {
public long wifiRunningTimeMs;
public long cpuFgTimeMs;
public long wakeLockTimeMs;
+ public long cameraTimeMs;
+ public long flashlightTimeMs;
public long mobileRxPackets;
public long mobileTxPackets;
@@ -67,6 +69,8 @@ public class BatterySipper implements Comparable<BatterySipper> {
public double mobileRadioPowerMah;
public double gpsPowerMah;
public double sensorPowerMah;
+ public double cameraPowerMah;
+ public double flashlightPowerMah;
public enum DrainType {
IDLE,
@@ -79,7 +83,8 @@ public class BatterySipper implements Comparable<BatterySipper> {
APP,
USER,
UNACCOUNTED,
- OVERCOUNTED
+ OVERCOUNTED,
+ CAMERA
}
public BatterySipper(DrainType drainType, Uid uid, double value) {
@@ -135,6 +140,8 @@ public class BatterySipper implements Comparable<BatterySipper> {
wifiRunningTimeMs += other.wifiRunningTimeMs;
cpuFgTimeMs += other.cpuFgTimeMs;
wakeLockTimeMs += other.wakeLockTimeMs;
+ cameraTimeMs += other.cameraTimeMs;
+ flashlightTimeMs += other.flashlightTimeMs;
mobileRxPackets += other.mobileRxPackets;
mobileTxPackets += other.mobileTxPackets;
mobileActive += other.mobileActive;
@@ -151,6 +158,8 @@ public class BatterySipper implements Comparable<BatterySipper> {
sensorPowerMah += other.sensorPowerMah;
mobileRadioPowerMah += other.mobileRadioPowerMah;
wakeLockPowerMah += other.wakeLockPowerMah;
+ cameraPowerMah += other.cameraPowerMah;
+ flashlightPowerMah += other.flashlightPowerMah;
}
/**
@@ -158,7 +167,8 @@ public class BatterySipper implements Comparable<BatterySipper> {
* @return the sum of all the power in this BatterySipper.
*/
public double sumPower() {
- return totalPowerMah = usagePowerMah + wifiPowerMah + gpsPowerMah + cpuPowerMah + sensorPowerMah
- + mobileRadioPowerMah + wakeLockPowerMah;
+ return totalPowerMah = usagePowerMah + wifiPowerMah + gpsPowerMah + cpuPowerMah +
+ sensorPowerMah + mobileRadioPowerMah + wakeLockPowerMah + cameraPowerMah +
+ flashlightPowerMah;
}
}
diff --git a/core/java/com/android/internal/os/BatteryStatsHelper.java b/core/java/com/android/internal/os/BatteryStatsHelper.java
index fbe87c5..e6165a1 100644
--- a/core/java/com/android/internal/os/BatteryStatsHelper.java
+++ b/core/java/com/android/internal/os/BatteryStatsHelper.java
@@ -122,6 +122,8 @@ public final class BatteryStatsHelper {
PowerCalculator mWifiPowerCalculator;
PowerCalculator mBluetoothPowerCalculator;
PowerCalculator mSensorPowerCalculator;
+ PowerCalculator mCameraPowerCalculator;
+ PowerCalculator mFlashlightPowerCalculator;
public static boolean checkWifiOnly(Context context) {
ConnectivityManager cm = (ConnectivityManager)context.getSystemService(
@@ -365,6 +367,16 @@ public final class BatteryStatsHelper {
}
mSensorPowerCalculator.reset();
+ if (mCameraPowerCalculator == null) {
+ mCameraPowerCalculator = new CameraPowerCalculator(mPowerProfile);
+ }
+ mCameraPowerCalculator.reset();
+
+ if (mFlashlightPowerCalculator == null) {
+ mFlashlightPowerCalculator = new FlashlightPowerCalculator(mPowerProfile);
+ }
+ mFlashlightPowerCalculator.reset();
+
mStatsType = statsType;
mRawUptime = rawUptimeUs;
mRawRealtime = rawRealtimeUs;
@@ -480,6 +492,8 @@ public final class BatteryStatsHelper {
mWifiPowerCalculator.calculateApp(app, u, mRawRealtime, mRawUptime, mStatsType);
mBluetoothPowerCalculator.calculateApp(app, u, mRawRealtime, mRawUptime, mStatsType);
mSensorPowerCalculator.calculateApp(app, u, mRawRealtime, mRawUptime, mStatsType);
+ mCameraPowerCalculator.calculateApp(app, u, mRawRealtime, mRawUptime, mStatsType);
+ mFlashlightPowerCalculator.calculateApp(app, u, mRawRealtime, mRawUptime, mStatsType);
final double totalPower = app.sumPower();
if (DEBUG && totalPower != 0) {
@@ -619,15 +633,6 @@ public final class BatteryStatsHelper {
}
}
- private void addFlashlightUsage() {
- long flashlightOnTimeMs = mStats.getFlashlightOnTime(mRawRealtime, mStatsType) / 1000;
- double flashlightPower = flashlightOnTimeMs
- * mPowerProfile.getAveragePower(PowerProfile.POWER_FLASHLIGHT) / (60*60*1000);
- if (flashlightPower != 0) {
- addEntry(BatterySipper.DrainType.FLASHLIGHT, flashlightOnTimeMs, flashlightPower);
- }
- }
-
private void addUserUsage() {
for (int i = 0; i < mUserSippers.size(); i++) {
final int userId = mUserSippers.keyAt(i);
@@ -643,7 +648,6 @@ public final class BatteryStatsHelper {
addUserUsage();
addPhoneUsage();
addScreenUsage();
- addFlashlightUsage();
addWiFiUsage();
addBluetoothUsage();
addIdleUsage(); // Not including cellular idle power
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index eaca43b..ee7ed0b 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -105,7 +105,7 @@ public final class BatteryStatsImpl extends BatteryStats {
private static final int MAGIC = 0xBA757475; // 'BATSTATS'
// Current on-disk Parcel version
- private static final int VERSION = 126 + (USE_OLD_HISTORY ? 1000 : 0);
+ private static final int VERSION = 127 + (USE_OLD_HISTORY ? 1000 : 0);
// Maximum number of items we will record in the history.
private static final int MAX_HISTORY_ITEMS = 2000;
@@ -211,6 +211,8 @@ public final class BatteryStatsImpl extends BatteryStats {
final SparseArray<ArrayList<StopwatchTimer>> mWifiBatchedScanTimers = new SparseArray<>();
final ArrayList<StopwatchTimer> mAudioTurnedOnTimers = new ArrayList<>();
final ArrayList<StopwatchTimer> mVideoTurnedOnTimers = new ArrayList<>();
+ final ArrayList<StopwatchTimer> mFlashlightTurnedOnTimers = new ArrayList<>();
+ final ArrayList<StopwatchTimer> mCameraTurnedOnTimers = new ArrayList<>();
// Last partial timers we use for distributing CPU usage.
final ArrayList<StopwatchTimer> mLastPartialTimers = new ArrayList<>();
@@ -270,18 +272,19 @@ public final class BatteryStatsImpl extends BatteryStats {
final HistoryStepDetails mCurHistoryStepDetails = new HistoryStepDetails();
final HistoryStepDetails mReadHistoryStepDetails = new HistoryStepDetails();
final HistoryStepDetails mTmpHistoryStepDetails = new HistoryStepDetails();
+
/**
- * Total time (in 1/100 sec) spent executing in user code.
+ * Total time (in milliseconds) spent executing in user code.
*/
long mLastStepCpuUserTime;
long mCurStepCpuUserTime;
/**
- * Total time (in 1/100 sec) spent executing in kernel code.
+ * Total time (in milliseconds) spent executing in kernel code.
*/
long mLastStepCpuSystemTime;
long mCurStepCpuSystemTime;
/**
- * Times from /proc/stat
+ * Times from /proc/stat (but measured in milliseconds).
*/
long mLastStepStatUserTime;
long mLastStepStatSystemTime;
@@ -343,9 +346,12 @@ public final class BatteryStatsImpl extends BatteryStats {
int mVideoOnNesting;
StopwatchTimer mVideoOnTimer;
- boolean mFlashlightOn;
+ int mFlashlightOnNesting;
StopwatchTimer mFlashlightOnTimer;
+ int mCameraOnNesting;
+ StopwatchTimer mCameraOnTimer;
+
int mPhoneSignalStrengthBin = -1;
int mPhoneSignalStrengthBinRaw = -1;
final StopwatchTimer[] mPhoneSignalStrengthsTimer =
@@ -3710,30 +3716,100 @@ public final class BatteryStatsImpl extends BatteryStats {
getUidStatsLocked(uid).noteVibratorOffLocked();
}
- public void noteFlashlightOnLocked() {
- if (!mFlashlightOn) {
- final long elapsedRealtime = SystemClock.elapsedRealtime();
- final long uptime = SystemClock.uptimeMillis();
+ public void noteFlashlightOnLocked(int uid) {
+ uid = mapUid(uid);
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ if (mFlashlightOnNesting++ == 0) {
mHistoryCur.states2 |= HistoryItem.STATE2_FLASHLIGHT_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight on to: "
- + Integer.toHexString(mHistoryCur.states));
+ + Integer.toHexString(mHistoryCur.states2));
addHistoryRecordLocked(elapsedRealtime, uptime);
- mFlashlightOn = true;
mFlashlightOnTimer.startRunningLocked(elapsedRealtime);
}
+ getUidStatsLocked(uid).noteFlashlightTurnedOnLocked(elapsedRealtime);
}
- public void noteFlashlightOffLocked() {
+ public void noteFlashlightOffLocked(int uid) {
+ if (mFlashlightOnNesting == 0) {
+ return;
+ }
+ uid = mapUid(uid);
final long elapsedRealtime = SystemClock.elapsedRealtime();
final long uptime = SystemClock.uptimeMillis();
- if (mFlashlightOn) {
+ if (--mFlashlightOnNesting == 0) {
mHistoryCur.states2 &= ~HistoryItem.STATE2_FLASHLIGHT_FLAG;
if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight off to: "
- + Integer.toHexString(mHistoryCur.states));
+ + Integer.toHexString(mHistoryCur.states2));
addHistoryRecordLocked(elapsedRealtime, uptime);
- mFlashlightOn = false;
mFlashlightOnTimer.stopRunningLocked(elapsedRealtime);
}
+ getUidStatsLocked(uid).noteFlashlightTurnedOffLocked(elapsedRealtime);
+ }
+
+ public void noteCameraOnLocked(int uid) {
+ uid = mapUid(uid);
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ if (mCameraOnNesting++ == 0) {
+ mHistoryCur.states2 |= HistoryItem.STATE2_CAMERA_FLAG;
+ if (DEBUG_HISTORY) Slog.v(TAG, "Camera on to: "
+ + Integer.toHexString(mHistoryCur.states2));
+ addHistoryRecordLocked(elapsedRealtime, uptime);
+ mCameraOnTimer.startRunningLocked(elapsedRealtime);
+ }
+ getUidStatsLocked(uid).noteCameraTurnedOnLocked(elapsedRealtime);
+ }
+
+ public void noteCameraOffLocked(int uid) {
+ if (mCameraOnNesting == 0) {
+ return;
+ }
+ uid = mapUid(uid);
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ if (--mCameraOnNesting == 0) {
+ mHistoryCur.states2 &= ~HistoryItem.STATE2_CAMERA_FLAG;
+ if (DEBUG_HISTORY) Slog.v(TAG, "Camera off to: "
+ + Integer.toHexString(mHistoryCur.states2));
+ addHistoryRecordLocked(elapsedRealtime, uptime);
+ mCameraOnTimer.stopRunningLocked(elapsedRealtime);
+ }
+ getUidStatsLocked(uid).noteCameraTurnedOffLocked(elapsedRealtime);
+ }
+
+ public void noteResetCameraLocked() {
+ if (mCameraOnNesting > 0) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mCameraOnNesting = 0;
+ mHistoryCur.states2 &= ~HistoryItem.STATE2_CAMERA_FLAG;
+ if (DEBUG_HISTORY) Slog.v(TAG, "Camera off to: "
+ + Integer.toHexString(mHistoryCur.states2));
+ addHistoryRecordLocked(elapsedRealtime, uptime);
+ mCameraOnTimer.stopAllRunningLocked(elapsedRealtime);
+ for (int i=0; i<mUidStats.size(); i++) {
+ BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
+ uid.noteResetCameraLocked(elapsedRealtime);
+ }
+ }
+ }
+
+ public void noteResetFlashlightLocked() {
+ if (mFlashlightOnNesting > 0) {
+ final long elapsedRealtime = SystemClock.elapsedRealtime();
+ final long uptime = SystemClock.uptimeMillis();
+ mFlashlightOnNesting = 0;
+ mHistoryCur.states2 &= ~HistoryItem.STATE2_FLASHLIGHT_FLAG;
+ if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight off to: "
+ + Integer.toHexString(mHistoryCur.states2));
+ addHistoryRecordLocked(elapsedRealtime, uptime);
+ mFlashlightOnTimer.stopAllRunningLocked(elapsedRealtime);
+ for (int i=0; i<mUidStats.size(); i++) {
+ BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
+ uid.noteResetFlashlightLocked(elapsedRealtime);
+ }
+ }
}
public void noteWifiRadioPowerState(int powerState, long timestampNs) {
@@ -4262,15 +4338,22 @@ public final class BatteryStatsImpl extends BatteryStats {
return 0;
}
- @Override public long getFlashlightOnTime(long elapsedRealtimeUs, int which) {
+ @Override
+ public long getFlashlightOnTime(long elapsedRealtimeUs, int which) {
return mFlashlightOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
}
- @Override public long getFlashlightOnCount(int which) {
+ @Override
+ public long getFlashlightOnCount(int which) {
return mFlashlightOnTimer.getCountLocked(which);
}
@Override
+ public long getCameraOnTime(long elapsedRealtimeUs, int which) {
+ return mCameraOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
+ }
+
+ @Override
public long getNetworkActivityBytes(int type, int which) {
if (type >= 0 && type < mNetworkByteActivityCounters.length) {
return mNetworkByteActivityCounters[type].getCountLocked(which);
@@ -4350,6 +4433,9 @@ public final class BatteryStatsImpl extends BatteryStats {
StopwatchTimer mAudioTurnedOnTimer;
StopwatchTimer mVideoTurnedOnTimer;
+ StopwatchTimer mFlashlightTurnedOnTimer;
+ StopwatchTimer mCameraTurnedOnTimer;
+
StopwatchTimer mForegroundActivityTimer;
@@ -4650,6 +4736,54 @@ public final class BatteryStatsImpl extends BatteryStats {
}
}
+ public StopwatchTimer createFlashlightTurnedOnTimerLocked() {
+ if (mFlashlightTurnedOnTimer == null) {
+ mFlashlightTurnedOnTimer = new StopwatchTimer(Uid.this, FLASHLIGHT_TURNED_ON,
+ mFlashlightTurnedOnTimers, mOnBatteryTimeBase);
+ }
+ return mFlashlightTurnedOnTimer;
+ }
+
+ public void noteFlashlightTurnedOnLocked(long elapsedRealtimeMs) {
+ createFlashlightTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs);
+ }
+
+ public void noteFlashlightTurnedOffLocked(long elapsedRealtimeMs) {
+ if (mFlashlightTurnedOnTimer != null) {
+ mFlashlightTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs);
+ }
+ }
+
+ public void noteResetFlashlightLocked(long elapsedRealtimeMs) {
+ if (mFlashlightTurnedOnTimer != null) {
+ mFlashlightTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
+ }
+ }
+
+ public StopwatchTimer createCameraTurnedOnTimerLocked() {
+ if (mCameraTurnedOnTimer == null) {
+ mCameraTurnedOnTimer = new StopwatchTimer(Uid.this, CAMERA_TURNED_ON,
+ mCameraTurnedOnTimers, mOnBatteryTimeBase);
+ }
+ return mCameraTurnedOnTimer;
+ }
+
+ public void noteCameraTurnedOnLocked(long elapsedRealtimeMs) {
+ createCameraTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs);
+ }
+
+ public void noteCameraTurnedOffLocked(long elapsedRealtimeMs) {
+ if (mCameraTurnedOnTimer != null) {
+ mCameraTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs);
+ }
+ }
+
+ public void noteResetCameraLocked(long elapsedRealtimeMs) {
+ if (mCameraTurnedOnTimer != null) {
+ mCameraTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
+ }
+ }
+
public StopwatchTimer createForegroundActivityTimerLocked() {
if (mForegroundActivityTimer == null) {
mForegroundActivityTimer = new StopwatchTimer(
@@ -4762,19 +4896,23 @@ public final class BatteryStatsImpl extends BatteryStats {
}
@Override
- public long getAudioTurnedOnTime(long elapsedRealtimeUs, int which) {
- if (mAudioTurnedOnTimer == null) {
- return 0;
- }
- return mAudioTurnedOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
+ public Timer getAudioTurnedOnTimer() {
+ return mAudioTurnedOnTimer;
}
@Override
- public long getVideoTurnedOnTime(long elapsedRealtimeUs, int which) {
- if (mVideoTurnedOnTimer == null) {
- return 0;
- }
- return mVideoTurnedOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
+ public Timer getVideoTurnedOnTimer() {
+ return mVideoTurnedOnTimer;
+ }
+
+ @Override
+ public Timer getFlashlightTurnedOnTimer() {
+ return mFlashlightTurnedOnTimer;
+ }
+
+ @Override
+ public Timer getCameraTurnedOnTimer() {
+ return mCameraTurnedOnTimer;
}
@Override
@@ -4994,6 +5132,12 @@ public final class BatteryStatsImpl extends BatteryStats {
if (mVideoTurnedOnTimer != null) {
active |= !mVideoTurnedOnTimer.reset(false);
}
+ if (mFlashlightTurnedOnTimer != null) {
+ active |= !mFlashlightTurnedOnTimer.reset(false);
+ }
+ if (mCameraTurnedOnTimer != null) {
+ active |= !mCameraTurnedOnTimer.reset(false);
+ }
if (mForegroundActivityTimer != null) {
active |= !mForegroundActivityTimer.reset(false);
}
@@ -5155,6 +5299,14 @@ public final class BatteryStatsImpl extends BatteryStats {
mVideoTurnedOnTimer.detach();
mVideoTurnedOnTimer = null;
}
+ if (mFlashlightTurnedOnTimer != null) {
+ mFlashlightTurnedOnTimer.detach();
+ mFlashlightTurnedOnTimer = null;
+ }
+ if (mCameraTurnedOnTimer != null) {
+ mCameraTurnedOnTimer.detach();
+ mCameraTurnedOnTimer = null;
+ }
if (mForegroundActivityTimer != null) {
mForegroundActivityTimer.detach();
mForegroundActivityTimer = null;
@@ -5291,6 +5443,18 @@ public final class BatteryStatsImpl extends BatteryStats {
} else {
out.writeInt(0);
}
+ if (mFlashlightTurnedOnTimer != null) {
+ out.writeInt(1);
+ mFlashlightTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs);
+ } else {
+ out.writeInt(0);
+ }
+ if (mCameraTurnedOnTimer != null) {
+ out.writeInt(1);
+ mCameraTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs);
+ } else {
+ out.writeInt(0);
+ }
if (mForegroundActivityTimer != null) {
out.writeInt(1);
mForegroundActivityTimer.writeToParcel(out, elapsedRealtimeUs);
@@ -5469,6 +5633,18 @@ public final class BatteryStatsImpl extends BatteryStats {
mVideoTurnedOnTimer = null;
}
if (in.readInt() != 0) {
+ mFlashlightTurnedOnTimer = new StopwatchTimer(Uid.this, FLASHLIGHT_TURNED_ON,
+ mFlashlightTurnedOnTimers, mOnBatteryTimeBase, in);
+ } else {
+ mFlashlightTurnedOnTimer = null;
+ }
+ if (in.readInt() != 0) {
+ mCameraTurnedOnTimer = new StopwatchTimer(Uid.this, CAMERA_TURNED_ON,
+ mCameraTurnedOnTimers, mOnBatteryTimeBase, in);
+ } else {
+ mCameraTurnedOnTimer = null;
+ }
+ if (in.readInt() != 0) {
mForegroundActivityTimer = new StopwatchTimer(
Uid.this, FOREGROUND_ACTIVITY, null, mOnBatteryTimeBase, in);
} else {
@@ -6700,6 +6876,7 @@ public final class BatteryStatsImpl extends BatteryStats {
mAudioOnTimer = new StopwatchTimer(null, -7, null, mOnBatteryTimeBase);
mVideoOnTimer = new StopwatchTimer(null, -8, null, mOnBatteryTimeBase);
mFlashlightOnTimer = new StopwatchTimer(null, -9, null, mOnBatteryTimeBase);
+ mCameraOnTimer = new StopwatchTimer(null, -13, null, mOnBatteryTimeBase);
mOnBattery = mOnBatteryInternal = false;
long uptime = SystemClock.uptimeMillis() * 1000;
long realtime = SystemClock.elapsedRealtime() * 1000;
@@ -7285,6 +7462,7 @@ public final class BatteryStatsImpl extends BatteryStats {
mAudioOnTimer.reset(false);
mVideoOnTimer.reset(false);
mFlashlightOnTimer.reset(false);
+ mCameraOnTimer.reset(false);
for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
mPhoneSignalStrengthsTimer[i].reset(false);
}
@@ -8811,8 +8989,10 @@ public final class BatteryStatsImpl extends BatteryStats {
}
mNumConnectivityChange = mLoadedNumConnectivityChange = in.readInt();
- mFlashlightOn = false;
+ mFlashlightOnNesting = 0;
mFlashlightOnTimer.readSummaryFromParcelLocked(in);
+ mCameraOnNesting = 0;
+ mCameraOnTimer.readSummaryFromParcelLocked(in);
int NKW = in.readInt();
if (NKW > 10000) {
@@ -8883,6 +9063,12 @@ public final class BatteryStatsImpl extends BatteryStats {
u.createVideoTurnedOnTimerLocked().readSummaryFromParcelLocked(in);
}
if (in.readInt() != 0) {
+ u.createFlashlightTurnedOnTimerLocked().readSummaryFromParcelLocked(in);
+ }
+ if (in.readInt() != 0) {
+ u.createCameraTurnedOnTimerLocked().readSummaryFromParcelLocked(in);
+ }
+ if (in.readInt() != 0) {
u.createForegroundActivityTimerLocked().readSummaryFromParcelLocked(in);
}
u.mProcessState = Uid.PROCESS_STATE_NONE;
@@ -9132,6 +9318,7 @@ public final class BatteryStatsImpl extends BatteryStats {
}
out.writeInt(mNumConnectivityChange);
mFlashlightOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
+ mCameraOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
out.writeInt(mKernelWakelockStats.size());
for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
@@ -9208,6 +9395,18 @@ public final class BatteryStatsImpl extends BatteryStats {
} else {
out.writeInt(0);
}
+ if (u.mFlashlightTurnedOnTimer != null) {
+ out.writeInt(1);
+ u.mFlashlightTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
+ } else {
+ out.writeInt(0);
+ }
+ if (u.mCameraTurnedOnTimer != null) {
+ out.writeInt(1);
+ u.mCameraTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
+ } else {
+ out.writeInt(0);
+ }
if (u.mForegroundActivityTimer != null) {
out.writeInt(1);
u.mForegroundActivityTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
@@ -9453,8 +9652,10 @@ public final class BatteryStatsImpl extends BatteryStats {
mAudioOnTimer = new StopwatchTimer(null, -7, null, mOnBatteryTimeBase);
mVideoOnNesting = 0;
mVideoOnTimer = new StopwatchTimer(null, -8, null, mOnBatteryTimeBase);
- mFlashlightOn = false;
+ mFlashlightOnNesting = 0;
mFlashlightOnTimer = new StopwatchTimer(null, -9, null, mOnBatteryTimeBase, in);
+ mCameraOnNesting = 0;
+ mCameraOnTimer = new StopwatchTimer(null, -13, null, mOnBatteryTimeBase, in);
mDischargeUnplugLevel = in.readInt();
mDischargePlugLevel = in.readInt();
mDischargeCurrentLevel = in.readInt();
@@ -9499,6 +9700,8 @@ public final class BatteryStatsImpl extends BatteryStats {
mWifiMulticastTimers.clear();
mAudioTurnedOnTimers.clear();
mVideoTurnedOnTimers.clear();
+ mFlashlightTurnedOnTimers.clear();
+ mCameraTurnedOnTimers.clear();
sNumSpeedSteps = in.readInt();
@@ -9598,6 +9801,7 @@ public final class BatteryStatsImpl extends BatteryStats {
out.writeInt(mLoadedNumConnectivityChange);
out.writeInt(mUnpluggedNumConnectivityChange);
mFlashlightOnTimer.writeToParcel(out, uSecRealtime);
+ mCameraOnTimer.writeToParcel(out, uSecRealtime);
out.writeInt(mDischargeUnplugLevel);
out.writeInt(mDischargePlugLevel);
out.writeInt(mDischargeCurrentLevel);
@@ -9732,6 +9936,8 @@ public final class BatteryStatsImpl extends BatteryStats {
}
pr.println("*** Flashlight timer:");
mFlashlightOnTimer.logState(pr, " ");
+ pr.println("*** Camera timer:");
+ mCameraOnTimer.logState(pr, " ");
}
super.dumpLocked(context, pw, flags, reqUid, histStart);
}
diff --git a/core/java/com/android/internal/os/CameraPowerCalculator.java b/core/java/com/android/internal/os/CameraPowerCalculator.java
new file mode 100644
index 0000000..3273080
--- /dev/null
+++ b/core/java/com/android/internal/os/CameraPowerCalculator.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.os;
+
+import android.os.BatteryStats;
+
+/**
+ * Power calculator for the camera subsystem, excluding the flashlight.
+ *
+ * Note: Power draw for the flash unit should be included in the FlashlightPowerCalculator.
+ */
+public class CameraPowerCalculator extends PowerCalculator {
+ private final double mCameraPowerOnAvg;
+
+ public CameraPowerCalculator(PowerProfile profile) {
+ mCameraPowerOnAvg = profile.getAveragePower(PowerProfile.POWER_CAMERA);
+ }
+
+ @Override
+ public void calculateApp(BatterySipper app, BatteryStats.Uid u, long rawRealtimeUs,
+ long rawUptimeUs, int statsType) {
+
+ // Calculate camera power usage. Right now, this is a (very) rough estimate based on the
+ // average power usage for a typical camera application.
+ final BatteryStats.Timer timer = u.getCameraTurnedOnTimer();
+ if (timer != null) {
+ final long totalTime = timer.getTotalTimeLocked(rawRealtimeUs, statsType) / 1000;
+ app.cameraTimeMs = totalTime;
+ app.cameraPowerMah = (totalTime * mCameraPowerOnAvg) / (1000*60*60);
+ } else {
+ app.cameraTimeMs = 0;
+ app.cameraPowerMah = 0;
+ }
+ }
+}
diff --git a/core/java/com/android/internal/os/FlashlightPowerCalculator.java b/core/java/com/android/internal/os/FlashlightPowerCalculator.java
new file mode 100644
index 0000000..fef66ff
--- /dev/null
+++ b/core/java/com/android/internal/os/FlashlightPowerCalculator.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.internal.os;
+
+import android.os.BatteryStats;
+
+/**
+ * Power calculator for the flashlight.
+ */
+public class FlashlightPowerCalculator extends PowerCalculator {
+ private final double mFlashlightPowerOnAvg;
+
+ public FlashlightPowerCalculator(PowerProfile profile) {
+ mFlashlightPowerOnAvg = profile.getAveragePower(PowerProfile.POWER_FLASHLIGHT);
+ }
+
+ @Override
+ public void calculateApp(BatterySipper app, BatteryStats.Uid u, long rawRealtimeUs,
+ long rawUptimeUs, int statsType) {
+
+ // Calculate flashlight power usage. Right now, this is based on the average power draw
+ // of the flash unit when kept on over a short period of time.
+ final BatteryStats.Timer timer = u.getFlashlightTurnedOnTimer();
+ if (timer != null) {
+ final long totalTime = timer.getTotalTimeLocked(rawRealtimeUs, statsType) / 1000;
+ app.flashlightTimeMs = totalTime;
+ app.flashlightPowerMah = (totalTime * mFlashlightPowerOnAvg) / (1000*60*60);
+ } else {
+ app.flashlightTimeMs = 0;
+ app.flashlightPowerMah = 0;
+ }
+ }
+}
diff --git a/core/java/com/android/internal/os/PowerProfile.java b/core/java/com/android/internal/os/PowerProfile.java
index 1efa565..4ede8dd 100644
--- a/core/java/com/android/internal/os/PowerProfile.java
+++ b/core/java/com/android/internal/os/PowerProfile.java
@@ -152,10 +152,17 @@ public class PowerProfile {
public static final String POWER_VIDEO = "dsp.video";
/**
- * Power consumption when camera flashlight is on.
+ * Average power consumption when camera flashlight is on.
*/
public static final String POWER_FLASHLIGHT = "camera.flashlight";
+ /**
+ * Average power consumption when the camera is on over all standard use cases.
+ *
+ * TODO: Add more fine-grained camera power metrics.
+ */
+ public static final String POWER_CAMERA = "camera.avg";
+
public static final String POWER_CPU_SPEEDS = "cpu.speeds";
/**
diff --git a/core/java/com/android/internal/os/ProcessCpuTracker.java b/core/java/com/android/internal/os/ProcessCpuTracker.java
index 8393e2a..bf97f1f 100644
--- a/core/java/com/android/internal/os/ProcessCpuTracker.java
+++ b/core/java/com/android/internal/os/ProcessCpuTracker.java
@@ -139,6 +139,8 @@ public class ProcessCpuTracker {
private float mLoad5 = 0;
private float mLoad15 = 0;
+ // All times are in milliseconds. They are converted from jiffies to milliseconds
+ // when extracted from the kernel.
private long mCurrentSampleTime;
private long mLastSampleTime;
@@ -191,12 +193,34 @@ public class ProcessCpuTracker {
// filter out kernel processes.
public long vsize;
+ /**
+ * Time in milliseconds.
+ */
public long base_uptime;
+
+ /**
+ * Time in milliseconds.
+ */
public long rel_uptime;
+ /**
+ * Time in milliseconds.
+ */
public long base_utime;
+
+ /**
+ * Time in milliseconds.
+ */
public long base_stime;
+
+ /**
+ * Time in milliseconds.
+ */
public int rel_utime;
+
+ /**
+ * Time in milliseconds.
+ */
public int rel_stime;
public long base_minfaults;
@@ -558,7 +582,7 @@ public class ProcessCpuTracker {
}
/**
- * Returns the total time (in clock ticks, or 1/100 sec) spent executing in
+ * Returns the total time (in milliseconds) spent executing in
* both user and system code. Safe to call without lock held.
*/
public long getCpuTimeForPid(int pid) {
@@ -575,26 +599,44 @@ public class ProcessCpuTracker {
}
}
+ /**
+ * @return time in milliseconds.
+ */
final public int getLastUserTime() {
return mRelUserTime;
}
+ /**
+ * @return time in milliseconds.
+ */
final public int getLastSystemTime() {
return mRelSystemTime;
}
+ /**
+ * @return time in milliseconds.
+ */
final public int getLastIoWaitTime() {
return mRelIoWaitTime;
}
+ /**
+ * @return time in milliseconds.
+ */
final public int getLastIrqTime() {
return mRelIrqTime;
}
+ /**
+ * @return time in milliseconds.
+ */
final public int getLastSoftIrqTime() {
return mRelSoftIrqTime;
}
+ /**
+ * @return time in milliseconds.
+ */
final public int getLastIdleTime() {
return mRelIdleTime;
}
diff --git a/core/java/com/android/internal/os/SomeArgs.java b/core/java/com/android/internal/os/SomeArgs.java
index c977997..b0d24fd 100644
--- a/core/java/com/android/internal/os/SomeArgs.java
+++ b/core/java/com/android/internal/os/SomeArgs.java
@@ -46,6 +46,7 @@ public final class SomeArgs {
public Object arg4;
public Object arg5;
public Object arg6;
+ public Object arg7;
public int argi1;
public int argi2;
public int argi3;
@@ -97,6 +98,7 @@ public final class SomeArgs {
arg4 = null;
arg5 = null;
arg6 = null;
+ arg7 = null;
argi1 = 0;
argi2 = 0;
argi3 = 0;
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 5ed4f70..971da77 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -508,7 +508,7 @@ public class ZygoteInit {
String args[] = {
"--setuid=1000",
"--setgid=1000",
- "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1032,3001,3002,3003,3006,3007",
+ "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1032,3001,3002,3003,3006,3007",
"--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server",
"--runtime-args",
diff --git a/core/java/com/android/internal/policy/IKeyguardService.aidl b/core/java/com/android/internal/policy/IKeyguardService.aidl
index f93b1a1..7ab4651 100644
--- a/core/java/com/android/internal/policy/IKeyguardService.aidl
+++ b/core/java/com/android/internal/policy/IKeyguardService.aidl
@@ -22,6 +22,7 @@ import com.android.internal.policy.IKeyguardExitCallback;
import android.os.Bundle;
oneway interface IKeyguardService {
+
/**
* Sets the Keyguard as occluded when a window dismisses the Keyguard with flag
* FLAG_SHOW_ON_LOCK_SCREEN.
@@ -36,8 +37,27 @@ oneway interface IKeyguardService {
void dismiss();
void onDreamingStarted();
void onDreamingStopped();
- void onScreenTurnedOff(int reason);
- void onScreenTurnedOn(IKeyguardShowCallback callback);
+
+ /**
+ * Called when the device has started going to sleep.
+ *
+ * @param why {@link #OFF_BECAUSE_OF_USER}, {@link #OFF_BECAUSE_OF_ADMIN},
+ * or {@link #OFF_BECAUSE_OF_TIMEOUT}.
+ */
+ void onStartedGoingToSleep(int reason);
+
+ /**
+ * Called when the device has finished going to sleep.
+ *
+ * @param why {@link #OFF_BECAUSE_OF_USER}, {@link #OFF_BECAUSE_OF_ADMIN},
+ * or {@link #OFF_BECAUSE_OF_TIMEOUT}.
+ */
+ void onFinishedGoingToSleep(int reason);
+
+ /**
+ * Called when the device has started waking up.
+ */
+ void onStartedWakingUp(IKeyguardShowCallback callback);
void setKeyguardEnabled(boolean enabled);
void onSystemReady();
void doKeyguardTimeout(in Bundle options);
diff --git a/core/java/com/android/internal/policy/PhoneWindow.java b/core/java/com/android/internal/policy/PhoneWindow.java
index bc64373..c010dfe 100644
--- a/core/java/com/android/internal/policy/PhoneWindow.java
+++ b/core/java/com/android/internal/policy/PhoneWindow.java
@@ -56,7 +56,6 @@ import android.view.Window;
import android.view.WindowInsets;
import android.view.WindowManager;
import com.android.internal.R;
-import com.android.internal.util.ScreenShapeHelper;
import com.android.internal.view.FloatingActionMode;
import com.android.internal.view.RootViewSurfaceTaker;
import com.android.internal.view.StandaloneActionMode;
@@ -76,6 +75,7 @@ import com.android.internal.widget.SwipeDismissLayout;
import android.app.ActivityManager;
import android.app.KeyguardManager;
import android.content.Context;
+import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.content.res.Resources.Theme;
@@ -156,7 +156,6 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
TypedValue mFixedWidthMinor;
TypedValue mFixedHeightMajor;
TypedValue mFixedHeightMinor;
- int mOutsetBottomPx;
// This is the top-level view of the window, containing the window decor.
private DecorView mDecor;
@@ -289,6 +288,9 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
private Boolean mSharedElementsUseOverlay;
private Rect mTempRect;
+ private Rect mOutsets = new Rect();
+
+ private boolean mIsStartingWindow;
static class WindowManagerHolder {
static final IWindowManager sWindowManager = IWindowManager.Stub.asInterface(
@@ -2220,12 +2222,14 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
private final ColorViewState mStatusColorViewState = new ColorViewState(
SYSTEM_UI_FLAG_FULLSCREEN, FLAG_TRANSLUCENT_STATUS,
Gravity.TOP,
+ Gravity.LEFT,
STATUS_BAR_BACKGROUND_TRANSITION_NAME,
com.android.internal.R.id.statusBarBackground,
FLAG_FULLSCREEN);
private final ColorViewState mNavigationColorViewState = new ColorViewState(
SYSTEM_UI_FLAG_HIDE_NAVIGATION, FLAG_TRANSLUCENT_NAVIGATION,
Gravity.BOTTOM,
+ Gravity.RIGHT,
NAVIGATION_BAR_BACKGROUND_TRANSITION_NAME,
com.android.internal.R.id.navigationBarBackground,
0 /* hideWindowFlag */);
@@ -2241,6 +2245,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
private int mLastRightInset = 0;
private boolean mLastHasTopStableInset = false;
private boolean mLastHasBottomStableInset = false;
+ private boolean mLastHasRightStableInset = false;
private int mLastWindowFlags = 0;
private int mRootScrollY = 0;
@@ -2401,19 +2406,6 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
}
@Override
- public WindowInsets dispatchApplyWindowInsets(WindowInsets insets) {
- if (mOutsetBottomPx != 0) {
- WindowInsets newInsets = insets.replaceSystemWindowInsets(
- insets.getSystemWindowInsetLeft(), insets.getSystemWindowInsetTop(),
- insets.getSystemWindowInsetRight(), mOutsetBottomPx);
- return super.dispatchApplyWindowInsets(newInsets);
- } else {
- return super.dispatchApplyWindowInsets(insets);
- }
- }
-
-
- @Override
public boolean onTouchEvent(MotionEvent event) {
return onInterceptTouchEvent(event);
}
@@ -2624,11 +2616,21 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
}
}
- if (mOutsetBottomPx != 0) {
+ getOutsets(mOutsets);
+ if (mOutsets.top > 0 || mOutsets.bottom > 0) {
int mode = MeasureSpec.getMode(heightMeasureSpec);
if (mode != MeasureSpec.UNSPECIFIED) {
int height = MeasureSpec.getSize(heightMeasureSpec);
- heightMeasureSpec = MeasureSpec.makeMeasureSpec(height + mOutsetBottomPx, mode);
+ heightMeasureSpec = MeasureSpec.makeMeasureSpec(
+ height + mOutsets.top + mOutsets.bottom, mode);
+ }
+ }
+ if (mOutsets.left > 0 || mOutsets.right > 0) {
+ int mode = MeasureSpec.getMode(widthMeasureSpec);
+ if (mode != MeasureSpec.UNSPECIFIED) {
+ int width = MeasureSpec.getSize(widthMeasureSpec);
+ widthMeasureSpec = MeasureSpec.makeMeasureSpec(
+ width + mOutsets.left + mOutsets.right, mode);
}
}
@@ -2666,6 +2668,18 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
}
@Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ super.onLayout(changed, left, top, right, bottom);
+ getOutsets(mOutsets);
+ if (mOutsets.left > 0) {
+ offsetLeftAndRight(-mOutsets.left);
+ }
+ if (mOutsets.top > 0) {
+ offsetTopAndBottom(-mOutsets.top);
+ }
+ }
+
+ @Override
public void draw(Canvas canvas) {
super.draw(canvas);
@@ -2674,7 +2688,6 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
}
}
-
@Override
public boolean showContextMenuForChild(View originalView) {
// Reuse the context menu builder
@@ -2875,12 +2888,19 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
boolean hasBottomStableInset = insets.getStableInsetBottom() != 0;
disallowAnimate |= (hasBottomStableInset != mLastHasBottomStableInset);
mLastHasBottomStableInset = hasBottomStableInset;
+
+ boolean hasRightStableInset = insets.getStableInsetRight() != 0;
+ disallowAnimate |= (hasRightStableInset != mLastHasRightStableInset);
+ mLastHasRightStableInset = hasRightStableInset;
}
updateColorViewInt(mStatusColorViewState, sysUiVisibility, mStatusBarColor,
- mLastTopInset, animate && !disallowAnimate);
+ mLastTopInset, false /* matchVertical */, animate && !disallowAnimate);
+
+ boolean navBarToRightEdge = mLastBottomInset == 0 && mLastRightInset > 0;
+ int navBarSize = navBarToRightEdge ? mLastRightInset : mLastBottomInset;
updateColorViewInt(mNavigationColorViewState, sysUiVisibility, mNavigationBarColor,
- mLastBottomInset, animate && !disallowAnimate);
+ navBarSize, navBarToRightEdge, animate && !disallowAnimate);
}
// When we expand the window with FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS, we still need
@@ -2924,9 +2944,20 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
return insets;
}
+ /**
+ * Update a color view
+ *
+ * @param state the color view to update.
+ * @param sysUiVis the current systemUiVisibility to apply.
+ * @param color the current color to apply.
+ * @param size the current size in the non-parent-matching dimension.
+ * @param verticalBar if true the view is attached to a vertical edge, otherwise to a
+ * horizontal edge,
+ * @param animate if true, the change will be animated.
+ */
private void updateColorViewInt(final ColorViewState state, int sysUiVis, int color,
- int height, boolean animate) {
- boolean show = height > 0 && (sysUiVis & state.systemUiHideFlag) == 0
+ int size, boolean verticalBar, boolean animate) {
+ boolean show = size > 0 && (sysUiVis & state.systemUiHideFlag) == 0
&& (getAttributes().flags & state.hideWindowFlag) == 0
&& (getAttributes().flags & state.translucentFlag) == 0
&& (color & Color.BLACK) != 0
@@ -2935,6 +2966,10 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
boolean visibilityChanged = false;
View view = state.view;
+ int resolvedHeight = verticalBar ? LayoutParams.MATCH_PARENT : size;
+ int resolvedWidth = verticalBar ? size : LayoutParams.MATCH_PARENT;
+ int resolvedGravity = verticalBar ? state.horizontalGravity : state.verticalGravity;
+
if (view == null) {
if (show) {
state.view = view = new View(mContext);
@@ -2945,8 +2980,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
view.setVisibility(INVISIBLE);
state.targetVisibility = VISIBLE;
- addView(view, new LayoutParams(LayoutParams.MATCH_PARENT, height,
- Gravity.START | state.verticalGravity));
+ addView(view, new LayoutParams(resolvedWidth, resolvedHeight, resolvedGravity));
updateColorViewTranslations();
}
} else {
@@ -2955,8 +2989,11 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
state.targetVisibility = vis;
if (show) {
LayoutParams lp = (LayoutParams) view.getLayoutParams();
- if (lp.height != height) {
- lp.height = height;
+ if (lp.height != resolvedHeight || lp.width != resolvedWidth
+ || lp.gravity != resolvedGravity) {
+ lp.height = resolvedHeight;
+ lp.width = resolvedWidth;
+ lp.gravity = resolvedGravity;
view.setLayoutParams(lp);
}
view.setBackgroundColor(color);
@@ -3583,19 +3620,6 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
requestFeature(FEATURE_ACTIVITY_TRANSITIONS);
}
- final WindowManager windowService = (WindowManager) getContext().getSystemService(
- Context.WINDOW_SERVICE);
- if (windowService != null) {
- final Display display = windowService.getDefaultDisplay();
- final boolean shouldUseBottomOutset =
- display.getDisplayId() == Display.DEFAULT_DISPLAY
- || (getForcedWindowFlags() & FLAG_FULLSCREEN) != 0;
- if (shouldUseBottomOutset) {
- mOutsetBottomPx = ScreenShapeHelper.getWindowOutsetBottomPx(
- getContext().getResources().getDisplayMetrics(), a);
- }
- }
-
final Context context = getContext();
final int targetSdk = context.getApplicationInfo().targetSdkVersion;
final boolean targetPreHoneycomb = targetSdk < android.os.Build.VERSION_CODES.HONEYCOMB;
@@ -3870,7 +3894,7 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
// A pending invalidation will typically be resolved before the posted message
// would run normally in order to satisfy instance state restoration.
PanelFeatureState st = getPanelState(FEATURE_OPTIONS_PANEL, false);
- if (!isDestroyed() && (st == null || st.menu == null)) {
+ if (!isDestroyed() && (st == null || st.menu == null) && !mIsStartingWindow) {
invalidatePanelMenu(FEATURE_ACTION_BAR);
}
} else {
@@ -4296,8 +4320,10 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
if (!result && (getContext().getResources().getConfiguration().uiMode
& Configuration.UI_MODE_TYPE_MASK) == Configuration.UI_MODE_TYPE_TELEVISION) {
// On TVs, if the app doesn't implement search, we want to launch assist.
+ Bundle args = new Bundle();
+ args.putInt(Intent.EXTRA_ASSIST_INPUT_DEVICE_ID, event.getDeviceId());
return ((SearchManager)getContext().getSystemService(Context.SEARCH_SERVICE))
- .launchAssistAction(null, UserHandle.myUserId());
+ .launchAssistAction(null, UserHandle.myUserId(), args);
}
return result;
}
@@ -4884,16 +4910,18 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
final int systemUiHideFlag;
final int translucentFlag;
final int verticalGravity;
+ final int horizontalGravity;
final String transitionName;
final int hideWindowFlag;
ColorViewState(int systemUiHideFlag,
- int translucentFlag, int verticalGravity,
+ int translucentFlag, int verticalGravity, int horizontalGravity,
String transitionName, int id, int hideWindowFlag) {
this.id = id;
this.systemUiHideFlag = systemUiHideFlag;
this.translucentFlag = translucentFlag;
this.verticalGravity = verticalGravity;
+ this.horizontalGravity = horizontalGravity;
this.transitionName = transitionName;
this.hideWindowFlag = hideWindowFlag;
}
@@ -4943,4 +4971,8 @@ public class PhoneWindow extends Window implements MenuBuilder.Callback {
mDecor.updateColorViews(null, false /* animate */);
}
}
+
+ public void setIsStartingWindow(boolean isStartingWindow) {
+ mIsStartingWindow = isStartingWindow;
+ }
}
diff --git a/core/java/com/android/internal/util/ScreenShapeHelper.java b/core/java/com/android/internal/util/ScreenShapeHelper.java
index 58ae853..4a196f8 100644
--- a/core/java/com/android/internal/util/ScreenShapeHelper.java
+++ b/core/java/com/android/internal/util/ScreenShapeHelper.java
@@ -18,19 +18,13 @@ public class ScreenShapeHelper {
/**
* Return the bottom pixel window outset of a window given its style attributes.
- * @param displayMetrics Display metrics of the current device
- * @param windowStyle Window style attributes for the window.
* @return An outset dimension in pixels or 0 if no outset should be applied.
*/
- public static int getWindowOutsetBottomPx(DisplayMetrics displayMetrics,
- TypedArray windowStyle) {
+ public static int getWindowOutsetBottomPx(Resources resources) {
if (IS_EMULATOR) {
return SystemProperties.getInt(ViewRootImpl.PROPERTY_EMULATOR_WIN_OUTSET_BOTTOM_PX, 0);
- } else if (windowStyle.hasValue(R.styleable.Window_windowOutsetBottom)) {
- TypedValue outsetBottom = new TypedValue();
- windowStyle.getValue(R.styleable.Window_windowOutsetBottom, outsetBottom);
- return (int) outsetBottom.getDimension(displayMetrics);
+ } else {
+ return resources.getInteger(com.android.internal.R.integer.config_windowOutsetBottom);
}
- return 0;
}
}
diff --git a/core/java/com/android/internal/view/BaseIWindow.java b/core/java/com/android/internal/view/BaseIWindow.java
index e27ba13..3eeabcd 100644
--- a/core/java/com/android/internal/view/BaseIWindow.java
+++ b/core/java/com/android/internal/view/BaseIWindow.java
@@ -34,8 +34,8 @@ public class BaseIWindow extends IWindow.Stub {
}
@Override
- public void resized(Rect frame, Rect overscanInsets, Rect contentInsets,
- Rect visibleInsets, Rect stableInsets, boolean reportDraw, Configuration newConfig) {
+ public void resized(Rect frame, Rect overscanInsets, Rect contentInsets, Rect visibleInsets,
+ Rect stableInsets, Rect outsets, boolean reportDraw, Configuration newConfig) {
if (reportDraw) {
try {
mSession.finishDrawing(this);
diff --git a/core/java/com/android/internal/view/FloatingActionMode.java b/core/java/com/android/internal/view/FloatingActionMode.java
index 93d2a1d..661dce1 100644
--- a/core/java/com/android/internal/view/FloatingActionMode.java
+++ b/core/java/com/android/internal/view/FloatingActionMode.java
@@ -23,6 +23,7 @@ import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
+import android.view.ViewConfiguration;
import com.android.internal.util.Preconditions;
import com.android.internal.view.menu.MenuBuilder;
@@ -30,7 +31,7 @@ import com.android.internal.widget.FloatingToolbar;
public class FloatingActionMode extends ActionMode {
- private static final int MAX_SNOOZE_TIME = 3000;
+ private static final int MAX_HIDE_DURATION = 3000;
private static final int MOVING_HIDE_DELAY = 300;
private final Context mContext;
@@ -50,9 +51,9 @@ public class FloatingActionMode extends ActionMode {
}
};
- private final Runnable mSnoozeOff = new Runnable() {
+ private final Runnable mHideOff = new Runnable() {
public void run() {
- mFloatingToolbarVisibilityHelper.setSnoozed(false);
+ mFloatingToolbarVisibilityHelper.setHideRequested(false);
}
};
@@ -127,11 +128,16 @@ public class FloatingActionMode extends ActionMode {
private void repositionToolbar() {
checkToolbarInitialized();
+
+ mContentRectOnWindow.set(mContentRect);
+ mContentRectOnWindow.offset(mViewPosition[0], mViewPosition[1]);
+ // Make sure that content rect is not out of the view's visible bounds.
mContentRectOnWindow.set(
- mContentRect.left + mViewPosition[0],
- mContentRect.top + mViewPosition[1],
- mContentRect.right + mViewPosition[0],
- mContentRect.bottom + mViewPosition[1]);
+ Math.max(mContentRectOnWindow.left, mViewRect.left),
+ Math.max(mContentRectOnWindow.top, mViewRect.top),
+ Math.min(mContentRectOnWindow.right, mViewRect.right),
+ Math.min(mContentRectOnWindow.bottom, mViewRect.bottom));
+
if (!mContentRectOnWindow.equals(mPreviousContentRectOnWindow)) {
if (!mPreviousContentRectOnWindow.isEmpty()) {
notifyContentRectMoving();
@@ -166,15 +172,19 @@ public class FloatingActionMode extends ActionMode {
}
@Override
- public void snooze(int snoozeTime) {
+ public void hide(long duration) {
checkToolbarInitialized();
- snoozeTime = Math.min(MAX_SNOOZE_TIME, snoozeTime);
- mOriginatingView.removeCallbacks(mSnoozeOff);
- if (snoozeTime <= 0) {
- mSnoozeOff.run();
+
+ if (duration == ActionMode.DEFAULT_HIDE_DURATION) {
+ duration = ViewConfiguration.getDefaultActionModeHideDuration();
+ }
+ duration = Math.min(MAX_HIDE_DURATION, duration);
+ mOriginatingView.removeCallbacks(mHideOff);
+ if (duration <= 0) {
+ mHideOff.run();
} else {
- mFloatingToolbarVisibilityHelper.setSnoozed(true);
- mOriginatingView.postDelayed(mSnoozeOff, snoozeTime);
+ mFloatingToolbarVisibilityHelper.setHideRequested(true);
+ mOriginatingView.postDelayed(mHideOff, duration);
}
}
@@ -220,7 +230,7 @@ public class FloatingActionMode extends ActionMode {
private void reset() {
mOriginatingView.removeCallbacks(mMovingOff);
- mOriginatingView.removeCallbacks(mSnoozeOff);
+ mOriginatingView.removeCallbacks(mHideOff);
}
@@ -231,7 +241,7 @@ public class FloatingActionMode extends ActionMode {
private final FloatingToolbar mToolbar;
- private boolean mSnoozed;
+ private boolean mHideRequested;
private boolean mMoving;
private boolean mOutOfBounds;
@@ -239,8 +249,8 @@ public class FloatingActionMode extends ActionMode {
mToolbar = Preconditions.checkNotNull(toolbar);
}
- public void setSnoozed(boolean snoozed) {
- mSnoozed = snoozed;
+ public void setHideRequested(boolean hide) {
+ mHideRequested = hide;
updateToolbarVisibility();
}
@@ -255,7 +265,7 @@ public class FloatingActionMode extends ActionMode {
}
private void updateToolbarVisibility() {
- if (mSnoozed || mMoving || mOutOfBounds) {
+ if (mHideRequested || mMoving || mOutOfBounds) {
mToolbar.hide();
} else if (mToolbar.isHidden()) {
mToolbar.show();
diff --git a/core/java/com/android/internal/widget/FloatingToolbar.java b/core/java/com/android/internal/widget/FloatingToolbar.java
index 3cff59a..c77d614 100644
--- a/core/java/com/android/internal/widget/FloatingToolbar.java
+++ b/core/java/com/android/internal/widget/FloatingToolbar.java
@@ -37,6 +37,7 @@ import android.view.View.MeasureSpec;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.Window;
+import android.view.WindowInsets;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.AnimationSet;
@@ -83,7 +84,7 @@ public final class FloatingToolbar {
private final Rect mContentRect = new Rect();
private Menu mMenu;
- private List<CharSequence> mShowingTitles = new ArrayList<CharSequence>();
+ private List<Object> mShowingMenuItems = new ArrayList<Object>();
private MenuItem.OnMenuItemClickListener mMenuItemClickListener = NO_OP_MENUITEM_CLICK_LISTENER;
private int mSuggestedWidth;
@@ -155,7 +156,7 @@ public final class FloatingToolbar {
if (!isCurrentlyShowing(menuItems) || mWidthChanged) {
mPopup.dismiss();
mPopup.layoutMenuItems(menuItems, mMenuItemClickListener, mSuggestedWidth);
- mShowingTitles = getMenuItemTitles(menuItems);
+ mShowingMenuItems = getShowingMenuItemsReferences(menuItems);
}
mPopup.updateCoordinates(mContentRect);
if (!mPopup.isShowing()) {
@@ -210,7 +211,7 @@ public final class FloatingToolbar {
* Returns true if this floating toolbar is currently showing the specified menu items.
*/
private boolean isCurrentlyShowing(List<MenuItem> menuItems) {
- return mShowingTitles.equals(getMenuItemTitles(menuItems));
+ return mShowingMenuItems.equals(getShowingMenuItemsReferences(menuItems));
}
/**
@@ -233,12 +234,16 @@ public final class FloatingToolbar {
return menuItems;
}
- private List<CharSequence> getMenuItemTitles(List<MenuItem> menuItems) {
- List<CharSequence> titles = new ArrayList<CharSequence>();
+ private List<Object> getShowingMenuItemsReferences(List<MenuItem> menuItems) {
+ List<Object> references = new ArrayList<Object>();
for (MenuItem menuItem : menuItems) {
- titles.add(menuItem.getTitle());
+ if (isIconOnlyMenuItem(menuItem)) {
+ references.add(menuItem.getIcon());
+ } else {
+ references.add(menuItem.getTitle());
+ }
}
- return titles;
+ return references;
}
@@ -289,7 +294,6 @@ public final class FloatingToolbar {
public void onAnimationRepeat(Animation animation) {
}
};
- private final AnimatorSet mShowAnimation;
private final AnimatorSet mDismissAnimation;
private final AnimatorSet mHideAnimation;
private final AnimationSet mOpenOverflowAnimation = new AnimationSet(true) {
@@ -324,6 +328,7 @@ public final class FloatingToolbar {
}
};
+ private final Rect mViewPort = new Rect();
private final Point mCoords = new Point();
private final Region mTouchableRegion = new Region();
@@ -356,7 +361,6 @@ public final class FloatingToolbar {
mParent = Preconditions.checkNotNull(parent);
mContentContainer = createContentContainer(parent.getContext());
mPopupWindow = createPopupWindow(mContentContainer);
- mShowAnimation = createGrowFadeInFromBottom(mContentContainer);
mDismissAnimation = createShrinkFadeOutFromBottomAnimation(
mContentContainer,
150, // startDelay
@@ -385,8 +389,10 @@ public final class FloatingToolbar {
/**
* Lays out buttons for the specified menu items.
*/
- public void layoutMenuItems(List<MenuItem> menuItems,
- MenuItem.OnMenuItemClickListener menuItemClickListener, int suggestedWidth) {
+ public void layoutMenuItems(
+ List<MenuItem> menuItems,
+ MenuItem.OnMenuItemClickListener menuItemClickListener,
+ int suggestedWidth) {
Preconditions.checkNotNull(menuItems);
mContentContainer.removeAllViews();
@@ -394,7 +400,7 @@ public final class FloatingToolbar {
mMainPanel = new FloatingToolbarMainPanel(mParent.getContext(), mOpenOverflow);
}
List<MenuItem> overflowMenuItems =
- mMainPanel.layoutMenuItems(menuItems, suggestedWidth);
+ mMainPanel.layoutMenuItems(menuItems, getToolbarWidth(suggestedWidth));
mMainPanel.setOnMenuItemClickListener(menuItemClickListener);
if (!overflowMenuItems.isEmpty()) {
if (mOverflowPanel == null) {
@@ -430,7 +436,8 @@ public final class FloatingToolbar {
// The "show" animation will make this visible.
mContentContainer.setAlpha(0);
}
- updateOverflowHeight(contentRect.top - (mMarginVertical * 2));
+ refreshViewPort();
+ updateOverflowHeight(contentRect.top - (mMarginVertical * 2) - mViewPort.top);
refreshCoordinatesAndOverflowDirection(contentRect);
preparePopupContent();
mPopupWindow.showAtLocation(mParent, Gravity.NO_GRAVITY, mCoords.x, mCoords.y);
@@ -494,6 +501,7 @@ public final class FloatingToolbar {
}
cancelOverflowAnimations();
+ refreshViewPort();
refreshCoordinatesAndOverflowDirection(contentRect);
preparePopupContent();
mPopupWindow.update(mCoords.x, mCoords.y, getWidth(), getHeight());
@@ -521,18 +529,24 @@ public final class FloatingToolbar {
}
private void refreshCoordinatesAndOverflowDirection(Rect contentRect) {
+ // NOTE: Ensure that mViewPort has been refreshed before this.
+
int x = contentRect.centerX() - getWidth() / 2;
int y;
- if (contentRect.top > getHeight()) {
+ if (contentRect.top - getHeight() > mViewPort.top) {
y = contentRect.top - getHeight();
mOverflowDirection = FloatingToolbarPopup.OVERFLOW_DIRECTION_UP;
- } else if (contentRect.top > getToolbarHeightWithVerticalMargin()) {
+ } else if (contentRect.top - getToolbarHeightWithVerticalMargin() > mViewPort.top) {
y = contentRect.top - getToolbarHeightWithVerticalMargin();
mOverflowDirection = FloatingToolbarPopup.OVERFLOW_DIRECTION_DOWN;
} else {
y = contentRect.bottom;
mOverflowDirection = FloatingToolbarPopup.OVERFLOW_DIRECTION_DOWN;
}
+
+ // Update x so that the toolbar isn't rendered behind the nav bar in landscape.
+ x = Math.max(0, Math.min(x, mViewPort.right - getWidth()));
+
mCoords.set(x, y);
if (mOverflowPanel != null) {
mOverflowPanel.setOverflowDirection(mOverflowDirection);
@@ -547,7 +561,7 @@ public final class FloatingToolbar {
* Performs the "show" animation on the floating popup.
*/
private void runShowAnimation() {
- mShowAnimation.start();
+ createGrowFadeInFromBottom(mContentContainer).start();
}
/**
@@ -593,7 +607,8 @@ public final class FloatingToolbar {
final int startWidth = mContentContainer.getWidth();
final int startHeight = mContentContainer.getHeight();
final float startY = mContentContainer.getY();
- final float right = mContentContainer.getX() + mContentContainer.getWidth();
+ final float left = mContentContainer.getX();
+ final float right = left + mContentContainer.getWidth();
Animation widthAnimation = new Animation() {
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
@@ -601,7 +616,11 @@ public final class FloatingToolbar {
int deltaWidth = (int) (interpolatedTime * (targetWidth - startWidth));
params.width = startWidth + deltaWidth;
mContentContainer.setLayoutParams(params);
- mContentContainer.setX(right - mContentContainer.getWidth());
+ if (isRTL()) {
+ mContentContainer.setX(left);
+ } else {
+ mContentContainer.setX(right - mContentContainer.getWidth());
+ }
}
};
Animation heightAnimation = new Animation() {
@@ -644,9 +663,10 @@ public final class FloatingToolbar {
final int targetHeight = mainPanelSize.getHeight();
final int startWidth = mContentContainer.getWidth();
final int startHeight = mContentContainer.getHeight();
- final float right = mContentContainer.getX() + mContentContainer.getWidth();
final float bottom = mContentContainer.getY() + mContentContainer.getHeight();
final boolean morphedUpwards = (mOverflowDirection == OVERFLOW_DIRECTION_UP);
+ final float left = mContentContainer.getX();
+ final float right = left + mContentContainer.getWidth();
Animation widthAnimation = new Animation() {
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
@@ -654,7 +674,11 @@ public final class FloatingToolbar {
int deltaWidth = (int) (interpolatedTime * (targetWidth - startWidth));
params.width = startWidth + deltaWidth;
mContentContainer.setLayoutParams(params);
- mContentContainer.setX(right - mContentContainer.getWidth());
+ if (isRTL()) {
+ mContentContainer.setX(left);
+ } else {
+ mContentContainer.setX(right - mContentContainer.getWidth());
+ }
}
};
Animation heightAnimation = new Animation() {
@@ -747,9 +771,7 @@ public final class FloatingToolbar {
*/
private void positionMainPanel() {
Preconditions.checkNotNull(mMainPanel);
- float x = mPopupWindow.getWidth()
- - (mMainPanel.getView().getMeasuredWidth() + mMarginHorizontal);
- mContentContainer.setX(x);
+ mContentContainer.setX(mMarginHorizontal);
float y = mMarginVertical;
if (mOverflowDirection == OVERFLOW_DIRECTION_UP) {
@@ -765,8 +787,13 @@ public final class FloatingToolbar {
*/
private void positionOverflowPanel() {
Preconditions.checkNotNull(mOverflowPanel);
- float x = mPopupWindow.getWidth()
+ float x;
+ if (isRTL()) {
+ x = mMarginHorizontal;
+ } else {
+ x = mPopupWindow.getWidth()
- (mOverflowPanel.getView().getMeasuredWidth() + mMarginHorizontal);
+ }
mContentContainer.setX(x);
mContentContainer.setY(mMarginVertical);
setContentAreaAsTouchableSurface();
@@ -808,6 +835,29 @@ public final class FloatingToolbar {
mPopupWindow.setHeight(height + mMarginVertical * 2);
}
+
+ private void refreshViewPort() {
+ mParent.getGlobalVisibleRect(mViewPort);
+ WindowInsets windowInsets = mParent.getRootWindowInsets();
+ mViewPort.set(
+ mViewPort.left + windowInsets.getStableInsetLeft(),
+ mViewPort.top + windowInsets.getStableInsetTop(),
+ mViewPort.right - windowInsets.getStableInsetRight(),
+ mViewPort.bottom - windowInsets.getStableInsetBottom());
+ }
+
+ private int getToolbarWidth(int suggestedWidth) {
+ int width = suggestedWidth;
+ refreshViewPort();
+ int maximumWidth = mViewPort.width() - 2 * mParent.getResources()
+ .getDimensionPixelSize(R.dimen.floating_toolbar_horizontal_margin);
+ if (width <= 0) {
+ width = mParent.getResources()
+ .getDimensionPixelSize(R.dimen.floating_toolbar_preferred_width);
+ }
+ return Math.min(width, maximumWidth);
+ }
+
/**
* Sets the touchable region of this popup to be zero. This means that all touch events on
* this popup will go through to the surface behind it.
@@ -844,6 +894,10 @@ public final class FloatingToolbar {
viewTreeObserver.removeOnComputeInternalInsetsListener(mInsetsComputer);
viewTreeObserver.addOnComputeInternalInsetsListener(mInsetsComputer);
}
+
+ private boolean isRTL() {
+ return mContentContainer.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
+ }
}
/**
@@ -889,12 +943,11 @@ public final class FloatingToolbar {
*
* @return The menu items that are not included in this main panel.
*/
- public List<MenuItem> layoutMenuItems(List<MenuItem> menuItems, int suggestedWidth) {
+ public List<MenuItem> layoutMenuItems(List<MenuItem> menuItems, int width) {
Preconditions.checkNotNull(menuItems);
- final int toolbarWidth = getAdjustedToolbarWidth(mContext, suggestedWidth)
- // Reserve space for the "open overflow" button.
- - getEstimatedOpenOverflowButtonWidth(mContext);
+ // Reserve space for the "open overflow" button.
+ final int toolbarWidth = width - getEstimatedOpenOverflowButtonWidth(mContext);
int availableWidth = toolbarWidth;
final LinkedList<MenuItem> remainingMenuItems = new LinkedList<MenuItem>(menuItems);
@@ -1325,7 +1378,9 @@ public final class FloatingToolbar {
growFadeInFromBottomAnimation.playTogether(
ObjectAnimator.ofFloat(view, View.SCALE_X, 0.5f, 1).setDuration(125),
ObjectAnimator.ofFloat(view, View.SCALE_Y, 0.5f, 1).setDuration(125),
- ObjectAnimator.ofFloat(view, View.ALPHA, 0, 1).setDuration(75));
+ ObjectAnimator.ofFloat(view, View.ALPHA, 0, 1).setDuration(75),
+ // Make sure that view.x is always fixed throughout the duration of this animation.
+ ObjectAnimator.ofFloat(view, View.X, view.getX(), view.getX()));
growFadeInFromBottomAnimation.setStartDelay(50);
return growFadeInFromBottomAnimation;
}
diff --git a/core/java/com/android/internal/widget/LockPatternUtils.java b/core/java/com/android/internal/widget/LockPatternUtils.java
index aee0ff6..86d11be 100644
--- a/core/java/com/android/internal/widget/LockPatternUtils.java
+++ b/core/java/com/android/internal/widget/LockPatternUtils.java
@@ -841,7 +841,7 @@ public class LockPatternUtils {
final byte[] bytes = string.getBytes();
for (int i = 0; i < bytes.length; i++) {
- byte b = bytes[i];
+ byte b = (byte) (bytes[i] - '1');
result.add(LockPatternView.Cell.of(b / 3, b % 3));
}
return result;
@@ -861,7 +861,21 @@ public class LockPatternUtils {
byte[] res = new byte[patternSize];
for (int i = 0; i < patternSize; i++) {
LockPatternView.Cell cell = pattern.get(i);
- res[i] = (byte) (cell.getRow() * 3 + cell.getColumn());
+ res[i] = (byte) (cell.getRow() * 3 + cell.getColumn() + '1');
+ }
+ return new String(res);
+ }
+
+ public static String patternStringToBaseZero(String pattern) {
+ if (pattern == null) {
+ return "";
+ }
+ final int patternSize = pattern.length();
+
+ byte[] res = new byte[patternSize];
+ final byte[] bytes = pattern.getBytes();
+ for (int i = 0; i < patternSize; i++) {
+ res[i] = (byte) (bytes[i] - '1');
}
return new String(res);
}
diff --git a/core/java/com/android/internal/widget/SwipeDismissLayout.java b/core/java/com/android/internal/widget/SwipeDismissLayout.java
index 6d4e058..35ed63b 100644
--- a/core/java/com/android/internal/widget/SwipeDismissLayout.java
+++ b/core/java/com/android/internal/widget/SwipeDismissLayout.java
@@ -16,9 +16,11 @@
package com.android.internal.widget;
-import android.animation.TimeInterpolator;
import android.app.Activity;
+import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.util.Log;
@@ -28,8 +30,6 @@ import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
-import android.view.animation.AccelerateInterpolator;
-import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;
/**
@@ -62,10 +62,6 @@ public class SwipeDismissLayout extends FrameLayout {
// Cached ViewConfiguration and system-wide constant values
private int mSlop;
private int mMinFlingVelocity;
- private int mMaxFlingVelocity;
- private long mAnimationTime;
- private TimeInterpolator mCancelInterpolator;
- private TimeInterpolator mDismissInterpolator;
// Transient properties
private int mActiveTouchId;
@@ -92,6 +88,18 @@ public class SwipeDismissLayout extends FrameLayout {
}
}
};
+ private BroadcastReceiver mScreenOffReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (mDismissed) {
+ dismiss();
+ } else {
+ cancel();
+ }
+ resetMembers();
+ }
+ };
+ private IntentFilter mScreenOffFilter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
private float mLastX;
@@ -114,11 +122,6 @@ public class SwipeDismissLayout extends FrameLayout {
ViewConfiguration vc = ViewConfiguration.get(context);
mSlop = vc.getScaledTouchSlop();
mMinFlingVelocity = vc.getScaledMinimumFlingVelocity();
- mMaxFlingVelocity = vc.getScaledMaximumFlingVelocity();
- mAnimationTime = getContext().getResources().getInteger(
- android.R.integer.config_shortAnimTime);
- mCancelInterpolator = new DecelerateInterpolator(1.5f);
- mDismissInterpolator = new AccelerateInterpolator(1.5f);
TypedArray a = context.getTheme().obtainStyledAttributes(
com.android.internal.R.styleable.Theme);
mUseDynamicTranslucency = !a.hasValue(
@@ -141,15 +144,17 @@ public class SwipeDismissLayout extends FrameLayout {
getViewTreeObserver().addOnEnterAnimationCompleteListener(
mOnEnterAnimationCompleteListener);
}
+ getContext().registerReceiver(mScreenOffReceiver, mScreenOffFilter);
}
@Override
protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
+ getContext().unregisterReceiver(mScreenOffReceiver);
if (getContext() instanceof Activity) {
getViewTreeObserver().removeOnEnterAnimationCompleteListener(
mOnEnterAnimationCompleteListener);
}
+ super.onDetachedFromWindow();
}
@Override