am 1668b19d: Merge "Battery stats tweaks."
* commit '1668b19d4ce7361144a6668b52434508d8311ab2': Battery stats tweaks.
This commit is contained in:
@@ -21,6 +21,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Formatter;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -30,6 +31,8 @@ import android.telephony.SignalStrength;
|
||||
import android.text.format.DateFormat;
|
||||
import android.util.Printer;
|
||||
import android.util.SparseArray;
|
||||
import android.util.SparseBooleanArray;
|
||||
import android.util.SparseIntArray;
|
||||
import android.util.TimeUtils;
|
||||
import com.android.internal.os.BatterySipper;
|
||||
import com.android.internal.os.BatteryStatsHelper;
|
||||
@@ -537,6 +540,7 @@ public abstract class BatteryStats implements Parcelable {
|
||||
public static final byte CMD_START = 4;
|
||||
public static final byte CMD_CURRENT_TIME = 5;
|
||||
public static final byte CMD_OVERFLOW = 6;
|
||||
public static final byte CMD_RESET = 7;
|
||||
|
||||
public byte cmd = CMD_NULL;
|
||||
|
||||
@@ -620,6 +624,8 @@ public abstract class BatteryStats implements Parcelable {
|
||||
public static final int EVENT_SYNC = 0x0004;
|
||||
// Number of event types.
|
||||
public static final int EVENT_COUNT = 0x0005;
|
||||
// Mask to extract out only the type part of the event.
|
||||
public static final int EVENT_TYPE_MASK = ~(EVENT_FLAG_START|EVENT_FLAG_FINISH);
|
||||
|
||||
public static final int EVENT_PROC_START = EVENT_PROC | EVENT_FLAG_START;
|
||||
public static final int EVENT_PROC_FINISH = EVENT_PROC | EVENT_FLAG_FINISH;
|
||||
@@ -684,7 +690,7 @@ public abstract class BatteryStats implements Parcelable {
|
||||
dest.writeInt(eventCode);
|
||||
eventTag.writeToParcel(dest, flags);
|
||||
}
|
||||
if (cmd == CMD_CURRENT_TIME) {
|
||||
if (cmd == CMD_CURRENT_TIME || cmd == CMD_RESET) {
|
||||
dest.writeLong(currentTime);
|
||||
}
|
||||
}
|
||||
@@ -722,7 +728,7 @@ public abstract class BatteryStats implements Parcelable {
|
||||
eventCode = EVENT_NONE;
|
||||
eventTag = null;
|
||||
}
|
||||
if (cmd == CMD_CURRENT_TIME) {
|
||||
if (cmd == CMD_CURRENT_TIME || cmd == CMD_RESET) {
|
||||
currentTime = src.readLong();
|
||||
} else {
|
||||
currentTime = 0;
|
||||
@@ -833,7 +839,59 @@ public abstract class BatteryStats implements Parcelable {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public final static class HistoryEventTracker {
|
||||
private final HashMap<String, SparseIntArray>[] mActiveEvents
|
||||
= (HashMap<String, SparseIntArray>[]) new HashMap[HistoryItem.EVENT_COUNT];
|
||||
|
||||
public boolean updateState(int code, String name, int uid, int poolIdx) {
|
||||
if ((code&HistoryItem.EVENT_FLAG_START) != 0) {
|
||||
int idx = code&HistoryItem.EVENT_TYPE_MASK;
|
||||
HashMap<String, SparseIntArray> active = mActiveEvents[idx];
|
||||
if (active == null) {
|
||||
active = new HashMap<String, SparseIntArray>();
|
||||
mActiveEvents[idx] = active;
|
||||
}
|
||||
SparseIntArray uids = active.get(name);
|
||||
if (uids == null) {
|
||||
uids = new SparseIntArray();
|
||||
active.put(name, uids);
|
||||
}
|
||||
if (uids.indexOfKey(uid) >= 0) {
|
||||
// Already set, nothing to do!
|
||||
return false;
|
||||
}
|
||||
uids.put(uid, poolIdx);
|
||||
} else if ((code&HistoryItem.EVENT_FLAG_FINISH) != 0) {
|
||||
int idx = code&HistoryItem.EVENT_TYPE_MASK;
|
||||
HashMap<String, SparseIntArray> active = mActiveEvents[idx];
|
||||
if (active == null) {
|
||||
// not currently active, nothing to do.
|
||||
return false;
|
||||
}
|
||||
SparseIntArray uids = active.get(name);
|
||||
if (uids == null) {
|
||||
// not currently active, nothing to do.
|
||||
return false;
|
||||
}
|
||||
idx = uids.indexOfKey(uid);
|
||||
if (idx < 0) {
|
||||
// not currently active, nothing to do.
|
||||
return false;
|
||||
}
|
||||
uids.removeAt(idx);
|
||||
if (uids.size() <= 0) {
|
||||
active.remove(name);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public HashMap<String, SparseIntArray> getStateForEvent(int code) {
|
||||
return mActiveEvents[code];
|
||||
}
|
||||
}
|
||||
|
||||
public static final class BitDescription {
|
||||
public final int mask;
|
||||
public final int shift;
|
||||
@@ -861,7 +919,7 @@ public abstract class BatteryStats implements Parcelable {
|
||||
this.shortValues = shortValues;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public abstract int getHistoryTotalSize();
|
||||
|
||||
public abstract int getHistoryUsedSize();
|
||||
@@ -2958,10 +3016,14 @@ public abstract class BatteryStats implements Parcelable {
|
||||
pw.print(":");
|
||||
}
|
||||
pw.println("START");
|
||||
} else if (rec.cmd == HistoryItem.CMD_CURRENT_TIME) {
|
||||
} else if (rec.cmd == HistoryItem.CMD_CURRENT_TIME
|
||||
|| rec.cmd == HistoryItem.CMD_RESET) {
|
||||
if (checkin) {
|
||||
pw.print(":");
|
||||
}
|
||||
if (rec.cmd == HistoryItem.CMD_RESET) {
|
||||
pw.print("RESET:");
|
||||
}
|
||||
pw.print("TIME:");
|
||||
if (checkin) {
|
||||
pw.println(rec.currentTime);
|
||||
@@ -3187,6 +3249,86 @@ public abstract class BatteryStats implements Parcelable {
|
||||
public static final int DUMP_INCLUDE_HISTORY = 1<<3;
|
||||
public static final int DUMP_VERBOSE = 1<<4;
|
||||
|
||||
private void dumpHistoryLocked(PrintWriter pw, int flags, long histStart, boolean checkin) {
|
||||
final HistoryPrinter hprinter = new HistoryPrinter();
|
||||
final HistoryItem rec = new HistoryItem();
|
||||
long lastTime = -1;
|
||||
long baseTime = -1;
|
||||
boolean printed = false;
|
||||
HistoryEventTracker tracker = null;
|
||||
while (getNextHistoryLocked(rec)) {
|
||||
lastTime = rec.time;
|
||||
if (baseTime < 0) {
|
||||
baseTime = lastTime;
|
||||
}
|
||||
if (rec.time >= histStart) {
|
||||
if (histStart >= 0 && !printed) {
|
||||
if (rec.cmd == HistoryItem.CMD_CURRENT_TIME
|
||||
|| rec.cmd == HistoryItem.CMD_RESET) {
|
||||
printed = true;
|
||||
} else if (rec.currentTime != 0) {
|
||||
printed = true;
|
||||
byte cmd = rec.cmd;
|
||||
rec.cmd = HistoryItem.CMD_CURRENT_TIME;
|
||||
if (checkin) {
|
||||
pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
|
||||
pw.print(HISTORY_DATA); pw.print(',');
|
||||
}
|
||||
hprinter.printNextItem(pw, rec, baseTime, checkin,
|
||||
(flags&DUMP_VERBOSE) != 0);
|
||||
rec.cmd = cmd;
|
||||
}
|
||||
if (tracker != null) {
|
||||
int oldCode = rec.eventCode;
|
||||
HistoryTag oldTag = rec.eventTag;
|
||||
rec.eventTag = new HistoryTag();
|
||||
for (int i=0; i<HistoryItem.EVENT_COUNT; i++) {
|
||||
HashMap<String, SparseIntArray> active
|
||||
= tracker.getStateForEvent(i);
|
||||
if (active == null) {
|
||||
continue;
|
||||
}
|
||||
for (HashMap.Entry<String, SparseIntArray> ent
|
||||
: active.entrySet()) {
|
||||
SparseIntArray uids = ent.getValue();
|
||||
for (int j=0; j<uids.size(); j++) {
|
||||
rec.eventCode = i;
|
||||
rec.eventTag.string = ent.getKey();
|
||||
rec.eventTag.uid = uids.keyAt(j);
|
||||
rec.eventTag.poolIdx = uids.valueAt(j);
|
||||
if (checkin) {
|
||||
pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
|
||||
pw.print(HISTORY_DATA); pw.print(',');
|
||||
}
|
||||
hprinter.printNextItem(pw, rec, baseTime, checkin,
|
||||
(flags&DUMP_VERBOSE) != 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
rec.eventCode = oldCode;
|
||||
rec.eventTag = oldTag;
|
||||
tracker = null;
|
||||
}
|
||||
}
|
||||
if (checkin) {
|
||||
pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
|
||||
pw.print(HISTORY_DATA); pw.print(',');
|
||||
}
|
||||
hprinter.printNextItem(pw, rec, baseTime, checkin,
|
||||
(flags&DUMP_VERBOSE) != 0);
|
||||
} else if (rec.eventCode != HistoryItem.EVENT_NONE) {
|
||||
if (tracker == null) {
|
||||
tracker = new HistoryEventTracker();
|
||||
}
|
||||
tracker.updateState(rec.eventCode, rec.eventTag.string,
|
||||
rec.eventTag.uid, rec.eventTag.poolIdx);
|
||||
}
|
||||
}
|
||||
if (histStart >= 0) {
|
||||
pw.print(checkin ? "NEXT: " : " NEXT: "); pw.println(lastTime+1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps a human-readable summary of the battery statistics to the given PrintWriter.
|
||||
*
|
||||
@@ -3200,9 +3342,6 @@ public abstract class BatteryStats implements Parcelable {
|
||||
(flags&(DUMP_HISTORY_ONLY|DUMP_UNPLUGGED_ONLY|DUMP_CHARGED_ONLY)) != 0;
|
||||
|
||||
if ((flags&DUMP_HISTORY_ONLY) != 0 || !filtering) {
|
||||
long now = getHistoryBaseTime() + SystemClock.elapsedRealtime();
|
||||
|
||||
final HistoryItem rec = new HistoryItem();
|
||||
final long historyTotalSize = getHistoryTotalSize();
|
||||
final long historyUsedSize = getHistoryUsedSize();
|
||||
if (startIteratingHistoryLocked()) {
|
||||
@@ -3218,35 +3357,7 @@ public abstract class BatteryStats implements Parcelable {
|
||||
pw.print(" strings using ");
|
||||
printSizeValue(pw, getHistoryStringPoolBytes());
|
||||
pw.println("):");
|
||||
HistoryPrinter hprinter = new HistoryPrinter();
|
||||
long lastTime = -1;
|
||||
long baseTime = -1;
|
||||
boolean printed = false;
|
||||
while (getNextHistoryLocked(rec)) {
|
||||
lastTime = rec.time;
|
||||
if (baseTime < 0) {
|
||||
baseTime = lastTime;
|
||||
}
|
||||
if (rec.time >= histStart) {
|
||||
if (histStart >= 0 && !printed) {
|
||||
if (rec.cmd == HistoryItem.CMD_CURRENT_TIME) {
|
||||
printed = true;
|
||||
} else if (rec.currentTime != 0) {
|
||||
printed = true;
|
||||
byte cmd = rec.cmd;
|
||||
rec.cmd = HistoryItem.CMD_CURRENT_TIME;
|
||||
hprinter.printNextItem(pw, rec, baseTime, false,
|
||||
(flags&DUMP_VERBOSE) != 0);
|
||||
rec.cmd = cmd;
|
||||
}
|
||||
}
|
||||
hprinter.printNextItem(pw, rec, baseTime, false,
|
||||
(flags&DUMP_VERBOSE) != 0);
|
||||
}
|
||||
}
|
||||
if (histStart >= 0) {
|
||||
pw.print(" NEXT: "); pw.println(lastTime+1);
|
||||
}
|
||||
dumpHistoryLocked(pw, flags, histStart, false);
|
||||
pw.println();
|
||||
} finally {
|
||||
finishIteratingHistoryLocked();
|
||||
@@ -3255,6 +3366,7 @@ public abstract class BatteryStats implements Parcelable {
|
||||
|
||||
if (startIteratingOldHistoryLocked()) {
|
||||
try {
|
||||
final HistoryItem rec = new HistoryItem();
|
||||
pw.println("Old battery History:");
|
||||
HistoryPrinter hprinter = new HistoryPrinter();
|
||||
long baseTime = -1;
|
||||
@@ -3348,7 +3460,6 @@ public abstract class BatteryStats implements Parcelable {
|
||||
(flags&(DUMP_HISTORY_ONLY|DUMP_UNPLUGGED_ONLY|DUMP_CHARGED_ONLY)) != 0;
|
||||
|
||||
if ((flags&DUMP_INCLUDE_HISTORY) != 0 || (flags&DUMP_HISTORY_ONLY) != 0) {
|
||||
final HistoryItem rec = new HistoryItem();
|
||||
if (startIteratingHistoryLocked()) {
|
||||
try {
|
||||
for (int i=0; i<getHistoryStringPoolSize(); i++) {
|
||||
@@ -3365,37 +3476,7 @@ public abstract class BatteryStats implements Parcelable {
|
||||
pw.print("\"");
|
||||
pw.println();
|
||||
}
|
||||
HistoryPrinter hprinter = new HistoryPrinter();
|
||||
long lastTime = -1;
|
||||
long baseTime = -1;
|
||||
boolean printed = false;
|
||||
while (getNextHistoryLocked(rec)) {
|
||||
lastTime = rec.time;
|
||||
if (baseTime < 0) {
|
||||
baseTime = lastTime;
|
||||
}
|
||||
if (rec.time >= histStart) {
|
||||
if (histStart >= 0 && !printed) {
|
||||
if (rec.cmd == HistoryItem.CMD_CURRENT_TIME) {
|
||||
printed = true;
|
||||
} else if (rec.currentTime != 0) {
|
||||
printed = true;
|
||||
byte cmd = rec.cmd;
|
||||
rec.cmd = HistoryItem.CMD_CURRENT_TIME;
|
||||
pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
|
||||
pw.print(HISTORY_DATA); pw.print(',');
|
||||
hprinter.printNextItem(pw, rec, baseTime, true, false);
|
||||
rec.cmd = cmd;
|
||||
}
|
||||
}
|
||||
pw.print(BATTERY_STATS_CHECKIN_VERSION); pw.print(',');
|
||||
pw.print(HISTORY_DATA); pw.print(',');
|
||||
hprinter.printNextItem(pw, rec, baseTime, true, false);
|
||||
}
|
||||
}
|
||||
if (histStart >= 0) {
|
||||
pw.print("NEXT: "); pw.println(lastTime+1);
|
||||
}
|
||||
dumpHistoryLocked(pw, flags, histStart, true);
|
||||
} finally {
|
||||
finishIteratingHistoryLocked();
|
||||
}
|
||||
|
||||
@@ -188,8 +188,7 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
|
||||
boolean mShuttingDown;
|
||||
|
||||
HashMap<String, SparseBooleanArray>[] mActiveEvents
|
||||
= (HashMap<String, SparseBooleanArray>[]) new HashMap[HistoryItem.EVENT_COUNT];
|
||||
final HistoryEventTracker mActiveEvents = new HistoryEventTracker();
|
||||
|
||||
long mHistoryBaseTime;
|
||||
boolean mHaveBatteryLevel = false;
|
||||
@@ -2297,44 +2296,8 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
|
||||
public void noteEventLocked(int code, String name, int uid) {
|
||||
uid = mapUid(uid);
|
||||
if ((code&HistoryItem.EVENT_FLAG_START) != 0) {
|
||||
int idx = code&~HistoryItem.EVENT_FLAG_START;
|
||||
HashMap<String, SparseBooleanArray> active = mActiveEvents[idx];
|
||||
if (active == null) {
|
||||
active = new HashMap<String, SparseBooleanArray>();
|
||||
mActiveEvents[idx] = active;
|
||||
}
|
||||
SparseBooleanArray uids = active.get(name);
|
||||
if (uids == null) {
|
||||
uids = new SparseBooleanArray();
|
||||
active.put(name, uids);
|
||||
}
|
||||
if (uids.get(uid)) {
|
||||
// Already set, nothing to do!
|
||||
return;
|
||||
}
|
||||
uids.put(uid, true);
|
||||
} else if ((code&HistoryItem.EVENT_FLAG_FINISH) != 0) {
|
||||
int idx = code&~HistoryItem.EVENT_FLAG_FINISH;
|
||||
HashMap<String, SparseBooleanArray> active = mActiveEvents[idx];
|
||||
if (active == null) {
|
||||
// not currently active, nothing to do.
|
||||
return;
|
||||
}
|
||||
SparseBooleanArray uids = active.get(name);
|
||||
if (uids == null) {
|
||||
// not currently active, nothing to do.
|
||||
return;
|
||||
}
|
||||
idx = uids.indexOfKey(uid);
|
||||
if (idx < 0 || !uids.valueAt(idx)) {
|
||||
// not currently active, nothing to do.
|
||||
return;
|
||||
}
|
||||
uids.removeAt(idx);
|
||||
if (uids.size() <= 0) {
|
||||
active.remove(name);
|
||||
}
|
||||
if (!mActiveEvents.updateState(code, name, uid, 0)) {
|
||||
return;
|
||||
}
|
||||
final long elapsedRealtime = SystemClock.elapsedRealtime();
|
||||
final long uptime = SystemClock.uptimeMillis();
|
||||
@@ -2348,6 +2311,9 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
}
|
||||
}
|
||||
|
||||
private String mInitialAcquireWakeName;
|
||||
private int mInitialAcquireWakeUid = -1;
|
||||
|
||||
public void noteStartWakeLocked(int uid, int pid, String name, String historyName, int type,
|
||||
boolean unimportantForLogging, long elapsedRealtime, long uptime) {
|
||||
uid = mapUid(uid);
|
||||
@@ -2360,8 +2326,9 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
if (DEBUG_HISTORY) Slog.v(TAG, "Start wake lock to: "
|
||||
+ Integer.toHexString(mHistoryCur.states));
|
||||
mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag;
|
||||
mHistoryCur.wakelockTag.string = historyName != null ? historyName : name;
|
||||
mHistoryCur.wakelockTag.uid = uid;
|
||||
mHistoryCur.wakelockTag.string = mInitialAcquireWakeName
|
||||
= historyName != null ? historyName : name;
|
||||
mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = uid;
|
||||
mWakeLockImportant = !unimportantForLogging;
|
||||
addHistoryRecordLocked(elapsedRealtime, uptime);
|
||||
} else if (!mWakeLockImportant && !unimportantForLogging) {
|
||||
@@ -2369,8 +2336,9 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
// We'll try to update the last tag.
|
||||
mHistoryLastWritten.wakelockTag = null;
|
||||
mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag;
|
||||
mHistoryCur.wakelockTag.string = historyName != null ? historyName : name;
|
||||
mHistoryCur.wakelockTag.uid = uid;
|
||||
mHistoryCur.wakelockTag.string = mInitialAcquireWakeName
|
||||
= historyName != null ? historyName : name;
|
||||
mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = uid;
|
||||
addHistoryRecordLocked(elapsedRealtime, uptime);
|
||||
}
|
||||
mWakeLockImportant = true;
|
||||
@@ -2395,6 +2363,14 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
mHistoryCur.states &= ~HistoryItem.STATE_WAKE_LOCK_FLAG;
|
||||
if (DEBUG_HISTORY) Slog.v(TAG, "Stop wake lock to: "
|
||||
+ Integer.toHexString(mHistoryCur.states));
|
||||
if ((name != null && !name.equals(mInitialAcquireWakeName))
|
||||
|| uid != mInitialAcquireWakeUid) {
|
||||
mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag;
|
||||
mHistoryCur.wakelockTag.string = name;
|
||||
mHistoryCur.wakelockTag.uid = uid;
|
||||
}
|
||||
mInitialAcquireWakeName = null;
|
||||
mInitialAcquireWakeUid = -1;
|
||||
addHistoryRecordLocked(elapsedRealtime, uptime);
|
||||
}
|
||||
}
|
||||
@@ -5699,7 +5675,8 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
final long lastRealtime = out.time;
|
||||
final long lastWalltime = out.currentTime;
|
||||
readHistoryDelta(mHistoryBuffer, out);
|
||||
if (out.cmd != HistoryItem.CMD_CURRENT_TIME && lastWalltime != 0) {
|
||||
if (out.cmd != HistoryItem.CMD_CURRENT_TIME
|
||||
&& out.cmd != HistoryItem.CMD_RESET && lastWalltime != 0) {
|
||||
out.currentTime = lastWalltime + (out.time - lastRealtime);
|
||||
}
|
||||
return true;
|
||||
@@ -5845,17 +5822,15 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
|
||||
private void initActiveHistoryEventsLocked(long elapsedRealtimeMs, long uptimeMs) {
|
||||
for (int i=0; i<HistoryItem.EVENT_COUNT; i++) {
|
||||
HashMap<String, SparseBooleanArray> active = mActiveEvents[i];
|
||||
HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent(i);
|
||||
if (active == null) {
|
||||
continue;
|
||||
}
|
||||
for (HashMap.Entry<String, SparseBooleanArray> ent : active.entrySet()) {
|
||||
SparseBooleanArray uids = ent.getValue();
|
||||
for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) {
|
||||
SparseIntArray uids = ent.getValue();
|
||||
for (int j=0; j<uids.size(); j++) {
|
||||
if (uids.valueAt(j)) {
|
||||
addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, i, ent.getKey(),
|
||||
uids.keyAt(j));
|
||||
}
|
||||
addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, i, ent.getKey(),
|
||||
uids.keyAt(j));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5971,7 +5946,8 @@ public final class BatteryStatsImpl extends BatteryStats {
|
||||
boolean reset) {
|
||||
mRecordingHistory = true;
|
||||
mHistoryCur.currentTime = System.currentTimeMillis();
|
||||
addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_CURRENT_TIME,
|
||||
addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs,
|
||||
reset ? HistoryItem.CMD_RESET : HistoryItem.CMD_CURRENT_TIME,
|
||||
mHistoryCur);
|
||||
mHistoryCur.currentTime = 0;
|
||||
if (reset) {
|
||||
|
||||
Reference in New Issue
Block a user