summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
Diffstat (limited to 'services')
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java108
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java9
-rw-r--r--services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java38
3 files changed, 126 insertions, 29 deletions
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index cdaa5a3..8895a15 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -1124,7 +1124,7 @@ public final class ActivityManagerService extends ActivityManagerNative
boolean mAutoStopProfiler = false;
int mProfileType = 0;
String mOpenGlTraceApp = null;
- final ArrayMap<String, Long> mMemWatchProcesses = new ArrayMap<>();
+ final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
String mMemWatchDumpProcName;
String mMemWatchDumpFile;
int mMemWatchDumpPid;
@@ -1830,11 +1830,21 @@ public final class ActivityManagerService extends ActivityManagerNative
final String procName;
final int uid;
final long memLimit;
+ final String reportPackage;
synchronized (ActivityManagerService.this) {
procName = mMemWatchDumpProcName;
uid = mMemWatchDumpUid;
- Long limit = mMemWatchProcesses.get(procName);
- memLimit = limit != null ? limit : 0;
+ Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
+ if (val == null) {
+ val = mMemWatchProcesses.get(procName, 0);
+ }
+ if (val != null) {
+ memLimit = val.first;
+ reportPackage = val.second;
+ } else {
+ memLimit = 0;
+ reportPackage = null;
+ }
}
if (procName == null) {
return;
@@ -1867,6 +1877,9 @@ public final class ActivityManagerService extends ActivityManagerNative
intent.setClassName("android", DumpHeapActivity.class.getName());
intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
+ if (reportPackage != null) {
+ intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
+ }
int userId = UserHandle.getUserId(uid);
notification.setLatestEventInfo(mContext, text,
mContext.getText(R.string.dump_heap_notification_detail),
@@ -2474,11 +2487,19 @@ public final class ActivityManagerService extends ActivityManagerNative
final void setFocusedActivityLocked(ActivityRecord r, String reason) {
if (r != null && mFocusedActivity != r) {
if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
+ ActivityRecord last = mFocusedActivity;
mFocusedActivity = r;
if (r.task != null && r.task.voiceInteractor != null) {
startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
} else {
finishRunningVoiceLocked();
+ if (last != null && last.task.voiceSession != null) {
+ // We had been in a voice interaction session, but now focused has
+ // move to something different. Just finish the session, we can't
+ // return to it and retain the proper state and synchronization with
+ // the voice interaction service.
+ finishVoiceTask(last.task.voiceSession);
+ }
}
if (mStackSupervisor.setFocusedStack(r, reason + " setFocusedActivity")) {
mWindowManager.setFocusedApp(r.appToken, true);
@@ -12856,16 +12877,28 @@ public final class ActivityManagerService extends ActivityManagerNative
+ " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
}
}
- if (mMemWatchProcesses.size() > 0) {
+ if (mMemWatchProcesses.getMap().size() > 0) {
pw.println(" Mem watch processes:");
- for (int i=0; i<mMemWatchProcesses.size(); i++) {
- if (needSep) {
- pw.println();
- needSep = false;
+ final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
+ = mMemWatchProcesses.getMap();
+ for (int i=0; i<procs.size(); i++) {
+ final String proc = procs.keyAt(i);
+ final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
+ for (int j=0; j<uids.size(); j++) {
+ if (needSep) {
+ pw.println();
+ needSep = false;
+ }
+ StringBuilder sb = new StringBuilder();
+ sb.append(" ").append(proc).append('/');
+ UserHandle.formatUid(sb, uids.keyAt(j));
+ Pair<Long, String> val = uids.valueAt(i);
+ sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
+ if (val.second != null) {
+ sb.append(", report to ").append(val.second);
+ }
+ pw.println(sb.toString());
}
- pw.print(" "); pw.print(mMemWatchProcesses.keyAt(i));
- pw.print(": "); DebugUtils.printSizeValue(pw, mMemWatchProcesses.valueAt(i));
- pw.println();
}
pw.print(" mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
pw.print(" mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
@@ -17390,7 +17423,18 @@ public final class ActivityManagerService extends ActivityManagerNative
proc.lastCachedPss = pss;
}
- Long check = mMemWatchProcesses.get(proc.processName);
+ final SparseArray<Pair<Long, String>> watchUids
+ = mMemWatchProcesses.getMap().get(proc.processName);
+ Long check = null;
+ if (watchUids != null) {
+ Pair<Long, String> val = watchUids.get(proc.uid);
+ if (val == null) {
+ val = watchUids.get(0);
+ }
+ if (val != null) {
+ check = val.first;
+ }
+ }
if (check != null) {
if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
@@ -17426,7 +17470,8 @@ public final class ActivityManagerService extends ActivityManagerNative
IApplicationThread thread = myProc.thread;
if (thread != null) {
try {
- if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting dump heap from "
+ if (true || DEBUG_PSS) Slog.d(TAG_PSS,
+ "Requesting dump heap from "
+ myProc + " to " + heapdumpFile);
thread.dumpHeap(true, heapdumpFile.toString(), fd);
} catch (RemoteException e) {
@@ -18661,15 +18706,38 @@ public final class ActivityManagerService extends ActivityManagerNative
}
@Override
- public void setDumpHeapDebugLimit(String processName, long maxMemSize) {
- enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
- "setDumpHeapDebugLimit()");
+ public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
+ String reportPackage) {
+ if (processName != null) {
+ enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
+ "setDumpHeapDebugLimit()");
+ } else {
+ if (!Build.IS_DEBUGGABLE) {
+ throw new SecurityException("Not running a debuggable build");
+ }
+ synchronized (mPidsSelfLocked) {
+ ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
+ if (proc == null) {
+ throw new SecurityException("No process found for calling pid "
+ + Binder.getCallingPid());
+ }
+ processName = proc.processName;
+ uid = proc.uid;
+ if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
+ throw new SecurityException("Package " + reportPackage + " is not running in "
+ + proc);
+ }
+ }
+ }
synchronized (this) {
if (maxMemSize > 0) {
- mMemWatchProcesses.put(processName, maxMemSize);
- mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
+ mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
} else {
- mMemWatchProcesses.remove(processName);
+ if (uid != 0) {
+ mMemWatchProcesses.remove(processName, uid);
+ } else {
+ mMemWatchProcesses.getMap().remove(processName);
+ }
}
}
}
@@ -18687,7 +18755,7 @@ public final class ActivityManagerService extends ActivityManagerNative
+ " does not match last path " + mMemWatchDumpFile);
return;
}
- if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
+ if (true || DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
}
}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
index 1aa0d0b..bca757b 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerServiceImpl.java
@@ -145,7 +145,10 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne
}
public boolean hideSessionLocked(int callingPid, int callingUid) {
- return mActiveSession.hideLocked();
+ if (mActiveSession != null) {
+ return mActiveSession.hideLocked();
+ }
+ return false;
}
public boolean deliverNewSessionLocked(int callingPid, int callingUid, IBinder token,
@@ -165,6 +168,10 @@ class VoiceInteractionManagerServiceImpl implements VoiceInteractionSessionConne
Slog.w(TAG, "startVoiceActivity does not match active session");
return ActivityManager.START_CANCELED;
}
+ if (!mActiveSession.mShown) {
+ Slog.w(TAG, "startVoiceActivity not allowed on hidden session");
+ return ActivityManager.START_CANCELED;
+ }
intent = new Intent(intent);
intent.addCategory(Intent.CATEGORY_VOICE);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
index 73c7363..607df2d 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionSessionConnection.java
@@ -18,6 +18,7 @@ package com.android.server.voiceinteraction;
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
+import android.app.AppOpsManager;
import android.app.AssistContent;
import android.app.IActivityManager;
import android.content.ClipData;
@@ -62,6 +63,7 @@ final class VoiceInteractionSessionConnection implements ServiceConnection {
final int mCallingUid;
final IActivityManager mAm;
final IWindowManager mIWindowManager;
+ final AppOpsManager mAppOps;
final IBinder mPermissionOwner;
boolean mShown;
Bundle mShowArgs;
@@ -148,6 +150,7 @@ final class VoiceInteractionSessionConnection implements ServiceConnection {
mAm = ActivityManagerNative.getDefault();
mIWindowManager = IWindowManager.Stub.asInterface(
ServiceManager.getService(Context.WINDOW_SERVICE));
+ mAppOps = context.getSystemService(AppOpsManager.class);
IBinder permOwner = null;
try {
permOwner = mAm.newUriPermissionOwner("voicesession:"
@@ -159,7 +162,8 @@ final class VoiceInteractionSessionConnection implements ServiceConnection {
mBindIntent = new Intent(VoiceInteractionService.SERVICE_INTERFACE);
mBindIntent.setComponent(mSessionComponentName);
mBound = mContext.bindServiceAsUser(mBindIntent, this,
- Context.BIND_AUTO_CREATE|Context.BIND_ALLOW_OOM_MANAGEMENT, new UserHandle(mUser));
+ Context.BIND_AUTO_CREATE|Context.BIND_WAIVE_PRIORITY
+ |Context.BIND_ALLOW_OOM_MANAGEMENT, new UserHandle(mUser));
if (mBound) {
try {
mIWindowManager.addWindowToken(mToken,
@@ -186,19 +190,31 @@ final class VoiceInteractionSessionConnection implements ServiceConnection {
mShowFlags = flags;
mHaveAssistData = false;
if ((flags&VoiceInteractionService.START_WITH_ASSIST) != 0) {
- try {
- mAm.requestAssistContextExtras(ActivityManager.ASSIST_CONTEXT_FULL,
- mAssistReceiver);
- } catch (RemoteException e) {
+ if (mAppOps.noteOpNoThrow(AppOpsManager.OP_ASSIST_STRUCTURE, mCallingUid,
+ mSessionComponentName.getPackageName()) == AppOpsManager.MODE_ALLOWED) {
+ try {
+ mAm.requestAssistContextExtras(ActivityManager.ASSIST_CONTEXT_FULL,
+ mAssistReceiver);
+ } catch (RemoteException e) {
+ }
+ } else {
+ mHaveAssistData = true;
+ mAssistData = null;
}
} else {
mAssistData = null;
}
mHaveScreenshot = false;
if ((flags&VoiceInteractionService.START_WITH_SCREENSHOT) != 0) {
- try {
- mIWindowManager.requestAssistScreenshot(mScreenshotReceiver);
- } catch (RemoteException e) {
+ if (mAppOps.noteOpNoThrow(AppOpsManager.OP_ASSIST_SCREENSHOT, mCallingUid,
+ mSessionComponentName.getPackageName()) == AppOpsManager.MODE_ALLOWED) {
+ try {
+ mIWindowManager.requestAssistScreenshot(mScreenshotReceiver);
+ } catch (RemoteException e) {
+ }
+ } else {
+ mHaveScreenshot = true;
+ mScreenshot = null;
}
} else {
mScreenshot = null;
@@ -335,6 +351,12 @@ final class VoiceInteractionSessionConnection implements ServiceConnection {
mUser);
} catch (RemoteException e) {
}
+ if (mSession != null) {
+ try {
+ mAm.finishVoiceTask(mSession);
+ } catch (RemoteException e) {
+ }
+ }
}
if (mFullyBound) {
mContext.unbindService(mFullConnection);