diff options
Diffstat (limited to 'services')
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); |