use of android.util.SparseIntArray in project AndroidChromium by JackyAndroid.
the class TabPersistentStore method mergeState.
/**
* Merge the tabs of the other Chrome instance into this instance by reading its tab metadata
* file and tab state files.
*
* This method should be called after a change in activity state indicates that a merge is
* necessary. #loadState() will take care of merging states on application cold start if needed.
*
* If there is currently a merge or load in progress then this method will return early.
*/
public void mergeState() {
if (mLoadInProgress || mPersistencePolicy.isMergeInProgress() || !mTabsToRestore.isEmpty()) {
Log.e(TAG, "Tab load still in progress when merge was attempted.");
return;
}
// Initialize variables.
mCancelNormalTabLoads = false;
mCancelIncognitoTabLoads = false;
mNormalTabsRestored = new SparseIntArray();
mIncognitoTabsRestored = new SparseIntArray();
try {
long time = SystemClock.uptimeMillis();
// Read the tab state metadata file.
DataInputStream stream = startFetchTabListTask(AsyncTask.SERIAL_EXECUTOR, mPersistencePolicy.getStateToBeMergedFileName()).get();
// to merge.
if (stream == null)
return;
logExecutionTime("MergeStateInternalFetchTime", time);
mPersistencePolicy.setMergeInProgress(true);
readSavedStateFile(stream, createOnTabStateReadCallback(mTabModelSelector.isIncognitoSelected(), true), null, true);
logExecutionTime("MergeStateInternalTime", time);
} catch (Exception e) {
// Catch generic exception to prevent a corrupted state from crashing app.
Log.d(TAG, "meregeState exception: " + e.toString(), e);
}
// Restore the tabs from the second activity asynchronously.
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... voids) {
mMergeTabCount = mTabsToRestore.size();
mRestoreMergedTabsStartTime = SystemClock.uptimeMillis();
restoreTabs(false);
return null;
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
use of android.util.SparseIntArray in project AndroidChromium by JackyAndroid.
the class TabPersistentStore method restoreTab.
private void restoreTab(TabRestoreDetails tabToRestore, TabState tabState, boolean setAsActive) {
// If we don't have enough information about the Tab, bail out.
boolean isIncognito = isIncognitoTabBeingRestored(tabToRestore, tabState);
if (tabState == null) {
if (tabToRestore.isIncognito == null) {
Log.w(TAG, "Failed to restore tab: not enough info about its type was available.");
return;
} else if (isIncognito) {
Log.i(TAG, "Failed to restore Incognito tab: its TabState could not be restored.");
return;
}
}
TabModel model = mTabModelSelector.getModel(isIncognito);
SparseIntArray restoredTabs = isIncognito ? mIncognitoTabsRestored : mNormalTabsRestored;
int restoredIndex = 0;
if (tabToRestore.fromMerge) {
// Put any tabs being merged into this list at the end.
restoredIndex = mTabModelSelector.getModel(isIncognito).getCount();
} else if (restoredTabs.size() > 0 && tabToRestore.originalIndex > restoredTabs.keyAt(restoredTabs.size() - 1)) {
// If the tab's index is too large, restore it at the end of the list.
restoredIndex = restoredTabs.size();
} else {
// Otherwise try to find the tab we should restore before, if any.
for (int i = 0; i < restoredTabs.size(); i++) {
if (restoredTabs.keyAt(i) > tabToRestore.originalIndex) {
Tab nextTabByIndex = TabModelUtils.getTabById(model, restoredTabs.valueAt(i));
restoredIndex = nextTabByIndex != null ? model.indexOf(nextTabByIndex) : -1;
break;
}
}
}
int tabId = tabToRestore.id;
if (tabState != null) {
mTabCreatorManager.getTabCreator(isIncognito).createFrozenTab(tabState, tabToRestore.id, restoredIndex);
} else {
Log.w(TAG, "Failed to restore TabState; creating Tab with last known URL.");
Tab fallbackTab = mTabCreatorManager.getTabCreator(isIncognito).createNewTab(new LoadUrlParams(tabToRestore.url), TabModel.TabLaunchType.FROM_RESTORE, null);
tabId = fallbackTab.getId();
model.moveTab(tabId, restoredIndex);
}
// was selected in the other model before the merge should be selected after the merge.
if (setAsActive || (tabToRestore.fromMerge && restoredIndex == 0)) {
boolean wasIncognitoTabModelSelected = mTabModelSelector.isIncognitoSelected();
int selectedModelTabCount = mTabModelSelector.getCurrentModel().getCount();
TabModelUtils.setIndex(model, TabModelUtils.getTabIndexById(model, tabId));
boolean isIncognitoTabModelSelected = mTabModelSelector.isIncognitoSelected();
// view on tablets).
if (tabToRestore.fromMerge && wasIncognitoTabModelSelected != isIncognitoTabModelSelected && selectedModelTabCount != 0) {
mTabModelSelector.selectModel(wasIncognitoTabModelSelected);
}
}
restoredTabs.put(tabToRestore.originalIndex, tabId);
}
use of android.util.SparseIntArray in project android_frameworks_base by DirtyUnicorns.
the class AppOpsService method setUidMode.
@Override
public void setUidMode(int code, int uid, int mode) {
if (Binder.getCallingPid() != Process.myPid()) {
mContext.enforcePermission(android.Manifest.permission.UPDATE_APP_OPS_STATS, Binder.getCallingPid(), Binder.getCallingUid(), null);
}
verifyIncomingOp(code);
code = AppOpsManager.opToSwitch(code);
synchronized (this) {
final int defaultMode = AppOpsManager.opToDefaultMode(code);
UidState uidState = getUidStateLocked(uid, false);
if (uidState == null) {
if (mode == defaultMode) {
return;
}
uidState = new UidState(uid);
uidState.opModes = new SparseIntArray();
uidState.opModes.put(code, mode);
mUidStates.put(uid, uidState);
scheduleWriteLocked();
} else if (uidState.opModes == null) {
if (mode != defaultMode) {
uidState.opModes = new SparseIntArray();
uidState.opModes.put(code, mode);
scheduleWriteLocked();
}
} else {
if (uidState.opModes.get(code) == mode) {
return;
}
if (mode == defaultMode) {
uidState.opModes.delete(code);
if (uidState.opModes.size() <= 0) {
uidState.opModes = null;
}
} else {
uidState.opModes.put(code, mode);
}
scheduleWriteLocked();
}
}
String[] uidPackageNames = getPackagesForUid(uid);
ArrayMap<Callback, ArraySet<String>> callbackSpecs = null;
synchronized (this) {
ArrayList<Callback> callbacks = mOpModeWatchers.get(code);
if (callbacks != null) {
final int callbackCount = callbacks.size();
for (int i = 0; i < callbackCount; i++) {
Callback callback = callbacks.get(i);
ArraySet<String> changedPackages = new ArraySet<>();
Collections.addAll(changedPackages, uidPackageNames);
callbackSpecs = new ArrayMap<>();
callbackSpecs.put(callback, changedPackages);
}
}
for (String uidPackageName : uidPackageNames) {
callbacks = mPackageModeWatchers.get(uidPackageName);
if (callbacks != null) {
if (callbackSpecs == null) {
callbackSpecs = new ArrayMap<>();
}
final int callbackCount = callbacks.size();
for (int i = 0; i < callbackCount; i++) {
Callback callback = callbacks.get(i);
ArraySet<String> changedPackages = callbackSpecs.get(callback);
if (changedPackages == null) {
changedPackages = new ArraySet<>();
callbackSpecs.put(callback, changedPackages);
}
changedPackages.add(uidPackageName);
}
}
}
}
if (callbackSpecs == null) {
return;
}
// There are components watching for mode changes such as window manager
// and location manager which are in our process. The callbacks in these
// components may require permissions our remote caller does not have.
final long identity = Binder.clearCallingIdentity();
try {
for (int i = 0; i < callbackSpecs.size(); i++) {
Callback callback = callbackSpecs.keyAt(i);
ArraySet<String> reportedPackageNames = callbackSpecs.valueAt(i);
try {
if (reportedPackageNames == null) {
callback.mCallback.opChanged(code, uid, null);
} else {
final int reportedPackageCount = reportedPackageNames.size();
for (int j = 0; j < reportedPackageCount; j++) {
String reportedPackageName = reportedPackageNames.valueAt(j);
callback.mCallback.opChanged(code, uid, reportedPackageName);
}
}
} catch (RemoteException e) {
Log.w(TAG, "Error dispatching op op change", e);
}
}
} finally {
Binder.restoreCallingIdentity(identity);
}
}
use of android.util.SparseIntArray in project android_frameworks_base by DirtyUnicorns.
the class AppOpsService method writeState.
void writeState() {
synchronized (mFile) {
FileOutputStream stream;
try {
stream = mFile.startWrite();
} catch (IOException e) {
Slog.w(TAG, "Failed to write state: " + e);
return;
}
SparseArray<UidState> outUidStates = null;
synchronized (this) {
final int uidStateCount = mUidStates.size();
for (int i = 0; i < uidStateCount; i++) {
UidState uidState = mUidStates.valueAt(i);
SparseIntArray opModes = uidState.opModes;
if (opModes != null && opModes.size() > 0) {
UidState outUidState = new UidState(uidState.uid);
outUidState.opModes = opModes.clone();
if (outUidStates == null) {
outUidStates = new SparseArray<>();
}
outUidStates.put(mUidStates.keyAt(i), outUidState);
}
}
}
List<AppOpsManager.PackageOps> allOps = getPackagesForOps(null);
try {
XmlSerializer out = new FastXmlSerializer();
out.setOutput(stream, StandardCharsets.UTF_8.name());
out.startDocument(null, true);
out.startTag(null, "app-ops");
final int uidStateCount = outUidStates != null ? outUidStates.size() : 0;
for (int i = 0; i < uidStateCount; i++) {
UidState uidState = outUidStates.valueAt(i);
if (uidState.opModes != null && uidState.opModes.size() > 0) {
out.startTag(null, "uid");
out.attribute(null, "n", Integer.toString(uidState.uid));
SparseIntArray uidOpModes = uidState.opModes;
final int opCount = uidOpModes.size();
for (int j = 0; j < opCount; j++) {
final int op = uidOpModes.keyAt(j);
final int mode = uidOpModes.valueAt(j);
out.startTag(null, "op");
out.attribute(null, "n", Integer.toString(op));
out.attribute(null, "m", Integer.toString(mode));
out.endTag(null, "op");
}
out.endTag(null, "uid");
}
}
if (allOps != null) {
String lastPkg = null;
for (int i = 0; i < allOps.size(); i++) {
AppOpsManager.PackageOps pkg = allOps.get(i);
if (!pkg.getPackageName().equals(lastPkg)) {
if (lastPkg != null) {
out.endTag(null, "pkg");
}
lastPkg = pkg.getPackageName();
out.startTag(null, "pkg");
out.attribute(null, "n", lastPkg);
}
out.startTag(null, "uid");
out.attribute(null, "n", Integer.toString(pkg.getUid()));
synchronized (this) {
Ops ops = getOpsRawLocked(pkg.getUid(), pkg.getPackageName(), false);
// from Ops.
if (ops != null) {
out.attribute(null, "p", Boolean.toString(ops.isPrivileged));
} else {
out.attribute(null, "p", Boolean.toString(false));
}
}
List<AppOpsManager.OpEntry> ops = pkg.getOps();
for (int j = 0; j < ops.size(); j++) {
AppOpsManager.OpEntry op = ops.get(j);
out.startTag(null, "op");
out.attribute(null, "n", Integer.toString(op.getOp()));
if (op.getMode() != AppOpsManager.opToDefaultMode(op.getOp())) {
out.attribute(null, "m", Integer.toString(op.getMode()));
}
long time = op.getTime();
if (time != 0) {
out.attribute(null, "t", Long.toString(time));
}
time = op.getRejectTime();
if (time != 0) {
out.attribute(null, "r", Long.toString(time));
}
int dur = op.getDuration();
if (dur != 0) {
out.attribute(null, "d", Integer.toString(dur));
}
int proxyUid = op.getProxyUid();
if (proxyUid != -1) {
out.attribute(null, "pu", Integer.toString(proxyUid));
}
String proxyPackageName = op.getProxyPackageName();
if (proxyPackageName != null) {
out.attribute(null, "pp", proxyPackageName);
}
out.endTag(null, "op");
}
out.endTag(null, "uid");
}
if (lastPkg != null) {
out.endTag(null, "pkg");
}
}
out.endTag(null, "app-ops");
out.endDocument();
mFile.finishWrite(stream);
} catch (IOException e) {
Slog.w(TAG, "Failed to write state, restoring backup.", e);
mFile.failWrite(stream);
}
}
}
use of android.util.SparseIntArray in project android_frameworks_base by DirtyUnicorns.
the class AppOpsService method dump.
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) != PackageManager.PERMISSION_GRANTED) {
pw.println("Permission Denial: can't dump ApOps service from from pid=" + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
return;
}
if (args != null) {
for (int i = 0; i < args.length; i++) {
String arg = args[i];
if ("-h".equals(arg)) {
dumpHelp(pw);
return;
} else if ("-a".equals(arg)) {
// dump all data
} else if (arg.length() > 0 && arg.charAt(0) == '-') {
pw.println("Unknown option: " + arg);
return;
} else {
pw.println("Unknown command: " + arg);
return;
}
}
}
synchronized (this) {
pw.println("Current AppOps Service state:");
final long now = System.currentTimeMillis();
boolean needSep = false;
if (mOpModeWatchers.size() > 0) {
needSep = true;
pw.println(" Op mode watchers:");
for (int i = 0; i < mOpModeWatchers.size(); i++) {
pw.print(" Op ");
pw.print(AppOpsManager.opToName(mOpModeWatchers.keyAt(i)));
pw.println(":");
ArrayList<Callback> callbacks = mOpModeWatchers.valueAt(i);
for (int j = 0; j < callbacks.size(); j++) {
pw.print(" #");
pw.print(j);
pw.print(": ");
pw.println(callbacks.get(j));
}
}
}
if (mPackageModeWatchers.size() > 0) {
needSep = true;
pw.println(" Package mode watchers:");
for (int i = 0; i < mPackageModeWatchers.size(); i++) {
pw.print(" Pkg ");
pw.print(mPackageModeWatchers.keyAt(i));
pw.println(":");
ArrayList<Callback> callbacks = mPackageModeWatchers.valueAt(i);
for (int j = 0; j < callbacks.size(); j++) {
pw.print(" #");
pw.print(j);
pw.print(": ");
pw.println(callbacks.get(j));
}
}
}
if (mModeWatchers.size() > 0) {
needSep = true;
pw.println(" All mode watchers:");
for (int i = 0; i < mModeWatchers.size(); i++) {
pw.print(" ");
pw.print(mModeWatchers.keyAt(i));
pw.print(" -> ");
pw.println(mModeWatchers.valueAt(i));
}
}
if (mClients.size() > 0) {
needSep = true;
pw.println(" Clients:");
for (int i = 0; i < mClients.size(); i++) {
pw.print(" ");
pw.print(mClients.keyAt(i));
pw.println(":");
ClientState cs = mClients.valueAt(i);
pw.print(" ");
pw.println(cs);
if (cs.mStartedOps != null && cs.mStartedOps.size() > 0) {
pw.println(" Started ops:");
for (int j = 0; j < cs.mStartedOps.size(); j++) {
Op op = cs.mStartedOps.get(j);
pw.print(" ");
pw.print("uid=");
pw.print(op.uid);
pw.print(" pkg=");
pw.print(op.packageName);
pw.print(" op=");
pw.println(AppOpsManager.opToName(op.op));
}
}
}
}
if (mAudioRestrictions.size() > 0) {
boolean printedHeader = false;
for (int o = 0; o < mAudioRestrictions.size(); o++) {
final String op = AppOpsManager.opToName(mAudioRestrictions.keyAt(o));
final SparseArray<Restriction> restrictions = mAudioRestrictions.valueAt(o);
for (int i = 0; i < restrictions.size(); i++) {
if (!printedHeader) {
pw.println(" Audio Restrictions:");
printedHeader = true;
needSep = true;
}
final int usage = restrictions.keyAt(i);
pw.print(" ");
pw.print(op);
pw.print(" usage=");
pw.print(AudioAttributes.usageToString(usage));
Restriction r = restrictions.valueAt(i);
pw.print(": mode=");
pw.println(r.mode);
if (!r.exceptionPackages.isEmpty()) {
pw.println(" Exceptions:");
for (int j = 0; j < r.exceptionPackages.size(); j++) {
pw.print(" ");
pw.println(r.exceptionPackages.valueAt(j));
}
}
}
}
}
if (needSep) {
pw.println();
}
for (int i = 0; i < mUidStates.size(); i++) {
UidState uidState = mUidStates.valueAt(i);
pw.print(" Uid ");
UserHandle.formatUid(pw, uidState.uid);
pw.println(":");
SparseIntArray opModes = uidState.opModes;
if (opModes != null) {
final int opModeCount = opModes.size();
for (int j = 0; j < opModeCount; j++) {
final int code = opModes.keyAt(j);
final int mode = opModes.valueAt(j);
pw.print(" ");
pw.print(AppOpsManager.opToName(code));
pw.print(": mode=");
pw.println(mode);
}
}
ArrayMap<String, Ops> pkgOps = uidState.pkgOps;
if (pkgOps == null) {
continue;
}
for (Ops ops : pkgOps.values()) {
pw.print(" Package ");
pw.print(ops.packageName);
pw.println(":");
for (int j = 0; j < ops.size(); j++) {
Op op = ops.valueAt(j);
pw.print(" ");
pw.print(AppOpsManager.opToName(op.op));
pw.print(": mode=");
pw.print(op.mode);
if (op.time != 0) {
pw.print("; time=");
TimeUtils.formatDuration(now - op.time, pw);
pw.print(" ago");
}
if (op.rejectTime != 0) {
pw.print("; rejectTime=");
TimeUtils.formatDuration(now - op.rejectTime, pw);
pw.print(" ago");
}
if (op.duration == -1) {
pw.print(" (running)");
} else if (op.duration != 0) {
pw.print("; duration=");
TimeUtils.formatDuration(op.duration, pw);
}
pw.println();
}
}
}
}
}
Aggregations